From 00d51df3c63f7572ed59e3a6ede0840fc9fe653a Mon Sep 17 00:00:00 2001 From: Ralph Weng Date: Wed, 26 Nov 2025 06:23:28 +1100 Subject: [PATCH 1/4] Improve documentation for sprite_bitmap_collision cell parameter - Enhanced header comments in collisions.h to explain cell parameter usage - Added detailed description of bitmap cells for sprite sheets and animations - Included practical examples and cross-references to related functions - Created interactive test demonstrating cell-based collision detection - Integrated test into main test suite for easy verification The cell parameter allows collision testing against specific animation frames within a sprite sheet rather than the entire bitmap, useful for games with different collision areas per animation state (e.g. idle vs attack frames). --- coresdk/src/coresdk/collisions.h | 32 +++- coresdk/src/test/test_main.cpp | 1 + coresdk/src/test/test_main.h | 1 + .../test_sprite_bitmap_cell_collision.cpp | 151 ++++++++++++++++++ 4 files changed, 179 insertions(+), 6 deletions(-) create mode 100644 coresdk/src/test/test_sprite_bitmap_cell_collision.cpp diff --git a/coresdk/src/coresdk/collisions.h b/coresdk/src/coresdk/collisions.h index 8a6a0d3b..0da93477 100644 --- a/coresdk/src/coresdk/collisions.h +++ b/coresdk/src/coresdk/collisions.h @@ -558,17 +558,27 @@ namespace splashkit_lib bool bitmap_quad_collision(bitmap bmp, const point_2d &pt, const quad &q); /** - * Tests if a sprite will collide with a bitmap drawn at the indicated - * location. + * Tests if a sprite will collide with a specific cell of a bitmap drawn at + * the indicated location. This is useful when the bitmap contains multiple + * animation frames or states organised as cells. * * @param s The sprite to test * @param bmp The bitmap to test - * @param cell The cell of the bitmap to check + * @param cell The index of the specific cell/frame within the bitmap to check for collision. + * Bitmaps can be divided into a grid of cells using `bitmap_set_cell_details`, + * which is useful for sprite sheets containing animation frames or tile sets. + * Use this parameter to test collision against a specific frame rather than + * the entire bitmap. For example, checking if a player collides with frame 3 + * of an enemy animation (attack frame) vs frame 0 (idle frame). * @param x The x location where the bitmap is drawn * @param y The y location where the bitmap is drawn * @return True if the sprite collides with the bitmap cell when drawn * at the indicated location. * + * @see bitmap_set_cell_details + * @see bitmap_cell_count + * @see sprite_bitmap_collision (without cell parameter for collision with entire bitmap) + * * @attribute suffix with_cell * * @attribute class sprite @@ -577,16 +587,26 @@ namespace splashkit_lib bool sprite_bitmap_collision(sprite s, bitmap bmp, int cell, double x, double y); /** - * Tests if a sprite will collide with a bitmap drawn at the indicated - * location. + * Tests if a sprite will collide with a specific cell of a bitmap drawn at + * the indicated point. This is useful when the bitmap contains multiple + * animation frames or states organised as cells. * * @param s The sprite to test * @param bmp The bitmap to test - * @param cell The cell of the bitmap to check + * @param cell The index of the specific cell/frame within the bitmap to check for collision. + * Bitmaps can be divided into a grid of cells using `bitmap_set_cell_details`, + * which is useful for sprite sheets containing animation frames or tile sets. + * Use this parameter to test collision against a specific frame rather than + * the entire bitmap. For example, checking if a player collides with frame 3 + * of an enemy animation (attack frame) vs frame 0 (idle frame). * @param pt The point where the bitmap is drawn * @return True if the sprite collides with the bitmap cell when drawn * at the indicated location. * + * @see bitmap_set_cell_details + * @see bitmap_cell_count + * @see sprite_bitmap_collision (without cell parameter for collision with entire bitmap) + * * @attribute suffix with_cell_at_point * * @attribute class sprite diff --git a/coresdk/src/test/test_main.cpp b/coresdk/src/test/test_main.cpp index bd02b9af..92ab1908 100644 --- a/coresdk/src/test/test_main.cpp +++ b/coresdk/src/test/test_main.cpp @@ -65,6 +65,7 @@ void setup_tests() add_test("Remote GPIO Tests", run_remote_gpio_tests); add_test("GPIO Tests - SPI", run_gpio_spi_tests); add_test("UI Tests", run_ui_test); + add_test("Sprite Bitmap Cell Collision", run_sprite_bitmap_cell_collision_test); } diff --git a/coresdk/src/test/test_main.h b/coresdk/src/test/test_main.h index 2c3c5afd..db5ddda5 100644 --- a/coresdk/src/test/test_main.h +++ b/coresdk/src/test/test_main.h @@ -41,5 +41,6 @@ void run_gpio_spi_tests(); void run_terminal_test(); void run_logging_test(); void run_ui_test(); +void run_sprite_bitmap_cell_collision_test(); #endif /* test_main_h */ diff --git a/coresdk/src/test/test_sprite_bitmap_cell_collision.cpp b/coresdk/src/test/test_sprite_bitmap_cell_collision.cpp new file mode 100644 index 00000000..918e78f9 --- /dev/null +++ b/coresdk/src/test/test_sprite_bitmap_cell_collision.cpp @@ -0,0 +1,151 @@ +// +// test_sprite_bitmap_cell_collision.cpp +// splashkit +// +// Example demonstrating sprite-bitmap collision detection using cells. +// This shows how to check collision against specific animation frames +// within a sprite sheet rather than the entire bitmap. +// + +#include "sprites.h" +#include "images.h" +#include "graphics.h" +#include "window_manager.h" +#include "input.h" +#include "collisions.h" +#include "text.h" +#include + +using namespace std; +using namespace splashkit_lib; + +void run_sprite_bitmap_cell_collision_test() +{ + open_window("Sprite Bitmap Cell Collision Test", 800, 600); + + // Load a sprite sheet with multiple frames + // In this example, we'll create a simple bitmap with cells representing + // different animation states (e.g., idle, walk, attack) + bitmap enemy_spritesheet = create_bitmap("enemy_sheet", 300, 100); + + // Set up cell details: 3 frames (100x100 each) in a horizontal strip + // Frame 0: Idle (small collision area) + // Frame 1: Walking (medium collision area) + // Frame 2: Attacking (large collision area) + bitmap_set_cell_details(enemy_spritesheet, 100, 100, 3, 1, 3); + + // Draw different coloured rectangles in each cell to represent different states + // Note: In a real game, you'd load an actual sprite sheet image + clear_bitmap(enemy_spritesheet, COLOR_TRANSPARENT); + + // Frame 0 (Idle): Small red square (30x30) centred in the cell + fill_rectangle_on_bitmap(enemy_spritesheet, COLOR_RED, 35, 35, 30, 30); + + // Frame 1 (Walking): Medium green square (50x50) centred in the cell + fill_rectangle_on_bitmap(enemy_spritesheet, COLOR_GREEN, 125, 25, 50, 50); + + // Frame 2 (Attacking): Large blue square (70x70) centred in the cell + fill_rectangle_on_bitmap(enemy_spritesheet, COLOR_BLUE, 215, 15, 70, 70); + + setup_collision_mask(enemy_spritesheet); + + // Create a player sprite + bitmap player_bmp = create_bitmap("player", 40, 40); + fill_rectangle_on_bitmap(player_bmp, COLOR_YELLOW, 0, 0, 40, 40); + setup_collision_mask(player_bmp); + + sprite player = create_sprite("player", player_bmp); + sprite_set_x(player, 400); + sprite_set_y(player, 300); + + // Enemy bitmap position (we'll check collision with different cells) + double enemy_x = 400; + double enemy_y = 100; + + int current_cell = 0; // Start with idle frame + + cout << "Sprite Bitmap Cell Collision Test" << endl; + cout << "Use LEFT/RIGHT arrows to change enemy animation frame (cell)" << endl; + cout << "Use WASD to move the player sprite" << endl; + cout << "Observe how collision changes with different cells!" << endl; + + while (!quit_requested()) + { + process_events(); + + // Handle input for changing cells + if (key_typed(RIGHT_KEY)) + { + current_cell = (current_cell + 1) % 3; + } + if (key_typed(LEFT_KEY)) + { + current_cell = (current_cell - 1 + 3) % 3; + } + + // Move player with WASD + if (key_down(W_KEY)) sprite_set_y(player, sprite_y(player) - 3); + if (key_down(S_KEY)) sprite_set_y(player, sprite_y(player) + 3); + if (key_down(A_KEY)) sprite_set_x(player, sprite_x(player) - 3); + if (key_down(D_KEY)) sprite_set_x(player, sprite_x(player) + 3); + + // Check collision with the SPECIFIC CELL (frame) of the enemy sprite sheet + // This is the key function we're demonstrating! + bool colliding = sprite_bitmap_collision(player, enemy_spritesheet, current_cell, enemy_x, enemy_y); + + // Also demonstrate the point-based version + point_2d enemy_pt = point_at(enemy_x, enemy_y); + bool colliding_pt = sprite_bitmap_collision(player, enemy_spritesheet, current_cell, enemy_pt); + + // Draw + clear_screen(COLOR_WHITE); + + // Draw the current cell of the enemy sprite sheet + drawing_options opts = option_part_bmp( + current_cell * 100, // x offset in source + 0, // y offset in source + 100, // width + 100 // height + ); + draw_bitmap(enemy_spritesheet, enemy_x, enemy_y, opts); + + // Draw a rectangle around the enemy to show cell boundary + draw_rectangle(COLOR_BLACK, enemy_x, enemy_y, 100, 100); + + // Draw the player sprite (colour changes based on collision) + if (colliding) + { + // Player is colliding - draw in red + fill_circle(COLOR_RED, sprite_x(player) + 20, sprite_y(player) + 20, 25); + } + else + { + // No collision - draw normally + draw_sprite(player); + } + + // Display information + string cell_names[] = {"Idle (small)", "Walking (medium)", "Attacking (large)"}; + draw_text("Current Enemy Frame: " + cell_names[current_cell], COLOR_BLACK, 10, 10); + draw_text("Cell Index: " + to_string(current_cell), COLOR_BLACK, 10, 30); + draw_text("Collision Detected: " + string(colliding ? "YES" : "NO"), + colliding ? COLOR_RED : COLOR_GREEN, 10, 50); + + draw_text("Instructions:", COLOR_BLACK, 10, 500); + draw_text("LEFT/RIGHT: Change enemy animation frame", COLOR_BLACK, 10, 520); + draw_text("WASD: Move player", COLOR_BLACK, 10, 540); + + // Explain the concept + draw_text("This demonstrates checking collision with SPECIFIC CELLS (frames)", + COLOR_BLUE, 10, 450); + draw_text("Different animation frames have different collision areas!", + COLOR_BLUE, 10, 470); + + refresh_screen(60); + } + + free_sprite(player); + free_bitmap(player_bmp); + free_bitmap(enemy_spritesheet); + close_all_windows(); +} From 10ee6d41d11ff6b4c06a8244eef0a94dc74e0167 Mon Sep 17 00:00:00 2001 From: Ralph Weng Date: Sun, 30 Nov 2025 20:14:03 +1100 Subject: [PATCH 2/4] Address code review feedback Changes made: - Removed @see tags from documentation (not used elsewhere in project) - Changed examples from enemy to spike trap environmental hazard - Removed unused colliding_pt variable from test - Completely rewrote test program to fix transparency collision issues: * Added proper transparent backgrounds to bitmap cells * Ensured setup_collision_mask() is called correctly * Changed from solid rectangles to spike trap shapes with varying sizes * Improved visual feedback and UI layout * Added more detailed instructions and explanations The test now properly demonstrates collision detection with different cell collision areas, with visible differences between retracted, extending, and extended spike states. --- coresdk/src/coresdk/collisions.h | 16 +-- .../test_sprite_bitmap_cell_collision.cpp | 136 +++++++++++------- 2 files changed, 88 insertions(+), 64 deletions(-) diff --git a/coresdk/src/coresdk/collisions.h b/coresdk/src/coresdk/collisions.h index 0da93477..03ba64d4 100644 --- a/coresdk/src/coresdk/collisions.h +++ b/coresdk/src/coresdk/collisions.h @@ -568,17 +568,13 @@ namespace splashkit_lib * Bitmaps can be divided into a grid of cells using `bitmap_set_cell_details`, * which is useful for sprite sheets containing animation frames or tile sets. * Use this parameter to test collision against a specific frame rather than - * the entire bitmap. For example, checking if a player collides with frame 3 - * of an enemy animation (attack frame) vs frame 0 (idle frame). + * the entire bitmap. For example, checking if a player collides with frame 2 + * of a spike trap animation (spikes extended) vs frame 0 (spikes retracted). * @param x The x location where the bitmap is drawn * @param y The y location where the bitmap is drawn * @return True if the sprite collides with the bitmap cell when drawn * at the indicated location. * - * @see bitmap_set_cell_details - * @see bitmap_cell_count - * @see sprite_bitmap_collision (without cell parameter for collision with entire bitmap) - * * @attribute suffix with_cell * * @attribute class sprite @@ -597,16 +593,12 @@ namespace splashkit_lib * Bitmaps can be divided into a grid of cells using `bitmap_set_cell_details`, * which is useful for sprite sheets containing animation frames or tile sets. * Use this parameter to test collision against a specific frame rather than - * the entire bitmap. For example, checking if a player collides with frame 3 - * of an enemy animation (attack frame) vs frame 0 (idle frame). + * the entire bitmap. For example, checking if a player collides with frame 2 + * of a spike trap animation (spikes extended) vs frame 0 (spikes retracted). * @param pt The point where the bitmap is drawn * @return True if the sprite collides with the bitmap cell when drawn * at the indicated location. * - * @see bitmap_set_cell_details - * @see bitmap_cell_count - * @see sprite_bitmap_collision (without cell parameter for collision with entire bitmap) - * * @attribute suffix with_cell_at_point * * @attribute class sprite diff --git a/coresdk/src/test/test_sprite_bitmap_cell_collision.cpp b/coresdk/src/test/test_sprite_bitmap_cell_collision.cpp index 918e78f9..c170dffc 100644 --- a/coresdk/src/test/test_sprite_bitmap_cell_collision.cpp +++ b/coresdk/src/test/test_sprite_bitmap_cell_collision.cpp @@ -23,51 +23,70 @@ void run_sprite_bitmap_cell_collision_test() { open_window("Sprite Bitmap Cell Collision Test", 800, 600); - // Load a sprite sheet with multiple frames - // In this example, we'll create a simple bitmap with cells representing - // different animation states (e.g., idle, walk, attack) - bitmap enemy_spritesheet = create_bitmap("enemy_sheet", 300, 100); + // Load a sprite sheet with multiple frames representing an environmental hazard + // In this example, we'll create a bitmap representing a spike trap with different states + // Frame 0: Retracted (no spikes - safe) + // Frame 1: Extending (medium spikes - some danger) + // Frame 2: Fully Extended (large spikes - dangerous) + bitmap hazard_spritesheet = create_bitmap("spike_trap_sheet", 300, 100); // Set up cell details: 3 frames (100x100 each) in a horizontal strip - // Frame 0: Idle (small collision area) - // Frame 1: Walking (medium collision area) - // Frame 2: Attacking (large collision area) - bitmap_set_cell_details(enemy_spritesheet, 100, 100, 3, 1, 3); + bitmap_set_cell_details(hazard_spritesheet, 100, 100, 3, 1, 3); - // Draw different coloured rectangles in each cell to represent different states - // Note: In a real game, you'd load an actual sprite sheet image - clear_bitmap(enemy_spritesheet, COLOR_TRANSPARENT); + // Draw different spike states in each cell with TRANSPARENT backgrounds + // This is crucial - the background must be transparent for proper collision detection + clear_bitmap(hazard_spritesheet, COLOR_TRANSPARENT); - // Frame 0 (Idle): Small red square (30x30) centred in the cell - fill_rectangle_on_bitmap(enemy_spritesheet, COLOR_RED, 35, 35, 30, 30); + // Frame 0 (Retracted): Small grey square (20x20) at bottom - minimal collision area + fill_rectangle_on_bitmap(hazard_spritesheet, rgba_color(128, 128, 128, 255), 40, 75, 20, 20); - // Frame 1 (Walking): Medium green square (50x50) centred in the cell - fill_rectangle_on_bitmap(enemy_spritesheet, COLOR_GREEN, 125, 25, 50, 50); + // Frame 1 (Extending): Medium red trapezoid shape (40x40) - moderate collision area + // Draw a simple trapezoid to represent extending spikes + fill_rectangle_on_bitmap(hazard_spritesheet, rgba_color(200, 0, 0, 255), 130, 55, 40, 40); + fill_triangle_on_bitmap(hazard_spritesheet, rgba_color(200, 0, 0, 255), + 130, 55, 170, 55, 150, 40); - // Frame 2 (Attacking): Large blue square (70x70) centred in the cell - fill_rectangle_on_bitmap(enemy_spritesheet, COLOR_BLUE, 215, 15, 70, 70); + // Frame 2 (Extended): Large bright red spike pattern (60x70) - maximum collision area + // Draw multiple triangular shapes to represent fully extended spikes + // Base platform + fill_rectangle_on_bitmap(hazard_spritesheet, rgba_color(150, 0, 0, 255), 220, 75, 60, 20); + // Spikes pointing up + fill_triangle_on_bitmap(hazard_spritesheet, rgba_color(255, 0, 0, 255), + 220, 75, 230, 75, 225, 25); + fill_triangle_on_bitmap(hazard_spritesheet, rgba_color(255, 0, 0, 255), + 235, 75, 245, 75, 240, 25); + fill_triangle_on_bitmap(hazard_spritesheet, rgba_color(255, 0, 0, 255), + 250, 75, 260, 75, 255, 25); + fill_triangle_on_bitmap(hazard_spritesheet, rgba_color(255, 0, 0, 255), + 265, 75, 275, 75, 270, 25); - setup_collision_mask(enemy_spritesheet); + // IMPORTANT: Setup collision mask for the hazard bitmap + // This ensures transparent areas are NOT counted in collision detection + setup_collision_mask(hazard_spritesheet); - // Create a player sprite + // Create a player sprite with a solid circle bitmap player_bmp = create_bitmap("player", 40, 40); - fill_rectangle_on_bitmap(player_bmp, COLOR_YELLOW, 0, 0, 40, 40); + clear_bitmap(player_bmp, COLOR_TRANSPARENT); + fill_circle_on_bitmap(player_bmp, COLOR_YELLOW, 20, 20, 18); + + // Setup collision mask for player too setup_collision_mask(player_bmp); sprite player = create_sprite("player", player_bmp); sprite_set_x(player, 400); sprite_set_y(player, 300); - // Enemy bitmap position (we'll check collision with different cells) - double enemy_x = 400; - double enemy_y = 100; + // Hazard bitmap position (fixed on screen) + double hazard_x = 350; + double hazard_y = 250; - int current_cell = 0; // Start with idle frame + int current_cell = 0; // Start with retracted spikes cout << "Sprite Bitmap Cell Collision Test" << endl; - cout << "Use LEFT/RIGHT arrows to change enemy animation frame (cell)" << endl; + cout << "Use LEFT/RIGHT arrows to change spike trap animation frame (cell)" << endl; cout << "Use WASD to move the player sprite" << endl; cout << "Observe how collision changes with different cells!" << endl; + cout << "The trap cycles through: Retracted -> Extending -> Extended" << endl; while (!quit_requested()) { @@ -89,34 +108,32 @@ void run_sprite_bitmap_cell_collision_test() if (key_down(A_KEY)) sprite_set_x(player, sprite_x(player) - 3); if (key_down(D_KEY)) sprite_set_x(player, sprite_x(player) + 3); - // Check collision with the SPECIFIC CELL (frame) of the enemy sprite sheet + // Check collision with the SPECIFIC CELL (frame) of the hazard sprite sheet // This is the key function we're demonstrating! - bool colliding = sprite_bitmap_collision(player, enemy_spritesheet, current_cell, enemy_x, enemy_y); - - // Also demonstrate the point-based version - point_2d enemy_pt = point_at(enemy_x, enemy_y); - bool colliding_pt = sprite_bitmap_collision(player, enemy_spritesheet, current_cell, enemy_pt); + bool colliding = sprite_bitmap_collision(player, hazard_spritesheet, current_cell, hazard_x, hazard_y); // Draw clear_screen(COLOR_WHITE); - // Draw the current cell of the enemy sprite sheet + // Draw the current cell of the hazard sprite sheet drawing_options opts = option_part_bmp( current_cell * 100, // x offset in source 0, // y offset in source 100, // width 100 // height ); - draw_bitmap(enemy_spritesheet, enemy_x, enemy_y, opts); + draw_bitmap(hazard_spritesheet, hazard_x, hazard_y, opts); - // Draw a rectangle around the enemy to show cell boundary - draw_rectangle(COLOR_BLACK, enemy_x, enemy_y, 100, 100); + // Draw a dashed rectangle around the hazard to show cell boundary + draw_rectangle(rgba_color(0, 0, 0, 100), hazard_x, hazard_y, 100, 100); // Draw the player sprite (colour changes based on collision) if (colliding) { - // Player is colliding - draw in red - fill_circle(COLOR_RED, sprite_x(player) + 20, sprite_y(player) + 20, 25); + // Player is colliding - draw in red with pulsing effect + fill_circle(rgba_color(255, 0, 0, 200), sprite_x(player) + 20, sprite_y(player) + 20, 20); + // Draw warning outline + draw_circle(COLOR_RED, sprite_x(player) + 20, sprite_y(player) + 20, 25); } else { @@ -124,28 +141,43 @@ void run_sprite_bitmap_cell_collision_test() draw_sprite(player); } - // Display information - string cell_names[] = {"Idle (small)", "Walking (medium)", "Attacking (large)"}; - draw_text("Current Enemy Frame: " + cell_names[current_cell], COLOR_BLACK, 10, 10); - draw_text("Cell Index: " + to_string(current_cell), COLOR_BLACK, 10, 30); - draw_text("Collision Detected: " + string(colliding ? "YES" : "NO"), - colliding ? COLOR_RED : COLOR_GREEN, 10, 50); + // Display information with better formatting + string cell_names[] = {"Retracted (safe)", "Extending (danger!)", "Extended (deadly!)"}; + color cell_colors[] = {COLOR_GREEN, rgba_color(255, 140, 0, 255), COLOR_RED}; + + // Title + draw_text("Spike Trap Cell Collision Demo", COLOR_BLACK, "Arial", 20, 10, 10); + + // Current state info + draw_text("Current Trap State: " + cell_names[current_cell], cell_colors[current_cell], "Arial", 16, 10, 40); + draw_text("Cell Index: " + to_string(current_cell), COLOR_BLACK, 10, 60); + + // Collision status with prominent display + string collision_text = colliding ? "COLLISION DETECTED!" : "No Collision"; + color collision_color = colliding ? COLOR_RED : COLOR_GREEN; + draw_text(collision_text, collision_color, "Arial", 18, 10, 90); - draw_text("Instructions:", COLOR_BLACK, 10, 500); - draw_text("LEFT/RIGHT: Change enemy animation frame", COLOR_BLACK, 10, 520); - draw_text("WASD: Move player", COLOR_BLACK, 10, 540); + // Instructions box + fill_rectangle(rgba_color(240, 240, 240, 255), 10, 480, 380, 110); + draw_rectangle(COLOR_BLACK, 10, 480, 380, 110); + draw_text("Instructions:", COLOR_BLACK, "Arial", 14, 20, 490); + draw_text("LEFT/RIGHT: Change spike trap animation state", COLOR_BLACK, 20, 510); + draw_text("WASD: Move player", COLOR_BLACK, 20, 530); + draw_text("Move close to see collision detection in action!", COLOR_BLACK, 20, 550); - // Explain the concept - draw_text("This demonstrates checking collision with SPECIFIC CELLS (frames)", - COLOR_BLUE, 10, 450); - draw_text("Different animation frames have different collision areas!", - COLOR_BLUE, 10, 470); + // Explanation box + fill_rectangle(rgba_color(230, 240, 255, 255), 400, 480, 390, 110); + draw_rectangle(COLOR_BLUE, 400, 480, 390, 110); + draw_text("What This Demonstrates:", COLOR_BLUE, "Arial", 14, 410, 490); + draw_text("Testing collision with SPECIFIC CELLS (frames)", COLOR_BLACK, 410, 510); + draw_text("Different animation states = different collision areas", COLOR_BLACK, 410, 530); + draw_text("Notice: Retracted trap has tiny hitbox, extended has large hitbox!", COLOR_BLACK, 410, 550); refresh_screen(60); } free_sprite(player); free_bitmap(player_bmp); - free_bitmap(enemy_spritesheet); + free_bitmap(hazard_spritesheet); close_all_windows(); } From f8f562565b9614ffb2c19b4fdf6b1aacd6360da0 Mon Sep 17 00:00:00 2001 From: Ralph Weng Date: Thu, 4 Dec 2025 16:02:14 +1100 Subject: [PATCH 3/4] Fix collision mask not working for created bitmaps When calling setup_collision_mask() on bitmaps created with create_bitmap(), the collision detection was not working correctly because the pixel data could not be read from the texture. The issue was in _sk_bitmap_be_texture_to_pixels() - when reading pixels from a created bitmap's texture, SDL's pending render commands were not being flushed before calling SDL_RenderReadPixels(). This meant the drawing operations (fill_rectangle_on_bitmap, fill_triangle_on_bitmap, etc.) were not yet committed to the texture when the collision mask tried to read the pixel data. The fix adds SDL_RenderPresent() before reading pixels to ensure all pending render commands are flushed to the texture first. This fixes the sprite_bitmap_collision() function not detecting collisions correctly when using specific cells of a created bitmap spritesheet. --- coresdk/src/backend/graphics_driver.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/coresdk/src/backend/graphics_driver.cpp b/coresdk/src/backend/graphics_driver.cpp index 1a7623b5..1bbbb8ef 100644 --- a/coresdk/src/backend/graphics_driver.cpp +++ b/coresdk/src/backend/graphics_driver.cpp @@ -380,6 +380,9 @@ namespace splashkit_lib { // read pixels from the texture _sk_set_renderer_target(0, bitmap_be); + // Flush any pending render commands before reading pixels + // This ensures drawing operations are committed to the texture + SDL_RenderPresent(_sk_open_windows[0]->renderer); _sk_get_pixels_from_renderer(_sk_open_windows[0]->renderer, 0, 0, w, h, pixels); _sk_restore_default_render_target(_sk_open_windows[0], bitmap_be); } From 8a442c97113ec7f144c6aa8eb4c947526e9db227 Mon Sep 17 00:00:00 2001 From: Ralph Weng Date: Sun, 7 Dec 2025 23:29:20 +1100 Subject: [PATCH 4/4] Fix collision test: remove clear_bitmap with COLOR_TRANSPARENT Per reviewer feedback, removed the clear_bitmap(hazard_spritesheet, COLOR_TRANSPARENT) call which was causing the collision mask issue. COLOR_TRANSPARENT has an alpha value of 255 (opaque) instead of 0, which was making the collision mask treat the entire bitmap as opaque. Also reverted the unnecessary SDL_RenderPresent change to graphics_driver.cpp. --- coresdk/src/backend/graphics_driver.cpp | 3 --- coresdk/src/test/test_sprite_bitmap_cell_collision.cpp | 4 ---- 2 files changed, 7 deletions(-) diff --git a/coresdk/src/backend/graphics_driver.cpp b/coresdk/src/backend/graphics_driver.cpp index 1bbbb8ef..1a7623b5 100644 --- a/coresdk/src/backend/graphics_driver.cpp +++ b/coresdk/src/backend/graphics_driver.cpp @@ -380,9 +380,6 @@ namespace splashkit_lib { // read pixels from the texture _sk_set_renderer_target(0, bitmap_be); - // Flush any pending render commands before reading pixels - // This ensures drawing operations are committed to the texture - SDL_RenderPresent(_sk_open_windows[0]->renderer); _sk_get_pixels_from_renderer(_sk_open_windows[0]->renderer, 0, 0, w, h, pixels); _sk_restore_default_render_target(_sk_open_windows[0], bitmap_be); } diff --git a/coresdk/src/test/test_sprite_bitmap_cell_collision.cpp b/coresdk/src/test/test_sprite_bitmap_cell_collision.cpp index c170dffc..6b83d342 100644 --- a/coresdk/src/test/test_sprite_bitmap_cell_collision.cpp +++ b/coresdk/src/test/test_sprite_bitmap_cell_collision.cpp @@ -33,10 +33,6 @@ void run_sprite_bitmap_cell_collision_test() // Set up cell details: 3 frames (100x100 each) in a horizontal strip bitmap_set_cell_details(hazard_spritesheet, 100, 100, 3, 1, 3); - // Draw different spike states in each cell with TRANSPARENT backgrounds - // This is crucial - the background must be transparent for proper collision detection - clear_bitmap(hazard_spritesheet, COLOR_TRANSPARENT); - // Frame 0 (Retracted): Small grey square (20x20) at bottom - minimal collision area fill_rectangle_on_bitmap(hazard_spritesheet, rgba_color(128, 128, 128, 255), 40, 75, 20, 20);