This commit is contained in:
sli97
2022-11-27 23:23:47 +08:00
commit 1a27f478d0
219 changed files with 15759 additions and 0 deletions

View File

@@ -0,0 +1,164 @@
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
}
}
}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "1682ed16-4e4f-46b3-8aca-92baecd30b9d",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,42 @@
import Singleton from '../Base/Singleton';
import { EventEnum } from '../Enum';
interface IItem {
func: Function;
ctx: unknown;
}
export default class EventManager extends Singleton {
static get Instance() {
return super.GetInstance<EventManager>();
}
private eventMap: Map<EventEnum, Array<IItem>> = new Map();
on(event: EventEnum, func: Function, ctx?: unknown) {
if (this.eventMap.has(event)) {
this.eventMap.get(event).push({ func, ctx });
} else {
this.eventMap.set(event, [{ func, ctx }]);
}
}
off(event: EventEnum, func: Function, ctx?: unknown) {
if (this.eventMap.has(event)) {
const index = this.eventMap.get(event).findIndex(i => func === i.func && i.ctx === ctx);
index > -1 && this.eventMap.get(event).splice(index, 1);
}
}
emit(event: EventEnum, ...params: unknown[]) {
if (this.eventMap.has(event)) {
this.eventMap.get(event).forEach(({ func, ctx }) => {
ctx ? func.apply(ctx, params) : func(...params);
});
}
}
clear() {
this.eventMap.clear();
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "2aa2e7de-b014-4ee7-a537-4bc99dbf9164",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,44 @@
import Singleton from '../Base/Singleton'
export default class NetworkManager extends Singleton {
static get Instance() {
return super.GetInstance<NetworkManager>()
}
ws: WebSocket
port = 8888
connect() {
return new Promise((resolve, reject) => {
this.ws = new WebSocket(`ws://localhost:${this.port}`)
this.ws.onopen = () => {
console.log("ws onopen")
resolve(null)
}
this.ws.onerror = () => {
console.log("ws onerror")
reject()
}
this.ws.onclose = () => {
console.log("ws onclose")
reject()
}
this.ws.onmessage = (data) => {
console.log("onmessage", data);
}
})
}
sendMsg(data) {
this.ws.send(data)
}
async callApi(path: string) {
return await fetch(`http://localhost:${this.port}${path}`).then((res) => res.json())
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "588dfbf5-0456-472f-8382-746392fb1a06",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,52 @@
import Singleton from '../Base/Singleton'
import { instantiate, Node, Prefab } from 'cc'
import { EntityTypeEnum } from '../Enum'
import DataManager from './DataManager'
import { ResourceManager } from './ResourceManager'
export default class ObjectPoolManager extends Singleton {
static get Instance() {
return super.GetInstance<ObjectPoolManager>()
}
private objectPool: Node = null
private poolObjectMap: Map<EntityTypeEnum, Node[]> = new Map()
private getObjectContainerName(objectName: EntityTypeEnum) {
return objectName + 'Pool'
}
getPoolObject(objectName: EntityTypeEnum) {
if (this.objectPool === null) {
this.objectPool = new Node("ObjectPool")
this.objectPool.setParent(DataManager.Instance.gm.stage)
}
if (!this.poolObjectMap.has(objectName)) {
this.poolObjectMap.set(objectName, [])
const container = new Node(this.getObjectContainerName(objectName))
container.setParent(this.objectPool)
}
let node: Node
const nodes = this.poolObjectMap.get(objectName)
const index = nodes.findIndex(node => node.active)
if (index === -1) {
const prefab = DataManager.Instance.prefabMap.get(objectName)
node = instantiate(prefab)
node.name = objectName
node.setParent(this.objectPool.getChildByName(this.getObjectContainerName(objectName)))
} else {
node = nodes.splice(index, 1)[0]
}
node.active = true
return node
}
returnPoolObject(object: Node) {
object.active = false
const objectName = object.name as EntityTypeEnum
this.poolObjectMap.get(objectName).push(object)
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "01a37612-1a4a-45ee-8be8-3e3360996442",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,32 @@
import { _decorator, resources, SpriteFrame, Asset } from 'cc'
import Singleton from '../Base/Singleton'
export class ResourceManager extends Singleton {
static get Instance() {
return super.GetInstance<ResourceManager>()
}
loadRes<T extends Asset>(path: string, type: new (...args: any[]) => T) {
return new Promise<T>((resolve, reject) => {
resources.load(path, type, (err, res) => {
if (err) {
reject(err)
return
}
resolve(res)
})
})
}
loadDir<T extends Asset>(path: string, type: new (...args: any[]) => T) {
return new Promise<T[]>((resolve, reject) => {
resources.loadDir(path, type, (err, res) => {
if (err) {
reject(err)
return
}
resolve(res)
})
})
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "6278727d-3641-46d1-ae43-52b7829402d1",
"files": [],
"subMetas": {},
"userData": {}
}