Skip to content

Commit

Permalink
v1.7 修复防御塔子弹丢失目标原地滞留的BUG;模仿优先队列处理防御塔的攻击目标,修复自动攻击时目标锁定错误的BUG
Browse files Browse the repository at this point in the history
  • Loading branch information
yu0107an committed Oct 13, 2024
1 parent 6d95fa6 commit 3fc6c5f
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 32 deletions.
4 changes: 1 addition & 3 deletions assets/Script/MainScene/Bullet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,4 @@ export class Bullet extends Component implements IObserver {
let bulletPool = this.node.parent.getComponent(BulletLayer).bulletPools.get(this.id);
bulletPool.put(this.node);
}
}


}
4 changes: 4 additions & 0 deletions assets/Script/MainScene/BulletChildren.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ export class BulletChildren extends Component {
EventManager.Instance.reduceHp_Enemy(other.node, this.node.parent.getComponent(Bullet).atk);
break;
case 32:
if (this.node.parent.getComponent(Bullet).target !== other.node)
{
return;
}
EventManager.Instance.reduceHp_Obstacle(other.node, this.node.parent.getComponent(Bullet).atk);
break;
default:
Expand Down
4 changes: 4 additions & 0 deletions assets/Script/MainScene/BulletLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ export class BulletLayer extends Component {

addBullet(name: string, towerId: number, towerLevel: number, pos: Vec3, target: Node, angle: number)
{
if (!target || !target.parent)
{
return;
}
let bulletPool = this.bulletPools.get(towerId);
let bullet = bulletPool.get(name, towerLevel, target);
if (bullet === null)
Expand Down
6 changes: 5 additions & 1 deletion assets/Script/MainScene/Enemy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,12 @@ export class Enemy extends Component implements IObserver {

recycleSelf()
{
if (this.node.parent.children.length === 1)
{
this.node.parent.getComponent(EnemyLayer).createEnemy();
}
EventManager.Instance.createEffect(this.node.position, 'Air');
let enemyPool = this.node.parent.getComponent(EnemyLayer).enemyPool;
let enemyPool = this.node.parent.getComponent(EnemyLayer).enemyPools.get(this.node.name);
enemyPool.put(this.node);
}

Expand Down
52 changes: 39 additions & 13 deletions assets/Script/MainScene/EnemyLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,58 +7,78 @@ const { ccclass, property } = _decorator;
@ccclass('EnemyLayer')
export class EnemyLayer extends Component implements IObserver {

enemyPool: NodePool;
enemyPools: Map<string, NodePool> = new Map<string, NodePool>();
@property(JsonAsset)
monsterDt: JsonAsset;
@property([Prefab])
enemyPrefab: Prefab[] = new Array<Prefab>();
curWave: number = 1;
curWave: number = 0;
monsterId: any;
waveDt: any;
path: Array<struct>;
enemyCount: number = 0;
eventIndex: number = 0;
curWaveFinish: boolean = true;

start() {

}

init(monsterId: any, waveDt: any, path: struct[])
{
this.enemyPool = new NodePool('Enemy');
this.path = path;
this.enemyPrefab.forEach((value,index) => {
this.enemyPrefab.forEach((prefab, index) => {
let enemyPool = new NodePool('Enemy');
for (let i = 0; i < 8; i++)
{
let newNode = instantiate(value);
newNode.name = value.name;
let newNode = instantiate(prefab);
newNode.name = prefab.name;
newNode.getComponent(Enemy).init(this.monsterDt.json[index]);
this.enemyPool.put(newNode);
enemyPool.put(newNode);
}
this.enemyPools.set(prefab.name, enemyPool);
})
this.monsterId = monsterId;
this.waveDt = waveDt;
EventManager.Instance.addObserver(this, IObserverType.GameState);
}

//创建一波敌人
createEnemy()
{
if (!this.curWaveFinish)
{
return;
}
this.curWave += 1;
this.curWaveFinish = false;
let totalEnemies = this.waveDt[this.curWave - 1];
this.enemyCount = 0;
EventManager.Instance.addObserver(this, IObserverType.GameState);
this.schedule(this.createEnemyTimer, 0.8, totalEnemies - this.enemyCount - 1, 2);
}

createEnemyTimer()
{
let newEnemy = this.enemyPool.get(this.path);
if (newEnemy === null)
let availablePools = Array.from(this.enemyPools.values()).filter(pool => pool.size() > 0);
let newEnemy;
if (availablePools.length > 0)
{
let enemyPool = availablePools[Math.floor(Math.random() * availablePools.length)];
newEnemy = enemyPool.get(this.path);
}
else
{
let monsterId = this.monsterId[Math.floor(Math.random() * this.monsterId.length)];
newEnemy = instantiate(this.enemyPrefab[monsterId]);
}
this.node.addChild(newEnemy);
EventManager.Instance.createEffect(v3(-360, 120), 'Appear', newEnemy);
this.enemyCount += 1;
//当前波次出怪完成
if (this.enemyCount === this.waveDt[this.curWave - 1])
{
this.curWaveFinish = true;
}
}

reduceHp_Enemy(enemy: Node, atk: number)
Expand All @@ -80,12 +100,18 @@ export class EnemyLayer extends Component implements IObserver {

pauseCreateEnemy()
{
this.unschedule(this.createEnemyTimer);
if (!this.curWaveFinish)
{
this.unschedule(this.createEnemyTimer);
}
}

resumeCreateEnemy()
{
let totalEnemies = this.waveDt[this.curWave - 1];
this.schedule(this.createEnemyTimer, 0.8, totalEnemies - this.enemyCount - 1, 0);
if (!this.curWaveFinish)
{
let totalEnemies = this.waveDt[this.curWave - 1];
this.schedule(this.createEnemyTimer, 0.8, totalEnemies - this.enemyCount - 1, 0);
}
}
}
4 changes: 2 additions & 2 deletions assets/Script/MainScene/EventManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ export class EventManager {
this.UI2Ts.enableAllButton();
}

//创建一波敌人
//开始创建敌人(一关只调用一次)
createEnemy()
{
this.enemyLayerTs.createEnemy();
Expand Down Expand Up @@ -229,7 +229,7 @@ export class EventManager {
//Carrot扣血
reduceHp_Carrot(count: number)
{
this.carrotTs.reduceHp(count);
//this.carrotTs.reduceHp(count);
}

//障碍物扣血
Expand Down
1 change: 1 addition & 0 deletions assets/Script/MainScene/Obstacle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export class Obstacle extends Component {
{
EventManager.Instance.createEffect(this.node.position, 'Air', null, null);
EventManager.Instance.createEffect(this.node.position, 'Money', null, this.reward);
EventManager.Instance.cancelAttackPoint();
this.node.destroy();
}
let percent = this.curHp / this.maxHp;
Expand Down
36 changes: 24 additions & 12 deletions assets/Script/MainScene/Tower.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { _decorator, Component, Node, v2, Animation } from 'cc';
import { EventManager, IObserverType } from './EventManager';
import { TowerChildren } from './TowerChildren';
import { PriorityQueue } from '../PriorityQueue';
const { ccclass, property } = _decorator;

@ccclass('Tower')
Expand All @@ -12,7 +13,7 @@ export class Tower extends Component implements IObserver {
sellPrice: number[];//卖塔所得费用
shootSpeed: number[];//射击速度
attackRange: number[];//攻击范围
attackTarget_Enemy: Node[] = new Array<Node>();//在范围内的敌人集合
attackTarget_Enemy: PriorityQueue = new PriorityQueue;//在范围内的敌人集合
attackTarget_Obstacle: Node[] = new Array<Node>();//在范围内的障碍物集合
curAttackTarget: Node;//当前攻击目标
attackPoint: Node;//攻击点(玩家手动点击的攻击目标,优先处理攻击点)
Expand Down Expand Up @@ -83,19 +84,25 @@ export class Tower extends Component implements IObserver {
if (target === EventManager.Instance.getAttackPoint())
{
this.attackPoint = target;
this.curAttackTarget = target;
}
}
else
{
if (this.attackTarget_Enemy[0] === EventManager.Instance.getAttackPoint())
if (target)
{
this.attackPoint = null;
this.attackTarget_Enemy.splice(this.attackTarget_Enemy.findIndex(target), 1);
}
else
{
if (this.attackTarget_Enemy[0] === EventManager.Instance.getAttackPoint())
{
this.attackPoint = null;
}
this.attackTarget_Enemy.shift();
}
this.attackTarget_Enemy.shift();
this.changeState('idle');
}
this.curAttackTarget = this.attackTarget_Enemy[0];
this.curAttackTarget = this.attackTarget_Enemy.get(0);
}

//将障碍物加进自身范围
Expand All @@ -110,11 +117,11 @@ export class Tower extends Component implements IObserver {
let index = -1;
if (target.parent.name === 'EnemyLayer')
{
index = this.attackTarget_Enemy.findIndex(value => value === target)
index = this.attackTarget_Enemy.findIndex(target);
}
else if (target.parent.name === 'ObstacleLayer')
{
index = this.attackTarget_Obstacle.findIndex(value => value === target)
index = this.attackTarget_Obstacle.findIndex(value => value === target);
}

if (index !== -1)
Expand Down Expand Up @@ -176,22 +183,27 @@ export class Tower extends Component implements IObserver {
}

update(deltaTime: number) {
if (this.isPause || (!this.attackPoint && !this.curAttackTarget))
if (this.isPause || (!this.attackPoint && this.attackTarget_Enemy.size() === 0))
{
return;
}

let target;
let target = null;
if (this.attackPoint)
{
target = this.attackPoint;
this.update_attackPoint(target);
}
else
else if(this.curAttackTarget)
{
target = this.curAttackTarget;
this.update_attackTarget(target);
}
else
{
console.log(1)
this.changeAttackNumber(false);
}
}

// 插值函数,用于计算平滑角度变化
Expand Down Expand Up @@ -235,7 +247,7 @@ export class Tower extends Component implements IObserver {
let rotation = Math.atan2(dir.y, dir.x) * (180 / Math.PI) - 90;
this.node.children[this.level - 1].angle = this.lerpAngle(this.node.children[this.level - 1].angle, rotation, 0.15);

if (Math.floor(this.node.children[this.level - 1].angle) + 1 >= Math.floor(rotation) - 1)
if (Math.floor(this.node.children[this.level - 1].angle) + 3 >= Math.floor(rotation) - 1)
{
this.changeState('shot');
}
Expand Down
2 changes: 1 addition & 1 deletion assets/Script/MainScene/TowerChildren.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export class TowerChildren extends Component {
switch (other.group)
{
case 4:
this.node.parent.getComponent(Tower).changeAttackNumber(false);
this.node.parent.getComponent(Tower).changeAttackNumber(false, other.node);
break;
default:
break;
Expand Down
92 changes: 92 additions & 0 deletions assets/Script/PriorityQueue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Component, Node } from "cc";
import { Enemy } from "./MainScene/Enemy";

export class PriorityQueue extends Component
{

nodes: Node[];

constructor()
{
super();
this.nodes = new Array<Node>();
}

swap(curIndex: number, targetIndex: number)
{
let temp = this.nodes[curIndex];
this.nodes[curIndex] = this.nodes[targetIndex];
this.nodes[targetIndex] = temp;
}

get(index: number): Node | undefined
{
return this.nodes[index];
}

push(node: Node)
{
this.nodes.push(node);
if (this.nodes.length <= 1)
{
return;
}
for (let i = this.nodes.length - 1; i > 0; i--)
{
if (this.compare(i, i - 1))
{
this.swap(i, i - 1);
}
else
{
break;
}
}
}

shift()
{
this.nodes.shift();
}

splice(index: number, count: number)
{
this.nodes.splice(index, count);
}

findIndex(node: Node): number
{
return this.nodes.findIndex(value => value === node);
}

size(): number
{
return this.nodes.length;
}

private compare(curIndex: number, targetIndex: number): Boolean
{
let curNode = this.nodes[curIndex].getComponent(Enemy);
let targetNode = this.nodes[targetIndex].getComponent(Enemy);
if (curNode.curPath > targetNode.curPath)
{
return true;
}
else if (curNode.curPath === targetNode.curPath)
{
let x1 = Math.abs(curNode.node.position.x - curNode.path[curNode.curPath + 1].x);
let y1 = Math.abs(curNode.node.position.y - curNode.path[curNode.curPath + 1].y);

let x2 = Math.abs(targetNode.node.position.x - targetNode.path[targetNode.curPath + 1].x);
let y2 = Math.abs(targetNode.node.position.y - targetNode.path[targetNode.curPath + 1].y);
return x1 + y1 < x2 + y2;
}
else
{
return false;
}

}
}


9 changes: 9 additions & 0 deletions assets/Script/PriorityQueue.ts.meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "86d93424-7905-407b-9f17-6e7f31581546",
"files": [],
"subMetas": {},
"userData": {}
}

0 comments on commit 3fc6c5f

Please sign in to comment.