Make phase a block property rather than a distinct type

This commit is contained in:
James Campbell
2026-08-02 00:03:58 -04:00
parent a17a68a07e
commit 7b7b005823
5 changed files with 515 additions and 201 deletions

View File

@@ -1,10 +1,10 @@
"""Spike, arrow_shooter, warp, phase_block + the invisible flag & block arrays."""
"""Spike, arrow_shooter, warp, phase blocks + the invisible flag & block arrays."""
import hashlib
import pygame
from conftest import FakeGame, step, run, place, hold, DT
from game.assets import AssetStore
from game.traps import Spike, ArrowShooter, Warp, PhaseBlock, Block
from game.traps import Spike, ArrowShooter, Warp, Block
# --- spike -------------------------------------------------------------------
@@ -211,17 +211,18 @@ map: |
#P......G#
##########
traps:
- type: phase_block
- type: block
at: [4, 3]
phase: true
fade: 0.2
trigger: { within: 2 }
""")
pb = g.level.traps[0]
place(g, 1, 3)
step(g)
assert not pb.solid and pb.alpha == 0 # dormant far away
assert not pb.materialized and pb.alpha == 0 # dormant far away
run(g, 40, lambda i: hold(right=True))
assert pb.solid and pb.alpha > 0 # phased in solid on approach
assert pb.materialized and pb.alpha > 0 # phased in solid on approach
def test_phase_block_kills_if_inside_when_it_forms(make_game):
@@ -234,8 +235,9 @@ map: |
#.....G#
########
traps:
- type: phase_block
- type: block
at: [3, 2]
phase: true
fade: 0.2
trigger: { within: 3 }
""")
@@ -261,8 +263,9 @@ map: |
#......G#
#########
traps:
- type: phase_block
- type: block
at: [4, 1]
phase: true
fade: 0.2
trigger: { within: 5 }
""")
@@ -278,7 +281,7 @@ traps:
# survived, and pushed out to the left so it no longer overlaps the cell
assert g.deaths == d0
assert g.player.rect.right <= b.left
assert pb.solid and not pb.emerge_kill
assert pb.materialized and not pb.emerge_kill
def test_phase_block_kills_when_shove_would_squish(make_game):
@@ -292,8 +295,9 @@ map: |
#.....G#
########
traps:
- type: phase_block
- type: block
at: [1, 1]
phase: true
fade: 0.2
trigger: { within: 5 }
""")
@@ -326,8 +330,9 @@ map: |
#.....G#
########
traps:
- type: phase_block
- type: block
at: [3, 2]
phase: true
fade: 0.5
trigger: { within: 3 }
""")
@@ -337,7 +342,44 @@ traps:
step(g)
assert 0 < pb.alpha < 1
g._start_death() # die from something
assert pb.alpha == 1.0 and pb.solid # snapped fully visible for the freeze
assert pb.alpha == 1.0 and pb.materialized # snapped fully visible for the freeze
def test_deadly_phase_block_harmless_until_materialized(make_game):
# A deadly phase block is neither solid nor a hazard while dormant, then
# becomes a (never-solid) hazard once it materialises.
g = make_game("""
name: t
tile_size: 32
map: |
##########
#........#
#........#
#P......G#
##########
traps:
- type: block
at: [4, 2]
phase: true
deadly: true
fade: 0.15
trigger: { within: 3 }
""")
b = g.level.traps[0]
place(g, 1, 3) # far away -> dormant
step(g)
assert not b.solid_rects() and not b.hazard_rects()
# Materialise it by standing on the cell; a deadly block never becomes solid.
place(g, 4, 2)
d0 = g.deaths
killed = False
for _ in range(12):
step(g)
if g.deaths > d0:
killed = True
break
assert killed # the materialised hazard kills
assert not b.solid_rects() # deadly -> never solid, even materialised
def test_debug_overscan_reveals_offmap_trap(make_level):