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