diff --git a/public/project/floors/MT36.js b/public/project/floors/MT36.js index 4cec21e..4cd6ebd 100644 --- a/public/project/floors/MT36.js +++ b/public/project/floors/MT36.js @@ -33,7 +33,8 @@ main.floors.MT36= "8,14": [ "从本区域开始将会出现各种光环怪,这需要你认真思考解决办法", "注意坚固怪受到光环加成后可能无法被打败,因为会首先计算坚固属性再计算光环", - "本区域的地图较为复杂,请善用楼传的小地图功能" + "本区域的地图较为复杂,请善用楼传的小地图功能", + "本区域的跳跃技能效果会比较奇怪()" ] }, "changeFloor": { diff --git a/public/project/floors/MT42.js b/public/project/floors/MT42.js index be735b8..c1b32b3 100644 --- a/public/project/floors/MT42.js +++ b/public/project/floors/MT42.js @@ -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": [ diff --git a/public/project/functions.js b/public/project/functions.js index b362973..de37930 100644 --- a/public/project/functions.js +++ b/public/project/functions.js @@ -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(); } diff --git a/src/data/desc.json b/src/data/desc.json index a8091ea..1fa349f 100644 --- a/src/data/desc.json +++ b/src/data/desc.json @@ -25,7 +25,7 @@ "
", "
", "5. 本塔主要面向电脑端设计,", - "建议使用电脑游玩以获得更好的游戏体验,同时使用16:9的比例游玩更加合适", + "建议使用电脑游玩以获得更好的游戏体验,同时使用约16:9的比例游玩更加合适", "。但是手机依然可以游玩本塔,", "但部分操作可能不是很方便,ui 也可能不是很美观,不过依然可以完整体验本游戏。", "
", @@ -54,6 +54,8 @@ "
", "游戏作者:古祠", "
", + "本塔遵循MIT开源协议,你可随意使用本塔的任何代码,不需要作者授权,也可以随意用于商业用途。", + "
", "BGM来源:网易云音乐等", "
", "素材来源:大素材库、爱给网、网站素材库等", diff --git a/src/data/skillTree.json b/src/data/skillTree.json deleted file mode 100644 index e6f60b2..0000000 --- a/src/data/skillTree.json +++ /dev/null @@ -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": [ - "主动技能,快捷键1,", - "开启后会在战斗时会额外增加一定量的攻击,但同时减少一定量的防御。" - ], - "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": [ - "第一章终极技能,战斗时智慧会充当等量护盾" - ], - "consume": "50 + level * 50", - "front": [ - [ - 3, - 5 - ] - ], - "loc": [ - 5, - 3 - ], - "max": 1, - "effect": [ - "战斗时智慧会充当护盾" - ] - } - ] -} \ No newline at end of file diff --git a/src/initPlugin.ts b/src/initPlugin.ts index 67dc0da..30b72c9 100644 --- a/src/initPlugin.ts +++ b/src/initPlugin.ts @@ -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(), diff --git a/src/plugin/particle/camera.ts b/src/plugin/particle/camera.ts new file mode 100644 index 0000000..42ed59b --- /dev/null +++ b/src/plugin/particle/camera.ts @@ -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; + } +} diff --git a/src/plugin/particle/particle.ts b/src/plugin/particle/particle.ts new file mode 100644 index 0000000..481136f --- /dev/null +++ b/src/plugin/particle/particle.ts @@ -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): 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; + } +} diff --git a/src/plugin/particle/render.ts b/src/plugin/particle/render.ts new file mode 100644 index 0000000..c4398bc --- /dev/null +++ b/src/plugin/particle/render.ts @@ -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); + } +} diff --git a/src/plugin/webgl/martrix.ts b/src/plugin/webgl/martrix.ts index d7d6b41..ec6692d 100644 --- a/src/plugin/webgl/martrix.ts +++ b/src/plugin/webgl/martrix.ts @@ -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], diff --git a/vite.config.ts b/vite.config.ts index f3e362b..5ad46f0 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -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/**'] - } + }, } });