#include #include #include #ifdef PLATFORM_WEB #include RAYLIB_SRC #else #include #endif typedef uint32_t u32; #define MOONS_CAP 4 #define PLANETS_CAP 10 int SW = 1200; int SH = 800; #define OFF_Y (7*SH/9) int sector_len = 16; u32 seed = 0; typedef struct { int diameter; u32 color; bool ring; int moons[MOONS_CAP]; } planet_t; typedef struct { int diameter; u32 color; } star_t; star_t star_gen(); void planets_gen(planet_t *planets); uint32_t lehmer(); int rnd_int(int max, int min); #define HEX_TO_COL(col) {((col) >> 16) & 0xFF, \ ((col) >> 8) & 0xFF, \ (col) & 0xFF, 0xFF} int main(void) { InitWindow(SW, SH, "Procedural Generation"); SetTargetFPS(30); SetWindowState(FLAG_WINDOW_RESIZABLE); int offset_x = 0; int offset_y = 0; while (!WindowShouldClose()) { SW = GetScreenWidth(); SH = GetScreenHeight(); int sectors_x = SW/sector_len; int sectors_y = SH/sector_len; sector_len += (int)GetMouseWheelMove(); if(sector_len <= 0) sector_len = 1; if(IsKeyDown(KEY_W)) offset_y -= 1; if(IsKeyDown(KEY_A)) offset_x -= 1; if(IsKeyDown(KEY_S)) offset_y += 1; if(IsKeyDown(KEY_D)) offset_x += 1; static bool extra_info = false; star_t info_star; planet_t info_planets[PLANETS_CAP]; if(IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) extra_info = false; BeginDrawing(); ClearBackground(BLACK); // gen each sector for(int i = 0; i < sectors_x; i++) for(int j = 0; j < sectors_y; j++) { seed = ((i+offset_x) & 0xFFFF) << 16 | ((j+offset_y) & 0xFFFF); if(rnd_int(25, 0) != 0) continue; star_t star = star_gen(); int x = i * sector_len + (sector_len/2); int y = j * sector_len + (sector_len/2); float diam = (float)star.diameter*sector_len/96; DrawCircle(x, y, diam, (Color)HEX_TO_COL(star.color)); // hover over star if(GetMouseX()/sector_len == i && GetMouseY()/sector_len == j) { DrawCircleLines(x, y, diam + 4, (Color)HEX_TO_COL(star.color)); // click on star if(IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { extra_info = true; info_star = star; planets_gen(info_planets); } } } // extra info rec if(extra_info) { DrawRectangle(0, 2*SH/3, SW, SH/3, BLUE); // draw star int body_offset = 50 + info_star.diameter; DrawCircle(body_offset, OFF_Y, info_star.diameter, (Color)HEX_TO_COL(info_star.color)); body_offset += 90 + info_star.diameter; // draw planets for(int i = 0; i < PLANETS_CAP; i++) { if(info_planets[i].diameter == 0) continue; body_offset += info_planets[i].diameter; DrawCircle(body_offset, OFF_Y, info_planets[i].diameter, (Color)HEX_TO_COL(info_planets[i].color)); if(info_planets[i].ring) { DrawCircleLines(body_offset, OFF_Y, info_planets[i].diameter + 6, (Color)HEX_TO_COL(info_planets[i].color)); DrawCircleLines(body_offset, OFF_Y, info_planets[i].diameter + 7, (Color)HEX_TO_COL(info_planets[i].color)); } // draw moons int y_off = info_planets[i].diameter + 10; for(int j = 0; j < MOONS_CAP; j++) { if(info_planets[i].moons[j] == 0) continue; y_off += info_planets[i].moons[j]; DrawCircle(body_offset, OFF_Y + y_off, info_planets[i].moons[j], GRAY); y_off += 10 + info_planets[i].moons[j]; } body_offset += 50 + info_planets[i].diameter; } } DrawFPS(10, 10); EndDrawing(); } CloseWindow(); } star_t star_gen() { star_t star; star.diameter = rnd_int(80, 20); star.color = rnd_int(0xFFFFFF, 0); return star; } void planets_gen(planet_t *planets) { int n = rnd_int(PLANETS_CAP, 0); for(int i = 0; i < PLANETS_CAP; i++) { if(i >= n) { planets[i].diameter = 0; continue; } planets[i].diameter = rnd_int(40, 10); planets[i].color = rnd_int(0xFFFFFF, 0); planets[i].ring = (rnd_int(5, 0) == 1); for(int j = 0; j < MOONS_CAP; j++) planets[i].moons[j] = rnd_int(15, 0); } } uint32_t lehmer() { seed += 0xe120fc15; uint64_t tmp; tmp = (uint64_t)seed * 0x4a39b70d; uint32_t m1 = (tmp >> 32) ^ tmp; tmp = (uint64_t)m1 * 0x12fad5c9; uint32_t m2 = (tmp >> 32) ^ tmp; return m2; } int rnd_int(int max, int min) { return (lehmer() % (max - min)) + min; }