This commit is contained in:
2024-10-05 04:22:34 +08:00
parent 5993f231fd
commit 30911fcf5c
298 changed files with 28632 additions and 28632 deletions

View File

@@ -1,156 +1,156 @@
import {
Component,
EventTouch,
Node,
NodePool,
Prefab,
UITransform,
Vec2,
Vec3,
_decorator,
instantiate,
sys,
} from 'cc'
import FishBulletBase from '../../../fish/script/FishBulletBase'
import FishUI from '../../../fish/script/FishUI'
import CommonTips from '../../engine/uicomponent/CommonTips'
import MathUtils from '../../engine/utils/MathUtils'
import { MoveHelper } from '../../engine/utils/MoveHelper'
import GameMusicHelper from '../utils/GameMusicHelper'
import CannonManager from './CannonManager'
import FishNetManager from './FishNetManager'
import WsManager from './WsManager'
const { ccclass, property } = _decorator
// 子弹管理类
@ccclass('BulletManager')
export default class BulletManager extends Component {
public static instance: BulletManager = null
@property({ type: [Prefab] })
private bulletPrefabList: Prefab[] | [] = []
private bulletPool: Array<NodePool> = []
private bulletList: Array<FishBulletBase> = []
private bulletMoveSpeed: number = 30
private _vec3Cache: Vec3
private _vec2Cache: Vec2
private _fireTime: number = 0
private _fireTimeNew: number
onLoad() {
this._vec3Cache = new Vec3()
this._vec2Cache = new Vec2()
BulletManager.instance = this
this.node.on(Node.EventType.TOUCH_START, this.onShootBullet, this)
}
start() {}
update() {
this.checkMoveBullet()
}
// 检测子弹是否移动完成
private checkMoveBullet() {
for (let i = this.bulletList.length - 1; i >= 0; i--) {
const bullet: FishBulletBase = this.bulletList[i]
const isMoving: boolean = MoveHelper.moveNode(
bullet.node,
this.bulletMoveSpeed,
bullet.targetP.x,
bullet.targetP.y,
)
if (!isMoving) {
bullet.node.getPosition(this._vec3Cache)
this._vec2Cache.x = this._vec3Cache.x
this._vec2Cache.y = this._vec3Cache.y
FishNetManager.instance.addFishNet(bullet.bulletType, this._vec2Cache)
this.bulletList.splice(i, 1)
this.destroyBullet(bullet)
}
}
}
// 发射炮弹
private onShootBullet(event: EventTouch) {
// TOUCH_START 在Editor上连续触发2次导致发2次炮弹bug
if (sys.platform === 'EDITOR_PAGE') {
this._fireTimeNew = new Date().getTime()
if (this._fireTimeNew - this._fireTime < 15000) return
this._fireTime = this._fireTimeNew
}
const tran = this.node.getComponent(UITransform)
const location = event.getUILocation()
this._vec3Cache.x = location.x
this._vec3Cache.y = location.y
this._vec3Cache.z = 0
tran.convertToNodeSpaceAR(this._vec3Cache, this._vec3Cache)
const localP: Vec2 = new Vec2(this._vec3Cache.x, this._vec3Cache.y)
FishUI.instance.playClickEffect(localP)
// 子弹发射
if (FishUI.instance.dz_score >= CannonManager.instance.cannonType) {
FishUI.instance.dz_score -= CannonManager.instance.cannonType
// FishUI.instance.refreshScore()
this._vec3Cache = CannonManager.instance.getCannonPosition()
const rad: number = MathUtils.p2pRad(new Vec2(this._vec3Cache.x, this._vec3Cache.y), localP)
const rot: number = MathUtils.radiansToDegrees(rad)
const bullet: FishBulletBase = this.createBullet(CannonManager.instance.cannonType - 1)
bullet.targetP = localP
this.node.addChild(bullet.node)
bullet.node.setPosition(CannonManager.instance.getCannonPosition())
this._vec3Cache.x = 1
this._vec3Cache.y = 1
this._vec3Cache.y = 1
Vec3.multiplyScalar(this._vec3Cache, this._vec3Cache, 2)
bullet.node.setScale(this._vec3Cache)
bullet.node.angle = rot
this.bulletList.push(bullet)
GameMusicHelper.playFire()
// 旋转炮台
CannonManager.instance.rotateCannon(location)
} else {
CommonTips.showMsg('豆子不足!')
}
}
// 创建子弹
private createBullet(bulletType: number) {
let bulletNode: Node
if (this.bulletPool[bulletType] && this.bulletPool[bulletType].size() > 0) {
bulletNode = this.bulletPool[bulletType].get()
} else {
bulletNode = instantiate(this.bulletPrefabList[bulletType])
}
bulletNode.getComponent(FishBulletBase).bulletType = bulletType
return bulletNode.getComponent(FishBulletBase)
}
public killBullet(bullet: FishBulletBase) {
const index: number = this.bulletList.indexOf(bullet)
if (index >= 0) {
this.bulletList.splice(index, 1)
this.destroyBullet(bullet)
}
}
// 销毁子弹
private destroyBullet(bullet: FishBulletBase) {
// 临时代码,因为回收在内存卡顿。后面在优化 2023-2-10
if (sys.platform === 'EDITOR_PAGE') {
bullet.node.destroy()
return
}
if (!this.bulletPool[bullet.bulletType]) this.bulletPool[bullet.bulletType] = new NodePool()
this.bulletPool[bullet.bulletType].put(bullet.node)
}
onDestroy() {
BulletManager.instance = null
}
}
import {
Component,
EventTouch,
Node,
NodePool,
Prefab,
UITransform,
Vec2,
Vec3,
_decorator,
instantiate,
sys,
} from 'cc'
import FishBulletBase from '../../../fish/script/FishBulletBase'
import FishUI from '../../../fish/script/FishUI'
import CommonTips from '../../engine/uicomponent/CommonTips'
import MathUtils from '../../engine/utils/MathUtils'
import { MoveHelper } from '../../engine/utils/MoveHelper'
import GameMusicHelper from '../utils/GameMusicHelper'
import CannonManager from './CannonManager'
import FishNetManager from './FishNetManager'
import WsManager from './WsManager'
const { ccclass, property } = _decorator
// 子弹管理类
@ccclass('BulletManager')
export default class BulletManager extends Component {
public static instance: BulletManager = null
@property({ type: [Prefab] })
private bulletPrefabList: Prefab[] | [] = []
private bulletPool: Array<NodePool> = []
private bulletList: Array<FishBulletBase> = []
private bulletMoveSpeed: number = 30
private _vec3Cache: Vec3
private _vec2Cache: Vec2
private _fireTime: number = 0
private _fireTimeNew: number
onLoad() {
this._vec3Cache = new Vec3()
this._vec2Cache = new Vec2()
BulletManager.instance = this
this.node.on(Node.EventType.TOUCH_START, this.onShootBullet, this)
}
start() {}
update() {
this.checkMoveBullet()
}
// 检测子弹是否移动完成
private checkMoveBullet() {
for (let i = this.bulletList.length - 1; i >= 0; i--) {
const bullet: FishBulletBase = this.bulletList[i]
const isMoving: boolean = MoveHelper.moveNode(
bullet.node,
this.bulletMoveSpeed,
bullet.targetP.x,
bullet.targetP.y,
)
if (!isMoving) {
bullet.node.getPosition(this._vec3Cache)
this._vec2Cache.x = this._vec3Cache.x
this._vec2Cache.y = this._vec3Cache.y
FishNetManager.instance.addFishNet(bullet.bulletType, this._vec2Cache)
this.bulletList.splice(i, 1)
this.destroyBullet(bullet)
}
}
}
// 发射炮弹
private onShootBullet(event: EventTouch) {
// TOUCH_START 在Editor上连续触发2次导致发2次炮弹bug
if (sys.platform === 'EDITOR_PAGE') {
this._fireTimeNew = new Date().getTime()
if (this._fireTimeNew - this._fireTime < 15000) return
this._fireTime = this._fireTimeNew
}
const tran = this.node.getComponent(UITransform)
const location = event.getUILocation()
this._vec3Cache.x = location.x
this._vec3Cache.y = location.y
this._vec3Cache.z = 0
tran.convertToNodeSpaceAR(this._vec3Cache, this._vec3Cache)
const localP: Vec2 = new Vec2(this._vec3Cache.x, this._vec3Cache.y)
FishUI.instance.playClickEffect(localP)
// 子弹发射
if (FishUI.instance.dz_score >= CannonManager.instance.cannonType) {
FishUI.instance.dz_score -= CannonManager.instance.cannonType
// FishUI.instance.refreshScore()
this._vec3Cache = CannonManager.instance.getCannonPosition()
const rad: number = MathUtils.p2pRad(new Vec2(this._vec3Cache.x, this._vec3Cache.y), localP)
const rot: number = MathUtils.radiansToDegrees(rad)
const bullet: FishBulletBase = this.createBullet(CannonManager.instance.cannonType - 1)
bullet.targetP = localP
this.node.addChild(bullet.node)
bullet.node.setPosition(CannonManager.instance.getCannonPosition())
this._vec3Cache.x = 1
this._vec3Cache.y = 1
this._vec3Cache.y = 1
Vec3.multiplyScalar(this._vec3Cache, this._vec3Cache, 2)
bullet.node.setScale(this._vec3Cache)
bullet.node.angle = rot
this.bulletList.push(bullet)
GameMusicHelper.playFire()
// 旋转炮台
CannonManager.instance.rotateCannon(location)
} else {
CommonTips.showMsg('豆子不足!')
}
}
// 创建子弹
private createBullet(bulletType: number) {
let bulletNode: Node
if (this.bulletPool[bulletType] && this.bulletPool[bulletType].size() > 0) {
bulletNode = this.bulletPool[bulletType].get()
} else {
bulletNode = instantiate(this.bulletPrefabList[bulletType])
}
bulletNode.getComponent(FishBulletBase).bulletType = bulletType
return bulletNode.getComponent(FishBulletBase)
}
public killBullet(bullet: FishBulletBase) {
const index: number = this.bulletList.indexOf(bullet)
if (index >= 0) {
this.bulletList.splice(index, 1)
this.destroyBullet(bullet)
}
}
// 销毁子弹
private destroyBullet(bullet: FishBulletBase) {
// 临时代码,因为回收在内存卡顿。后面在优化 2023-2-10
if (sys.platform === 'EDITOR_PAGE') {
bullet.node.destroy()
return
}
if (!this.bulletPool[bullet.bulletType]) this.bulletPool[bullet.bulletType] = new NodePool()
this.bulletPool[bullet.bulletType].put(bullet.node)
}
onDestroy() {
BulletManager.instance = null
}
}

