Browse Source

sand is nice

master
alistair 3 years ago
parent
commit
30647a4797
  1. 43
      game.cpp
  2. 129
      particles.cpp
  3. 55
      particles.h

43
game.cpp

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
#include <SDL2/SDL_pixels.h>
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_surface.h>
#include <SDL2/SDL_timer.h>
#include <SDL2/SDL_video.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
@ -34,6 +35,7 @@ class GameWindow { @@ -34,6 +35,7 @@ class GameWindow {
}
~GameWindow() {
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
@ -45,6 +47,9 @@ class Game { @@ -45,6 +47,9 @@ class Game {
Grid grid;
SDL_Texture *grid_texture;
SDL_Renderer *ren;
int internal_sz[2];
int window_sz[2];
public:
Game(int x, int y, int gx, int gy):
@ -54,6 +59,10 @@ class Game { @@ -54,6 +59,10 @@ class Game {
ren = win.renderer;
grid_texture = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STATIC, gx,gy);
internal_sz[0] = gx;
internal_sz[1] = gy;
window_sz[0] = x;
window_sz[1] = y;
}
~Game() {
@ -65,14 +74,27 @@ class Game { @@ -65,14 +74,27 @@ class Game {
}
void draw() {
SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
SDL_SetRenderDrawColor(ren, 40, 40, 40, 255);
SDL_RenderClear(ren);
grid.update_texture(grid_texture);
SDL_RenderCopy(ren, grid_texture, NULL, NULL);
SDL_RenderPresent(ren);
SDL_RenderClear(ren);
}
struct su_pair {
int x;
int y;
};
struct su_pair get_click_location_in_grid(int x, int y) {
struct su_pair p;
p.x = internal_sz[0] * x/window_sz[0];
p.y = internal_sz[1] * y / window_sz[1];
return p;
}
void run() {
struct su_pair coord;
while (true) {
SDL_Event event;
while(SDL_PollEvent(&event)) {
@ -82,12 +104,23 @@ class Game { @@ -82,12 +104,23 @@ class Game {
case SDL_KEYDOWN:
case SDL_KEYUP:
case SDL_MOUSEBUTTONDOWN:
{
coord = get_click_location_in_grid(event.button.x, event.button.y);
break;
}
case SDL_MOUSEMOTION:
coord = get_click_location_in_grid(event.motion.x, event.motion.y);
if (event.motion.state & SDL_BUTTON_LMASK) {
grid.add_particle_at(coord.x, coord.y, ParticleID::SAND);
}
break;
case SDL_MOUSEBUTTONUP:
continue;
}
}
update();
draw();
update();
draw();
}
}
@ -101,7 +134,7 @@ int main(int argc, char **argv) { @@ -101,7 +134,7 @@ int main(int argc, char **argv) {
std::cout << error;
}
pengine::Game game {pengine::Game(500,500, 100,200)};
pengine::Game game {pengine::Game(500,500, 100,100)};
game.run();
return 0;

129
particles.cpp

@ -3,14 +3,29 @@ @@ -3,14 +3,29 @@
namespace pengine {
PixelColour::PixelColour(short r, short b, short g, short a) {
const Uint8 part_colours[][3] = {
{255,255,255}, // BASIC
{0,0,255}, // SAND
{252,250,148} // SAND
};
Particle *get_new_particle(ParticleID p) {
switch (p) {
case ParticleID::SAND:
return new Sand();
case ParticleID::BASIC:
return new BasicParticle();
}
}
PixelColour::PixelColour(short r, short g, short b, short a) {
this->r = r;
this->g = g;
this->b = b;
this->a = a;
}
PixelColour::PixelColour(short r, short b, short g) {
PixelColour::PixelColour(short r, short g, short b) {
this->r = r;
this->g = g;
this->b = b;
@ -24,6 +39,11 @@ namespace pengine { @@ -24,6 +39,11 @@ namespace pengine {
this->a = c.a;
}
PixelColour::PixelColour(const Uint8 p[3]) {
PixelColour(p[0], p[1], p[2]);
}
SDL_Color PixelColour::get_sdlcol() {
SDL_Color c;
c.r = r;
@ -42,29 +62,66 @@ namespace pengine { @@ -42,29 +62,66 @@ namespace pengine {
ysize = ys;
grid = new Particle *[xs * ys] {};
pixels = new Uint32[xs * ys] {};
pixels = new Uint32[xs * ys];
}
Grid::~Grid() {
delete grid;
delete pixels;
Grid::~Grid()
{
for (int i = 0; i < xsize * ysize; i++) {
if (grid[i])
delete grid[i];
}
delete[] grid;
delete[] pixels;
}
void Grid::update() {
void Grid::update()
{
static bool updated = false;
for (int i = 0; i < xsize * ysize; i++) {
if (grid[i]) {
grid[i]->update();
if (grid[i] != nullptr) {
if (grid[i]->updated != updated) {
grid[i]->updated = updated;
grid[i]->update(this, i % xsize, i / xsize);
}
}
}
updated = !updated;
}
void Grid::add_particle_at(int x, int y, ParticleID p)
{
if (x >= xsize || y >= ysize || x < 0 || y < 0) {
std::cout << "invalid position " << x << " " << y << std::endl;
throw "invalid boundaries";
}
if (grid[x + y * xsize]) {
return;
}
grid[x + y * xsize] = get_new_particle(p);
}
Particle * Grid::get_particle(int x, int y) {
if (!inside_grid(x,y)) {
return nullptr;
}
return grid[x + xsize * y];
}
void Grid::update_texture(SDL_Texture *texture) {
PixelColour defaultcol = PixelColour(255,0,255,255);
PixelColour defaultcol = PixelColour(255,0,0,0);
PixelColour defaultcoll = PixelColour(255,255,0,0);
for (int i = 0; i < xsize; i++) {
for (int j = 0; j < ysize; j++) {
int p = j * xsize + i;
if (grid[p]) {
// pixels[i] = grid[i]->get_colour().get_pixelcol();
pixels[p] = defaultcoll.pixel;
} else {
pixels[p] = defaultcol.get_pixelcol();
}
@ -73,6 +130,56 @@ namespace pengine { @@ -73,6 +130,56 @@ namespace pengine {
// SDL_Rect r {.x = 0, .y = 0, .w = xsize, .h = ysize};
SDL_UpdateTexture(texture, NULL, pixels, xsize * sizeof(Uint32));
}
bool Grid::inside_grid(int x, int y) {
if (x >= xsize - 1 || y >= ysize - 1 || x < 1 || y < 1) {
return false;
}
return true;
}
bool Grid::move_particle(int xa, int ya, int xb, int yb) {
if (!inside_grid(xb, yb)) {
return false;
}
if (!inside_grid(xa, ya)) {
return false;
}
if ((get_particle(xa,ya) != nullptr) && (get_particle(xb,yb) == nullptr)) {
grid[xb + yb * xsize] = grid[xa + ya * xsize];
grid[xa + ya * xsize] = nullptr;
return true;
}
return false;
}
void Sand::update(Grid * const g, int x, int y) {
if (g->move_particle(x, y, x, y+1)) {
return;
}
if (g->move_particle(x, y, x-1, y+1)) {
return;
}
if (g->move_particle(x, y, x+1, y+1)) {
return;
}
}
BasicParticle::BasicParticle() : Particle(ParticleID::BASIC) {}
void BasicParticle::update(Grid * const g, int x, int y) {
return;
}
PixelColour BasicParticle::get_colour() {
return PixelColour {part_colours[1]};
}
}

55
particles.h

@ -9,15 +9,18 @@ @@ -9,15 +9,18 @@
#include <SDL2/SDL_video.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
#include <vector>
namespace pengine {
enum class ParticleID
{
SAND,
BASIC = 0,
SAND = 1,
};
class PixelColour {
public:
union {
struct {
Uint8 b;
@ -27,38 +30,62 @@ class PixelColour { @@ -27,38 +30,62 @@ class PixelColour {
};
Uint32 pixel;
};
public:
Uint32 get_pixelcol();
SDL_Color get_sdlcol();
PixelColour(short r, short b, short g, short a);
PixelColour(short r, short b, short g);
PixelColour(short r, short g, short b, short a);
PixelColour(short r, short g, short b);
PixelColour(const Uint8[3]);
PixelColour(SDL_Color c);
};
class Particle
{
public:
enum ParticleID id;
virtual PixelColour get_colour() = 0;
virtual void update(void) = 0;
};
class Particle;
class Grid {
private:
public:
Particle **grid;
Uint32 *pixels;
int xsize;
int ysize;
public:
Grid(int xs, int ys);
virtual ~Grid();
void update();
void update_texture(SDL_Texture *texture);
void add_particle_at(int x, int y, ParticleID p);
bool move_particle(int xa, int ya, int xb, int yb);
bool inside_grid(int x, int y);
Particle *get_particle(int x, int y);
// std::vector<Particle *> get_particles_near(int x, int y);
};
class Particle
{
public:
bool updated = 0;
enum ParticleID id;
virtual void update(Grid *const, int x, int y) = 0;
virtual PixelColour get_colour() = 0;
Particle(ParticleID id) : id{id} {};
};
class BasicParticle : public Particle
{
public:
BasicParticle();
BasicParticle(ParticleID id) : Particle(id) {};
void update(Grid *const, int x, int y) override;
PixelColour get_colour() override;
};
class Sand:public BasicParticle {
public:
void update(Grid *const, int x, int y) override;
Sand() : BasicParticle(ParticleID::SAND) {};
};
}
#endif

Loading…
Cancel
Save