diff --git a/inc/util.inc b/inc/util.inc new file mode 100644 index 0000000..21cdfc0 --- /dev/null +++ b/inc/util.inc @@ -0,0 +1,7 @@ +; Stores a 16-bit register into the address stored in HL +; \1 The register to store +MACRO STORE16 + ld [hl], HIGH(\1) + inc hl + ld [hl], LOW(\1) +ENDM diff --git a/src/collision.s b/src/collision.s index 83d3e2e..fb4f7fb 100644 --- a/src/collision.s +++ b/src/collision.s @@ -2,6 +2,8 @@ INCLUDE "oam.inc" SECTION "Collision", ROMX +; Determines if player has hit the background +; @return NZ = false, Z = true player_bg_collides:: ; c = x % 8 == 0 ? x/8 : x/8 + 1 ld hl, PLAYER_X diff --git a/src/player.s b/src/player.s index 1ec10db..d4540b1 100644 --- a/src/player.s +++ b/src/player.s @@ -1,6 +1,7 @@ INCLUDE "hardware.inc" INCLUDE "input.inc" INCLUDE "oam.inc" +INCLUDE "util.inc" Section "Player Data", WRAM0 @@ -12,6 +13,10 @@ PLAYER_X:: db PLAYER_Y:: db PLAYER_DIR:: db +PLAYER_JUMPING:: db +PLAYER_VY:: dw +PLAYER_OLD_Y: db + Section "Player Code", ROM0 spriteData: @@ -22,6 +27,9 @@ DEF SPRITE_IDX EQU 32 ; tile index, rename later DEF SPRITE_WIDTH EQU 2 DEF SPRITE_HEIGHT EQU 2 +DEF GRAVITY EQU (0 << 8) | 8 +DEF INIT_VY EQU (2 << 8) | 40 + Player_Init:: ; clear player data ld hl, PLAYER_X @@ -30,6 +38,12 @@ Player_Init:: ld [hl], 144-32 inc hl ld [hl], 0 + inc hl + ld [hl], 0 + inc hl + ld [hl], 0 + inc hl + ld [hl], 0 ld a, 8 ld hl, _OAM + 1 @@ -56,8 +70,85 @@ Player_Update:: ld hl, keys ld b, [hl] - ; check for move right + ; check for jump + ld a, b + and BTN_UP + jr z, .update_jump + + ; initialize jump state if not already jumping + ld hl, PLAYER_JUMPING + ld a, [hl] + or a + jr nz, .update_jump + + ld [hl], 1 + + ld hl, PLAYER_VY + ld [hl], HIGH(INIT_VY) + inc hl + ld [hl], LOW(INIT_VY) + +.update_jump: + ld hl, PLAYER_JUMPING + ld a, [hl] + or a + jr z, .right + + ; load y velocity into bc + ld hl, PLAYER_VY + ld b, [hl] + inc hl + ld c, [hl] + + ; adjust velocity by gravity + ld a, c + sub LOW(GRAVITY) + ld c, a ld a, b + sbc HIGH(GRAVITY) + ld b, a + + ld hl, PLAYER_VY + STORE16 bc + + ; old_y = y + ld hl, PLAYER_Y + ld a, [hl] + ld hl, PLAYER_OLD_Y + ld [hl], a + + ; y -= floor(vy) + ld hl, PLAYER_Y + ld a, [hl] + sub b + ld [hl], a + + ; roll back jump if there was a collision + call player_bg_collides + jr nz, .update_jump_oam + + ld hl, PLAYER_OLD_Y + ld a, [hl] + ld hl, PLAYER_Y + ld b, [hl] + + ld hl, PLAYER_VY + ld [hl], 0 + + ; if colliding below, stop jump state + cp b + jr nc, .right + + ld hl, PLAYER_JUMPING + ld [hl], 0 + +.update_jump_oam: + call update_oam + + ; check for move right +.right: + ld hl, keys + ld a, [hl] and BTN_RIGHT jr z, .left @@ -88,7 +179,8 @@ Player_Update:: .left: ; check for left button - ld a, b + ld hl, keys + ld a, [hl] and BTN_LEFT ret z