View File

@@ -1,11 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "bd065d0b-0b60-4981-aea0-75d2f209b7ea",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "bd065d0b-0b60-4981-aea0-75d2f209b7ea",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -1,72 +1,72 @@
import {
Component,
EventMouse,
Node,
Sprite,
SpriteFrame,
UITransform,
Vec2,
Vec3,
_decorator,
} from 'cc'
import MathUtils from '../../engine/utils/MathUtils'
const { ccclass, property } = _decorator
// 炮塔管理类
@ccclass('CannonManager')
export default class CannonManager extends Component {
public static instance: CannonManager = null
@property({ type: Node })
private view: Node | null = null
@property({ type: [SpriteFrame] })
private cannonSpriteFrame: Array<SpriteFrame> | [] = []
// 炮塔倍数
public cannonType: number = 1
private _vec3Cache: Vec3
onLoad() {
this._vec3Cache = new Vec3()
CannonManager.instance = this
this.node.parent.on(Node.EventType.MOUSE_MOVE, this.onMeMove.bind(this))
this.refreshCannon()
}
// 炮塔移动
private onMeMove(event: EventMouse) {
this.rotateCannon(event.getUILocation())
}
// 炮塔旋转
public rotateCannon(uilocation: Vec2) {
const location = uilocation
this._vec3Cache.x = location.x
this._vec3Cache.y = location.y
this._vec3Cache.z = 0
const tran = this.node.getComponent(UITransform)
tran.convertToNodeSpaceAR(this._vec3Cache, this._vec3Cache)
const localTouch: Vec2 = new Vec2(this._vec3Cache.x, this._vec3Cache.y)
this.view.getPosition(this._vec3Cache)
const rad: number = MathUtils.p2pRad(new Vec2(this._vec3Cache.x, this._vec3Cache.y), localTouch)
const rot: number = MathUtils.radiansToDegrees(rad)
this.view.angle = rot - 90
}
// 刷新炮塔
public refreshCannon() {
this.view.getComponent(Sprite).spriteFrame = this.cannonSpriteFrame[this.cannonType - 1]
}
// 获取炮塔位置
public getCannonPosition() {
return this.view.getPosition()
}
onDestroy() {
CannonManager.instance = null
}
}
import {
Component,
EventMouse,
Node,
Sprite,
SpriteFrame,
UITransform,
Vec2,
Vec3,
_decorator,
} from 'cc'
import MathUtils from '../../engine/utils/MathUtils'
const { ccclass, property } = _decorator
// 炮塔管理类
@ccclass('CannonManager')
export default class CannonManager extends Component {
public static instance: CannonManager = null
@property({ type: Node })
private view: Node | null = null
@property({ type: [SpriteFrame] })
private cannonSpriteFrame: Array<SpriteFrame> | [] = []
// 炮塔倍数
public cannonType: number = 1
private _vec3Cache: Vec3
onLoad() {
this._vec3Cache = new Vec3()
CannonManager.instance = this
this.node.parent.on(Node.EventType.MOUSE_MOVE, this.onMeMove.bind(this))
this.refreshCannon()
}
// 炮塔移动
private onMeMove(event: EventMouse) {
this.rotateCannon(event.getUILocation())
}
// 炮塔旋转
public rotateCannon(uilocation: Vec2) {
const location = uilocation
this._vec3Cache.x = location.x
this._vec3Cache.y = location.y
this._vec3Cache.z = 0
const tran = this.node.getComponent(UITransform)
tran.convertToNodeSpaceAR(this._vec3Cache, this._vec3Cache)
const localTouch: Vec2 = new Vec2(this._vec3Cache.x, this._vec3Cache.y)
this.view.getPosition(this._vec3Cache)
const rad: number = MathUtils.p2pRad(new Vec2(this._vec3Cache.x, this._vec3Cache.y), localTouch)
const rot: number = MathUtils.radiansToDegrees(rad)
this.view.angle = rot - 90
}
// 刷新炮塔
public refreshCannon() {
this.view.getComponent(Sprite).spriteFrame = this.cannonSpriteFrame[this.cannonType - 1]
}
// 获取炮塔位置
public getCannonPosition() {
return this.view.getPosition()
}
onDestroy() {
CannonManager.instance = null
}
}

