Browse Source

wow liquid density

master
alistair 3 years ago
parent
commit
c5348883bb
  1. 33
      game.cpp
  2. 206
      particles.cpp
  3. 45
      particles.h

33
game.cpp

@ -46,6 +46,7 @@ class PaintTool { @@ -46,6 +46,7 @@ class PaintTool {
public:
int particle_selected = 0;
int size = 1;
int mouse_state = 0;
};
class Game {
@ -78,11 +79,16 @@ class Game { @@ -78,11 +79,16 @@ class Game {
particles.push_back(new Sand());
particles.push_back(new Water());
particles.push_back(new Steam());
particles.push_back(new Lava());
}
~Game() {
SDL_DestroyTexture(grid_texture);
for (auto p : particles) {
delete p;
}
}
void update() {
@ -104,8 +110,8 @@ class Game { @@ -104,8 +110,8 @@ class Game {
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] % internal_sz[0];
p.y = internal_sz[1] * y / window_sz[1] % internal_sz[1];
p.x = (internal_sz[0] * x/window_sz[0]) % internal_sz[0];
p.y = (internal_sz[1] * y / window_sz[1]) % internal_sz[1];
return p;
}
@ -124,24 +130,31 @@ class Game { @@ -124,24 +130,31 @@ class Game {
if (event.key.keysym.scancode == SDL_SCANCODE_2) {
tool.particle_selected = 1;
};
if (event.key.keysym.scancode == SDL_SCANCODE_3) {
tool.particle_selected = 2;
};
if (event.key.keysym.scancode == SDL_SCANCODE_4) {
tool.particle_selected = 3;
};
break;
case SDL_KEYUP:
break;
case SDL_MOUSEBUTTONDOWN:
coord = get_click_location_in_grid(event.button.x, event.button.y);
grid.add_particle_at(coord.x, coord.y, particles[tool.particle_selected]->id);
tool.mouse_state = 1;
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, particles[tool.particle_selected]->id);
}
break;
case SDL_MOUSEBUTTONUP:
continue;
tool.mouse_state = 0;
break;
}
}
if (tool.mouse_state) {
coord = get_click_location_in_grid(event.motion.x, event.motion.y);
grid.add_particle_at(coord.x, coord.y, particles[tool.particle_selected]->id);
}
update();
draw();
}
@ -157,7 +170,7 @@ int main(int argc, char **argv) { @@ -157,7 +170,7 @@ int main(int argc, char **argv) {
std::cout << error;
}
pengine::Game game {pengine::Game(500,500, 100,100)};
pengine::Game game {pengine::Game(500,500, 80,80)};
game.run();
return 0;

206
particles.cpp

@ -6,13 +6,16 @@ namespace pengine { @@ -6,13 +6,16 @@ namespace pengine {
Uint8 part_colours[][3] = {
{255,255,255}, // BASIC
{252,250,148}, // SAND
{70,90,255} // WATER
{70,90,255}, // WATER
{200,220,255}, // STEAM
{200,20,20} // LAVA
};
std::string part_names[] = {
"default",
"Sand"
"Sand",
"Water",
"Steam"
};
Particle *get_new_particle(ParticleID p) {
@ -23,6 +26,13 @@ namespace pengine { @@ -23,6 +26,13 @@ namespace pengine {
return new Water();
case ParticleID::BASIC:
return new BasicParticle();
case ParticleID::STEAM:
return new Steam();
case ParticleID::LAVA:
return new Lava();
default:
std::cout << "Unknown particle create\n";
throw "unknown particle";
}
}
@ -67,8 +77,13 @@ namespace pengine { @@ -67,8 +77,13 @@ namespace pengine {
xsize = xs;
ysize = ys;
grid = new Particle *[xs * ys] {0};
pixels = new Uint32[xs * ys];
grid = new Particle *[xs * ys] {};
pixels = new Uint32[xs * ys] {};
for (int i = 0; i < xs * ys; i++) {
grid[i] = 0;
pixels[i] = 0;
}
}
Grid::~Grid()
@ -84,15 +99,20 @@ namespace pengine { @@ -84,15 +99,20 @@ namespace pengine {
void Grid::update()
{
static bool updated = false;
for (int i = 0; i < xsize; i++) {
for (int j = 0; j < ysize; j++) {
int p = j * xsize + i;
if (grid[p] != nullptr) {
if (grid[p]->updated != updated) {
grid[p]->updated = updated;
grid[p]->update(this, i, j);
bool done = true;
while (done) {
done = false;
for (int i = 0; i < xsize; i++) {
for (int j = 0; j < ysize; j++) {
int p = j * xsize + i;
if (grid[p]) {
if (grid[p]->updated != updated) {
grid[p]->updated = updated;
grid[p]->update(this, i, j);
done = true;
}
}
}
}
@ -130,7 +150,7 @@ namespace pengine { @@ -130,7 +150,7 @@ namespace pengine {
for (int i = 0; i < xsize; i++) {
for (int j = 0; j < ysize; j++) {
int p = j * xsize + i;
if (grid[p]) {
if (grid[p] != nullptr) {
//:w pixels[p] = defaultcoll.pixel;
pixels[p] = grid[p]->get_colour().get_pixelcol();
} else {
@ -168,64 +188,112 @@ namespace pengine { @@ -168,64 +188,112 @@ namespace pengine {
return false;
}
bool Grid::swap_particle(int xa, int ya, int xb, int yb) {
int Grid::swap_particle(int xa, int ya, int xb, int yb) {
if (!inside_grid(xb, yb)) {
return false;
return 0;
}
if (!inside_grid(xa, ya)) {
return false;
return 0;
}
if ((get_particle(xa,ya) != nullptr) || (get_particle(xb,yb) != nullptr)) {
int num = 0;
if (get_particle(xa,ya) != nullptr) {
num++;
}
if (get_particle(xb,yb) != nullptr) {
num++;
}
if (num > 0) {
Particle *temp = grid[xb + yb * xsize];
grid[xb + yb * xsize] = grid[xa + ya * xsize];
grid[xa + ya * xsize] = temp;
return true;
return num;
}
return false;
return 0;
}
void Sand::update(Grid * const g, int x, int y) {
Particle *p;
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;
}
p = g->get_particle(x, y+1);
if (p) {
if (p->density < density) {
if (p != nullptr) {
if (p->data.density < data.density || p->data.liquid) {
g->swap_particle(x, y, x, y+1);
return;
}
} else {
g->swap_particle(x, y, x, y+1);
return;
if (g->swap_particle(x, y, x, y+1)) {
return;
}
}
p = g->get_particle(x-1, y+1);
if (p) {
if (p->density < density) {
if (p != nullptr) {
if (p->data.density < data.density || p->data.liquid) {
g->swap_particle(x, y, x-1, y+1);
return;
}
} else {
g->swap_particle(x, y, x-1, y+1);
if
(g->swap_particle(x, y, x-1, y+1))
return;
}
p = g->get_particle(x+1, y+1);
if (p) {
if (p->density < density) {
g->swap_particle(x, y, x-1, y+1);
if (p != nullptr) {
if (p->data.density < data.density || p->data.liquid) {
g->swap_particle(x, y, x+1, y+1);
return;
}
} else {
g->swap_particle(x, y, x+1, y+1);
return;
if (g->swap_particle(x, y, x+1, y+1))
return;
}
}
BasicParticle::BasicParticle() : Particle(ParticleID::BASIC) {}
struct particle_data BasicParticle::default_data(ParticleID id) {
struct particle_data datap;
switch (id) {
case ParticleID::WATER:
datap = {.density=10, .liquid = true};
break;
case ParticleID::LAVA:
datap = {.density=20, .liquid = true};
break;
case ParticleID::STEAM:
datap = {.density=0, .liquid = false};
break;
case ParticleID::SAND:
datap = {.density=100, .liquid = false};
break;
default:
datap = {};
break;
}
return datap;
}
BasicParticle::BasicParticle(ParticleID id) : Particle(id) {
this->id = id;
data = default_data(id);
};
void BasicParticle::update(Grid * const g, int x, int y) {
return;
@ -240,7 +308,29 @@ namespace pengine { @@ -240,7 +308,29 @@ namespace pengine {
}
void Water::update(Grid * const g, int x, int y) {
if (g->move_particle(x, y, x, y+1)) {
auto p = g->get_particle(x,y+1);
if (p && p->data.liquid && p->id != id && this->data.density > p->data.density) {
if (g->swap_particle(x, y, x, y+1))
return;
}
p = g->get_particle(x-1,y+1);
if ((p && p->data.liquid && p->id != id && data.density > p->data.density)) {
if (g->swap_particle(x, y, x-1, y+1)) {
return;
}
}
p = g->get_particle(x+1,y+1);
if ((p && p->data.liquid && p->id != id && data.density > p->data.density)) {
if (g->swap_particle(x, y, x+1, y+1)) {
return;
}
}
if(g->move_particle(x, y, x, y+1)) {
return;
}
if (g->move_particle(x, y, x-1, y+1)) {
@ -249,13 +339,63 @@ namespace pengine { @@ -249,13 +339,63 @@ namespace pengine {
if (g->move_particle(x, y, x+1, y+1)) {
return;
}
/* laksjdlaj */
if (g->move_particle(x, y, x-1, y)) {
return;
}
if (g->move_particle(x, y, x+1, y)) {
return;
}
p = g->get_particle(x-1,y);
if ((p && p->data.liquid)) {
if (g->swap_particle(x, y, x-1, y)) {
return;
}
}
p = g->get_particle(x+1,y);
if ((p && p->data.liquid)) {
if (g->swap_particle(x, y, x+1, y)) {
return;
}
}
}
void Steam::update(Grid *const g, int x, int y) {
Particle *p = g->get_particle(x,y-1);
if (g->move_particle(x, y, x, y-1)) {
return;
}
p = g->get_particle(x-1,y-1);
if (g->move_particle(x, y, x-1, y-1)) {
return;
}
p = g->get_particle(x+1,y-1);
if (g->move_particle(x, y, x+1, y-1)) {
return;
}
p = g->get_particle(x+1,y);
if (g->move_particle(x, y, x+1, y)) {
return;
}
p = g->get_particle(x-1,y);
if (g->move_particle(x, y, x-1, y)) {
return;
}
}
Lava::Lava() : Water(ParticleID::LAVA) {};
void Lava::update(Grid *const g, int x, int y) {
Water::update(g,x,y);
}
}

45
particles.h

@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
#include <SDL2/SDL_ttf.h>
#include <vector>
#include <string>
#include <memory>
namespace pengine {
@ -19,6 +20,8 @@ enum class ParticleID @@ -19,6 +20,8 @@ enum class ParticleID
BASIC = 0,
SAND = 1,
WATER = 2,
STEAM = 3,
LAVA = 4,
};
class PixelColour {
@ -41,13 +44,19 @@ class PixelColour { @@ -41,13 +44,19 @@ class PixelColour {
};
struct particle_data {
double density;
bool liquid;
};
class Particle;
class Grid {
public:
private:
Particle **grid;
Uint32 *pixels;
public:
int xsize;
int ysize;
@ -59,7 +68,7 @@ class Grid { @@ -59,7 +68,7 @@ class Grid {
void add_particle_at(int x, int y, ParticleID p);
bool move_particle(int xa, int ya, int xb, int yb);
bool swap_particle(int xa, int ya, int xb, int yb);
int swap_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);
@ -68,8 +77,7 @@ class Grid { @@ -68,8 +77,7 @@ class Grid {
class Particle
{
public:
double density;
struct particle_data data;
bool updated = false;
enum ParticleID id;
@ -77,36 +85,45 @@ class Particle @@ -77,36 +85,45 @@ class Particle
virtual PixelColour get_colour() = 0;
Particle(ParticleID id) : id{id} {};
virtual std::string get_name() = 0;
virtual ~Particle() = default;
};
class BasicParticle : public Particle
{
public:
double density = 2;
BasicParticle();
BasicParticle(ParticleID id) : Particle(id) {};
BasicParticle(ParticleID id);
struct particle_data default_data(ParticleID id);
void update(Grid *const, int x, int y) override;
PixelColour get_colour() override;
std::string get_name() override;
};
class Sand:public BasicParticle {
public:
/* data */
double density = 2;
public:
void update(Grid *const, int x, int y) override;
Sand() : BasicParticle(ParticleID::SAND) {};
Sand() : BasicParticle(ParticleID::SAND){};
};
class Water:public BasicParticle {
public:
/* data */
double density = 1;
void update(Grid *const, int x, int y) override;
Water() : BasicParticle(ParticleID::WATER) {};
Water(ParticleID id) : BasicParticle(id) {};
};
class Steam:public BasicParticle {
public:
void update(Grid *const, int x, int y) override;
Steam() : BasicParticle(ParticleID::STEAM) {};
};
class Lava:public Water {
public:
void update(Grid *const, int x, int y) override;
Lava();
};
}

Loading…
Cancel
Save