diff --git a/src/collision.s b/src/collision.s index ad791c2..d135080 100644 --- a/src/collision.s +++ b/src/collision.s @@ -54,6 +54,49 @@ player_bg_collides:: ret +; Check if the player is in mid-air +; @note NZ = false, Z = true +player_in_air:: + ; c = x % 8 == 0 ? x/8 : x/8 + 1 + ld hl, PLAYER_X + ld a, [hl] + ld c, a + and %111 + jr z, .skip_inc_c + ld a, c + add 8 + ld c, a +.skip_inc_c: + srl c + srl c + srl c + + ; b = y % 8 == 0 ? y/8 : y/8 + 1 + inc hl + ld a, [hl] + ld b, a + and %111 + jr z, .skip_inc_b + ld a, b + add 8 + ld b, a +.skip_inc_b: + srl b + srl b + srl b + + ; check underneath player (2 tiles down from top-left sprite) + inc b + inc b + + call can_move_to + ret nz + + inc c + call can_move_to + + ret + ; Check whether the location can be moved to or not ; @param b y-coordinate ; @param c x-coordinate diff --git a/src/player.s b/src/player.s index 8c9f7e1..96618f3 100644 --- a/src/player.s +++ b/src/player.s @@ -29,6 +29,7 @@ DEF PLAYER_SPEED EQU 2 DEF GRAVITY EQU (0 << 8) | $2e ; 0.18 DEF INIT_VY EQU (3 << 8) | $99 ; 3.60 +DEF INIT_FALL_VY EQU ($ff << 8) | $1a ; a.b Player_Init:: ; Clear player data @@ -76,9 +77,7 @@ Player_Update:: ld [hl], 1 ld hl, PLAYER_VY - ld [hl], HIGH(INIT_VY) - inc hl - ld [hl], LOW(INIT_VY) + STORE16 INIT_VY ; todo: deduplicate .jump_update_check: @@ -188,13 +187,13 @@ Player_Update:: ld hl, keys ld a, [hl] and BTN_LEFT - ret z + jr z, .fall ; check for left boundary ld hl, PLAYER_X ld a, [hl] or a - ret z + jr z, .fall sub PLAYER_SPEED ld [hl], a @@ -206,12 +205,28 @@ Player_Update:: ld [hl], $ff call update_oam - ret + jr .fall .left_rollback: ld hl, PLAYER_X inc [hl] inc [hl] + +.fall: + call player_in_air + ret nz + + ; only set jump state if not already jumping + ld hl, PLAYER_JUMPING + ld a, [hl] + or a + ret nz + + ld [hl], 1 + + ld hl, PLAYER_VY + STORE16 INIT_FALL_VY + ret ; Update player metasprite with positional data