View File

@@ -1,11 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "d03d3fa0-9f23-4106-be05-9d106bd8f8c8",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "d03d3fa0-9f23-4106-be05-9d106bd8f8c8",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -1,272 +1,272 @@
import {
Animation,
Component,
Node,
NodePool,
Prefab,
Tween,
Vec2,
Vec3,
_decorator,
game,
instantiate,
tween,
} from 'cc'
import FishBase from '../../../fish/script/FishBase'
import FishMover from '../../../fish/script/FishMover'
import FishUI from '../../../fish/script/FishUI'
import { Logger } from '../../engine/utils/Logger'
import RandomUtil from '../../engine/utils/RandomUtil'
import { FishConfig } from '../config/FishConfig'
import { FishInfo } from '../config/FishInfo'
import { FishMap } from '../config/FishMap'
import { FishMapInfo } from '../config/FishMapInfo'
import { FishPathConfig } from '../config/FishPathConfig'
import GameMusicHelper from '../utils/GameMusicHelper'
import TimeHelper from '../utils/TimeHelper'
import ScoreManager from './ScoreManager'
import WsManager from './WsManager'
import { FishPathInfo } from '../config/FishPathInfo'
const { ccclass, property } = _decorator
interface dataType {
fisn: Array<FishType>
}
interface FishType {
fishId: string
fishInfo: FishInfo
fishType: string
isDead: number
fishPathInfo: Array<fishPathInfoType>
}
interface fishPathInfoType {
pathId: string
path: Array<PathPoint>
}
interface PathPoint {
x: number
y: number
}
// 鱼管理类
@ccclass('FishManager')
export default class FishManager extends Component {
public static instance: FishManager = null
@property({ type: Node })
private fishContainer: Node | null = null
@property({ type: [Prefab] })
public fishPrefabList: Array<Prefab> = []
private fishPool: Array<NodePool> = []
private fishList: Map<string, FishBase> = new Map()
private nextRandomFishTime: number = 0
private minRandomTime: number = 2 * (game.frameRate as number)
private maxRandomTime: number = 5 * (game.frameRate as number)
private isFishMap: boolean = false
private mapCount: number = 0
private _fishPosCache: Vec3
onLoad() {
WsManager.instance.on(100, this.randomFish, this)
FishManager.instance = this
this._fishPosCache = new Vec3()
Logger.log('maxRandomTime=', this.minRandomTime, this.maxRandomTime, game.frameRate)
}
start() {
// this.randomFish()
}
update() {
// this.checkRandomFish()
this.checkFishMoveEnd()
// this.checkFishMap()
}
private checkFishMap() {
if (!this.isFishMap) {
if (this.mapCount > 0) {
this.mapCount--
if (this.mapCount <= 0) FishUI.instance.playWaveEffect()
}
}
}
// 检测是否随机鱼
private checkRandomFish() {
if (!this.isFishMap) {
if (this.nextRandomFishTime > 0) {
this.nextRandomFishTime--
// if (this.nextRandomFishTime === 0) this.randomFish()
}
}
}
// 检测鱼是否移动结束
private checkFishMoveEnd() {
this.fishList.forEach(async (item: FishBase, key: string) => {
if (this.isFishMap) {
// 鱼阵回收
if (item.isDead === 2) {
item.node.getPosition(this._fishPosCache)
this._fishPosCache.x -= 2
item.node.setPosition(this._fishPosCache)
if (this._fishPosCache.x <= -screen.width / 2) {
// winSize.width
await WsManager.instance.onSend({
type: 102,
fish_id: item.fishId,
})
// this.fishList.splice(index, 1)
this.destroyFish(item)
// this.fishList.delete(item.fishId)
this.checkEndFishMap()
}
}
} else if (!item.getComponent(FishMover).isMoving) {
// 普通鱼回收
await WsManager.instance.onSend({
type: 102,
fish_id: item.fishId,
})
// this.fishList.splice(index, 1)
this.destroyFish(item)
// this.fishList.delete(item.fishId)
}
})
}
private checkEndFishMap() {
// Logger.log('checkEndFishMap==', this.isFishMap, this.fishList)
if (this.isFishMap && this.fishList.size <= 0) {
this.isFishMap = false
// this.randomFish()
}
}
/**
* 原:本地随机生成鱼
* 新:服务端生成鱼
*/
private async randomFish(data: dataType) {
const arr = data.fisn
const paths: Array<FishPathInfo> = []
if (!Array.isArray(arr) || this.isFishMap) return
for (let i = 0; i < arr.length; i++) {
const fish: FishBase = this.createFishByType(arr[i])
for (let k = 0; k < arr[i].fishPathInfo.length; k++) {
const path: Array<Vec2> = []
for (let j = 0; j < arr[i].fishPathInfo[k].path.length; j++) {
const p: Vec2 = new Vec2(
arr[i].fishPathInfo[k].path[j].x,
arr[i].fishPathInfo[k].path[j].y,
)
path.push(p)
}
paths.push(new FishPathInfo(arr[i].fishPathInfo[k].pathId, path))
}
fish.fishPathInfo = paths[0]
this._fishPosCache.z = 0
this._fishPosCache.x = fish.fishPathInfo.path[0].x
this._fishPosCache.y = fish.fishPathInfo.path[0].y
fish.node.setPosition(this._fishPosCache)
fish.getComponent(FishMover).bezierPList = fish.fishPathInfo.path
fish.getComponent(FishMover).startMove()
// this.fishList.push(fish)
this.fishList.set(fish.fishId, fish)
// this.fishContainer.addChild(fish.node)
this.fishContainer.addChild(this.fishList.get(fish.fishId).node)
}
}
// 创建鱼类
public createFishByType(data: FishType | any): FishBase {
let fishNode: Node
const fishType: number = Number(data.fishType)
if (this.fishPool[fishType - 1] && this.fishPool[fishType - 1].size() > 0) {
fishNode = this.fishPool[fishType - 1].get()
} else {
fishNode = instantiate(this.fishPrefabList[fishType - 1])
}
TimeHelper.exeNextFrame(fishNode, () => fishNode.getComponent(Animation).play())
const fishInfo: FishInfo = FishConfig.getFishInfoByType(fishType)
fishNode.getComponent(FishBase).fishInfo = fishInfo
fishNode.getComponent(FishBase).fishType = fishType
fishNode.getComponent(FishBase).fishId = data.fishId
fishNode.getComponent(FishBase).isDead = 2
return fishNode.getComponent(FishBase)
}
// 销毁鱼类
public killFish(res: any) {
const fishCheck = this.fishList.get(res.fish_id)
// console.log('正在执行销毁=', fishCheck.fishId, res.fish_id, res.fish_status, fishCheck.isDead)
if (fishCheck) {
fishCheck.isDead = 1
setTimeout(() => {
GameMusicHelper.playFishDead(fishCheck.fishType)
fishCheck.node.getPosition(this._fishPosCache)
const vec2 = new Vec2(this._fishPosCache.x, this._fishPosCache.y)
ScoreManager.instance.addScore(Number(res.fish_number), vec2)
this.destroyFish(fishCheck)
// console.log('killFish=', fishCheck.fishId, fishCheck.fishInfo.name)
this.checkEndFishMap()
}, 500)
tween(fishCheck.node)
.repeatForever(tween().by(0.6, { angle: -360 }))
.start()
// this.fishList.splice(index, 1)
}
}
private destroyFish(fish: FishBase) {
const f = this.fishList.get(fish.fishId)
if (!f) return
if (!this.fishPool[f.fishType - 1]) {
this.fishPool[f.fishType - 1] = new NodePool()
}
this.fishPool[f.fishType - 1].put(f.node)
this.fishList.delete(f.fishId)
}
public playFishMap() {
this.isFishMap = true
this.fishList.forEach((fish: FishBase, key: string) => {
this.destroyFish(fish)
})
}
public startFishMap() {
const map: FishMap = FishPathConfig.randomFishMap()
const fishMapInfoList: Array<FishMapInfo> = map.fishMapInfoList
Logger.log('startFishMap==', this.isFishMap, this.fishList, map)
for (let i = 0; i < fishMapInfoList.length; i++) {
const fishMapInfo: FishMapInfo = fishMapInfoList[i]
// 暂时屏蔽
// @ts-ignore
const fish: FishBase = this.createFishByType(fishMapInfo.fishType)
fish.node.angle = 0
this.fishContainer.addChild(fish.node)
fish.node.setPosition(fishMapInfo.x + screen.width, fishMapInfo.y)
this.fishList.set(fish.fishId, fish)
}
}
onDestroy() {
FishManager.instance = null
WsManager.instance.off(100)
}
protected onDisable(): void {}
}
import {
Animation,
Component,
Node,
NodePool,
Prefab,
Tween,
Vec2,
Vec3,
_decorator,
game,
instantiate,
tween,
} from 'cc'
import FishBase from '../../../fish/script/FishBase'
import FishMover from '../../../fish/script/FishMover'
import FishUI from '../../../fish/script/FishUI'
import { Logger } from '../../engine/utils/Logger'
import RandomUtil from '../../engine/utils/RandomUtil'
import { FishConfig } from '../config/FishConfig'
import { FishInfo } from '../config/FishInfo'
import { FishMap } from '../config/FishMap'
import { FishMapInfo } from '../config/FishMapInfo'
import { FishPathConfig } from '../config/FishPathConfig'
import GameMusicHelper from '../utils/GameMusicHelper'
import TimeHelper from '../utils/TimeHelper'
import ScoreManager from './ScoreManager'
import WsManager from './WsManager'
import { FishPathInfo } from '../config/FishPathInfo'
const { ccclass, property } = _decorator
interface dataType {
fisn: Array<FishType>
}
interface FishType {
fishId: string
fishInfo: FishInfo
fishType: string
isDead: number
fishPathInfo: Array<fishPathInfoType>
}
interface fishPathInfoType {
pathId: string
path: Array<PathPoint>
}
interface PathPoint {
x: number
y: number
}
// 鱼管理类
@ccclass('FishManager')
export default class FishManager extends Component {
public static instance: FishManager = null
@property({ type: Node })
private fishContainer: Node | null = null
@property({ type: [Prefab] })
public fishPrefabList: Array<Prefab> = []
private fishPool: Array<NodePool> = []
private fishList: Map<string, FishBase> = new Map()
private nextRandomFishTime: number = 0
private minRandomTime: number = 2 * (game.frameRate as number)
private maxRandomTime: number = 5 * (game.frameRate as number)
private isFishMap: boolean = false
private mapCount: number = 0
private _fishPosCache: Vec3
onLoad() {
WsManager.instance.on(100, this.randomFish, this)
FishManager.instance = this
this._fishPosCache = new Vec3()
Logger.log('maxRandomTime=', this.minRandomTime, this.maxRandomTime, game.frameRate)
}
start() {
// this.randomFish()
}
update() {
// this.checkRandomFish()
this.checkFishMoveEnd()
// this.checkFishMap()
}
private checkFishMap() {
if (!this.isFishMap) {
if (this.mapCount > 0) {
this.mapCount--
if (this.mapCount <= 0) FishUI.instance.playWaveEffect()
}
}
}
// 检测是否随机鱼
private checkRandomFish() {
if (!this.isFishMap) {
if (this.nextRandomFishTime > 0) {
this.nextRandomFishTime--
// if (this.nextRandomFishTime === 0) this.randomFish()
}
}
}
// 检测鱼是否移动结束
private checkFishMoveEnd() {
this.fishList.forEach(async (item: FishBase, key: string) => {
if (this.isFishMap) {
// 鱼阵回收
if (item.isDead === 2) {
item.node.getPosition(this._fishPosCache)
this._fishPosCache.x -= 2
item.node.setPosition(this._fishPosCache)
if (this._fishPosCache.x <= -screen.width / 2) {
// winSize.width
await WsManager.instance.onSend({
type: 102,
fish_id: item.fishId,
})
// this.fishList.splice(index, 1)
this.destroyFish(item)
// this.fishList.delete(item.fishId)
this.checkEndFishMap()
}
}
} else if (!item.getComponent(FishMover).isMoving) {
// 普通鱼回收
await WsManager.instance.onSend({
type: 102,
fish_id: item.fishId,
})
// this.fishList.splice(index, 1)
this.destroyFish(item)
// this.fishList.delete(item.fishId)
}
})
}
private checkEndFishMap() {
// Logger.log('checkEndFishMap==', this.isFishMap, this.fishList)
if (this.isFishMap && this.fishList.size <= 0) {
this.isFishMap = false
// this.randomFish()
}
}
/**
* 原:本地随机生成鱼
* 新:服务端生成鱼
*/
private async randomFish(data: dataType) {
const arr = data.fisn
const paths: Array<FishPathInfo> = []
if (!Array.isArray(arr) || this.isFishMap) return
for (let i = 0; i < arr.length; i++) {
const fish: FishBase = this.createFishByType(arr[i])
for (let k = 0; k < arr[i].fishPathInfo.length; k++) {
const path: Array<Vec2> = []
for (let j = 0; j < arr[i].fishPathInfo[k].path.length; j++) {
const p: Vec2 = new Vec2(
arr[i].fishPathInfo[k].path[j].x,
arr[i].fishPathInfo[k].path[j].y,
)
path.push(p)
}
paths.push(new FishPathInfo(arr[i].fishPathInfo[k].pathId, path))
}
fish.fishPathInfo = paths[0]
this._fishPosCache.z = 0
this._fishPosCache.x = fish.fishPathInfo.path[0].x
this._fishPosCache.y = fish.fishPathInfo.path[0].y
fish.node.setPosition(this._fishPosCache)
fish.getComponent(FishMover).bezierPList = fish.fishPathInfo.path
fish.getComponent(FishMover).startMove()
// this.fishList.push(fish)
this.fishList.set(fish.fishId, fish)
// this.fishContainer.addChild(fish.node)
this.fishContainer.addChild(this.fishList.get(fish.fishId).node)
}
}
// 创建鱼类
public createFishByType(data: FishType | any): FishBase {
let fishNode: Node
const fishType: number = Number(data.fishType)
if (this.fishPool[fishType - 1] && this.fishPool[fishType - 1].size() > 0) {
fishNode = this.fishPool[fishType - 1].get()
} else {
fishNode = instantiate(this.fishPrefabList[fishType - 1])
}
TimeHelper.exeNextFrame(fishNode, () => fishNode.getComponent(Animation).play())
const fishInfo: FishInfo = FishConfig.getFishInfoByType(fishType)
fishNode.getComponent(FishBase).fishInfo = fishInfo
fishNode.getComponent(FishBase).fishType = fishType
fishNode.getComponent(FishBase).fishId = data.fishId
fishNode.getComponent(FishBase).isDead = 2
return fishNode.getComponent(FishBase)
}
// 销毁鱼类
public killFish(res: any) {
const fishCheck = this.fishList.get(res.fish_id)
// console.log('正在执行销毁=', fishCheck.fishId, res.fish_id, res.fish_status, fishCheck.isDead)
if (fishCheck) {
fishCheck.isDead = 1
setTimeout(() => {
GameMusicHelper.playFishDead(fishCheck.fishType)
fishCheck.node.getPosition(this._fishPosCache)
const vec2 = new Vec2(this._fishPosCache.x, this._fishPosCache.y)
ScoreManager.instance.addScore(Number(res.fish_number), vec2)
this.destroyFish(fishCheck)
// console.log('killFish=', fishCheck.fishId, fishCheck.fishInfo.name)
this.checkEndFishMap()
}, 500)
tween(fishCheck.node)
.repeatForever(tween().by(0.6, { angle: -360 }))
.start()
// this.fishList.splice(index, 1)
}
}
private destroyFish(fish: FishBase) {
const f = this.fishList.get(fish.fishId)
if (!f) return
if (!this.fishPool[f.fishType - 1]) {
this.fishPool[f.fishType - 1] = new NodePool()
}
this.fishPool[f.fishType - 1].put(f.node)
this.fishList.delete(f.fishId)
}
public playFishMap() {
this.isFishMap = true
this.fishList.forEach((fish: FishBase, key: string) => {
this.destroyFish(fish)
})
}
public startFishMap() {
const map: FishMap = FishPathConfig.randomFishMap()
const fishMapInfoList: Array<FishMapInfo> = map.fishMapInfoList
Logger.log('startFishMap==', this.isFishMap, this.fishList, map)
for (let i = 0; i < fishMapInfoList.length; i++) {
const fishMapInfo: FishMapInfo = fishMapInfoList[i]
// 暂时屏蔽
// @ts-ignore
const fish: FishBase = this.createFishByType(fishMapInfo.fishType)
fish.node.angle = 0
this.fishContainer.addChild(fish.node)
fish.node.setPosition(fishMapInfo.x + screen.width, fishMapInfo.y)
this.fishList.set(fish.fishId, fish)
}
}
onDestroy() {
FishManager.instance = null
WsManager.instance.off(100)
}
protected onDisable(): void {}
}

