2022-12-01 22:26:41 +08:00

174 lines
4.4 KiB
TypeScript

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<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>()
}
stage: Node
jm: JoyStickManager
prefabMap: Map<string, Prefab> = new Map()
textureMap: Map<string, SpriteFrame[]> = new Map()
playerMap: Map<number, PlayerManager> = new Map()
bulletMap: Map<number, BulletManager> = 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
}
}
}
}
}