Initial commit
This commit is contained in:
151
tests/test_physics.py
Normal file
151
tests/test_physics.py
Normal file
@@ -0,0 +1,151 @@
|
||||
"""Player movement & collision."""
|
||||
|
||||
from conftest import step, run, place, hold
|
||||
from game import settings as S
|
||||
|
||||
FLAT = """
|
||||
name: t
|
||||
tile_size: 32
|
||||
map: |
|
||||
##########
|
||||
#........#
|
||||
#........#
|
||||
#........#
|
||||
#P......G#
|
||||
##########
|
||||
"""
|
||||
|
||||
|
||||
def test_falls_and_lands_on_floor(make_game):
|
||||
g = make_game(FLAT)
|
||||
place(g, 4, 1) # up in the air
|
||||
run(g, 60)
|
||||
assert g.player.on_ground
|
||||
assert g.player.rect.bottom == 5 * 32 # floor is row 5's top (y=160)
|
||||
|
||||
|
||||
def test_terminal_velocity(make_game):
|
||||
g = make_game(FLAT)
|
||||
place(g, 4, 1)
|
||||
for _ in range(200):
|
||||
step(g)
|
||||
assert g.player.vy <= S.MAX_FALL + 1
|
||||
|
||||
|
||||
def test_jump_gains_height_then_returns(make_game):
|
||||
g = make_game(FLAT)
|
||||
run(g, 30) # settle on floor
|
||||
ground = g.player.rect.bottom
|
||||
peak = ground
|
||||
for i in range(60):
|
||||
step(g, hold(jump_pressed=(i == 0), jump_held=True))
|
||||
peak = min(peak, g.player.rect.bottom)
|
||||
assert peak < ground - 32 # rose at least a tile
|
||||
|
||||
|
||||
def test_variable_jump_height(make_game):
|
||||
# Full-hold jump should out-climb a 1-frame tap.
|
||||
def peak(hold_frames):
|
||||
g = make_game(FLAT)
|
||||
run(g, 30)
|
||||
ground = g.player.rect.bottom
|
||||
hi = ground
|
||||
for i in range(60):
|
||||
held = i < hold_frames
|
||||
step(g, hold(jump_pressed=(i == 0), jump_held=held))
|
||||
hi = min(hi, g.player.rect.bottom)
|
||||
return ground - hi
|
||||
assert peak(60) > peak(1) + 8
|
||||
|
||||
|
||||
def test_coyote_time_allows_jump_after_leaving_ledge(make_game):
|
||||
# Walk off a ledge, then jump within the coyote window -> should rise.
|
||||
g = make_game("""
|
||||
name: t
|
||||
tile_size: 32
|
||||
map: |
|
||||
#######
|
||||
#.....#
|
||||
#.....#
|
||||
##....#
|
||||
#P#...#
|
||||
#######
|
||||
""")
|
||||
place(g, 1, 3) # standing on the little step at [1,3] top
|
||||
# walk right off the step for a couple frames, then jump
|
||||
run(g, 4, lambda i: hold(right=True))
|
||||
y_before = g.player.rect.bottom
|
||||
step(g, hold(right=True, jump_pressed=True, jump_held=True))
|
||||
step(g, hold(right=True, jump_held=True))
|
||||
assert g.player.vy < 0 # a jump actually started
|
||||
|
||||
|
||||
def test_walls_stop_horizontal_movement(make_game):
|
||||
g = make_game(FLAT)
|
||||
place(g, 1, 4)
|
||||
run(g, 120, lambda i: hold(right=True))
|
||||
assert g.player.rect.right <= 9 * 32 # right wall inner edge (x=288)
|
||||
run(g, 120, lambda i: hold(left=True))
|
||||
assert g.player.rect.left >= 1 * 32 # left wall inner edge (x=32)
|
||||
|
||||
|
||||
def test_oneway_platform_land_from_above_pass_from_below(make_game):
|
||||
g = make_game("""
|
||||
name: t
|
||||
tile_size: 32
|
||||
map: |
|
||||
#######
|
||||
#.....#
|
||||
#.....#
|
||||
#--...#
|
||||
#.....#
|
||||
#P...G#
|
||||
#######
|
||||
""")
|
||||
# Fall onto the one-way from above -> lands on it.
|
||||
place(g, 1, 1) # open air above the one-way (row 3)
|
||||
run(g, 60)
|
||||
assert g.player.on_ground and g.player.rect.bottom == 3 * 32
|
||||
|
||||
# From below, jumping up passes through it (doesn't block the head).
|
||||
g2 = make_game("""
|
||||
name: t
|
||||
tile_size: 32
|
||||
map: |
|
||||
#######
|
||||
#.....#
|
||||
#--...#
|
||||
#.....#
|
||||
#P...G#
|
||||
#######
|
||||
""")
|
||||
place(g2, 1, 4) # on the floor, below the one-way (row 2)
|
||||
run(g2, 5) # settle so on_ground is set before jumping
|
||||
passed = False
|
||||
for i in range(40):
|
||||
step(g2, hold(jump_pressed=(i == 0), jump_held=(i < 12)))
|
||||
if g2.player.rect.top < 2 * 32: # rose above the one-way row
|
||||
passed = True
|
||||
assert passed
|
||||
|
||||
|
||||
def test_drop_through_oneway(make_game):
|
||||
g = make_game("""
|
||||
name: t
|
||||
tile_size: 32
|
||||
map: |
|
||||
#######
|
||||
#.....#
|
||||
#.....#
|
||||
#--...#
|
||||
#.....#
|
||||
#....G#
|
||||
#######
|
||||
""")
|
||||
place(g, 1, 2) # standing on the one-way at row 3
|
||||
run(g, 20)
|
||||
assert g.player.on_ground
|
||||
# press down + jump to drop through
|
||||
for i in range(30):
|
||||
step(g, hold(down=True, jump_pressed=(i == 0)))
|
||||
assert g.player.rect.top > 3 * 32 # fell below the one-way
|
||||
Reference in New Issue
Block a user