View File

@@ -1,11 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "b20609a9-5a1b-4119-9fb1-399b45155aab",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "b20609a9-5a1b-4119-9fb1-399b45155aab",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -1,53 +1,53 @@
import { Component, Node, NodePool, Prefab, Vec2, Vec3, _decorator, instantiate } from 'cc'
import FishNetBase from '../../../fish/script/FishNetBase'
const { ccclass, property } = _decorator
// 鱼网管理类
@ccclass('FishNetManager')
export default class FishNetManager extends Component {
public static instance: FishNetManager = null
@property({ type: [Prefab] })
private netPrefabList: Prefab[] | [] = []
private fishNetPool: Array<NodePool> = []
onLoad() {
FishNetManager.instance = this
}
// 添加鱼网
public addFishNet(netType: number, p: Vec2) {
const fishNet: FishNetBase = this.createFishNet(netType)
this.node.addChild(fishNet.node)
fishNet.node.setPosition(new Vec3(p.x, p.y, 0))
fishNet.playMv()
}
// 创建鱼网
private createFishNet(netType: number) {
let fishNetNode: Node
if (this.fishNetPool[netType] && this.fishNetPool[netType].size() > 0) {
fishNetNode = this.fishNetPool[netType].get()
} else {
fishNetNode = instantiate(this.netPrefabList[netType])
}
fishNetNode.getComponent(FishNetBase).netType = netType
return fishNetNode.getComponent(FishNetBase)
}
// 销毁鱼网
public destroyFishNet(fishNet: FishNetBase) {
if (!this.fishNetPool[fishNet.netType]) {
this.fishNetPool[fishNet.netType] = new NodePool()
}
this.fishNetPool[fishNet.netType].put(fishNet.node)
}
onDestroy() {
FishNetManager.instance = null
}
}
import { Component, Node, NodePool, Prefab, Vec2, Vec3, _decorator, instantiate } from 'cc'
import FishNetBase from '../../../fish/script/FishNetBase'
const { ccclass, property } = _decorator
// 鱼网管理类
@ccclass('FishNetManager')
export default class FishNetManager extends Component {
public static instance: FishNetManager = null
@property({ type: [Prefab] })
private netPrefabList: Prefab[] | [] = []
private fishNetPool: Array<NodePool> = []
onLoad() {
FishNetManager.instance = this
}
// 添加鱼网
public addFishNet(netType: number, p: Vec2) {
const fishNet: FishNetBase = this.createFishNet(netType)
this.node.addChild(fishNet.node)
fishNet.node.setPosition(new Vec3(p.x, p.y, 0))
fishNet.playMv()
}
// 创建鱼网
private createFishNet(netType: number) {
let fishNetNode: Node
if (this.fishNetPool[netType] && this.fishNetPool[netType].size() > 0) {
fishNetNode = this.fishNetPool[netType].get()
} else {
fishNetNode = instantiate(this.netPrefabList[netType])
}
fishNetNode.getComponent(FishNetBase).netType = netType
return fishNetNode.getComponent(FishNetBase)
}
// 销毁鱼网
public destroyFishNet(fishNet: FishNetBase) {
if (!this.fishNetPool[fishNet.netType]) {
this.fishNetPool[fishNet.netType] = new NodePool()
}
this.fishNetPool[fishNet.netType].put(fishNet.node)
}
onDestroy() {
FishNetManager.instance = null
}
}

