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
; 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:
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
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
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:
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:
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
ld b, PLAYER_SPEED
ld c, 0
call player_stage_move_p
+
+ ld a, DIRDOWN
call player_try_move
@not_down:
ld b, 0
ld c, PLAYER_SPEED
call player_stage_move_n
+
+ ld a, DIRLEFT
call player_try_move
@not_left:
ld b, 0
ld c, PLAYER_SPEED
call player_stage_move_p
+
+ ld a, DIRRIGHT
call player_try_move
@not_right:
; 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
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