Untitled

 avatar
unknown
plain_text
2 months ago
5.3 kB
7
Indexable
#include "raylib.h"
#include <time.h>
#include <stdlib.h>

#define SCR_WIDTH       1280
#define SCR_HEIGHT      720
#define CELL_SIZE       5
#define ROWS            (SCR_WIDTH / CELL_SIZE)
#define COLS            (SCR_HEIGHT / CELL_SIZE)
#define OFFSET_X        SCR_WIDTH % CELL_SIZE
#define OFFSET_Y        SCR_HEIGHT % CELL_SIZE
#define SPAWN_RADIUS    5

void ProcessInput(int grid[ROWS][COLS]);
void Update(int grid[ROWS][COLS]);
void Draw(int grid[ROWS][COLS]);

void CreateGrid(int grid[ROWS][COLS]);
void GetCurrentGridPosition(int* gridX, int* gridY);
void SpawnSand(int grid[ROWS][COLS]);
void RemoveSand(int grid[ROWS][COLS]);
void SimulateSand(int grid[ROWS][COLS]);

int main(void)
{
    InitWindow(SCR_WIDTH, SCR_HEIGHT, "Simple Sand Simulation");
    SetTargetFPS(60);

    int grid[ROWS][COLS];
    CreateGrid(grid);

    srand(time(NULL));   

    while (!WindowShouldClose())
    {
        ProcessInput(grid);
        Update(grid);
        Draw(grid);
    }

    CloseWindow();

    return 0;
}

void ProcessInput(int grid[ROWS][COLS])
{
    if (IsMouseButtonDown(MOUSE_BUTTON_LEFT))
    {
        SpawnSand(grid);
    }
    if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT))
    {
        RemoveSand(grid);
    }
}


void Update(int grid[ROWS][COLS])
{
    SimulateSand(grid);
}

void Draw(int grid[ROWS][COLS])
{
    BeginDrawing();
    ClearBackground(BLACK);

    // Draw grid and cells
    for (int x = 0; x < ROWS; x++)
    {
        for (int y = 0; y < COLS; y++)
        {
            // Determine cell color
            Color cellColor = (grid[x][y] == 1) ? BEIGE : BLACK;

            // Draw the cell
            DrawRectangle(
                CELL_SIZE * x + OFFSET_X / 2, 
                CELL_SIZE * y + OFFSET_Y / 2, 
                CELL_SIZE, 
                CELL_SIZE, 
                cellColor
            );
            
            // Draw grid lines (optional)
            /*DrawRectangleLines(
                CELL_SIZE * x + OFFSET_X / 2, 
                CELL_SIZE * y + OFFSET_Y / 2, 
                CELL_SIZE, 
                CELL_SIZE, 
                GRAY
            );*/
            
        }
    }

    EndDrawing();
}

void CreateGrid(int grid[ROWS][COLS])
{
    for (int x = 0; x < ROWS; x++)
    {
        for (int y = 0; y < COLS; y++)
        {
            grid[x][y] = 0; // Initialize all cells to inactive
        }
    }
}

void GetCurrentGridPosition(int* gridX, int* gridY)
{
    Vector2 mousePosition   = GetMousePosition();
    int cell_center_x       = OFFSET_X / 2;
    int cell_center_y       = OFFSET_X / 2;
    *gridX                  = (mousePosition.x - cell_center_x) / CELL_SIZE;
    *gridY                  = (mousePosition.y - cell_center_y) / CELL_SIZE;
}

void SpawnSand(int grid[ROWS][COLS])
{
    // Get mouse position and calculate grid coordinates
    int gridX = 0, gridY = 0;
    GetCurrentGridPosition(&gridX, &gridY); 

    for (int dx = -SPAWN_RADIUS; dx <= SPAWN_RADIUS; dx++)
    {
        for (int dy = -SPAWN_RADIUS; dy <= SPAWN_RADIUS; dy++)
        {
            int nx = gridX + dx;
            int ny = gridY + dy;    
            if (nx >= 0 && nx < ROWS && ny >= 0 && ny < COLS)
            {
                if (rand() % 2 == 0) // 50% chance to spawn
                {
                    grid[nx][ny] = 1;
                }
            }
        }
    }   
}

void RemoveSand(int grid[ROWS][COLS])
{
    int gridX = 0, gridY = 0;
    GetCurrentGridPosition(&gridX, &gridY); 

    // Erase particles within the same radius
    for (int dx = -SPAWN_RADIUS; dx <= SPAWN_RADIUS; dx++)
    {
        for (int dy = -SPAWN_RADIUS; dy <= SPAWN_RADIUS; dy++)
        {
            int nx = gridX + dx;
            int ny = gridY + dy;    
            // Check if within grid bounds
            if (nx >= 0 && nx < ROWS && ny >= 0 && ny < COLS)
            {
                grid[nx][ny] = 0; // Clear the cell
            }
        }
    }   
}

void SimulateSand(int grid[ROWS][COLS])
{
    // Process the grid from bottom to top for stability
    for (int y = COLS - 1; y >= 0; y--)  // Iterate rows from bottom to top
    {
        for (int x = 0; x < ROWS; x++)  // Iterate columns left to right
        {
            if (grid[x][y] == 1) // If the current cell contains a particle
            {
                // Check if the cell below is empty
                if (y + 1 < COLS && grid[x][y + 1] == 0)
                {
                    // Move the particle down
                    grid[x][y]      = 0;
                    grid[x][y + 1]  = 1;
                }
                else if (y < COLS - 1 && grid[x][y + 1] == 1) // If the cell below is occupied
                {
                    // Attempt random movement to the left or right
                    int direction = GetRandomValue(0, 1) == 0 ? -1 : 1;
                
                    // Check bounds for horizontal movement
                    if (x + direction >= 0 && x + direction < ROWS && grid[x + direction][y + 1] == 0)
                    {
                        // Move diagonally down left or down right
                        grid[x][y]                  = 0;
                        grid[x + direction][y + 1]  = 1;
                    }
                }
            }
        }
    }
}
Editor is loading...
Leave a Comment