View File

@@ -1,11 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "fec491b0-4f6f-4a17-928d-a4ee3c2bb567",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "fec491b0-4f6f-4a17-928d-a4ee3c2bb567",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -1,54 +1,54 @@
import { Component, Node, NodePool, Prefab, Vec2, Vec3, _decorator, instantiate } from 'cc'
import FishUI from '../../../fish/script/FishUI'
import ScorePrefab from '../prefab/ScorePrefab'
const { ccclass, property } = _decorator
@ccclass('ScoreManager')
export default class ScoreManager extends Component {
public static instance: ScoreManager = null
@property({ type: Prefab })
private scrorePrefab: Prefab | null = null
private scorePool: NodePool
onLoad() {
ScoreManager.instance = this
this.scorePool = new NodePool()
}
// 添加积分
public addScore(score: number, p: Vec2) {
const scorePrefab: ScorePrefab = this.createScore(score)
this.node.addChild(scorePrefab.node)
scorePrefab.node.setPosition(new Vec3(p.x, p.y, 0))
scorePrefab.init(score)
scorePrefab.playMoveEffect(new Vec2(-472.398, -547.481), () => {
this.destroyScore(scorePrefab)
// 本地不在添加积分
// FishUI.instance.jf_score += score
// FishUI.instance.refreshScore()
})
}
// 创建积分
private createScore(score: number): ScorePrefab {
let scoreNode: Node
if (this.scorePool && this.scorePool.size() > 0) scoreNode = this.scorePool.get()
else scoreNode = instantiate(this.scrorePrefab)
return scoreNode.getComponent(ScorePrefab)
}
// 销毁积分
private destroyScore(scorePrefab: ScorePrefab) {
this.scorePool.put(scorePrefab.node)
}
onDisable() {}
onDestroy() {
ScoreManager.instance = null
}
}
import { Component, Node, NodePool, Prefab, Vec2, Vec3, _decorator, instantiate } from 'cc'
import FishUI from '../../../fish/script/FishUI'
import ScorePrefab from '../prefab/ScorePrefab'
const { ccclass, property } = _decorator
@ccclass('ScoreManager')
export default class ScoreManager extends Component {
public static instance: ScoreManager = null
@property({ type: Prefab })
private scrorePrefab: Prefab | null = null
private scorePool: NodePool
onLoad() {
ScoreManager.instance = this
this.scorePool = new NodePool()
}
// 添加积分
public addScore(score: number, p: Vec2) {
const scorePrefab: ScorePrefab = this.createScore(score)
this.node.addChild(scorePrefab.node)
scorePrefab.node.setPosition(new Vec3(p.x, p.y, 0))
scorePrefab.init(score)
scorePrefab.playMoveEffect(new Vec2(-472.398, -547.481), () => {
this.destroyScore(scorePrefab)
// 本地不在添加积分
// FishUI.instance.jf_score += score
// FishUI.instance.refreshScore()
})
}
// 创建积分
private createScore(score: number): ScorePrefab {
let scoreNode: Node
if (this.scorePool && this.scorePool.size() > 0) scoreNode = this.scorePool.get()
else scoreNode = instantiate(this.scrorePrefab)
return scoreNode.getComponent(ScorePrefab)
}
// 销毁积分
private destroyScore(scorePrefab: ScorePrefab) {
this.scorePool.put(scorePrefab.node)
}
onDisable() {}
onDestroy() {
ScoreManager.instance = null
}
}

