crocparty/game/game_player.c

289 lines
8.2 KiB
C
Raw Normal View History

2024-02-29 20:08:50 +00:00
#include <assert.h>
#include "art/game_hud.h"
2024-02-28 05:07:15 +00:00
#include "art/game_player.h"
#include "art/game_tiles.h"
#include "device/device.h"
#include "map/game_map.h"
#include "game.h"
#include "sys/sys.h"
game_bbox game_player_bbox = {
2024-02-28 20:54:59 +00:00
.x_origin=0x0500,
.y_origin=0x0c00,
2024-02-28 05:07:15 +00:00
.x=0x9000,
2024-02-28 20:54:59 +00:00
.y=0x1000,
.w=0x0a00,
2024-02-28 05:49:20 +00:00
.h=0x0c00,
2024-02-28 05:07:15 +00:00
};
bool game_player_grounded = false;
sys_i32 game_player_jump_frames = 0;
sys_i32 game_player_coyote_frames = 0;
sys_i32 game_player_dx = 0;
sys_i32 game_player_dy = 0;
bool game_player_faceleft = false;
2024-02-29 20:08:50 +00:00
game_player_collectibles_t game_player_collectibles = {
.n_cake=0,
.n_dollars=0
};
2024-02-29 22:31:44 +00:00
game_player_phase_t game_player_phase = GAME_PLAYER_PHASE_CROC;
2024-02-28 05:07:15 +00:00
typedef enum {
GAME_PLAYER_ANIM_STANDING,
GAME_PLAYER_ANIM_WALKING,
GAME_PLAYER_ANIM_FLOATING,
} game_player_anim;
game_player_anim game_player_anim_state = GAME_PLAYER_ANIM_STANDING;
uint8_t game_player_anim_progress = 0;
void game_player_anim_transition(game_player_anim anim);
void game_player_anim_add_progress(uint8_t amt);
void game_player_init() {
2024-02-28 21:14:48 +00:00
game_player_bbox.x = game_map_player_start_x;
game_player_bbox.y = game_map_player_start_y;
2024-02-28 05:07:15 +00:00
}
2024-02-29 04:48:22 +00:00
void game_player_update(bool* allow_input) {
2024-02-29 22:31:44 +00:00
sys_i32 dx_max, ddx;
switch (game_player_phase) {
case GAME_PLAYER_PHASE_CROC:
dx_max = 0x140;
ddx = 0x50;
game_player_bbox.x_origin=0x500;
game_player_bbox.w = 0xa00;
game_player_bbox.y_origin = game_player_bbox.h = 0xa00; break;
break;
case GAME_PLAYER_PHASE_CHICKEN:
dx_max = 0xd0;
ddx = 0x30;
game_player_bbox.x_origin=0x300;
game_player_bbox.w = 0x600;
game_player_bbox.y_origin = game_player_bbox.h = 0x700; break;
break;
}
2024-02-28 05:07:15 +00:00
game_collision collision = game_collision_move_to_contact(
&game_player_bbox,
game_player_dx,
game_player_dy
);
2024-02-28 05:07:15 +00:00
if (collision.collided_x) { game_player_dx = 0; }
if (collision.collided_y) { game_player_dy = 0; }
2024-02-28 05:49:20 +00:00
game_player_grounded = !game_collision_can_move(
game_player_bbox, 0, 1
2024-02-28 05:49:20 +00:00
);
2024-02-28 05:07:15 +00:00
{
sys_i32 fric_numerator = game_player_grounded ? 0x70 : 0x7f;
game_player_dx = (
game_player_dx * fric_numerator +
// round up
0x7f * sys_sgn_i32(game_player_dx)
) / 0x80;
2024-02-29 22:31:44 +00:00
if (sys_abs_i32(game_player_dx) > dx_max) {
game_player_dx = sys_sgn_i32(game_player_dx) * dx_max;
2024-02-28 05:07:15 +00:00
}
int wanted_dx = game_player_dx;
2024-02-29 22:31:44 +00:00
if (*allow_input && sys_btn(DEVICE_BUTTON_L)) { wanted_dx -= ddx; }
if (*allow_input && sys_btn(DEVICE_BUTTON_R)) { wanted_dx += ddx; }
2024-02-28 05:07:15 +00:00
// allow this if grounded or if it's not a change of direction
if (
2024-02-28 05:49:20 +00:00
/*
2024-02-28 05:07:15 +00:00
game_player_grounded ||
(sys_sgn_i32(wanted_dx) == sys_sgn_i32(game_player_dx))
2024-02-28 05:49:20 +00:00
*/
true
2024-02-28 05:07:15 +00:00
) {
game_player_dx = wanted_dx;
} else {
// the smallest possible amount of movement without changing sign
game_player_dx = sys_sgn_i32(game_player_dx);
}
}
if (game_player_grounded || game_player_coyote_frames > 0) {
2024-02-29 04:48:22 +00:00
if (*allow_input && sys_btnp(DEVICE_BUTTON_U, false)) {
game_player_dy = -0x200;
game_player_jump_frames = 13;
2024-02-28 05:07:15 +00:00
game_player_grounded = false;
}
}
2024-02-28 05:49:20 +00:00
if (game_player_dx < 0) { game_player_faceleft = true; }
if (game_player_dx > 0) { game_player_faceleft = false; }
2024-02-28 05:07:15 +00:00
bool wants_to_go_higher = false;
if (game_player_grounded) {
game_player_coyote_frames = 5;
if (game_player_dy > 0) { game_player_dy = 0; }
if (sys_abs_i32(game_player_dx) < 0x20) { game_player_dx = 0; }
}
else {
game_player_coyote_frames =
sys_max_i32(0, game_player_coyote_frames - 1);
wants_to_go_higher = sys_btn(DEVICE_BUTTON_U);
bool is_going_higher = wants_to_go_higher && game_player_jump_frames > 0;
if (game_player_dy >= 0 || !is_going_higher) {
game_player_dy += 48;
} else {
game_player_jump_frames -= 1;
}
}
// deduce animation state
if (game_player_grounded) {
if (game_player_dx == 0) {
game_player_anim_transition(GAME_PLAYER_ANIM_STANDING);
} else {
game_player_anim_transition(GAME_PLAYER_ANIM_WALKING);
game_player_anim_add_progress(
2024-02-28 05:49:20 +00:00
sys_min_i32(sys_abs_i32(game_player_dx) / 0x10, 0x20)
2024-02-28 05:07:15 +00:00
);
}
} else {
if (wants_to_go_higher) {
game_player_anim_transition(GAME_PLAYER_ANIM_FLOATING);
} else {
game_player_anim_transition(GAME_PLAYER_ANIM_STANDING);
}
}
}
2024-02-29 20:08:50 +00:00
void game_player_get_center(sys_i32* x, sys_i32* y) {
*x = game_player_bbox.x;
// center on me, not on feet
*y = game_player_bbox.y - 8 * PIXEL_SZ_MICROPIXEL;
}
2024-02-28 20:54:59 +00:00
void game_player_set_camera() {
sys_i32 x = game_player_bbox.x;
sys_i32 y = game_player_bbox.y;
// TODO: Use round_down et al
sys_i32 x_pixel = x / PIXEL_SZ_MICROPIXEL;
sys_i32 y_pixel = y / PIXEL_SZ_MICROPIXEL;
sys_i32 x_topcorner = x_pixel - x_pixel % DEVICE_W;
sys_i32 y_topcorner = y_pixel - y_pixel % DEVICE_H;
sys_camera_set(x_topcorner, y_topcorner);
}
2024-02-28 05:07:15 +00:00
void game_player_draw() {
2024-02-29 22:31:44 +00:00
uint8_t game_player_image;
uint8_t base = 0;
switch (game_player_phase) {
default: case GAME_PLAYER_PHASE_CROC: base = 0; break;
case GAME_PLAYER_PHASE_CHICKEN: base = 32; break;
}
2024-02-28 05:07:15 +00:00
switch (game_player_anim_state) {
case GAME_PLAYER_ANIM_WALKING:
2024-02-29 22:31:44 +00:00
game_player_image = base + 2 + (game_player_anim_progress / 0x80) * 2;
2024-02-28 05:07:15 +00:00
break;
case GAME_PLAYER_ANIM_FLOATING:
2024-02-29 22:31:44 +00:00
game_player_image = base + 6;
2024-02-28 05:07:15 +00:00
break;
default:
case GAME_PLAYER_ANIM_STANDING:
2024-02-29 22:31:44 +00:00
game_player_image = base + 0;
2024-02-28 05:07:15 +00:00
break;
}
sys_sprite_draw_ext(
spr_game_player,
game_player_image,
2024-02-28 20:54:59 +00:00
game_player_bbox.x / 0x100 - 8,
game_player_bbox.y / 0x100 - 16,
2024-02-28 05:07:15 +00:00
2, 2,
game_player_faceleft, false
);
}
void game_player_anim_transition(game_player_anim anim) {
if (game_player_anim_state == anim) { return ;}
game_player_anim_state = anim;
game_player_anim_progress = 0;
}
void game_player_anim_add_progress(uint8_t amt) {
game_player_anim_progress = (
(uint32_t) game_player_anim_progress +
(uint32_t) amt
) & 0xff;
}
2024-02-29 01:36:06 +00:00
2024-02-29 20:08:50 +00:00
void game_player_draw_hud_number(sys_i32 number, sys_i32 x, sys_i32 y);
void game_player_draw_hud() {
sys_i32 y = 4;
if (game_player_collectibles.n_dollars > 0) {
sys_sprite_draw_ext(
spr_game_hud,
1,
4, y,
1, 1,
false, false
);
game_player_draw_hud_number(game_player_collectibles.n_dollars, 16, y);
y += 10;
}
if (game_player_collectibles.n_cake > 0) {
sys_sprite_draw_ext(
spr_game_hud,
0,
4, y - 1,
1, 1,
false, false
);
game_player_draw_hud_number(game_player_collectibles.n_cake, 16, y);
y += 10;
}
}
2024-02-29 01:36:06 +00:00
2024-02-29 20:08:50 +00:00
void game_player_draw_hud_number1(sys_i32 number, sys_i32 x, sys_i32 y, uint8_t color) {
number = sys_min_i32(sys_max_i32(number, 0), 255);
char s[2];
s[1] = 0;
if (number >= 100) {
sys_i32 top_digit = number / 100;
assert(0 <= top_digit && top_digit < 10);
s[0] = '0' + top_digit;
number = number % 100;
sys_print(s, x, y, color);
x += 8;
}
if (number >= 10) {
sys_i32 top_digit = number / 10;
assert(0 <= top_digit && top_digit < 10);
s[0] = '0' + top_digit;
number = number % 10;
sys_print(s, x, y, color);
x += 8;
}
sys_i32 top_digit = number;
assert(0 <= top_digit && top_digit < 10);
s[0] = '0' + top_digit;
sys_print(s, x, y, color);
}
void game_player_draw_hud_number(sys_i32 number, sys_i32 x_start, sys_i32 y_start) {
for (sys_i32 dy = -1; dy <= 1; dy++) {
for (sys_i32 dx = -1; dx <= 1; dx++) {
game_player_draw_hud_number1(number, x_start+dx, y_start+dy, 0);
}
}
game_player_draw_hud_number1(number, x_start, y_start, 7);
2024-02-29 01:36:06 +00:00
}