actor: collision checks now only check points that matter when moving
authorLukas Krickl <lukas@krickl.dev>
Thu, 25 Sep 2025 04:01:57 +0000 (06:01 +0200)
committerLukas Krickl <lukas@krickl.dev>
Thu, 25 Sep 2025 04:01:57 +0000 (06:01 +0200)
src/actor.s
src/player.s
src/wram.s

index 7a3a776e6474dfcf715c3cd641492010ab3cf6be..86017cf03ef4b2901d8ef51c2f004aa692bf9073 100644 (file)
@@ -137,6 +137,11 @@ actor_load_test:
        actor_spawn_test_guard 4, 20, 70
        actor_spawn_test_guard 5, 20, 80
        actor_spawn_test_guard 6, 30, 80
+       actor_spawn_test_guard 7, 30, 80
+       actor_spawn_test_guard 8, 30, 80
+       actor_spawn_test_guard 9, 30, 80
+       actor_spawn_test_guard 10, 30, 80
+       actor_spawn_test_guard 11, 30, 80
        ret
        
        ; despawns an actor
@@ -197,6 +202,7 @@ actor_write_default_collider:
        ; tests movement against all collision rectangles
        ; inputs:
        ;                            a: collision mask
+       ;                                        b: direction
        ;                                       de: current actor (this actor is skipped)
        ;               tmp_rect: new collision rectangle
        ; returns:
@@ -206,6 +212,10 @@ actor_write_default_collider:
 actor_test_movement:
        push de
        ld [tmp_rect_mask], a
+
+       ld a, b
+       ld [tmp_act_direction], a
+
        ; check all static rectangles
        ld hl, rectangles
        ld b, RECT_MAX
@@ -274,7 +284,9 @@ actor_test_movement:
        ret
 
        ; tests a single rectangle against an actor 
+       ; based on the current direction only 2 points are tested
        ; inputs:
+       ;               tmp_act_direction: direction
        ;               tmp_rect: new collision rectangle
        ;         tmp_rect_mask: mask to test agains
        ;   hl: rectangle to test
@@ -286,14 +298,25 @@ actor_test_rect:
        ld a, [tmp_rect_mask]
        call rect_test_mask
        ret z
-
-       ; test all corners of tmp_rect 
+       
+       ld a, [tmp_act_direction]
+       cp a, DIRUP
+       jp z, @up
+       cp a, DIRDOWN
+       jp z, @down
+       cp a, DIRLEFT
+       jp z, @left
+       cp a, DIRRIGHT
+       jp z, @right
+
+       ; default: test all corners of tmp_rect 
 
        actor_test_movement_corner rect_bl, @rect_collision
        actor_test_movement_corner rect_br, @rect_collision
        actor_test_movement_corner rect_tl, @rect_collision
        actor_test_movement_corner rect_tr, @rect_collision
-       
+
+@no_collision:
        xor a, a
        ret
 @rect_collision:
@@ -302,6 +325,26 @@ actor_test_rect:
        pop_all
        ld a, 1
        ret
+@up:
+       actor_test_movement_corner rect_tl, @rect_collision
+       actor_test_movement_corner rect_tr, @rect_collision
+       xor a, a
+       ret
+@down:
+       actor_test_movement_corner rect_bl, @rect_collision
+       actor_test_movement_corner rect_br, @rect_collision
+       xor a, a
+       ret
+@right:
+       actor_test_movement_corner rect_br, @rect_collision
+       actor_test_movement_corner rect_tr, @rect_collision
+       xor a, a
+       ret
+@left:
+       actor_test_movement_corner rect_bl, @rect_collision
+       actor_test_movement_corner rect_tl, @rect_collision
+       xor a, a
+       ret
        
        ; calls collision resolution 
        ; inputs:
index 62024d26ace3198c0abcb159f5906e0efb939ca3..52ddc6c591ec4c1c3544ad5944e3e773c94697cb 100644 (file)
@@ -27,6 +27,8 @@ player_update:
                ld b, PLAYER_SPEED
                ld c, 0
                call player_stage_move_n
+
+               ld a, DIRUP
                call player_try_move
 
                ; only scroll if player actually moved
@@ -41,6 +43,8 @@ player_update:
                ld b, PLAYER_SPEED
                ld c, 0
                call player_stage_move_p
+               
+               ld a, DIRDOWN 
                call player_try_move
 
 @not_down:
@@ -54,6 +58,8 @@ player_update:
                ld b, 0 
                ld c, PLAYER_SPEED 
                call player_stage_move_n
+
+               ld a, DIRLEFT
                call player_try_move
 @not_left:
 
@@ -64,6 +70,8 @@ player_update:
                ld b, 0
                ld c, PLAYER_SPEED
                call player_stage_move_p
+
+               ld a, DIRRIGHT
                call player_try_move
 @not_right:
 
@@ -180,11 +188,15 @@ player_stage_move_n:
        ; performs a collision check
        ; moves scroll and performs map loads if needed
        ; inputs:
+       ;                 a: direction
        ;               b/c: new y/x position
        ;       returns:
        ;               a: 1 == collision
        ;               a: 0 no collision
 player_try_move:
+       ; store direction for now
+       ld [tmp_act_direction], a
+
        ; write temporary collider
        push bc
        ld a, RF_PLAYER
@@ -192,6 +204,8 @@ player_try_move:
        call actor_write_default_collider
        
        ; test collision agains walls and enemies
+       ld a, [tmp_act_direction]
+       ld b, a ; b = direction
        ld a, RF_WALL | RF_ENEMY
        ld de, player
        call actor_test_movement
index 3e9c7bc80d886658137776692ed67653460a85a1..a8ab6cbb68c0e45df3c4c0c15290d0e55e82132b 100644 (file)
@@ -82,6 +82,9 @@ rectangles: .adv r_size * RECT_MAX
        ; during movement
 tmp_rect: .adv r_size
 tmp_rect_mask: .adv 1
+       
+       ; temporary actor direction mask
+tmp_act_direction: .adv 1
 
        ; current row that is being drawn
 map_curr_row: .adv 1