165 lines
4.2 KiB
TypeScript
165 lines
4.2 KiB
TypeScript
|
import { Input, Prefab, SpriteFrame } from 'cc'
|
||
|
import Singleton from '../Base/Singleton'
|
||
|
import { BulletManager } from '../Entity/Bullet/BulletManager'
|
||
|
import { PlayerManager } from '../Entity/Player/PlayerManager'
|
||
|
import { WeaponManager } from '../Entity/Weapon/WeaponManager'
|
||
|
import { EntityStateEnum, EntityTypeEnum, EventEnum, InputType } from '../Enum'
|
||
|
import { BattleManager } from '../Scene/BattleManager'
|
||
|
import { JoyStickManager } from '../UI/JoyStickManager'
|
||
|
import EventManager from './EventManager'
|
||
|
import ObjectPoolManager from './ObjectPoolManager'
|
||
|
|
||
|
export type IPlayer = Pick<PlayerManager, 'id' | 'nickname' | 'hp' | 'position' | 'direction' | 'type' | 'weaponType' | 'bulletType'>
|
||
|
export type IBullet = Pick<BulletManager, 'id' | 'owner' | 'position' | 'direction' | 'type'>
|
||
|
|
||
|
const PLAYER_SPEED = 100
|
||
|
const BULLET_SPEED = 600
|
||
|
|
||
|
const WEAPON_DAMAGE = 5
|
||
|
|
||
|
const PLAYER_RADIUS = 50
|
||
|
const BULLET_RADIUS = 10
|
||
|
|
||
|
export interface IVec2 {
|
||
|
x: number;
|
||
|
y: number
|
||
|
}
|
||
|
|
||
|
interface IState {
|
||
|
players: IPlayer[],
|
||
|
bullets: IBullet[],
|
||
|
nextBulletId: number
|
||
|
}
|
||
|
|
||
|
interface IPlayerMove {
|
||
|
type: InputType.PlayerMove
|
||
|
id: number;
|
||
|
direction: IVec2;
|
||
|
dt: number
|
||
|
|
||
|
}
|
||
|
|
||
|
interface IWeaponShoot {
|
||
|
type: InputType.WeaponShoot
|
||
|
owner: number;
|
||
|
position: IVec2;
|
||
|
direction: IVec2;
|
||
|
}
|
||
|
|
||
|
interface ITimePast {
|
||
|
type: InputType.TimePast;
|
||
|
dt: number
|
||
|
}
|
||
|
|
||
|
export default class DataManager extends Singleton {
|
||
|
static get Instance() {
|
||
|
return super.GetInstance<DataManager>()
|
||
|
}
|
||
|
|
||
|
gm: BattleManager
|
||
|
jm: JoyStickManager
|
||
|
myPlayerId = 1
|
||
|
|
||
|
prefabMap: Map<string, Prefab> = new Map()
|
||
|
textureMap: Map<string, SpriteFrame[]> = new Map()
|
||
|
|
||
|
playerMap: Map<number, PlayerManager> = new Map()
|
||
|
bulletMap: Map<number, BulletManager> = new Map()
|
||
|
|
||
|
state: IState = {
|
||
|
players: [{
|
||
|
id: 2,
|
||
|
nickname: "哈哈1",
|
||
|
position: {
|
||
|
x: -200,
|
||
|
y: -200
|
||
|
},
|
||
|
direction: {
|
||
|
x: 1,
|
||
|
y: 0
|
||
|
},
|
||
|
hp: 100,
|
||
|
type: EntityTypeEnum.Player1,
|
||
|
weaponType: EntityTypeEnum.Weapon1,
|
||
|
bulletType: EntityTypeEnum.Bullet1,
|
||
|
}, {
|
||
|
id: 1,
|
||
|
nickname: "哈哈2",
|
||
|
position: {
|
||
|
x: 200,
|
||
|
y: 200
|
||
|
},
|
||
|
direction: {
|
||
|
x: 0,
|
||
|
y: -1
|
||
|
},
|
||
|
hp: 100,
|
||
|
type: EntityTypeEnum.Player2,
|
||
|
weaponType: EntityTypeEnum.Weapon2,
|
||
|
bulletType: EntityTypeEnum.Bullet2,
|
||
|
}],
|
||
|
bullets: [],
|
||
|
nextBulletId: 1
|
||
|
}
|
||
|
|
||
|
applyInput(input: IPlayerMove | IWeaponShoot | ITimePast) {
|
||
|
switch (input.type) {
|
||
|
case InputType.PlayerMove: {
|
||
|
const { direction: { x, y }, dt, id } = input
|
||
|
const player = this.state.players.find(e => e.id === id)
|
||
|
if (!player) {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
player.position.x += x * PLAYER_SPEED * dt
|
||
|
player.position.y += y * PLAYER_SPEED * dt
|
||
|
|
||
|
player.direction = { x, y }
|
||
|
|
||
|
break
|
||
|
}
|
||
|
|
||
|
case InputType.WeaponShoot: {
|
||
|
const { owner, position, direction } = input
|
||
|
const bullet: IBullet = {
|
||
|
id: this.state.nextBulletId++,
|
||
|
owner,
|
||
|
position,
|
||
|
direction,
|
||
|
type: this.playerMap.get(owner).bulletType
|
||
|
}
|
||
|
this.state.bullets.push(bullet)
|
||
|
|
||
|
EventManager.Instance.emit(EventEnum.WeaponShoot, owner)
|
||
|
break
|
||
|
}
|
||
|
case InputType.TimePast: {
|
||
|
const { dt } = input
|
||
|
const { bullets, players } = this.state
|
||
|
|
||
|
for (let i = bullets.length - 1; i >= 0; i--) {
|
||
|
const bullet = bullets[i];
|
||
|
for (let j = players.length - 1; j >= 0; j--) {
|
||
|
const player = players[j];
|
||
|
if (((player.position.x - bullet.position.x) ** 2 + (player.position.y - bullet.position.y) ** 2) < (PLAYER_RADIUS + BULLET_RADIUS) ** 2) {
|
||
|
EventManager.Instance.emit(EventEnum.Explosion, bullet.id, {
|
||
|
x: (player.position.x + bullet.position.x) / 2,
|
||
|
y: (player.position.y + bullet.position.y) / 2,
|
||
|
})
|
||
|
|
||
|
player.hp -= WEAPON_DAMAGE
|
||
|
bullets.splice(i, 1)
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (const bullet of this.state.bullets) {
|
||
|
bullet.position.x += bullet.direction.x * BULLET_SPEED * dt
|
||
|
bullet.position.y += bullet.direction.y * BULLET_SPEED * dt
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|