#include #include #include #define NOB_REALLOC realloc #define NOB_ASSERT assert // Initial capacity of a dynamic array #define NOB_DA_INIT_CAP 256 // Append an item to a dynamic array #define nob_da_append(da, item) \ do { \ if ((da)->count >= (da)->capacity) { \ (da)->capacity = (da)->capacity == 0 ? NOB_DA_INIT_CAP : (da)->capacity*2; \ (da)->items = NOB_REALLOC((da)->items, (da)->capacity*sizeof(*(da)->items)); \ NOB_ASSERT((da)->items != NULL && "Buy more RAM lol"); \ } \ \ (da)->items[(da)->count++] = (item); \ } while (0) #include "raylib.h" #include "raymath.h" #define PLAYER_SPEED 1000 #define REAL_FPS 30 #define TARGET_FPS 480 #define TARGET_DT (1.0/TARGET_FPS) #define GRAVITY 1000.0f #define COLLISION_DAMPING 0.8 typedef struct { Vector2 *items; size_t count; size_t capacity; } Vector2s; typedef struct { Color *items; size_t count; size_t capacity; } Colors; Texture tex_rac; int win_fun() { SetWindowState(FLAG_WINDOW_RESIZABLE); #ifdef RELEASE ShowCursor(); EnableCursor(); #endif #ifdef RELEASE SetWindowSize(690, 690); #else SetWindowSize(1600, 900); #endif SetTargetFPS(REAL_FPS); Vector2s positions = {0}; Vector2s velocities = {0}; Colors colors = {0}; #ifdef RELEASE #include "assets/raccon-delicieu.h" Image img_rac = LoadImageFromMemory(".png", raccoon_data, raccoon_size); tex_rac = LoadTextureFromImage(img_rac); #else tex_rac = LoadTexture("assets/raccon-delicieu.png"); #endif Vector2 prev_winpos = GetWindowPosition(); while (!WindowShouldClose()) { Vector2 winpos = GetWindowPosition(); Vector2 dwinpos = Vector2Subtract(winpos, prev_winpos); float w = GetScreenWidth(); float h = GetScreenHeight(); float real_dt = GetFrameTime(); float radius = 40.0f; BeginDrawing(); ClearBackground(GetColor(0x181818FF)); if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { nob_da_append(&positions, GetMousePosition()); float angle = DEG2RAD*GetRandomValue(0, 360); Vector2 dir = {500*cosf(angle), 500*sinf(angle)}; nob_da_append(&velocities, dir); nob_da_append(&colors, ColorFromHSV(GetRandomValue(0, 360), 1, 1)); } for (float t = 0.0; t < real_dt; t += TARGET_DT) { for (size_t i = 0; i < positions.count; ++i) { float f = t/real_dt; positions.items[i] = Vector2Subtract(positions.items[i], Vector2Scale(dwinpos, TARGET_DT/real_dt)); velocities.items[i].y += GRAVITY*TARGET_DT; float nx = positions.items[i].x + velocities.items[i].x*TARGET_DT; if (nx - radius <= 0) { positions.items[i].x = radius; velocities.items[i].x *= -COLLISION_DAMPING; velocities.items[i].x += dwinpos.x*TARGET_DT/real_dt*300; } else if (nx + radius >= w) { positions.items[i].x = w - radius; velocities.items[i].x *= -COLLISION_DAMPING; velocities.items[i].x += dwinpos.x*TARGET_DT/real_dt*300; } else { positions.items[i].x = nx; } float ny = positions.items[i].y + velocities.items[i].y*TARGET_DT; if (ny - radius <= 0) { positions.items[i].y = radius; velocities.items[i].y *= -COLLISION_DAMPING; velocities.items[i].y += dwinpos.y*TARGET_DT/real_dt*300; } else if (ny + radius >= h) { positions.items[i].y = h - radius; velocities.items[i].y *= -COLLISION_DAMPING; velocities.items[i].y += dwinpos.y*TARGET_DT/real_dt*300; } else { positions.items[i].y = ny; } // DrawRing(positions.items[i], radius*0.8, radius, 0, 360, 100, ColorAlpha(colors.items[i], f)); DrawTexturePro( tex_rac, (Rectangle) {0, 0, tex_rac.width, tex_rac.height}, (Rectangle) {positions.items[i].x-radius, positions.items[i].y-radius, radius*2, radius*2}, (Vector2) {0, 0}, 0.0f, ColorAlpha(colors.items[i], f) ); } } EndDrawing(); prev_winpos = winpos; } CloseWindow(); return 0; }