diff --git a/examples/textures_sprite_anim.c b/examples/textures_sprite_anim.c new file mode 100644 index 0000000..da51e29 --- /dev/null +++ b/examples/textures_sprite_anim.c @@ -0,0 +1,125 @@ +/******************************************************************************************* +* +* raylib [textures] example - Sprite animation +* +* Example originally created with raylib 1.3, last time updated with raylib 1.3 +* +* 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" + +void raylib_js_set_entry(void (*entry)(void)); + +#define MAX_FRAME_SPEED 15 +#define MIN_FRAME_SPEED 1 +const int screenWidth = 800; +const int screenHeight = 450; + +// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) +Texture2D scarfy; + +Vector2 position; +Rectangle frameRec; +int currentFrame = 0; +int framesCounter = 0; +int framesSpeed = 8; // Number of spritesheet frames shown by second + +void GameFrame() +{ + // Update + //---------------------------------------------------------------------------------- + framesCounter++; + + if (framesCounter >= (60/framesSpeed)) + { + framesCounter = 0; + currentFrame++; + + if (currentFrame > 5) currentFrame = 0; + + frameRec.x = (float)currentFrame*(float)scarfy.width/6; + } + + // Control frames speed + if (IsKeyPressed(KEY_RIGHT)) framesSpeed++; + else if (IsKeyPressed(KEY_LEFT)) framesSpeed--; + + if (framesSpeed > MAX_FRAME_SPEED) framesSpeed = MAX_FRAME_SPEED; + else if (framesSpeed < MIN_FRAME_SPEED) framesSpeed = MIN_FRAME_SPEED; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawTexture(scarfy, 15, 40, WHITE); + DrawRectangleLines(15, 40, scarfy.width, scarfy.height, LIME); + DrawRectangleLines(15 + (int)frameRec.x, 40 + (int)frameRec.y, (int)frameRec.width, (int)frameRec.height, RED); + + DrawText("FRAME SPEED: ", 165, 210, 10, DARKGRAY); + DrawText(TextFormat("%02i FPS", framesSpeed), 575, 210, 10, DARKGRAY); + DrawText("PRESS RIGHT/LEFT KEYS to CHANGE SPEED!", 290, 240, 10, DARKGRAY); + + for (int i = 0; i < MAX_FRAME_SPEED; i++) + { + if (i < framesSpeed) DrawRectangle(250 + 21*i, 205, 20, 20, RED); + DrawRectangleLines(250 + 21*i, 205, 20, 20, MAROON); + } + + DrawTextureRec(scarfy, frameRec, position, WHITE); // Draw part of the texture + + DrawText("(c) Scarfy sprite by Eiden Marsal", screenWidth - 200, screenHeight - 20, 10, GRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- +} + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + InitWindow(screenWidth, screenHeight, "raylib [texture] example - sprite anim"); + + // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) + scarfy = LoadTexture("resources/scarfy.png"); // Texture loading + + position = (Vector2){ 350.0f, 280.0f }; + frameRec = (Rectangle){ 0.0f, 0.0f, (float)scarfy.width/6, (float)scarfy.height }; + currentFrame = 0; + + framesCounter = 0; + framesSpeed = 8; // Number of spritesheet frames shown by second + + 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()) + { + GameFrame(); + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadTexture(scarfy); // Texture unloading + + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- +#endif + + return 0; +} \ No newline at end of file diff --git a/index.html b/index.html index 960a2cd..b39f5d2 100644 --- a/index.html +++ b/index.html @@ -71,7 +71,7 @@ "core": ["core_basic_window", "core_basic_screen_manager", "core_input_keys", "core_input_mouse_wheel",], "shapes": ["shapes_colors_palette"], "text": ["text_writing_anim"], - "textures": ["textures_logo_raylib"], + "textures": ["textures_logo_raylib","texture_sprite_anim"], } const defaultWasm = Object.values(wasmPaths)[0][0]; diff --git a/raylib.js b/raylib.js index a6a0154..6058099 100644 --- a/raylib.js +++ b/raylib.js @@ -248,7 +248,15 @@ class RaylibJs { this.ctx.fillStyle = color; this.ctx.fillRect(x, y, w, h); } - + DrawRectangleLines(x, y, w, h, color_ptr) { + const buffer = this.wasm.instance.exports.memory.buffer; + const color = getColorFromMemory(buffer, color_ptr); + const lineThick = 2; + this.ctx.strokeStyle = color; + this.ctx.lineWidth = lineThick; + this.ctx.strokeRect(x + lineThick/2, y + lineThick/2, w - lineThick, h - lineThick); + } + DrawRectangleLinesEx(rec_ptr, lineThick, color_ptr) { const buffer = this.wasm.instance.exports.memory.buffer; const [x, y, w, h] = new Float32Array(buffer, rec_ptr, 4); @@ -285,15 +293,22 @@ class RaylibJs { const buffer = this.wasm.instance.exports.memory.buffer; const filename = cstr_by_ptr(buffer, filename_ptr); - var result = new Uint32Array(buffer, result_ptr, 5) - var img = new Image(); + const result = new Uint32Array(buffer, result_ptr, 5) + const img = new Image(); img.src = filename; + + //wait for the image to load, busy loop no idea what the correct solution would be + let maxWait = 1000; + while(maxWait >= 0) + maxWait--; + + console.log("image loaded", filename, img.width, img.height); this.images.push(img); result[0] = this.images.indexOf(img); - // TODO: get the true width and height of the image - result[1] = 256; // width - result[2] = 256; // height + // TODO: get the true width and height of the image because it sometimes isnt loaded yet a refresh helps because it's cached + result[1] = img.width || 256; // width + result[2] = img.height || 256; // height result[3] = 1; // mipmaps result[4] = 7; // format PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 @@ -309,6 +324,18 @@ class RaylibJs { this.ctx.drawImage(this.images[id], posX, posY); } + //void DrawTextureRec(Texture2D texture, Rectangle source, Vector2 position, Color tint) + DrawTextureRec(texture_ptr, rec_ptr, position_ptr, color_ptr) { + const buffer = this.wasm.instance.exports.memory.buffer; + const [id, width, height, mipmaps, format] = new Uint32Array(buffer, texture_ptr, 5); + const [x, y, w, h] = new Float32Array(buffer, rec_ptr, 4); + const [px, py] = new Float32Array(buffer, position_ptr, 2); + // // TODO: implement tinting for DrawTexture + // const tint = getColorFromMemory(buffer, color_ptr); + + this.ctx.drawImage(this.images[id], x, y, w, h, px, py, w, h); + + } // TODO: codepoints are not implemented LoadFontEx(result_ptr, fileName_ptr/*, fontSize, codepoints, codepointCount*/) { diff --git a/resources/scarfy.png b/resources/scarfy.png new file mode 100644 index 0000000..be3b83d Binary files /dev/null and b/resources/scarfy.png differ