Files
ngzz-mc/internal/physics/player_test.go
2026-09-19 14:21:08 +08:00

106 lines
2.4 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package physics
import "testing"
// planeWorld 测试世界:y < 63 全固体,y >= 63 空气;x == 5 一堵墙。
type planeWorld struct{}
func (planeWorld) Solid(x, y, z int32) bool {
return y < 63 || x == 5
}
func (planeWorld) Fluid(x, y, z int32) bool { return false }
// TestFallOntoGround 下落 → 停在 63 层顶部(浮点余量内),OnGround 置位。
func TestFallOntoGround(t *testing.T) {
w := planeWorld{}
p := NewPlayer(0.5, 80, 0.5)
for i := 0; i < 200; i++ {
p.Tick(w, 1.0/20)
}
if p.Pos[1] < 63 || p.Pos[1] >= 63.5 {
t.Fatalf("脚底期望 [63, 63.5),实际 %v", p.Pos[1])
}
if !p.OnGround {
t.Fatal("应判定落地")
}
}
// TestWallBlock 水平移动撞墙不穿墙(物理与碰撞.md §8 踩坑)。
func TestWallBlock(t *testing.T) {
w := planeWorld{}
p := NewPlayer(4.0, 63, 0.5) // 墙在 x=5,玩家宽 0.6(右缘 4.3)
p.Vel[0] = 10
p.Tick(w, 1.0/20)
if p.Pos[0]+p.Width/2 > 5 {
t.Fatalf("穿墙:右缘 %v 超过墙 x=5", p.Pos[0]+p.Width/2)
}
}
// TestJump 起跳与回落。
func TestJump(t *testing.T) {
w := planeWorld{}
p := NewPlayer(0.5, 63, 0.5)
p.Tick(w, 1.0/20) // 先落地判定
if !p.OnGround {
t.Fatal("初始应在地面")
}
p.Jump()
peak := 0.0
for i := 0; i < 100; i++ {
p.Tick(w, 1.0/20)
if p.Pos[1] > peak {
peak = p.Pos[1]
}
if p.OnGround && i > 5 {
break
}
}
if peak < 64.0 {
t.Fatalf("起跳高度过低: %v", peak)
}
}
type waterWorld struct{}
func (waterWorld) Solid(x, y, z int32) bool { return y < 50 }
func (waterWorld) Fluid(x, y, z int32) bool { return y >= 50 && y <= 56 }
func TestOxygenDrainAndRefill(t *testing.T) {
w := waterWorld{}
p := NewPlayer(0.5, 52, 0.5) // 眼睛约 53.6,在水中
p.updateFluid(w)
if !p.EyeInWater {
t.Fatal("眼睛应在水中")
}
p.TickAir(1)
if p.Air >= AirMax {
t.Fatalf("水下氧气应递减,实际 %v", p.Air)
}
for i := 0; i < 20; i++ {
p.TickAir(1)
}
if p.Air != 0 {
t.Fatalf("长时间潜水氧气应为 0,实际 %v", p.Air)
}
p.Pos[1] = 60 // 出水
p.updateFluid(w)
p.TickAir(0.05)
if p.Air != AirMax {
t.Fatalf("出水应回满氧气,实际 %v", p.Air)
}
}
func TestSwimUpWithoutGround(t *testing.T) {
w := waterWorld{}
p := NewPlayer(0.5, 53, 0.5)
p.updateFluid(w)
if !p.InWater {
t.Fatal("应在水中")
}
p.OnGround = false
p.SwimUp()
if p.Vel[1] <= 0 {
t.Fatal("水中上浮速度应 > 0")
}
}