test: geometry and slope collision coverage

This commit is contained in:
dualfroz committed 2026-08-27 23:06:01 +02:00
1 parent a0222105d7
commit 1952538952
4 files changed
+161

No files matched your search

+28
View File
@@ -0,0 +1,28 @@
from game.sim.level import parseAscii
from game.sim.world import World
from game.sim.inputCommand import InputCommand
def makeLevel(lines, name="test"):
return parseAscii(name, lines)
def makeWorld(lines, name="test"):
return World(parseAscii(name, lines))
def command(**kwargs):
return InputCommand(**kwargs)
def stepWorld(world, times=1, **kwargs):
cmd = InputCommand(**kwargs)
for _ in range(times):
world.step(cmd)
return world
def settle(world, times=30):
for _ in range(times):
world.step(InputCommand())
return world
+71
View File
@@ -0,0 +1,71 @@
import pytest
from game.sim.geometry import Vec2, Aabb, clamp, sign, approach
def test_aabbIntersectsOverlapping():
a = Aabb(0, 0, 10, 10)
b = Aabb(5, 5, 10, 10)
assert a.intersects(b)
assert b.intersects(a)
def test_aabbDoesNotIntersectSeparated():
a = Aabb(0, 0, 10, 10)
b = Aabb(20, 0, 10, 10)
assert not a.intersects(b)
def test_aabbTouchingEdgeIsNotOverlap():
a = Aabb(0, 0, 10, 10)
b = Aabb(10, 0, 10, 10)
assert not a.intersects(b)
assert a.touches(b)
def test_aabbOverlapArea():
a = Aabb(0, 0, 10, 10)
b = Aabb(5, 5, 10, 10)
assert a.overlapArea(b) == pytest.approx(25.0)
assert a.overlapArea(Aabb(100, 100, 5, 5)) == 0.0
def test_aabbContainsAndEdges():
box = Aabb(4, 6, 8, 10)
assert box.left == 4 and box.right == 12
assert box.top == 6 and box.bottom == 16
assert box.centerX == pytest.approx(8.0)
assert box.containsPoint(8, 10)
assert not box.containsPoint(100, 10)
def test_aabbInflated():
box = Aabb(10, 10, 4, 4)
grown = box.inflated(2, 3)
assert grown.left == 8 and grown.right == 16
assert grown.top == 7 and grown.bottom == 17
def test_vecArithmetic():
a = Vec2(3, 4)
assert a.length() == pytest.approx(5.0)
assert a.add(Vec2(1, 1)).asTuple() == (4.0, 5.0)
assert a.sub(Vec2(3, 4)).asTuple() == (0.0, 0.0)
assert a.scale(2).asTuple() == (6.0, 8.0)
normalized = a.normalized()
assert normalized.length() == pytest.approx(1.0)
def test_vecDistanceAndZeroNormalize():
assert Vec2(0, 0).distanceTo(Vec2(3, 4)) == pytest.approx(5.0)
assert Vec2(0, 0).normalized().asTuple() == (0.0, 0.0)
def test_helpers():
assert clamp(5, 0, 3) == 3
assert clamp(-1, 0, 3) == 0
assert clamp(2, 0, 3) == 2
assert sign(-4) == -1 and sign(4) == 1 and sign(0) == 0
assert approach(0, 10, 3) == 3
assert approach(10, 0, 3) == 7
assert approach(1, 2, 5) == 2
+58
View File
@@ -0,0 +1,58 @@
import pytest
from game.sim import physics
from game.sim.entity import Actor
class FakeSlopeTerrain:
def __init__(self, slopes):
self.slopes = slopes
def slopeAt(self, col, row):
return self.slopes.get((col, row))
def test_slopeSurfaceAscendRight():
assert physics.slopeSurfaceY(0, 0, 0, "ascendRight") == pytest.approx(16.0)
assert physics.slopeSurfaceY(0, 0, 16, "ascendRight") == pytest.approx(0.0)
assert physics.slopeSurfaceY(0, 0, 8, "ascendRight") == pytest.approx(8.0)
def test_slopeSurfaceAscendLeft():
assert physics.slopeSurfaceY(0, 0, 0, "ascendLeft") == pytest.approx(0.0)
assert physics.slopeSurfaceY(0, 0, 16, "ascendLeft") == pytest.approx(16.0)
def test_resolveSlopeSnapsPenetratingActor():
terrain = FakeSlopeTerrain({(0, 0): "ascendRight"})
actor = Actor(2, -6, 12, 16)
actor.vy = 1.0
snapped = physics.resolveSlope(actor, terrain, wasOnGround=False)
assert snapped
assert actor.onGround
assert actor.bottom == pytest.approx(physics.slopeSurfaceY(0, 0, actor.centerX, "ascendRight"))
assert actor.vy == 0.0
def test_walkingUpSlopeGainsHeight():
terrain = FakeSlopeTerrain({(0, 0): "ascendRight"})
actor = Actor(0, 0, 12, 16)
actor.vy = 1.0
physics.resolveSlope(actor, terrain, wasOnGround=False)
lowBottom = actor.bottom
actor.x = 6
actor.vy = 1.0
physics.resolveSlope(actor, terrain, wasOnGround=True)
assert actor.bottom < lowBottom
def test_resolveSlopeClingsWhenDescending():
terrain = FakeSlopeTerrain({(0, 0): "ascendLeft"})
actor = Actor(2, 0, 12, 16)
surface = physics.slopeSurfaceY(0, 0, actor.centerX, "ascendLeft")
actor.y = surface - actor.h - 3.0
actor.vy = 0.5
snapped = physics.resolveSlope(actor, terrain, wasOnGround=True)
assert snapped
assert actor.onGround
assert actor.bottom == pytest.approx(surface)