random
This commit is contained in:
		| @@ -12,6 +12,7 @@ | ||||
|   "devDependencies": { | ||||
|     "@types/mocha": "^8.2.3", | ||||
|     "@types/node": "^15.14.9", | ||||
|     "@types/seedrandom": "^3.0.1", | ||||
|     "mocha": "^9.1.3", | ||||
|     "onchange": "^7.1.0", | ||||
|     "ts-node": "^10.4.0", | ||||
| @@ -19,6 +20,7 @@ | ||||
|     "typescript": "^4.5.4" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "seedrandom": "^3.0.5", | ||||
|     "tsrpc": "^3.1.4" | ||||
|   } | ||||
| } | ||||
| @@ -1,7 +1,8 @@ | ||||
| import seedrandom from "seedrandom"; | ||||
| import { gameConfig } from "./gameConfig"; | ||||
| import { GameSystemEvent } from "./GameSystemEvent"; | ||||
| import { GameSystemInput } from "./GameSystemInput"; | ||||
| import { GameSystemState } from "./GameSystemState"; | ||||
| import { EnemyState, EnemyType, GameSystemState } from "./GameSystemState"; | ||||
|  | ||||
| /** | ||||
|  * 前后端复用的状态计算模块 | ||||
| @@ -9,7 +10,17 @@ import { GameSystemState } from "./GameSystemState"; | ||||
| export class GameSystem { | ||||
|  | ||||
|     // 当前状态 | ||||
|     state: GameSystemState; | ||||
|     private _state!: GameSystemState; | ||||
|     get state(): Readonly<GameSystemState> { | ||||
|         return this._state; | ||||
|     } | ||||
|     set state(state: GameSystemState) { | ||||
|         this._state = state; | ||||
|         this._seedRandom = seedrandom(state.random.seed, state.random.state); | ||||
|     } | ||||
|  | ||||
|     // 伪随机数发生器 | ||||
|     private _seedRandom!: ReturnType<seedrandom>; | ||||
|  | ||||
|     constructor(state: GameSystemState) { | ||||
|         this.state = state; | ||||
| @@ -89,7 +100,7 @@ export class GameSystem { | ||||
|                 this.state.enemies.forEach(enemy => { | ||||
|                     // 更新敌机位置 | ||||
|                     const enemyTime = this.state.now - enemy.init.time; | ||||
|                     enemy.pos.y = enemy.init.pos.y - gameConfig.enemy.speed * enemyTime; | ||||
|                     enemy.pos.y = enemy.init.pos.y - gameConfig.enemy.speed[enemy.type] * enemyTime; | ||||
|  | ||||
|                     // 更新敌机子弹位置 | ||||
|                     enemy.bullets.forEach(bullet => { | ||||
| @@ -119,14 +130,36 @@ export class GameSystem { | ||||
|     } | ||||
|  | ||||
|     private _createEnemies() { | ||||
|         // 前 10 秒 | ||||
|         // 每 1 秒创建一个敌机 | ||||
|         if (this.state.now < this.state.lastCreateEnemyTime + gameConfig.enemy.bornY) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // 10~20秒 | ||||
|         // 每3秒一个组合,然后每秒一个敌机 | ||||
|         let time = this.state.now - (this.state.now % gameConfig.enemy.bornGapTime); | ||||
|         let pos = { x: this._random() * 750 - 375, y: gameConfig.enemy.bornY }; | ||||
|         let enemy: EnemyState = { | ||||
|             id: this.state.nextId.enemy++, | ||||
|             // 敌机类型 | ||||
|             type: this._random() > 0.5 ? EnemyType.E1 : EnemyType.E2, | ||||
|             pos: { ...pos }, | ||||
|             init: { | ||||
|                 time: time, | ||||
|                 pos: { ...pos }, | ||||
|             }, | ||||
|             bullets: [], | ||||
|             // 初次创建敌机,按 bulletDelayTime 倒推 lastBulletTime | ||||
|             lastBulletTime: time + gameConfig.enemy.bulletDelayTime - gameConfig.enemy.bulletGapTime, | ||||
|             nextId: { | ||||
|                 bullet: 0 | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // 20秒以后 | ||||
|         // 每 2 秒一个组合(组合1 / 组合2 / xxx) | ||||
|         this.state.enemies.push(enemy); | ||||
|     } | ||||
|  | ||||
|     private _random(): number { | ||||
|         let rand = this._seedRandom(); | ||||
|         this.state.random.state = this._seedRandom.state(); | ||||
|         return rand; | ||||
|     } | ||||
|  | ||||
|     // 简易的事件侦听器 | ||||
|   | ||||
| @@ -1,11 +1,19 @@ | ||||
| import { uint } from "tsrpc"; | ||||
|  | ||||
| // 坐标系:X-Y 原点在左下角 | ||||
| // 坐标系:X-Y 原点在中间下方 | ||||
| /* | ||||
| [ ]  [ ]  [ ] | ||||
|  | ||||
| [ ]  [ ]  [ ]      | ||||
|                   ↑ y | ||||
| [ ]  [x]  [ ]     → x | ||||
| */ | ||||
|  | ||||
| export interface GameSystemState { | ||||
|     // 游戏时间 | ||||
|     now: number, | ||||
|  | ||||
|     // 场景状态 | ||||
|     players: PlayerState[], | ||||
|     enemies: EnemyState[], | ||||
|     fightIcons: FightIconState[], | ||||
| @@ -15,10 +23,17 @@ export interface GameSystemState { | ||||
|         enemy: uint, | ||||
|         fightIcon: uint | ||||
|     }, | ||||
|  | ||||
|     // 上次创建敌机的时间 | ||||
|     lastCreateEnemyTime: number, | ||||
|     randomSeed: number, | ||||
|  | ||||
|     // 伪随机数发生器状态 | ||||
|     random: { | ||||
|         seed: string, | ||||
|         state: object | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| // 玩家 | ||||
| export interface PlayerState { | ||||
| @@ -52,12 +67,12 @@ export type PlayerBulletType = 'M' | 'H' | 'S'; | ||||
| // 敌机 | ||||
| export interface EnemyState { | ||||
|     id: uint, | ||||
|     type: uint, | ||||
|     // 敌机类型 | ||||
|     type: EnemyType, | ||||
|     pos: { x: number, y: number }, | ||||
|     init: { | ||||
|         time: number, | ||||
|         pos: { x: number, y: number }, | ||||
|         speed: { y: number } | ||||
|     } | ||||
|     bullets: { | ||||
|         id: uint, | ||||
| @@ -76,6 +91,11 @@ export interface EnemyState { | ||||
|     } | ||||
| } | ||||
|  | ||||
| export enum EnemyType { | ||||
|     E1, | ||||
|     E2 | ||||
| }; | ||||
|  | ||||
| // 子弹图标 | ||||
| export interface FightIconState { | ||||
|     id: uint, | ||||
|   | ||||
| @@ -1,13 +1,23 @@ | ||||
| import { EnemyType } from "./GameSystemState"; | ||||
|  | ||||
| export const gameConfig = { | ||||
|     syncRate: 10, | ||||
|  | ||||
|     enemy: { | ||||
|         speed: 10, | ||||
|         bulletSpeed: 20, | ||||
|         // 第一次发射子弹的延迟时间 | ||||
|         bulletDelayTime: 1500, | ||||
|         // 每次发射子弹的间隔 | ||||
|         bulletGapTime: 500 | ||||
|         bulletGapTime: 500, | ||||
|         // 出现位置(Y轴) | ||||
|         bornY: 1800, | ||||
|         // 敌机出现时间间隔(毫秒) | ||||
|         bornGapTime: 1000, | ||||
|         // 敌机速度 | ||||
|         speed: { | ||||
|             [EnemyType.E1]: 10, | ||||
|             [EnemyType.E2]: 20, | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     player: { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user