diff --git a/examples/cocos-creator-airplane/backend/package.json b/examples/cocos-creator-airplane/backend/package.json index 415ab15..f08fb27 100644 --- a/examples/cocos-creator-airplane/backend/package.json +++ b/examples/cocos-creator-airplane/backend/package.json @@ -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" } -} \ No newline at end of file +} diff --git a/examples/cocos-creator-airplane/backend/src/shared/game/GameSystem.ts b/examples/cocos-creator-airplane/backend/src/shared/game/GameSystem.ts index dda311f..05ad25c 100644 --- a/examples/cocos-creator-airplane/backend/src/shared/game/GameSystem.ts +++ b/examples/cocos-creator-airplane/backend/src/shared/game/GameSystem.ts @@ -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 { + return this._state; + } + set state(state: GameSystemState) { + this._state = state; + this._seedRandom = seedrandom(state.random.seed, state.random.state); + } + + // 伪随机数发生器 + private _seedRandom!: ReturnType; 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; } // 简易的事件侦听器 diff --git a/examples/cocos-creator-airplane/backend/src/shared/game/GameSystemState.ts b/examples/cocos-creator-airplane/backend/src/shared/game/GameSystemState.ts index a8783a9..6649912 100644 --- a/examples/cocos-creator-airplane/backend/src/shared/game/GameSystemState.ts +++ b/examples/cocos-creator-airplane/backend/src/shared/game/GameSystemState.ts @@ -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,11 +23,18 @@ export interface GameSystemState { enemy: uint, fightIcon: uint }, + // 上次创建敌机的时间 lastCreateEnemyTime: number, - randomSeed: number, + + // 伪随机数发生器状态 + random: { + seed: string, + state: object + } } + // 玩家 export interface PlayerState { id: uint, @@ -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, diff --git a/examples/cocos-creator-airplane/backend/src/shared/game/gameConfig.ts b/examples/cocos-creator-airplane/backend/src/shared/game/gameConfig.ts index 48d8801..2a50284 100644 --- a/examples/cocos-creator-airplane/backend/src/shared/game/gameConfig.ts +++ b/examples/cocos-creator-airplane/backend/src/shared/game/gameConfig.ts @@ -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: {