feat(game): 新增3个角色、修复实习生攻击特效、加速开发子弹、每波结束自动进入下一波
This commit is contained in:
@@ -1,21 +1,27 @@
|
||||
import type Phaser from 'phaser'
|
||||
import { GameManager } from '../GameManager'
|
||||
import { TILE_SIZE, HUD_HEIGHT, COFFEE_COST } from '../constants'
|
||||
import { PATH_TILES } from '../mapRenderer'
|
||||
import { getCellSize } from '../mapRenderer'
|
||||
import { COFFEE_COST } from '../constants'
|
||||
import type { EnemyBase } from '../enemies/EnemyBase'
|
||||
import { TowerBase } from './TowerBase'
|
||||
import { InternTower } from './InternTower'
|
||||
import { SeniorDevTower } from './SeniorDevTower'
|
||||
import { PPTMasterTower } from './PPTMasterTower'
|
||||
import { HRBPTower } from './HRBPTower'
|
||||
import { PMTower } from './PMTower'
|
||||
import { OpsTower } from './OpsTower'
|
||||
import { OutsourceTower } from './OutsourceTower'
|
||||
|
||||
export type TowerType = 'intern' | 'senior' | 'ppt' | 'hrbp'
|
||||
export type TowerType = 'intern' | 'senior' | 'ppt' | 'hrbp' | 'pm' | 'ops' | 'outsource'
|
||||
|
||||
export const TOWER_COSTS: Record<TowerType, number> = {
|
||||
intern: 50,
|
||||
senior: 120,
|
||||
ppt: 100,
|
||||
hrbp: 80,
|
||||
outsource: 30,
|
||||
intern: 50,
|
||||
hrbp: 80,
|
||||
ops: 90,
|
||||
ppt: 100,
|
||||
senior: 120,
|
||||
pm: 160,
|
||||
}
|
||||
|
||||
export class TowerManager {
|
||||
@@ -30,11 +36,22 @@ export class TowerManager {
|
||||
|
||||
canPlace(gridX: number, gridY: number): boolean {
|
||||
const key = `${gridX},${gridY}`
|
||||
return !PATH_TILES.has(key) && !this.occupiedCells.has(key)
|
||||
// 用 occupiedCells 判断,路径判断由 GameScene 传入的 currentPathTiles 负责
|
||||
return !this.occupiedCells.has(key)
|
||||
}
|
||||
|
||||
setCurrentPathTiles(tiles: Set<string>): void {
|
||||
this._pathTiles = tiles
|
||||
}
|
||||
private _pathTiles: Set<string> = new Set()
|
||||
|
||||
canPlaceWithPath(gridX: number, gridY: number): boolean {
|
||||
const key = `${gridX},${gridY}`
|
||||
return !this._pathTiles.has(key) && !this.occupiedCells.has(key)
|
||||
}
|
||||
|
||||
placeTower(gridX: number, gridY: number, type: TowerType): boolean {
|
||||
if (!this.canPlace(gridX, gridY)) return false
|
||||
if (!this.canPlaceWithPath(gridX, gridY)) return false
|
||||
|
||||
const cost = TOWER_COSTS[type]
|
||||
const manager = GameManager.getInstance()
|
||||
@@ -54,14 +71,13 @@ export class TowerManager {
|
||||
|
||||
private createTower(type: TowerType, gridX: number, gridY: number): TowerBase {
|
||||
switch (type) {
|
||||
case 'senior':
|
||||
return new SeniorDevTower(this.scene, gridX, gridY)
|
||||
case 'ppt':
|
||||
return new PPTMasterTower(this.scene, gridX, gridY)
|
||||
case 'hrbp':
|
||||
return new HRBPTower(this.scene, gridX, gridY)
|
||||
default:
|
||||
return new InternTower(this.scene, gridX, gridY)
|
||||
case 'senior': return new SeniorDevTower(this.scene, gridX, gridY)
|
||||
case 'ppt': return new PPTMasterTower(this.scene, gridX, gridY)
|
||||
case 'hrbp': return new HRBPTower(this.scene, gridX, gridY)
|
||||
case 'pm': return new PMTower(this.scene, gridX, gridY)
|
||||
case 'ops': return new OpsTower(this.scene, gridX, gridY)
|
||||
case 'outsource': return new OutsourceTower(this.scene, gridX, gridY)
|
||||
default: return new InternTower(this.scene, gridX, gridY)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,11 +120,12 @@ export class TowerManager {
|
||||
return
|
||||
}
|
||||
|
||||
const { cellW } = getCellSize()
|
||||
const hasTarget = enemies.some((e) => {
|
||||
if (e.isDead) return false
|
||||
const dx = e.x - tower['px']
|
||||
const dy = e.y - tower['py']
|
||||
return Math.sqrt(dx * dx + dy * dy) <= tower.attackRange * TILE_SIZE
|
||||
return Math.sqrt(dx * dx + dy * dy) <= tower.attackRange * cellW
|
||||
})
|
||||
|
||||
if (hasTarget && tower['attackCooldown'] <= 0) {
|
||||
@@ -149,14 +166,14 @@ export class TowerManager {
|
||||
|
||||
private showTowerInfo(tower: TowerBase): void {
|
||||
this.infoLabel?.destroy()
|
||||
|
||||
const px = tower.gridX * TILE_SIZE + TILE_SIZE / 2
|
||||
const py = tower.gridY * TILE_SIZE + TILE_SIZE / 2 + HUD_HEIGHT
|
||||
const { cellW, cellH } = getCellSize()
|
||||
const { x: cx, y: cy } = tower.getPixelCenter()
|
||||
void cx // suppress unused warning (used in label position below)
|
||||
|
||||
const label = this.scene.add
|
||||
.text(
|
||||
px,
|
||||
py - 40,
|
||||
cx,
|
||||
cy - 40,
|
||||
`精力: ${Math.floor(tower.stamina)}% [点击购买咖啡 ${COFFEE_COST}HC]`,
|
||||
{
|
||||
fontFamily: 'VT323, monospace',
|
||||
|
||||
Reference in New Issue
Block a user