diff --git a/data/background-day.png b/data/background-day.png index afcb5ec..f1af5fe 100644 Binary files a/data/background-day.png and b/data/background-day.png differ diff --git a/source/game.js b/source/game.js index ed5d9e6..e0c2afe 100644 --- a/source/game.js +++ b/source/game.js @@ -20,6 +20,8 @@ const PAD_BUTTON_A = 0x0100; const RED_COLOR = rgba(255, 0, 0, 255); const GREEN_COLOR = rgba(0, 255, 0, 255); const WHITE_COLOR = rgba(255, 255, 255, 255); +const FALLING_SPEED = 250; +const TERMINAL_VELOCITY_SPEED = 500; function rgba_compare(rgba1, rgba2) { return (rgba1[0] == rgba2[0]) && @@ -28,13 +30,26 @@ function rgba_compare(rgba1, rgba2) { (rgba1[3] == rgba2[3]); } -globalThis.rectangle_color = RED_COLOR; +/** + * clamps a number to the min and max values. + * @param {number} num + * @param {number} min + * @param {number} max + * @returns a clamped number + */ +function clamp(num, min, max) { + return Math.min(Math.max(num, min), max); +} +globalThis.rectangle_color = RED_COLOR; /** @type {GRRLibTexture} */ globalThis.background = null; /** @type {GRRLibTexture} */ globalThis.bird = null; +globalThis.bird_velocity = 0; +globalThis.bird_position = 0; + function swap_colors() { if (rgba_compare(rectangle_color, RED_COLOR)) { rectangle_color = GREEN_COLOR; @@ -51,6 +66,14 @@ function start() { globalThis.bird = wii.grrlib.load_texture(bird); } +function update_bird() { + const deltatime = wii.get_deltatime(); + bird_position -= bird_velocity * deltatime; + bird_velocity = clamp(bird_velocity - (FALLING_SPEED * deltatime), -TERMINAL_VELOCITY_SPEED, TERMINAL_VELOCITY_SPEED); + + wii.grrlib.draw_img(0, bird_position, bird, 0, 1, 1, WHITE_COLOR); +} + function update() { const pressed = wii.pad.buttons_down(); @@ -60,11 +83,10 @@ function update() { } if (pressed & PAD_BUTTON_A) { - wii.print("a pressed"); - swap_colors(); + bird_velocity = FALLING_SPEED; } - wii.grrlib.fill_screen(WHITE_COLOR); wii.grrlib.draw_img(0, 0, background, 0, 1, 1, WHITE_COLOR); - wii.grrlib.draw_img(0, 0, bird, 0, 1, 1, WHITE_COLOR); + update_bird(); + wii.print("deltatime: " + wii.get_deltatime()) } diff --git a/source/main.c b/source/main.c index 8435ebc..de09c28 100644 --- a/source/main.c +++ b/source/main.c @@ -2,14 +2,18 @@ #include #include #include +#include #include "data.h" #include "wii_duk.h" +const float MICROSECOND = 0.000001f; + extern const char * program; static bool running = true; static GRRLIB_ttfFont * font; static unsigned int green = RGBA(0, 255, 0, 255); +static float deltatime = 1.0f/60; static void duk_fatal_error(void *udata, const char *msg) { const char * err_message_format = "an error has occured: %s"; @@ -36,7 +40,7 @@ int main(int argc, char **argv) { duk_context * ctx = duk_create_heap(NULL, NULL, NULL, NULL, duk_fatal_error); // create a wii object on the global object (globalThis) - define_wii_object(ctx, font, &running); + define_wii_object(ctx, font, &running, &deltatime); duk_put_global_string(ctx, "wii"); // evaluate functions from game.js @@ -48,6 +52,8 @@ int main(int argc, char **argv) { duk_pop(ctx); while (running) { + const unsigned int beginningOfFrame = ticks_to_microsecs(gettime()); + PAD_ScanPads(); // call update function @@ -56,6 +62,9 @@ int main(int argc, char **argv) { duk_pop(ctx); GRRLIB_Render(); + + const unsigned int endOfFrame = ticks_to_microsecs(gettime()); + deltatime = (endOfFrame - beginningOfFrame) * MICROSECOND; } duk_destroy_heap(ctx); diff --git a/source/wii_duk.c b/source/wii_duk.c index e0d9c5a..fb46e00 100644 --- a/source/wii_duk.c +++ b/source/wii_duk.c @@ -5,24 +5,25 @@ static GRRLIB_ttfFont * font; static bool * running; static unsigned int green = RGBA(0, 255, 0, 255); +static float * deltatime; -static duk_ret_t native_print(duk_context *ctx) { +static duk_ret_t native_print(duk_context * ctx) { GRRLIB_PrintfTTF(0, 0, font, duk_to_string(ctx, 0), 32, green); return 0; } -static duk_ret_t native_exit(duk_context *ctx) { +static duk_ret_t native_exit(duk_context * ctx) { *running = false; return 0; } -static duk_ret_t pad_buttons_down(duk_context *ctx) { - u32 pressed = PAD_ButtonsDown(0); +static duk_ret_t pad_buttons_down(duk_context * ctx) { + unsigned int pressed = PAD_ButtonsDown(0); duk_push_number(ctx, pressed); return 1; } -static duk_ret_t get_file(duk_context *ctx) { +static duk_ret_t get_file(duk_context * ctx) { const char* filename = duk_to_string(ctx, 0); void* ptr; @@ -46,6 +47,11 @@ static duk_ret_t get_file(duk_context *ctx) { return duk_error(ctx, DUK_ERR_ERROR, "Error trying to get the file %s.", filename); } +static duk_ret_t get_deltatime(duk_context * ctx) { + duk_push_number(ctx, *deltatime); + return 1; +} + static void define_pad_object(duk_context *ctx) { duk_idx_t pad_obj = duk_push_object(ctx); @@ -53,9 +59,10 @@ static void define_pad_object(duk_context *ctx) { duk_put_prop_string(ctx, pad_obj, "buttons_down"); } -void define_wii_object(duk_context *ctx, struct GRRLIB_Font * grrlib_font, bool * global_running) { +void define_wii_object(duk_context * ctx, struct GRRLIB_Font * grrlib_font, bool * global_running, float * global_deltatime) { font = grrlib_font; - running = global_running; + running = global_running; + deltatime = global_deltatime; duk_idx_t wii_obj = duk_push_object(ctx); @@ -73,4 +80,7 @@ void define_wii_object(duk_context *ctx, struct GRRLIB_Font * grrlib_font, bool duk_push_c_function(ctx, get_file, 1); duk_put_prop_string(ctx, wii_obj, "get_file"); + + duk_push_c_function(ctx, get_deltatime, 0); + duk_put_prop_string(ctx, wii_obj, "get_deltatime"); } diff --git a/source/wii_duk.h b/source/wii_duk.h index 071f088..6c6fb39 100644 --- a/source/wii_duk.h +++ b/source/wii_duk.h @@ -2,5 +2,5 @@ #define WII_DUK_H #include #include -void define_wii_object(duk_context * ctx, struct GRRLIB_Font * grrlib_font, bool * global_running); +void define_wii_object(duk_context * ctx, struct GRRLIB_Font * grrlib_font, bool * global_running, float * global_deltatime); #endif diff --git a/types.d.ts b/types.d.ts index 11049c6..ce4db0a 100644 --- a/types.d.ts +++ b/types.d.ts @@ -5,6 +5,7 @@ declare interface GRRLibTexture {} declare namespace wii { function exit(): void function get_file(filename: string) : FilePtr + function get_deltatime() : number namespace grrlib { function load_texture(file: FilePtr) : GRRLibTexture function fill_screen(color: RGBA): void