View File

@@ -1,11 +1,11 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "ff2defbe-9c85-4632-b16a-021567da1bdd",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "ff2defbe-9c85-4632-b16a-021567da1bdd",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -1,137 +1,137 @@
import { _decorator } from 'cc'
import CommonTips from '../../engine/uicomponent/CommonTips'
import FishUI from '../../../fish/script/FishUI'
import config from '../config/Config'
export default class WsManager {
private static _instance: WsManager = null
uid: string
message: any
t_id: any = null
public static get instance() {
if (!this._instance) {
this._instance = new WsManager()
}
return this._instance
}
private _socket: WebSocket | null = null
protected m_mapCallbackFun: Map<number, Function>
constructor() {
this.m_mapCallbackFun = new Map<number, Function>()
}
public on(msgId: number, cb: Function, target: any) {
let callback = cb.bind(target)
let fnCallback: Function = this.m_mapCallbackFun.get(msgId)
if (fnCallback) {
console.error('重复注册消息处理函数! msgId:' + msgId)
} else {
this.m_mapCallbackFun.set(msgId, callback)
}
}
public off(msgId: number) {
if (this.m_mapCallbackFun.has(msgId)) {
this.m_mapCallbackFun.delete(msgId)
}
}
public get(msgId: number) {
return this.m_mapCallbackFun.get(msgId)
}
public offAll() {
this.m_mapCallbackFun.clear()
}
// 获取url参数
public getQueryString(name: string) {
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
var r = window.location.search.substr(1).match(reg)
if (r != null) {
return unescape(r[2])
}
return null
}
public init(): void {
this.uid = this.getQueryString('uid')
this._socket = new WebSocket(`wss://${config.wsUrl()}/fish/home?uid=${this.uid}`)
// 添加事件监听器
this._socket.onopen = this.onOpen.bind(this)
this._socket.onmessage = this.onMessage.bind(this)
this._socket.onclose = this.onClose.bind(this)
this._socket.onerror = this.onError.bind(this)
}
public onOpen(): void {
console.log('WebSocket connection opened.')
setInterval(() => {
this._socket.send(JSON.stringify('ping'))
}, 20000)
this.clear()
}
public async onSend(data: any): Promise<void> {
if (this._socket && this._socket.readyState === WebSocket.OPEN) {
this._socket.send(JSON.stringify(data))
} else {
console.error('消息发送失败!!!')
}
}
/**
* 处理接收到的消息
* @param event WebSocket message event
*/
public onMessage(event: MessageEvent): void {
this.message = JSON.parse(event.data)
if (this.message.code === 200 || this.message.code === 5) {
FishUI.instance.refreshScore(this.message)
}
let fnCallback: Function = this.m_mapCallbackFun.get(this.message.code)
if (fnCallback) {
fnCallback(this.message)
}
}
/**
* 关闭WebSocket连接
*/
public onClose(): void {
console.log('链接已关闭')
CommonTips.showMsg('游戏服务器中断关闭,正在重试')
// this.init()
if (this._socket) {
this._socket.close()
this._socket = null
}
this.t_id = setInterval(() => {
WsManager.instance.init()
}, 8000)
}
public onError(event: Event): void {
CommonTips.showMsg('网络连接失败,正在重试链接游戏服务器')
this.t_id = setInterval(() => {
WsManager.instance.init()
}, 8000)
}
public clear() {
if (this.t_id) {
clearInterval(this.t_id)
this.t_id = null
}
}
}
import { _decorator } from 'cc'
import CommonTips from '../../engine/uicomponent/CommonTips'
import FishUI from '../../../fish/script/FishUI'
import config from '../config/Config'
export default class WsManager {
private static _instance: WsManager = null
uid: string
message: any
t_id: any = null
public static get instance() {
if (!this._instance) {
this._instance = new WsManager()
}
return this._instance
}
private _socket: WebSocket | null = null
protected m_mapCallbackFun: Map<number, Function>
constructor() {
this.m_mapCallbackFun = new Map<number, Function>()
}
public on(msgId: number, cb: Function, target: any) {
let callback = cb.bind(target)
let fnCallback: Function = this.m_mapCallbackFun.get(msgId)
if (fnCallback) {
console.error('重复注册消息处理函数! msgId:' + msgId)
} else {
this.m_mapCallbackFun.set(msgId, callback)
}
}
public off(msgId: number) {
if (this.m_mapCallbackFun.has(msgId)) {
this.m_mapCallbackFun.delete(msgId)
}
}
public get(msgId: number) {
return this.m_mapCallbackFun.get(msgId)
}
public offAll() {
this.m_mapCallbackFun.clear()
}
// 获取url参数
public getQueryString(name: string) {
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
var r = window.location.search.substr(1).match(reg)
if (r != null) {
return unescape(r[2])
}
return null
}
public init(): void {
this.uid = this.getQueryString('uid')
this._socket = new WebSocket(`wss://${config.wsUrl()}/fish/home?uid=${this.uid}`)
// 添加事件监听器
this._socket.onopen = this.onOpen.bind(this)
this._socket.onmessage = this.onMessage.bind(this)
this._socket.onclose = this.onClose.bind(this)
this._socket.onerror = this.onError.bind(this)
}
public onOpen(): void {
console.log('WebSocket connection opened.')
setInterval(() => {
this._socket.send(JSON.stringify('ping'))
}, 20000)
this.clear()
}
public async onSend(data: any): Promise<void> {
if (this._socket && this._socket.readyState === WebSocket.OPEN) {
this._socket.send(JSON.stringify(data))
} else {
console.error('消息发送失败!!!')
}
}
/**
* 处理接收到的消息
* @param event WebSocket message event
*/
public onMessage(event: MessageEvent): void {
this.message = JSON.parse(event.data)
if (this.message.code === 200 || this.message.code === 5) {
FishUI.instance.refreshScore(this.message)
}
let fnCallback: Function = this.m_mapCallbackFun.get(this.message.code)
if (fnCallback) {
fnCallback(this.message)
}
}
/**
* 关闭WebSocket连接
*/
public onClose(): void {
console.log('链接已关闭')
CommonTips.showMsg('游戏服务器中断关闭,正在重试')
// this.init()
if (this._socket) {
this._socket.close()
this._socket = null
}
this.t_id = setInterval(() => {
WsManager.instance.init()
}, 8000)
}
public onError(event: Event): void {
CommonTips.showMsg('网络连接失败,正在重试链接游戏服务器')
this.t_id = setInterval(() => {
WsManager.instance.init()
}, 8000)
}
public clear() {
if (this.t_id) {
clearInterval(this.t_id)
this.t_id = null
}
}
}

View File

@@ -1,9 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "44f1bff8-2972-4ae5-8f53-e0daaa97b92e",
"files": [],
"subMetas": {},
"userData": {}
}
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "44f1bff8-2972-4ae5-8f53-e0daaa97b92e",
"files": [],
"subMetas": {},
"userData": {}
}