diff --git a/data/pipe-green-flipped.png b/data/pipe-green-flipped.png new file mode 100644 index 0000000..1c7247d Binary files /dev/null and b/data/pipe-green-flipped.png differ diff --git a/data/pipe-green.png b/data/pipe-green.png new file mode 100644 index 0000000..1d9c08b Binary files /dev/null and b/data/pipe-green.png differ diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 5e5c203..cc1a5a4 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -12,7 +12,7 @@ add_custom_command( COMMENT "Creating data_generated.c from the data directory" ) -add_executable(WiiDuktape main.c grrlib_duk.c wii_duk.c game.c data_generated.c) +add_executable(WiiDuktape main.c grrlib_duk.c wii_duk.c rgba.c game.c data_generated.c) target_link_libraries(WiiDuktape duktape) target_link_libraries(WiiDuktape GRRLIB) ogc_create_dol(WiiDuktape) diff --git a/source/game.js b/source/game.js index e0c2afe..9d2da69 100644 --- a/source/game.js +++ b/source/game.js @@ -1,34 +1,13 @@ -/** - * returns an RGBA buffer - * @param {number} r red - * @param {number} g green - * @param {number} b blue - * @param {number} a alpha - * @returns {RGBA} - */ -function rgba(r, g, b, a) { - const buffer = Uint8Array.allocPlain(4); - buffer[0] = r; - buffer[1] = g; - buffer[2] = b; - buffer[3] = a; - return buffer; -} - const PAD_BUTTON_START = 0x1000; 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 RED_COLOR = wii.rgba(255, 0, 0, 255); +const GREEN_COLOR = wii.rgba(0, 255, 0, 255); +const WHITE_COLOR = wii.rgba(255, 255, 255, 255); + const FALLING_SPEED = 250; const TERMINAL_VELOCITY_SPEED = 500; - -function rgba_compare(rgba1, rgba2) { - return (rgba1[0] == rgba2[0]) && - (rgba1[1] == rgba2[1]) && - (rgba1[2] == rgba2[2]) && - (rgba1[3] == rgba2[3]); -} +const PIPE_SPAWN_TIME = 4; +const PIPE_MAX_TIME = 5; /** * clamps a number to the min and max values. @@ -41,37 +20,81 @@ function clamp(num, min, max) { return Math.min(Math.max(num, min), max); } -globalThis.rectangle_color = RED_COLOR; +function random_range(min, max) { + const minCeiled = Math.ceil(min); + const maxFloored = Math.floor(max); + return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled); +} + /** @type {GRRLibTexture} */ globalThis.background = null; + +/** @type {DrawableObject} */ +globalThis.bird = { + velocity: 0, + position: 0 +}; + /** @type {GRRLibTexture} */ -globalThis.bird = null; +globalThis.pipe = null; -globalThis.bird_velocity = 0; -globalThis.bird_position = 0; +/** @type {GRRLibTexture} */ +globalThis.pipe_flipped = null; -function swap_colors() { - if (rgba_compare(rectangle_color, RED_COLOR)) { - rectangle_color = GREEN_COLOR; - } else if (rgba_compare(rectangle_color, GREEN_COLOR)) { - rectangle_color = RED_COLOR; - } -} +/** @type {Pipe[]} */ +globalThis.pipes = []; + +/** @type {number} */ +globalThis.timer = 0; function start() { const background = wii.get_file("background-day.png"); const bird = wii.get_file("yellowbird-midflap.png"); + const pipe = wii.get_file("pipe-green.png"); + const pipe_flipped = wii.get_file("pipe-green-flipped.png"); globalThis.background = wii.grrlib.load_texture(background); - globalThis.bird = wii.grrlib.load_texture(bird); + globalThis.bird.texture = wii.grrlib.load_texture(bird); + globalThis.pipe = wii.grrlib.load_texture(pipe); + globalThis.pipe_flipped = wii.grrlib.load_texture(pipe_flipped); } 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); + 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); + wii.grrlib.draw_img(0, bird.position, bird.texture, 0, 1, 1, WHITE_COLOR); +} + +function create_pipe() { + const top_max = 200; + const top_y = random_range(0, top_max); + + wii.grrlib.draw_img(100, -top_y, pipe_flipped, 0, 1, 1, WHITE_COLOR); + wii.grrlib.draw_img(100, top_y + 400, pipe, 0, 1, 1, WHITE_COLOR); + + return { + top_y: -top_y, + bottom_y: -top_y + 400, + position: 650, + time_active: 0 + } +} + +/** + * @param {Pipe} pipe + */ +function update_pipe(pipe) { + if (pipe.time_active >= PIPE_MAX_TIME) { + const index = pipes.indexOf(pipe); + pipes.splice(index, -1); + return; + } + wii.grrlib.draw_img(pipe.position, pipe.top_y, pipe_flipped, 0, 1, 1, WHITE_COLOR); + wii.grrlib.draw_img(pipe.position, pipe.bottom_y, globalThis.pipe, 0, 1, 1, WHITE_COLOR); + pipe.position -= 100 * wii.get_deltatime(); + pipe.time_active += wii.get_deltatime(); } function update() { @@ -83,10 +106,22 @@ function update() { } if (pressed & PAD_BUTTON_A) { - bird_velocity = FALLING_SPEED; + bird.velocity = FALLING_SPEED; + } + + if (timer >= PIPE_SPAWN_TIME) { + timer = 0; + } + + if (timer == 0) { + pipes.push(create_pipe()); } wii.grrlib.draw_img(0, 0, background, 0, 1, 1, WHITE_COLOR); update_bird(); + for (var i = 0; i < pipes.length; i++) { + update_pipe(pipes[i]); + } wii.print("deltatime: " + wii.get_deltatime()) + timer += wii.get_deltatime(); } diff --git a/source/grrlib_duk.c b/source/grrlib_duk.c index e972d3c..7fddb7c 100644 --- a/source/grrlib_duk.c +++ b/source/grrlib_duk.c @@ -1,13 +1,7 @@ #include "grrlib_duk.h" -#include "duk_config.h" -#include "duktape.h" +#include #include - -static unsigned int get_color(duk_context *ctx, duk_idx_t index) { - size_t rgba_size; - unsigned char * rgba = duk_get_buffer(ctx, index, &rgba_size); - return rgba[0] << 24 | rgba[1] << 16 | rgba[2] << 8 | rgba[3]; -} +#include "rgba.h" static duk_ret_t grrlib_fill_screen(duk_context *ctx) { unsigned int color = get_color(ctx, 0); diff --git a/source/rgba.c b/source/rgba.c new file mode 100644 index 0000000..92827d6 --- /dev/null +++ b/source/rgba.c @@ -0,0 +1,36 @@ +#include "rgba.h" + +duk_ret_t compare_rgba(duk_context * ctx) { + unsigned int color1 = get_color(ctx, 0); + unsigned int color2 = get_color(ctx, 1); + + duk_push_boolean(ctx, color1 == color2); + + return 1; +} + +duk_ret_t rgba(duk_context * ctx) { + int r = duk_get_number(ctx, 0); + int g = duk_get_number(ctx, 1); + int b = duk_get_number(ctx, 2); + int a = duk_get_number(ctx, 3); + + if (r > 255 || g > 255 || b > 255 || a > 255) { + return duk_error(ctx, DUK_ERR_ERROR, "You can't use a number bigger then 255."); + } + + unsigned char * buffer; + buffer = duk_push_fixed_buffer(ctx, 4); + buffer[0] = r; + buffer[1] = g; + buffer[2] = b; + buffer[3] = a; + + return 1; +} + +unsigned int get_color(duk_context * ctx, duk_idx_t index) { + size_t rgba_size; + unsigned char * rgba = duk_get_buffer(ctx, index, &rgba_size); + return rgba[0] << 24 | rgba[1] << 16 | rgba[2] << 8 | rgba[3]; +} diff --git a/source/rgba.h b/source/rgba.h new file mode 100644 index 0000000..9e1d5cb --- /dev/null +++ b/source/rgba.h @@ -0,0 +1,7 @@ +#ifndef RGBA_H +#define RGBA_H +#include +unsigned int get_color(duk_context * ctx, duk_idx_t index); +duk_ret_t rgba(duk_context * ctx); +duk_ret_t compare_rgba(duk_context * ctx); +#endif diff --git a/source/wii_duk.c b/source/wii_duk.c index fb46e00..fa6ea19 100644 --- a/source/wii_duk.c +++ b/source/wii_duk.c @@ -1,6 +1,7 @@ #include "wii_duk.h" #include "data.h" #include "grrlib_duk.h" +#include "rgba.h" static GRRLIB_ttfFont * font; static bool * running; @@ -83,4 +84,10 @@ void define_wii_object(duk_context * ctx, struct GRRLIB_Font * grrlib_font, bool duk_push_c_function(ctx, get_deltatime, 0); duk_put_prop_string(ctx, wii_obj, "get_deltatime"); + + duk_push_c_function(ctx, rgba, 4); + duk_put_prop_string(ctx, wii_obj, "rgba"); + + duk_push_c_function(ctx, compare_rgba, 2); + duk_put_prop_string(ctx, wii_obj, "compare_rgba"); } diff --git a/types.d.ts b/types.d.ts index ce4db0a..064f9ff 100644 --- a/types.d.ts +++ b/types.d.ts @@ -1,11 +1,23 @@ declare interface RGBA {} declare interface FilePtr {} declare interface GRRLibTexture {} +declare interface DrawableObject { + texture: GRRLibTexture +}; +declare interface Pipe { + top_y: number + bottom_y: number + position: number + time_active: number +}; declare namespace wii { function exit(): void function get_file(filename: string) : FilePtr function get_deltatime() : number + function compare_rgba(color1: RGBA, color2: RGBA) : boolean + function print(message: string) : void + function rgba(r: number, g: number, b: number, a: number): RGBA namespace grrlib { function load_texture(file: FilePtr) : GRRLibTexture function fill_screen(color: RGBA): void