2024-02-29 00:10:09 +00:00
|
|
|
#include <assert.h>
|
|
|
|
#include "game.h"
|
|
|
|
#include "art/game_collectibles.h"
|
|
|
|
|
|
|
|
// If this isn't enough, raise the number
|
|
|
|
#define GAME_COLLECTIBLES_N 32
|
|
|
|
|
|
|
|
sys_i32 game_collectible_next = 0;
|
|
|
|
game_collectible game_collectibles[GAME_COLLECTIBLES_N];
|
|
|
|
|
2024-02-29 01:36:06 +00:00
|
|
|
struct {
|
|
|
|
sys_i32 x;
|
|
|
|
sys_i32 y;
|
|
|
|
sys_i32 r;
|
|
|
|
} game_collectible_bubble = {
|
|
|
|
.x = 0,
|
|
|
|
.y = 0,
|
|
|
|
.r = 0
|
|
|
|
};
|
|
|
|
|
2024-02-29 00:10:09 +00:00
|
|
|
sys_i32 game_collectible_wobb_frame = 0;
|
|
|
|
|
|
|
|
void game_collectibles_preinit() {
|
|
|
|
}
|
|
|
|
void game_collectible_create(sys_i32 x, sys_i32 y, game_collectible_type type) {
|
|
|
|
assert(game_collectible_next < GAME_COLLECTIBLES_N && "too many collectibles");
|
|
|
|
|
|
|
|
sys_i32 id = game_collectible_next++;
|
|
|
|
game_collectibles[id].x = x;
|
|
|
|
game_collectibles[id].y = y;
|
|
|
|
game_collectibles[id].type = type;
|
|
|
|
}
|
|
|
|
|
|
|
|
void game_collectibles_init() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-02-29 01:36:06 +00:00
|
|
|
sys_i32 game_collectible_wobb() {
|
|
|
|
return game_wobb3(game_collectible_wobb_frame & 0xff);
|
|
|
|
}
|
|
|
|
|
2024-02-29 00:10:09 +00:00
|
|
|
void game_collectibles_update() {
|
|
|
|
game_collectible_wobb_frame += 1;
|
2024-02-29 01:36:06 +00:00
|
|
|
game_collectible_bubble.r = game_collectible_bubble.r * 7 / 8;
|
|
|
|
if (game_collectible_bubble.r < PIXEL_SZ_MICROPIXEL / 2) { game_collectible_bubble.r = 0; }
|
|
|
|
|
|
|
|
// check collision with player
|
|
|
|
sys_i32 player_x, player_y;
|
|
|
|
game_player_get_center(&player_x, &player_y);
|
|
|
|
|
|
|
|
for (sys_i32 i = 0; i < game_collectible_next; i++) {
|
|
|
|
sys_i32 r;
|
|
|
|
game_collectible* c = &game_collectibles[i];
|
|
|
|
|
|
|
|
if (c->collected) { continue; }
|
|
|
|
|
|
|
|
switch (c->type) {
|
|
|
|
case GAME_COLLECTIBLE_TYPE_CAKE: r = 16; break;
|
|
|
|
default: r = 8; break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// convert to micropixels
|
|
|
|
// add approx radius of player
|
|
|
|
sys_i32 r_distcheck = (r + 5) * PIXEL_SZ_MICROPIXEL;
|
|
|
|
|
|
|
|
int64_t dx = player_x - c->x;
|
|
|
|
int64_t dy = player_y - c->y;
|
|
|
|
|
|
|
|
if (dx * dx + dy * dy <= r_distcheck * r_distcheck) {
|
|
|
|
c->collected = true;
|
|
|
|
// TODO: Spawn effect
|
|
|
|
game_collectible_bubble.x=c->x / PIXEL_SZ_MICROPIXEL;
|
|
|
|
game_collectible_bubble.y=c->y / PIXEL_SZ_MICROPIXEL + game_collectible_wobb();
|
|
|
|
game_collectible_bubble.r=r * PIXEL_SZ_MICROPIXEL;
|
|
|
|
}
|
|
|
|
}
|
2024-02-29 00:10:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void game_collectibles_draw() {
|
2024-02-29 01:36:06 +00:00
|
|
|
if (game_collectible_bubble.r > 0) {
|
|
|
|
sys_circ_fill(
|
|
|
|
game_collectible_bubble.x,
|
|
|
|
game_collectible_bubble.y,
|
|
|
|
game_collectible_bubble.r / PIXEL_SZ_MICROPIXEL,
|
|
|
|
7
|
|
|
|
);
|
|
|
|
}
|
2024-02-29 00:10:09 +00:00
|
|
|
for (sys_i32 i = 0; i < game_collectible_next; i++) {
|
2024-02-29 01:36:06 +00:00
|
|
|
game_collectible* c = &game_collectibles[i];
|
|
|
|
|
|
|
|
if (c->collected) { continue; }
|
|
|
|
|
|
|
|
sys_i32 x = c->x / PIXEL_SZ_MICROPIXEL;
|
|
|
|
sys_i32 y = c->y / PIXEL_SZ_MICROPIXEL + game_collectible_wobb();
|
|
|
|
switch(c->type) {
|
2024-02-29 00:10:09 +00:00
|
|
|
case GAME_COLLECTIBLE_TYPE_CAKE:
|
|
|
|
sys_sprite_draw_ext(
|
|
|
|
spr_game_collectibles,0,x-16,y-16,4,4,false,false);
|
|
|
|
break;
|
|
|
|
case GAME_COLLECTIBLE_TYPE_MONEY_BIG:
|
|
|
|
sys_sprite_draw_ext(
|
|
|
|
spr_game_collectibles,4,x-8,y-8,2,2,false,false);
|
|
|
|
break;
|
|
|
|
case GAME_COLLECTIBLE_TYPE_MONEY_SMALL:
|
|
|
|
sys_sprite_draw_ext(
|
|
|
|
spr_game_collectibles,16,x-8,y-8,2,2,false,false);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
assert(false&&"invalid collectible");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|