1
This commit is contained in:
@@ -524,6 +524,11 @@ export class GameEngine {
|
||||
}
|
||||
}
|
||||
|
||||
// 更新坚果墙体
|
||||
if (state.nutWalls !== undefined) {
|
||||
this.scene.updateNutWalls(state.nutWalls)
|
||||
}
|
||||
|
||||
// 更新游戏状态
|
||||
if (state.gameTime !== undefined) this.gameTime = state.gameTime
|
||||
if (state.waveNumber !== undefined) this.waveNumber = state.waveNumber
|
||||
|
||||
@@ -33,6 +33,7 @@ export class GameScene {
|
||||
this.loots = new Map() // Map<lootId, {mesh, type}>
|
||||
this.effects = [] // 特效数组
|
||||
this.wallMeshes = [] // 墙壁网格
|
||||
this.nutWalls = new Map() // Map<key, {mesh, healthBar}>
|
||||
|
||||
// 摄像机辅助
|
||||
this.gridHelper = null
|
||||
@@ -228,6 +229,10 @@ export class GameScene {
|
||||
const zombieSpawnGeo = new THREE.BoxGeometry(1, 0.15, 1)
|
||||
const zombieSpawnMat = new THREE.MeshLambertMaterial({ color: 0xff4400, transparent: true, opacity: 0.7 })
|
||||
|
||||
// 坚果墙体
|
||||
const nutWallGeo = new THREE.BoxGeometry(1, 1.2, 1)
|
||||
const nutWallMat = new THREE.MeshLambertMaterial({ color: 0x8B4513 })
|
||||
|
||||
// 遍历地图数据
|
||||
for (let y = 0; y < GRID_SIZE; y++) {
|
||||
for (let x = 0; x < GRID_SIZE; x++) {
|
||||
@@ -256,6 +261,82 @@ export class GameScene {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新坚果墙体状态
|
||||
* @param {Array} nutWalls 坚果墙体状态数组 [{x, y, health, maxHealth}]
|
||||
*/
|
||||
updateNutWalls(nutWalls) {
|
||||
const currentKeys = new Set()
|
||||
|
||||
for (const wall of nutWalls) {
|
||||
const key = `${wall.x},${wall.y}`
|
||||
currentKeys.add(key)
|
||||
|
||||
if (this.nutWalls.has(key)) {
|
||||
// 更新已有墙体的血量表现
|
||||
const data = this.nutWalls.get(key)
|
||||
const healthPercent = wall.health / wall.maxHealth
|
||||
// 根据血量改变颜色:满血棕色 -> 低血红棕色
|
||||
const r = 0.545 + (1 - healthPercent) * 0.4
|
||||
const g = 0.271 - (1 - healthPercent) * 0.1
|
||||
const b = 0.075 - (1 - healthPercent) * 0.05
|
||||
data.mesh.material.color.setRGB(r, g, b)
|
||||
// 更新血条
|
||||
if (data.healthBar) {
|
||||
data.healthBar.scale.x = healthPercent
|
||||
data.healthBar.material.color.setHex(healthPercent > 0.5 ? 0x00ff00 : healthPercent > 0.25 ? 0xffff00 : 0xff0000)
|
||||
}
|
||||
} else {
|
||||
// 创建新的坚果墙体
|
||||
const nutWallGeo = new THREE.BoxGeometry(1, 1.2, 1)
|
||||
const nutWallMat = new THREE.MeshLambertMaterial({ color: 0x8B4513 })
|
||||
const mesh = new THREE.Mesh(nutWallGeo, nutWallMat)
|
||||
mesh.position.set(wall.x + 0.5, 0.6, wall.y + 0.5)
|
||||
mesh.castShadow = true
|
||||
mesh.receiveShadow = true
|
||||
this.scene.add(mesh)
|
||||
|
||||
// 创建血条背景
|
||||
const barBgGeo = new THREE.PlaneGeometry(0.8, 0.1)
|
||||
const barBgMat = new THREE.MeshBasicMaterial({ color: 0x333333 })
|
||||
const barBg = new THREE.Mesh(barBgGeo, barBgMat)
|
||||
barBg.position.set(wall.x + 0.5, 1.3, wall.y + 0.5)
|
||||
barBg.rotation.x = -Math.PI / 2
|
||||
this.scene.add(barBg)
|
||||
|
||||
// 创建血条前景
|
||||
const barFgGeo = new THREE.PlaneGeometry(0.8, 0.1)
|
||||
const barFgMat = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
|
||||
const barFg = new THREE.Mesh(barFgGeo, barFgMat)
|
||||
barFg.position.set(wall.x + 0.5, 1.31, wall.y + 0.5)
|
||||
barFg.rotation.x = -Math.PI / 2
|
||||
this.scene.add(barFg)
|
||||
|
||||
this.nutWalls.set(key, { mesh, healthBar: barFg, barBg })
|
||||
}
|
||||
}
|
||||
|
||||
// 移除已经不存在的墙体
|
||||
for (const [key, data] of this.nutWalls) {
|
||||
if (!currentKeys.has(key)) {
|
||||
this.scene.remove(data.mesh)
|
||||
data.mesh.geometry.dispose()
|
||||
data.mesh.material.dispose()
|
||||
if (data.healthBar) {
|
||||
this.scene.remove(data.healthBar)
|
||||
data.healthBar.geometry.dispose()
|
||||
data.healthBar.material.dispose()
|
||||
}
|
||||
if (data.barBg) {
|
||||
this.scene.remove(data.barBg)
|
||||
data.barBg.geometry.dispose()
|
||||
data.barBg.material.dispose()
|
||||
}
|
||||
this.nutWalls.delete(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建玩家3D模型
|
||||
* @param {number} color 玩家颜色
|
||||
|
||||
Reference in New Issue
Block a user