{"id":18897507,"url":"https://github.com/seoproductions/sand-demo","last_synced_at":"2026-02-28T22:30:16.693Z","repository":{"id":229923457,"uuid":"774974270","full_name":"seoProductions/Sand-Demo","owner":"seoProductions","description":"Quick and Easy sand simulation built in C++ using olc's PixelGameEngine","archived":false,"fork":false,"pushed_at":"2024-05-16T23:29:18.000Z","size":437,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-31T08:23:13.962Z","etag":null,"topics":["cplusplus-17","demo-app","olcpixelgameengine"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/seoProductions.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-20T14:38:20.000Z","updated_at":"2024-05-16T23:29:22.000Z","dependencies_parsed_at":"2024-11-08T08:50:09.298Z","dependency_job_id":null,"html_url":"https://github.com/seoProductions/Sand-Demo","commit_stats":null,"previous_names":["seoproductions/sand-demo"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seoProductions%2FSand-Demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seoProductions%2FSand-Demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seoProductions%2FSand-Demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seoProductions%2FSand-Demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seoProductions","download_url":"https://codeload.github.com/seoProductions/Sand-Demo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239878826,"owners_count":19712172,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cplusplus-17","demo-app","olcpixelgameengine"],"created_at":"2024-11-08T08:37:38.008Z","updated_at":"2026-02-28T22:30:16.304Z","avatar_url":"https://github.com/seoProductions.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Welcome to my Sand Demo, take a look!!\n\nA simple project that simulates sand and water particles acting on a 2D world. This project utilizes the concept of a cellular automata, combined with Object Oriented and Function programing.\n\n\n# Features\n#### Sand\n![sand_demonstration](https://github.com/seoProductions/Sand-Demo/assets/111206081/c46b3575-7001-45c1-91c8-3eb74aef66df)\n\n\n#### Water\n![water_demonstration](https://github.com/seoProductions/Sand-Demo/assets/111206081/f9902f85-b0b3-4a31-a1d5-f9c2f65e2d69)\n\n\n#### Solid (WALL)\n![water_pour](https://github.com/seoProductions/Sand-Demo/assets/111206081/5dedddaf-0efa-4da3-af5d-78d6465fee62)\n\n\n#### Here are some more demonstrations: \n![stream_demonstration](https://github.com/seoProductions/Sand-Demo/assets/111206081/b16c889f-c8e7-4672-9f94-90b2b38066bf)\n\n\n![Cube Demonstration](https://github.com/seoProductions/Sand-Demo/assets/111206081/494bbe5f-07b4-42a3-a54a-9f9a033c2324)\n\n\n#### This is a messy one!\n![messy_one](https://github.com/seoProductions/Sand-Demo/assets/111206081/ed71eea2-67c8-49b4-84a2-0453b6407f99)\n\n\n## Lessons Learned\n\nWhile building this project, I both learned and tested many skills including\n- Project Design\n   - This project had to be drawn out and well thought about before execution!\n\n- Memory manegment\n   - I dont want to eat up my computers memory!\n\n- Dynamic memory allocation\n   - Every particle on screen is allocated onto the Heap\n   - Used smart pointers for saftey\n\n- Debugging with memory issues\n   - Segmentation Faults!\n\n- Naming things! I am working on this one!\n\n- Polymorphism and Inheritance\n   - My particle system is built entirely from OOP\n   - Working with olc::PixelGameEngine derived classes and methods\n\n- Shell Scripting on linux\n   - Automated compiling system using bash scripting\n\n- Basics of version controll using git\n   - Learning to use git thru terminal will come in handy!\n\nHere is a birds eye view of the project and its structure. Included is a UML Diagram \n\n![SandSimulationUML](https://github.com/seoProductions/Sand-Demo/assets/111206081/e05571c7-4e0b-4b86-a1c3-d5505d28898a)\n\n\n# Gist of the program\n\nThe program first launches into the main function where I have created a class called Engine.\n\n```c++\nclass Engine : public olc::PixelGameEngine\n```\n\n\n\nThis class is derived directly from the PixelGameEngine's Base class. The base class handles nessesary functionality such as \n - Window creation\n - Drawing\n - Keyboard and Mouse Inputs\n\n Looking into the Engine Class, I have a collection of Pointers of type \"Particle\" (More info on that later). I have these pointers held into std::vector simply due to simplicity and efficiency.\n\n```c++\nstd::vector\u003cstd::shared_ptr\u003cParticle\u003e\u003e particles;\n```\n\n During the game loop, the Engine checks for a Left click from the user. If sucessfull, new \"Particle\" pointers are dynamically allocated into the std::vector container.\n\n ```c++\nif (GetMouse(0).bHeld)\n{\n\tswitch (CurrentKeyDown)\n\t{\n\t\tcase SandDown:\n\t\t\tparticles.push_back(\n\t\t\t\tstd::make_shared\u003cSand\u003e(GetMouseX(), GetMouseY()));\n\t\t\t\tbreak;\n\t\tcase WaterDown:\n\t\t\tparticles.push_back(\n\t\t\t\tstd::make_shared\u003cWater\u003e(GetMouseX(), GetMouseY()));\n\t\t\t\tbreak;\n\t\tcase SolidDown:\n\t\t\tparticles.push_back(\n\t\t\t\tstd::make_shared\u003cSolid\u003e(GetMouseX(), GetMouseY()));\n\t\t\t\tbreak;\n\t}\n}\n```\n\nEach Particle is iterated over as shown here:\n\n```c++\nfor (auto particle: particles)\n{\n\t// check bounds and idle status\n\tif (particle-\u003ey \u003c ScreenHeight() - 1 \u0026\u0026 !particle-\u003eidle)\n        particle-\u003eupdateParticle(); //update\n\n\t\n\t//draw a pixel depending on the particle's type\n\tswitch (particle-\u003egetDrawType())\n\t{\n\tcase DrawSand:\n\t\tDraw(particle-\u003ex, particle-\u003ey, sandColor);\n\t\tbreak;\n\tcase DrawWater:\n\t\tDraw(particle-\u003ex, particle-\u003ey, waterColor);\n\t\tbreak;\n\tcase DrawSolid:\n\t\tDraw(particle-\u003ex, particle-\u003ey, solidColor);\n\t\tbreak;\n\t}\n}\n ```\nthe virtual updateParticle() method is invoked, and the Engine chooses a pixel color and pixel position to draw onto the screen. \n\n## Particle\nThis is the meat and Potatoes. The Particle class is the parent class for all particle types.\n\n```c++\nclass Particle\n```\nthis class contains\n- x and y position\n- idle status\n- generic \"move\" methods\n- virtual methods\n\nBase classes are\n\n```c++\nclass Sand : public Particle\nclass Water: public Particle\nclass Solid: public Particle\n\n```\nThey each contain \n- specific update function \n- specific DrawType\n\n### Particle Rules and behavior\n- Solid particles never move and are always idle\n- Sand particles will try to move below, then below to the (left/right)\n- Water particles do the same as sand, exept they also try to move directly (left/right)\n\nThe implementation for the rules was the most tedious part of my project, including many long and painfull debugging sessions, and crazy unexpected bugs. At the end, I got a working prototype! Far from perfect, but much more better than what I started off with.\n\n### Special case:\nEach water particle has a structure called \"OscilationDetector\". It simply aids in determining when to put a water particle into idle.\n\n```c++\nstruct OscillationDetector\n{\n    bool bIsLeft = rand() % 2; \t\t//random\n    short count = 0;\n};\n//Once occil_count reaches max, water particle will be set to idle\nconst int max_Oscilations = 2;\n```\nEach water particle stores its current direction, and a count for direction changes ( hence the name: \"Oscilations\" )\nThe counter only works at a constant Y level, thus at every vertical movement, the counter is reset. Once the max_Oscilations value is met, the particle is put into idle.\n\n## Collision Detection using \"CollisionBoard\"\nEach particle has a static member of a CollisionBoard. This variable is set in the Engine class, and is used by all particles when checking their movements. Methods include:  \n```c++\nPixelType CheckBelow        (int x, int y);\nPixelType CheckBelowLeft    (int x, int y);\nPixelType CheckBelowRight   (int x, int y);\nPixelType CheckLeft         (int x, int y);\nPixelType CheckRight        (int x, int y);\n\nvoid setPixelType(int x, int y, PixelType type);\n```\n\nThe whole std::vector or \"board\" is initialized to FreeSpace inside the constructor.+\n\n\n\n## Enumerations\n\nLooking at the UML, you can see I have created three Enumerations scattered around my program. These are helpfull features that I used to develop this program\n - The \"KeyDown\" enum is used to track which keyboard buttons have been recently pressed\n - The \"DrawType\" enum is used to identify particle types present in the std::vector of Particles. I figured this was the simplest way to impliment this, wanting to avoid dynamic casting and other perplexing methods capable of throwing exeptions...\n - \"PixelType\" enum is primarily used in the \"CollisionBoard\" class. It servers as the collection type used in a 2D std::vector called \"board\". With this, the CollisionBoard class has a sence of - what particles are in the 2D worlds and the position in which it is at. This is crucial for simulating real-time collision\n\n```c++\nstd::vector\u003cstd::vector\u003cPixelType\u003e\u003e board;\n ```\n\n\n## Running the program\n\nTo run the program, run the following command\n\n```bash\nchmod +x run.sh\n./run.sh\n```\n\nOr simply compile with your compliler of choice. I am using g++ here\n\n```bash\n#!/bin/bash\ng++ -o driver driver.cpp \\\n              collision.h \\\n              collision.cpp \\\n              particles.h   \\\n              particles.cpp \\\n              -lX11 -lGL -lpthread -lpng -lstdc++fs -std=c++17\n./driver\n```\n\n\n## Q\u0026A\n\n\n#### What made you choose c++ for this project?\n\nI had been using c++ for close to a year now - at the time of making this project (2023). I had grown fairly comfortorable with the language, but not to the point where I could develop larger scale projects. I took on this project our of pure curiosity and initiative. As a result, I ended up learning  much more than I anticipated. And lets not forget the great performance c++ has!\n\n#### What made you choose olc's PixelGameEngine?\n\nThe developer of the game engine is a favorite youtuber of mine, and I take great inspiration from him. I picked up the game engine during Highschool - a time when I was exploring many fields in computing. This included: Reverse-Engineering, 3D graphics, Game Developement, and much more. I was exploring at the time, and I just so happened to be familiar with the PixelGameEngine I used in my Sand Demo.\n\n#### I see your std::vector uses shared_ptr's , why not unique_ptr's?\n\n\nI am using shared pointers because the iterator generated from the code block above - incriments the total instances of this pointer. A unique ptr woudnt allow me to generate an iterator of Particles, and I simply wanted to keep things simple\n\n#### I have another question!!\n\nFeel free to reach out to me through my email or LinkedIn:\n- [duque.eliseo.7@gmail.com](duque.eliseo.7@gmail.com)\n- [LinkedIn](https://www.linkedin.com/in/eliseo-duque)\n\n## Related\n\nHere are some related projects:\n\n[Physics-Simulation in C++](https://github.com/seoProductions/Sandy---Physics-Simulation)\n\n\n## Authors\n\n[@seoProductions](https://github.com/seoProductions)\n\n## License\n[MIT](https://choosealicense.com/licenses/mit/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseoproductions%2Fsand-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseoproductions%2Fsand-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseoproductions%2Fsand-demo/lists"}