import { Node, Prefab, SpriteFrame } from 'cc' import Singleton from '../Base/Singleton' import { BulletManager } from '../Entity/Bullet/BulletManager' import { PlayerManager } from '../Entity/Player/PlayerManager' import { EntityTypeEnum, EventEnum, InputType } from '../Enum' import { JoyStickManager } from '../UI/JoyStickManager' import EventManager from './EventManager' import { IData } from './NetworkManager' export type IPlayer = Pick export type IBullet = Pick 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() } stage: Node jm: JoyStickManager prefabMap: Map = new Map() textureMap: Map = new Map() playerMap: Map = new Map() bulletMap: Map = new Map() myPlayerId = 1 roomInfo: IData mapSize = { x: 960, y: 640, } 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.BulletBorn, 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.ExplosionBorn, 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 } } if (Math.abs(bullet.position.x) > this.mapSize.x / 2 || Math.abs(bullet.position.y) > this.mapSize.y / 2) { EventManager.Instance.emit(EventEnum.ExplosionBorn, bullet.id, { x: bullet.position.x, y: bullet.position.y, }) bullets.splice(i, 1) } } 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 } } } } }