This commit is contained in:
wfz
2026-04-26 11:00:59 +08:00
parent 7bffe41d41
commit f1a6f0fd75
19 changed files with 1026 additions and 142 deletions

View File

@@ -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

View File

@@ -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 玩家颜色