From 72b6f6e0c82b7a3adcf0d9159b733e301e86fcf4 Mon Sep 17 00:00:00 2001 From: overmyerD Date: Mon, 19 Feb 2024 16:04:25 -0600 Subject: [PATCH] Add shapes_following_eyes raylib example --- examples/shapes_following_eyes.c | 129 +++++++++++++++++++++++++++++++ index.html | 2 +- nob.c | 7 ++ raylib.js | 39 ++++++++++ wasm/shapes_following_eyes.wasm | Bin 0 -> 4249 bytes 5 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 examples/shapes_following_eyes.c create mode 100755 wasm/shapes_following_eyes.wasm diff --git a/examples/shapes_following_eyes.c b/examples/shapes_following_eyes.c new file mode 100644 index 0000000..39126eb --- /dev/null +++ b/examples/shapes_following_eyes.c @@ -0,0 +1,129 @@ +/******************************************************************************************* +* +* raylib [textures] example - Texture loading and drawing +* +* Example originally created with raylib 1.0, last time updated with raylib 1.0 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" +#include "math.h" + +void raylib_js_set_entry(void (*entry)(void)); + +Vector2 scleraLeftPosition; +Vector2 scleraRightPosition; +float scleraRadius; + +Vector2 irisLeftPosition; +Vector2 irisRightPosition; +float irisRadius; + +float angle; +float dx, dy, dxx, dyy; + +void GameFrame() { + // Update + //---------------------------------------------------------------------------------- + irisLeftPosition = GetMousePosition(); + irisRightPosition = GetMousePosition(); + + // Check not inside the left eye sclera + if (!CheckCollisionPointCircle(irisLeftPosition, scleraLeftPosition, scleraRadius - irisRadius)) + { + dx = irisLeftPosition.x - scleraLeftPosition.x; + dy = irisLeftPosition.y - scleraLeftPosition.y; + + angle = atan2f(dy, dx); + + dxx = (scleraRadius - irisRadius)*cosf(angle); + dyy = (scleraRadius - irisRadius)*sinf(angle); + + irisLeftPosition.x = scleraLeftPosition.x + dxx; + irisLeftPosition.y = scleraLeftPosition.y + dyy; + } + + // Check not inside the right eye sclera + if (!CheckCollisionPointCircle(irisRightPosition, scleraRightPosition, scleraRadius - irisRadius)) + { + dx = irisRightPosition.x - scleraRightPosition.x; + dy = irisRightPosition.y - scleraRightPosition.y; + + angle = atan2f(dy, dx); + + dxx = (scleraRadius - irisRadius)*cosf(angle); + dyy = (scleraRadius - irisRadius)*sinf(angle); + + irisRightPosition.x = scleraRightPosition.x + dxx; + irisRightPosition.y = scleraRightPosition.y + dyy; + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawCircleV(scleraLeftPosition, scleraRadius, LIGHTGRAY); + DrawCircleV(irisLeftPosition, irisRadius, BROWN); + DrawCircleV(irisLeftPosition, 10, BLACK); + + DrawCircleV(scleraRightPosition, scleraRadius, LIGHTGRAY); + DrawCircleV(irisRightPosition, irisRadius, DARKGREEN); + DrawCircleV(irisRightPosition, 10, BLACK); + + DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- +} + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - following eyes"); + + scleraLeftPosition = CLITERAL(Vector2){ GetScreenWidth()/2.0f - 100.0f, GetScreenHeight()/2.0f }; + scleraRightPosition = CLITERAL(Vector2){ GetScreenWidth()/2.0f + 100.0f, GetScreenHeight()/2.0f }; + scleraRadius = 80; + + irisLeftPosition = CLITERAL(Vector2){ GetScreenWidth()/2.0f - 100.0f, GetScreenHeight()/2.0f }; + irisRightPosition = CLITERAL(Vector2){ GetScreenWidth()/2.0f + 100.0f, GetScreenHeight()/2.0f }; + irisRadius = 24; + + angle = 0.0f; + float dx = 0.0f; + dy = 0.0f; + dxx = 0.0f; + dyy = 0.0f; + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + +#ifdef PLATFORM_WEB + raylib_js_set_entry(GameFrame); +#else + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + GameFrame(); + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- +#endif + return 0; +} diff --git a/index.html b/index.html index 960a2cd..1faa92e 100644 --- a/index.html +++ b/index.html @@ -69,7 +69,7 @@ const wasmPaths = { "tsoding": ["tsoding_ball", "tsoding_snake",], "core": ["core_basic_window", "core_basic_screen_manager", "core_input_keys", "core_input_mouse_wheel",], - "shapes": ["shapes_colors_palette"], + "shapes": ["shapes_colors_palette", "shapes_following_eyes"], "text": ["text_writing_anim"], "textures": ["textures_logo_raylib"], } diff --git a/nob.c b/nob.c index 15ef36d..5cb5fb1 100644 --- a/nob.c +++ b/nob.c @@ -48,6 +48,11 @@ Example examples[] = { .bin_path = "./build/text_writing_anim", .wasm_path = "./wasm/text_writing_anim.wasm", }, + { + .src_path = "./examples/shapes_following_eyes.c", + .bin_path = "./build/shapes_following_eyes", + .wasm_path = "./wasm/shapes_following_eyes.wasm", + }, }; bool build_native(void) @@ -60,6 +65,7 @@ bool build_native(void) nob_cmd_append(&cmd, "-L./lib/", "-lraylib", "-lm"); if (!nob_cmd_run_sync(cmd)) return 1; } + return 0; } bool build_wasm(void) @@ -81,6 +87,7 @@ bool build_wasm(void) nob_cmd_append(&cmd, "-DPLATFORM_WEB"); if (!nob_cmd_run_sync(cmd)) return 1; } + return 0; } int main(int argc, char **argv) diff --git a/raylib.js b/raylib.js index a6a0154..0c2db6a 100644 --- a/raylib.js +++ b/raylib.js @@ -344,6 +344,45 @@ class RaylibJs { this.ctx.fillText(text, posX, posY + fontSize); } + DrawFPS(x, y){ + // TODO: implement DrawFPS + } + + CheckCollisionCircles(center1_ptr, radius1, center2_ptr, radius2) { + const buffer = this.wasm.instance.exports.memory.buffer; + const [c1x, c1y] = new Float32Array(buffer, center1_ptr, 2); + const [c2x, c2y] = new Float32Array(buffer, center2_ptr, 2); + + var collision = false; + + var dx = c2x - c1x; // X distance between centers + var dy = c2y - c1y; // Y distance between centers + + var distance = Math.sqrt(dx*dx + dy*dy); // Distance between centers + + if (distance <= (radius1 + radius2)) collision = true; + + return collision; + } + + CheckCollisionPointCircle(point_ptr, center_ptr, radius) { + var collision = false; + collision = this.CheckCollisionCircles(point_ptr, 0, center_ptr, radius); + return collision; + } + + atan2f(x, y) { + return Math.atan2(x, y); + } + + cosf(x) { + return Math.cos(x); + } + + sinf(x) { + return Math.sin(x); + } + raylib_js_set_entry(entry) { this.entryFunction = this.wasm.instance.exports.__indirect_function_table.get(entry); } diff --git a/wasm/shapes_following_eyes.wasm b/wasm/shapes_following_eyes.wasm new file mode 100755 index 0000000000000000000000000000000000000000..380298d7a951c765421b0b035489f96563f68456 GIT binary patch literal 4249 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 literal 0 HcmV?d00001