mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-02-26 08:07:06 +08:00
粒子初步
This commit is contained in:
parent
4d45553c84
commit
40e20d9b4f
@ -33,7 +33,8 @@ main.floors.MT36=
|
||||
"8,14": [
|
||||
"从本区域开始将会出现各种光环怪,这需要你认真思考解决办法",
|
||||
"注意坚固怪受到光环加成后可能无法被打败,因为会首先计算坚固属性再计算光环",
|
||||
"本区域的地图较为复杂,请善用楼传的小地图功能"
|
||||
"本区域的地图较为复杂,请善用楼传的小地图功能",
|
||||
"本区域的跳跃技能效果会比较奇怪()"
|
||||
]
|
||||
},
|
||||
"changeFloor": {
|
||||
|
@ -80,19 +80,19 @@ main.floors.MT42=
|
||||
"cannotMoveIn": {},
|
||||
"map": [
|
||||
[ 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[604, 0,617,604, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[ 92,611,604,604, 0, 0, 0, 0, 0,543, 0, 0, 0, 0, 94],
|
||||
[604, 0, 0, 0, 0, 0, 0,604, 0, 0,588,588,588,614,584],
|
||||
[584,584,584,584,584, 0, 0,604, 0, 0, 0,592, 0, 0,584],
|
||||
[ 0, 0, 0, 0, 0,595,604,604,608,604,584,588, 0,584,584],
|
||||
[ 0, 0, 0, 0, 0,381, 0,274, 0, 0, 0,588, 0, 0, 0],
|
||||
[ 92, 0, 0, 0,617, 34,587,587, 0, 0,586,588,617,586,586],
|
||||
[584,584,617,70022,70023,611,70022,70023, 0,600,587, 0, 0, 0,586],
|
||||
[584, 0, 0,584,608,482,608,584, 0, 0,587,587,587,614,586],
|
||||
[584, 0, 0,584,584, 85,584,584, 0,602, 0, 0, 0, 0,586],
|
||||
[604, 21,617,604, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[ 92,611,604,604,482, 0, 0, 0, 0,543, 0, 27, 28,482, 94],
|
||||
[604, 0,376,378,403, 28, 0,604,390,396,588,588,588,614,584],
|
||||
[584,584,584,584,584, 34, 29,604,484,441, 34,592, 33,376,584],
|
||||
[ 0, 0, 0, 0, 0,595,604,604,608,604,584,588,403,584,584],
|
||||
[ 0, 0, 0, 0, 0,381, 0,274, 34, 0, 0,588, 0, 0, 0],
|
||||
[ 92, 0, 27, 0,617, 34,587,587, 0, 0,586,588,617,586,586],
|
||||
[584,584,617,70022,70023,611,70022,70023, 0,600,587,376,482,378,586],
|
||||
[584, 28, 34,584,608,482,608,584, 0, 33,587,587,587,614,586],
|
||||
[584, 34,403,584,584, 85,584,584, 0,602, 0, 27,381, 0,586],
|
||||
[584,584,584,584,466,484,467,584,602, 0,604,604,604,277,586],
|
||||
[584, 0, 0,584,584,468,585,585, 0, 0,604, 0,604, 0,586],
|
||||
[ 0, 0, 0,584,584,497,585,585, 0, 0,600, 0,604, 0, 94],
|
||||
[584, 0, 0,584,584,468,585,585, 0, 28,604,378,604,468,586],
|
||||
[ 0, 0, 0,584,584,497,585,585, 0, 0,600,403,604, 0, 94],
|
||||
[ 0, 0, 0,584,584, 93,585,585, 93,584,584,584,584,584,584]
|
||||
],
|
||||
"bgmap": [
|
||||
|
@ -481,7 +481,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
|
||||
}
|
||||
if (core.getFlag('springCount', 0) == 50) {
|
||||
core.setFlag('springCount', 0);
|
||||
core.status.hero.hpmax *= 1.1;
|
||||
core.status.hero.hpmax = core.getNakedStatus('hpmax') * 1.1;
|
||||
}
|
||||
core.updateStatusBar();
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
"<br>",
|
||||
"<br>",
|
||||
"5. 本塔主要面向电脑端设计,",
|
||||
"<span style=\"color: gold\">建议使用电脑游玩以获得更好的游戏体验,同时使用16:9的比例游玩更加合适",
|
||||
"<span style=\"color: gold\">建议使用电脑游玩以获得更好的游戏体验,同时使用约16:9的比例游玩更加合适",
|
||||
"</span>。但是手机依然可以游玩本塔,",
|
||||
"但部分操作可能不是很方便,ui 也可能不是很美观,不过依然可以完整体验本游戏。",
|
||||
"<br>",
|
||||
@ -54,6 +54,8 @@
|
||||
"<br>",
|
||||
"游戏作者:古祠",
|
||||
"<br>",
|
||||
"本塔遵循MIT开源协议,你可随意使用本塔的任何代码,不需要作者授权,也可以随意用于商业用途。",
|
||||
"<br>",
|
||||
"BGM来源:网易云音乐等",
|
||||
"<br>",
|
||||
"素材来源:大素材库、爱给网、网站素材库等",
|
||||
|
@ -1,171 +0,0 @@
|
||||
{
|
||||
"chapter1": [
|
||||
{
|
||||
"index": 0,
|
||||
"title": "力量",
|
||||
"desc": [
|
||||
"力量就是根本!可以通过智慧增加力量,每级增加2点攻击。"
|
||||
],
|
||||
"consume": "10 * level + 10",
|
||||
"front": [],
|
||||
"loc": [
|
||||
1,
|
||||
2
|
||||
],
|
||||
"max": 10,
|
||||
"effect": [
|
||||
"攻击 + ${level * 2}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"title": "致命一击",
|
||||
"desc": [
|
||||
"爆发出全部力量攻击敌人,每级增加5点额外攻击。"
|
||||
],
|
||||
"consume": "30 * level + 30",
|
||||
"front": [
|
||||
[
|
||||
0,
|
||||
5
|
||||
]
|
||||
],
|
||||
"loc": [
|
||||
2,
|
||||
1
|
||||
],
|
||||
"max": 10,
|
||||
"effect": [
|
||||
"额外攻击 + ${level * 5}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"title": "断灭之刃",
|
||||
"desc": [
|
||||
"<span style=\"color: gold\">主动技能,快捷键1<span>,",
|
||||
"开启后会在战斗时会额外增加一定量的攻击,但同时减少一定量的防御。"
|
||||
],
|
||||
"consume": "200 * level + 400",
|
||||
"front": [
|
||||
[
|
||||
1,
|
||||
5
|
||||
]
|
||||
],
|
||||
"loc": [
|
||||
4,
|
||||
1
|
||||
],
|
||||
"max": 5,
|
||||
"effect": [
|
||||
"增加${level * 10}%攻击,减少${level * 10}%防御"
|
||||
]
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"title": "坚韧",
|
||||
"desc": [
|
||||
"由智慧转化出坚韧!每级增加2点防御"
|
||||
],
|
||||
"consume": "10 * level + 10",
|
||||
"front": [],
|
||||
"loc": [
|
||||
1,
|
||||
4
|
||||
],
|
||||
"max": 10,
|
||||
"effect": [
|
||||
"防御 + ${level * 2}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"title": "回春",
|
||||
"desc": [
|
||||
"让智慧化为治愈之泉水!每级增加1点生命回复"
|
||||
],
|
||||
"consume": "20 * level + 20",
|
||||
"front": [
|
||||
[
|
||||
3,
|
||||
5
|
||||
]
|
||||
],
|
||||
"loc": [
|
||||
2,
|
||||
5
|
||||
],
|
||||
"max": 25,
|
||||
"effect": [
|
||||
"生命回复 + ${level}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"title": "治愈之泉",
|
||||
"desc": [
|
||||
"让生命变得更多一些吧!每吃50瓶血瓶就增加当前生命回复10%的生命回复"
|
||||
],
|
||||
"consume": "1500",
|
||||
"front": [
|
||||
[
|
||||
4,
|
||||
25
|
||||
]
|
||||
],
|
||||
"loc": [
|
||||
4,
|
||||
5
|
||||
],
|
||||
"max": 1,
|
||||
"effect": [
|
||||
"50瓶血10%生命回复"
|
||||
]
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"title": "坚固之盾",
|
||||
"desc": [
|
||||
"让护甲更加坚硬一些吧!每级增加10点防御"
|
||||
],
|
||||
"consume": "50 + level * 50",
|
||||
"front": [
|
||||
[
|
||||
3,
|
||||
5
|
||||
]
|
||||
],
|
||||
"loc": [
|
||||
2,
|
||||
3
|
||||
],
|
||||
"max": 10,
|
||||
"effect": [
|
||||
"防御 + ${level * 10}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"title": "无上之盾",
|
||||
"desc": [
|
||||
"<span style=\"color: #dd4\">第一章终极技能</span>,战斗时智慧会充当等量护盾"
|
||||
],
|
||||
"consume": "50 + level * 50",
|
||||
"front": [
|
||||
[
|
||||
3,
|
||||
5
|
||||
]
|
||||
],
|
||||
"loc": [
|
||||
5,
|
||||
3
|
||||
],
|
||||
"max": 1,
|
||||
"effect": [
|
||||
"战斗时智慧会充当护盾"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
// 需要引入所有的插件
|
||||
import pop from './plugin/pop';
|
||||
import ui from './plugin/uiController';
|
||||
import use from './plugin/use';
|
||||
@ -16,7 +15,6 @@ import shadow from './plugin/shadow/shadow';
|
||||
import gameShadow from './plugin/shadow/gameShadow';
|
||||
|
||||
function forward() {
|
||||
// 每个引入的插件都要在这里执行,否则不会被转发
|
||||
const toForward: any[] = [
|
||||
pop(),
|
||||
ui(),
|
||||
|
100
src/plugin/particle/camera.ts
Normal file
100
src/plugin/particle/camera.ts
Normal file
@ -0,0 +1,100 @@
|
||||
import { Matrix4 } from '../webgl/martrix';
|
||||
import { Renderer } from './render';
|
||||
|
||||
type Position3D = [number, number, number];
|
||||
|
||||
export class Camera {
|
||||
/** 视图矩阵 */
|
||||
matrix!: Matrix4;
|
||||
/** 绑定的渲染器 */
|
||||
renderer?: Renderer;
|
||||
|
||||
constructor() {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.matrix = new Matrix4();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将该摄像机与一个渲染器绑定
|
||||
* @param renderer 渲染器
|
||||
*/
|
||||
bind(renderer: Renderer) {
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消与渲染器的绑定
|
||||
*/
|
||||
unbind() {
|
||||
this.renderer = void 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置摄像机的观察方位
|
||||
* @param eye 视点位置
|
||||
* @param at 目标点位置
|
||||
* @param up 上方向
|
||||
*/
|
||||
lookAt(eye: Position3D, at: Position3D, up: Position3D) {
|
||||
this.matrix = this.calLookAt(eye, at, up);
|
||||
}
|
||||
|
||||
/**
|
||||
* 变换摄像机的观察方位
|
||||
* @param eye 视点位置
|
||||
* @param at 目标点位置
|
||||
* @param up 上方向
|
||||
*/
|
||||
transform(eye: Position3D, at: Position3D, up: Position3D) {
|
||||
this.matrix.multipy(this.calLookAt(eye, at, up));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算摄像机变换矩阵
|
||||
* @see https://github.com/bad4iz/cuon-matrix/blob/main/src/Matrix4/Matrix4.ts
|
||||
* @param eye 视点位置
|
||||
* @param at 目标点位置
|
||||
* @param up 上方向
|
||||
* @returns 转换矩阵
|
||||
*/
|
||||
private calLookAt(eye: Position3D, at: Position3D, up: Position3D) {
|
||||
const [eyeX, eyeY, eyeZ] = eye;
|
||||
const [centerX, centerY, centerZ] = at;
|
||||
const [upX, upY, upZ] = up;
|
||||
|
||||
let fx = centerX - eyeX;
|
||||
let fy = centerY - eyeY;
|
||||
let fz = centerZ - eyeZ;
|
||||
|
||||
const rlf = 1 / Math.sqrt(fx * fx + fy * fy + fz * fz);
|
||||
fx *= rlf;
|
||||
fy *= rlf;
|
||||
fz *= rlf;
|
||||
|
||||
let sx = fy * upZ - fz * upY;
|
||||
let sy = fz * upX - fx * upZ;
|
||||
let sz = fx * upY - fy * upX;
|
||||
|
||||
const rls = 1 / Math.sqrt(sx * sx + sy * sy + sz * sz);
|
||||
sx *= rls;
|
||||
sy *= rls;
|
||||
sz *= rls;
|
||||
|
||||
const ux = sy * fz - sz * fy;
|
||||
const uy = sz * fx - sx * fz;
|
||||
const uz = sx * fy - sy * fx;
|
||||
|
||||
const matrix = new Matrix4();
|
||||
|
||||
matrix[0] = [sx, sy, sz, 0];
|
||||
matrix[1] = [ux, uy, uz, 0];
|
||||
matrix[2] = [-fx, -fy, -fz, 0];
|
||||
matrix[4] = [0, 0, 0, 1];
|
||||
|
||||
matrix.translate(-eyeX, -eyeY, -eyeZ);
|
||||
return matrix;
|
||||
}
|
||||
}
|
112
src/plugin/particle/particle.ts
Normal file
112
src/plugin/particle/particle.ts
Normal file
@ -0,0 +1,112 @@
|
||||
import { Ticker } from 'mutate-animate';
|
||||
import { has } from '../utils';
|
||||
import { Camera } from './camera';
|
||||
import { Renderer } from './render';
|
||||
|
||||
interface ParticleThreshold {
|
||||
radius: number;
|
||||
color: number;
|
||||
position: number;
|
||||
}
|
||||
|
||||
interface ParticleOne {
|
||||
x: number;
|
||||
y: number;
|
||||
z: number;
|
||||
r: number;
|
||||
}
|
||||
|
||||
interface Loc3D extends Loc {
|
||||
z: number;
|
||||
}
|
||||
|
||||
export class Particle {
|
||||
/** 绑定的摄像机 */
|
||||
camera?: Camera;
|
||||
/** 粒子中心位置 */
|
||||
pos: Loc3D;
|
||||
/** 粒子密度 */
|
||||
density: number;
|
||||
/** 渲染器 */
|
||||
renderer?: Renderer;
|
||||
|
||||
/** 需要渲染的粒子列表 */
|
||||
list: ParticleOne[] = [];
|
||||
|
||||
/** 是否需要更新 */
|
||||
private needUpdate: boolean = false;
|
||||
private ticker: Ticker = new Ticker();
|
||||
|
||||
/** 各个属性的阈值 */
|
||||
threshold: ParticleThreshold = {
|
||||
radius: 2,
|
||||
color: 16,
|
||||
position: 50
|
||||
};
|
||||
|
||||
constructor(density: number, x: number, y: number, z: number) {
|
||||
this.pos = { x, y, z };
|
||||
this.density = density;
|
||||
this.ticker.add(this.updateParticleData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置粒子中心的位置
|
||||
* @param x 横坐标
|
||||
* @param y 纵坐标
|
||||
*/
|
||||
setPos(x?: number, y?: number): Particle {
|
||||
has(x) && (this.pos.x = x);
|
||||
has(y) && (this.pos.y = y);
|
||||
this.needUpdate = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置粒子的阈值信息
|
||||
* @param data 阈值信息
|
||||
*/
|
||||
setThreshold(data: Partial<ParticleThreshold>): Particle {
|
||||
const { radius, color, position } = data;
|
||||
has(radius) && (this.threshold.radius = radius);
|
||||
has(color) && (this.threshold.radius = color);
|
||||
has(position) && (this.threshold.radius = position);
|
||||
this.needUpdate = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成粒子
|
||||
*/
|
||||
generate() {}
|
||||
|
||||
/**
|
||||
* 添加到一个渲染器上
|
||||
* @param renderer 渲染器
|
||||
*/
|
||||
appendTo(renderer: Renderer) {
|
||||
renderer.addParticle(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从当前渲染器上移除
|
||||
*/
|
||||
remove() {
|
||||
this.renderer?.removeParticle(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新粒子信息
|
||||
*/
|
||||
update() {
|
||||
this.needUpdate = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 每帧执行的粒子更新器
|
||||
*/
|
||||
private updateParticleData() {
|
||||
if (!this.needUpdate) return;
|
||||
this.needUpdate = false;
|
||||
}
|
||||
}
|
83
src/plugin/particle/render.ts
Normal file
83
src/plugin/particle/render.ts
Normal file
@ -0,0 +1,83 @@
|
||||
import { isWebGLSupported } from '../webgl/utils';
|
||||
import { Camera } from './camera';
|
||||
import { Particle } from './particle';
|
||||
|
||||
export class Renderer {
|
||||
/** 粒子列表 */
|
||||
particleList: Particle[] = [];
|
||||
/** 渲染画布 */
|
||||
canvas: HTMLCanvasElement = document.createElement('canvas');
|
||||
/** webgl绘制上下文 */
|
||||
gl: WebGLRenderingContext;
|
||||
/** 绑定的摄像机 */
|
||||
camera?: Camera;
|
||||
/** 缩放比例 */
|
||||
ratio: number = devicePixelRatio;
|
||||
|
||||
constructor() {
|
||||
if (!isWebGLSupported) {
|
||||
throw new Error(`Your service or browser does not support webgl!`);
|
||||
}
|
||||
this.gl = this.canvas.getContext('webgl')!;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化粒子画布
|
||||
* @param width 画布宽度
|
||||
* @param height 画布高度
|
||||
*/
|
||||
initCanvas(width: number, height: number) {
|
||||
const ratio = devicePixelRatio;
|
||||
this.ratio = ratio;
|
||||
this.canvas.width = width * ratio;
|
||||
this.canvas.height = height * ratio;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定摄像机
|
||||
* @param camera 摄像机
|
||||
*/
|
||||
bindCamera(camera: Camera) {
|
||||
this.camera = camera;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消绑定摄像机
|
||||
*/
|
||||
unbindCamera() {
|
||||
this.camera = void 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加到一个html元素中
|
||||
* @param ele html元素
|
||||
*/
|
||||
append(ele: HTMLElement) {
|
||||
ele.appendChild(this.canvas);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从当前html元素中移除
|
||||
*/
|
||||
remove() {
|
||||
this.canvas.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个粒子
|
||||
* @param particle 粒子
|
||||
*/
|
||||
addParticle(particle: Particle) {
|
||||
this.particleList.push(particle);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除一个粒子
|
||||
* @param particle 粒子
|
||||
*/
|
||||
removeParticle(particle: Particle) {
|
||||
const index = this.particleList.findIndex(v => v === particle);
|
||||
if (index === -1) return;
|
||||
this.particleList.splice(index, 1);
|
||||
}
|
||||
}
|
@ -72,7 +72,7 @@ export class Matrix4 extends Matrix {
|
||||
* @param y 平移纵坐标
|
||||
* @param z 平移竖坐标
|
||||
*/
|
||||
translation(x: number, y: number, z: number) {
|
||||
translate(x: number, y: number, z: number) {
|
||||
this.multipy([
|
||||
[1, 0, 0, x],
|
||||
[0, 1, 0, y],
|
||||
|
@ -26,7 +26,7 @@ export default defineConfig({
|
||||
output: {
|
||||
manualChunks: {
|
||||
antdv: ['ant-design-vue', '@ant-design/icons-vue'],
|
||||
common: ['lodash', 'axios', 'lz-string']
|
||||
common: ['lodash', 'axios', 'lz-string', 'chart.js', 'mutate-animate']
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -59,6 +59,6 @@ export default defineConfig({
|
||||
},
|
||||
watch: {
|
||||
ignored: ['**/public/**']
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user