const PAD_BUTTON_START = 0x1000; const PAD_BUTTON_A = 0x0100; 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; const PIPE_SPAWN_TIME = 4; const PIPE_MAX_TIME = 5; /** * throws if input is nullish. * @template T * @param {T | null | undefined} value * @returns {T} */ function nonNull(value) { if (value == null) { throw new Error("unexpected " + (value === null ? 'null' : 'undefined')) } return value } /** * 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); } /** * picks a random number between the min and max values. * @param {number} min * @param {number} max * @returns a random number */ 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 | null} */ globalThis.background = null; /** @type {{velocity: number, position: number, texture?: GRRLibTexture}} */ globalThis.bird = { velocity: 0, position: 0 }; /** @type {GRRLibTexture | null} */ globalThis.pipe = null; /** @type {GRRLibTexture | null} */ globalThis.pipe_flipped = null; /** @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.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); wii.grrlib.draw_img(0, bird.position, nonNull(bird.texture), 0, 1, 1, WHITE_COLOR); } function Pipe() { const top_max = 200; const top_y = random_range(0, top_max); wii.grrlib.draw_img(100, -top_y, nonNull(pipe_flipped), 0, 1, 1, WHITE_COLOR); wii.grrlib.draw_img(100, top_y + 400, nonNull(pipe), 0, 1, 1, WHITE_COLOR); this.top_y = -top_y this.bottom_y = -top_y + 400 this.position = 650 this.time_active = 0 } Pipe.prototype.update = function () { if (this.time_active >= PIPE_MAX_TIME) { const index = pipes.indexOf(this); pipes.splice(index, -1); return; } wii.grrlib.draw_img(this.position, this.top_y, nonNull(pipe_flipped), 0, 1, 1, WHITE_COLOR); wii.grrlib.draw_img(this.position, this.bottom_y, nonNull(pipe), 0, 1, 1, WHITE_COLOR); this.position -= 100 * wii.get_deltatime(); this.time_active += wii.get_deltatime(); } function update() { const pressed = wii.pad.buttons_down(); if (pressed & PAD_BUTTON_START) { wii.print("exiting from js"); wii.exit(); } if (pressed & PAD_BUTTON_A) { bird.velocity = FALLING_SPEED; } if (timer >= PIPE_SPAWN_TIME) { globalThis.timer = 0; } if (timer == 0) { pipes.push(new Pipe()); } wii.grrlib.draw_img(0, 0, nonNull(background), 0, 1, 1, WHITE_COLOR); update_bird(); for (var i = 0; i < pipes.length; i++) { pipes[i].update(); } wii.print("deltatime: " + wii.get_deltatime()) globalThis.timer += wii.get_deltatime(); }