Skip to content

Instantly share code, notes, and snippets.

@andrew-raphael-lukasik
Last active October 16, 2023 17:23
Show Gist options
  • Save andrew-raphael-lukasik/abb41e01d5ccefb9ab2a283239fd9d90 to your computer and use it in GitHub Desktop.
Save andrew-raphael-lukasik/abb41e01d5ccefb9ab2a283239fd9d90 to your computer and use it in GitHub Desktop.
most basic sand sim you can create with Raylib 4.0

most basic sand sim you can create with Raylib 4.0

b2iqtgf9ejyhwr6krw5ytwsjty54yhr

#include <stdlib.h>
#include "raylib.h"
#include "math.h"
#include "rlgl.h"
bool SameRGB ( Color lhs , Color rhs );
bool SwapIf ( Color condition , int src , Color srcColor , int dst , char tick , Color* pixels );
#define AIR SKYBLUE
#define SAND ORANGE
#define WATER BLUE
const int screenWidth = 640;
const int screenHeight = 480;
const int pixelScale = 10;
const int pixelsWidth = screenWidth / pixelScale;
const int pixelsHeight = screenHeight / pixelScale;
const int pixelsLength = pixelsWidth * pixelsHeight;
int main ( void )
{
// Initialization
InitWindow( screenWidth , screenHeight , "sand" );
SetTargetFPS( 30 );
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
// Dynamic memory allocation to store pixels data (Color type)
Color *pixels = (Color*) malloc( pixelsLength * sizeof(Color) );
for( int i=0 ; i<pixelsLength ; i++ ) pixels[i] = AIR;
// Load pixels data into an image structure and create texture
Image pixelsImage = {
.data = pixels,
.width = pixelsWidth,
.height = pixelsHeight,
.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8,
.mipmaps = 1
};
Texture2D pixelsTexture = LoadTextureFromImage( pixelsImage );
SetTextureFilter( pixelsTexture , TEXTURE_FILTER_POINT );
// GAME LOOP
unsigned char tick = 0;
while( !WindowShouldClose() )
{
// UPDATE
float dt = GetFrameTime();
double time = GetTime();
tick++;
Vector2 mouse = GetMousePosition();
int mouseX = (int) mouse.x;
int mouseY = (int) mouse.y;
int mousePixelIndex = mouseY/pixelScale * pixelsWidth + mouseX/pixelScale;
{
for( int y=0 ; y<pixelsHeight ; y++ )
for( int x=0 ; x<pixelsWidth ; x++ )
{
int src = y*pixelsWidth + x;
Color srcColor = pixels[src];
if( SameRGB(srcColor,AIR) ) continue;// early exit
int down = (y+1)*pixelsWidth + x;
int downRight = (y+1)*pixelsWidth + x+1;
int downLeft = (y+1)*pixelsWidth + x-1;
int right = y*pixelsWidth + x+1;
int left = y*pixelsWidth + x-1;
if( SameRGB(srcColor,SAND) && srcColor.a!=tick )// is this SAND && not changed this frame
{
// falling down
if( SwapIf(AIR,src,srcColor,down,tick,pixels) ) continue;
else if( SwapIf(WATER,src,srcColor,down,tick,pixels ) ) continue;
if( GetRandomValue(0,1)==1 )
if( SwapIf(AIR,src,srcColor,downRight,tick,pixels) ) continue;
else if( SwapIf(WATER,src,srcColor,downRight,tick,pixels ) ) continue;
if( GetRandomValue(0,1)==1 )
if( SwapIf(AIR,src,srcColor,downLeft,tick,pixels) ) continue;
else if( SwapIf(WATER,src,srcColor,downLeft,tick,pixels ) ) continue;
}
else if( SameRGB(srcColor,WATER) && srcColor.a!=tick )// is this WATER && not changed this frame
{
// falling down
if( SwapIf(AIR,src,srcColor,down,tick,pixels) ) continue;
if( GetRandomValue(0,1)==1 )
if( SwapIf(AIR,src,srcColor,downRight,tick,pixels) ) continue;
if( GetRandomValue(0,1)==1 )
if( SwapIf(AIR,src,srcColor,downLeft,tick,pixels) ) continue;
// moving sideways
if( GetRandomValue(0,1)==1 )
if( SwapIf(AIR,src,srcColor,right,tick,pixels) ) continue;
if( GetRandomValue(0,1)==1 )
if( SwapIf(AIR,src,srcColor,left,tick,pixels) ) continue;
}
}
if( IsMouseButtonDown(0) )
{
pixels[mousePixelIndex] = SAND;
pixels[mousePixelIndex].a = tick;
}
else if( IsMouseButtonDown(1) )
{
pixels[mousePixelIndex] = WATER;
pixels[mousePixelIndex].a = tick;
}
else if( IsMouseButtonDown(2) )
{
pixels[mousePixelIndex] = AIR;
pixels[mousePixelIndex].a = tick;
}
}
// RENDER
BeginDrawing();
{
// ClearBackground( BLACK );
rlSetBlendFactors( 1 , 0 , 0x0104 );// 1 for GL_ONE, 0 for GL_ZERO, 0x0104 for GL_ADD
rlSetBlendMode( BLEND_CUSTOM );
UpdateTexture( pixelsTexture , pixels );
DrawTextureEx( pixelsTexture , (Vector2){ 0 , 0 } , 0 , pixelScale , WHITE );
// DrawText( TextFormat( "mouse:(%i,%i)" , mouseX , mouseY ), 72, 148, 30, BLUE );
}
EndDrawing();
}
// De-Initialization
UnloadImage( pixelsImage );// unloads CPU (RAM) image data (pixels)
UnloadTexture( pixelsTexture );
CloseWindow();// Close window and OpenGL context
return 0;
}
bool SameRGB ( Color lhs , Color rhs ) { return lhs.r==rhs.r && lhs.g==rhs.g && lhs.b==rhs.b; }
bool SwapIf ( Color condition , int src , Color srcColor , int dst , char tick , Color* pixels )
{
if( dst>=0 && dst<pixelsLength )
{
Color dstColor = pixels[dst];
if( dstColor.a!=tick )// not changed this frame
if( SameRGB(dstColor,condition) )
{
pixels[dst] = srcColor;
pixels[dst].a = tick;
pixels[src] = dstColor;
pixels[src].a = tick;
return true;
}
}
return false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment