fix(game): 崩溃修复(卸载区块实体冻结)+ 立面光照、掉落可见、打击感、水下效果、空手拳头、血条左/饥饿右
- 崩溃(index out of range):实体所在区块卸载后失去碰撞支撑无限下坠到 负坐标,光查询越界 panic——WorldView 增 ChunkLoaded,未加载区块实体冻结; chunk 光查询加越界防御(双保险) - 立面光照:mesh 每面取**邻格**光照(原版光照模型)——此前用方块自身光照 (sky=0)导致悬崖/矿洞立面全黑(泥土竖向黑色根因) - 掉落可见:生成后 1 秒拾取延迟 + 图标加大到 0.45 - 打击感:攻击命中音(block.hit)+ 实体受击白闪(uTint)+ 手持挥动动画 - 水下效果:相机入水蓝色叠加(渲染.md §8 水体) - 空手显示肤色拳头(白羊毛 × 肤色 tint),持方块正常显示 - HUD 布局:血条左下、饥饿右下(经典布局)
This commit is contained in:
@@ -204,6 +204,39 @@ func (w *World) BlockUnlocked(x, y, z int32) block.State {
|
||||
// VillageAt 返回 (x,z) 附近的村庄中心(村民生成定位,村民系统.md §2)。
|
||||
func (w *World) VillageAt(x, z int32) ([2]int32, bool) { return w.gen.VillageAt(x, z) }
|
||||
|
||||
// ChunkLoaded 区块是否已加载(entity.WorldView 接口:卸载区块冻结实体)。
|
||||
func (w *World) ChunkLoaded(x, z int32) bool {
|
||||
w.mu.RLock()
|
||||
_, ok := w.chunks[coordKey(coord.ChunkCoord(x), coord.ChunkCoord(z))]
|
||||
w.mu.RUnlock()
|
||||
return ok
|
||||
}
|
||||
|
||||
// SkyLightUnlocked 无锁读天空光(仅在 WithReadLock 回调内调用,mesh 构建面光照用;
|
||||
// 未加载区块返回 15——面朝向未加载区时按天空亮度处理)。
|
||||
func (w *World) SkyLightUnlocked(x, y, z int32) uint8 {
|
||||
if y < 0 || y >= chunk.Height {
|
||||
return 15
|
||||
}
|
||||
ch := w.chunks[coordKey(coord.ChunkCoord(x), coord.ChunkCoord(z))]
|
||||
if ch == nil {
|
||||
return 15
|
||||
}
|
||||
return ch.SkyLight(int(coord.LocalCoord(x)), int(y), int(coord.LocalCoord(z)))
|
||||
}
|
||||
|
||||
// BlockLightUnlocked 无锁读方块光(仅在 WithReadLock 回调内调用;未加载返回 0)。
|
||||
func (w *World) BlockLightUnlocked(x, y, z int32) uint8 {
|
||||
if y < 0 || y >= chunk.Height {
|
||||
return 0
|
||||
}
|
||||
ch := w.chunks[coordKey(coord.ChunkCoord(x), coord.ChunkCoord(z))]
|
||||
if ch == nil {
|
||||
return 0
|
||||
}
|
||||
return ch.BlockLight(int(coord.LocalCoord(x)), int(y), int(coord.LocalCoord(z)))
|
||||
}
|
||||
|
||||
// SetBlock 世界级写方块(含火把光源联动,方块交互与动画.md §9):
|
||||
// 放置光源 → 初始化亮度 + BFS;移除光源 → relight 重算。
|
||||
func (w *World) SetBlock(x, y, z int32, s block.State) {
|
||||
|
||||
Reference in New Issue
Block a user