Browse Source

state transitions

master
alistair 3 years ago
parent
commit
3a2ac11a0c
  1. 7
      Makefile
  2. 13
      game.cpp
  3. 123
      particles.cpp
  4. 26
      particles.h

7
Makefile

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
all:
g++ -c particles.cpp -lSDL2 -lSDL2_image -lSDL2_ttf -g -o particles.o
g++ -c game.cpp -lSDL2 -lSDL2_image -lSDL2_ttf -g -o game.o
g++ -lSDL2 -lSDL2_image -lSDL2_ttf -g particles.o game.o -o main
g++ -fsanitize=address -c particles.cpp -lSDL2 -lSDL2_image -lSDL2_ttf -g -o particles.o
g++ -fsanitize=address -c game.cpp -lSDL2 -lSDL2_image -lSDL2_ttf -g -o game.o
g++ -fsanitize=address -lSDL2 -lSDL2_image -lSDL2_ttf -g particles.o game.o -o main

13
game.cpp

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
#include <SDL2/SDL_events.h>
#include <SDL2/SDL_pixels.h>
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_scancode.h>
#include <SDL2/SDL_surface.h>
#include <SDL2/SDL_timer.h>
#include <SDL2/SDL_video.h>
@ -47,6 +48,7 @@ class PaintTool { @@ -47,6 +48,7 @@ class PaintTool {
int particle_selected = 0;
int size = 1;
int mouse_state = 0;
bool paused = false;
};
class Game {
@ -124,6 +126,11 @@ class Game { @@ -124,6 +126,11 @@ class Game {
case SDL_QUIT:
return;
case SDL_KEYDOWN:
if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE) {
tool.paused = !tool.paused;
}
if (event.key.keysym.scancode == SDL_SCANCODE_1) {
tool.particle_selected = 0;
};
@ -136,6 +143,7 @@ class Game { @@ -136,6 +143,7 @@ class Game {
if (event.key.keysym.scancode == SDL_SCANCODE_4) {
tool.particle_selected = 3;
};
break;
case SDL_KEYUP:
break;
@ -155,7 +163,10 @@ class Game { @@ -155,7 +163,10 @@ class Game {
grid.add_particle_at(coord.x, coord.y, particles[tool.particle_selected]->id);
}
update();
if (!tool.paused) {
update();
}
draw();
}
}

123
particles.cpp

@ -7,18 +7,24 @@ namespace pengine { @@ -7,18 +7,24 @@ namespace pengine {
{255,255,255}, // BASIC
{252,250,148}, // SAND
{70,90,255}, // WATER
{200,220,255}, // STEAM
{200,20,20} // LAVA
{200,220,255}, // STEAM
{200,20,20}, // LAVA
{140,111,71}, // ROCK
{200,20,20}, // LIQUID QUARTZ
{20,80,40}, // QUARTZ
};
std::string part_names[] = {
"default",
"Sand",
"Water",
"Steam"
"Steam",
"Lava",
"Rock"
};
Particle *get_new_particle(ParticleID p) {
switch (p) {
case ParticleID::SAND:
return new Sand();
@ -30,12 +36,31 @@ namespace pengine { @@ -30,12 +36,31 @@ namespace pengine {
return new Steam();
case ParticleID::LAVA:
return new Lava();
case ParticleID::ROCK:
return new Rock();
default:
std::cout << "Unknown particle create\n";
throw "unknown particle";
}
}
State BasicParticle::get_state() {
switch(id) {
case (ParticleID::STEAM):
return State::GAS;
case (ParticleID::WATER):
case (ParticleID::LAVA):
return State::LIQUID;
case (ParticleID::ROCK):
case (ParticleID::SAND):
return State::SOLID;
default:
return State::SOLID;
}
}
PixelColour::PixelColour(short r, short g, short b, short a) {
this->r = r;
this->g = g;
@ -216,9 +241,27 @@ namespace pengine { @@ -216,9 +241,27 @@ namespace pengine {
}
void Grid::replace_particle(int x, int y, Particle *new_particle) {
auto p = get_particle(x, y);
if (!p) {
return;
}
delete p;
grid[x + y * xsize] = new_particle;
}
void Sand::update(Grid * const g, int x, int y) {
Particle *p;
if (update_temperature(g, x, y)) {
return;
}
Particle *p;
if(g->move_particle(x, y, x, y+1)) {
return;
}
@ -272,19 +315,26 @@ namespace pengine { @@ -272,19 +315,26 @@ namespace pengine {
struct particle_data datap;
switch (id) {
case ParticleID::WATER:
datap = {.density=10, .liquid = true};
datap = {.density=10, .liquid = true, .temperature=20,
.boiling_point = 100, .gas_state = ParticleID::STEAM};
break;
case ParticleID::LAVA:
datap = {.density=20, .liquid = true};
datap = {.density=20, .liquid = true, .temperature=5000,
.boiling_point = 10000,.freezing_point=200, .solid_state=ParticleID::ROCK};
break;
case ParticleID::STEAM:
datap = {.density=0, .liquid = false};
datap = {.density=0, .liquid = false, .temperature=150,
.liquid_state = ParticleID::WATER};
break;
case ParticleID::SAND:
datap = {.density=100, .liquid = false};
datap = {.density=100, .liquid = false, .temperature=20};
break;
case ParticleID::ROCK:
datap = {.density=150, .liquid = false, .temperature=20,
.melting_point = 700, .liquid_state=ParticleID::LAVA};
break;
default:
datap = {};
datap = {.temperature = 0};
break;
}
return datap;
@ -307,10 +357,55 @@ namespace pengine { @@ -307,10 +357,55 @@ namespace pengine {
return part_names[((int)this->id)];
}
bool BasicParticle::update_temperature(Grid * const g, int x, int y)
{
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
int xa = x + i;
int ya = y + j;
auto p = g->get_particle(xa,ya);
if (p) {
data.temperature += (p->data.temperature - data.temperature) / 5;
}
}
}
/* apply state transition */
if (get_state() != State::GAS && data.temperature > data.boiling_point) {
if (data.gas_state != ParticleID::BASIC){
auto gas = get_new_particle(data.gas_state);
g->replace_particle(x,y,gas);
return true;
}
}
if (get_state() != State::LIQUID && data.temperature < data.boiling_point
&& data.temperature > data.freezing_point) {
if (data.liquid_state != ParticleID::BASIC){
auto liquid = get_new_particle(data.liquid_state);
g->replace_particle(x,y,liquid);
return true;
}
}
if (get_state() != State::SOLID && data.temperature < data.freezing_point) {
if (data.solid_state != ParticleID::BASIC){
auto gas = get_new_particle(data.solid_state);
g->replace_particle(x,y,gas);
return true;
}
}
return false;
}
void Water::update(Grid * const g, int x, int y) {
if (update_temperature(g,x,y)) {
return;
}
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;
@ -364,8 +459,6 @@ namespace pengine { @@ -364,8 +459,6 @@ namespace pengine {
}
}
}
void Steam::update(Grid *const g, int x, int y) {
@ -393,9 +486,15 @@ namespace pengine { @@ -393,9 +486,15 @@ namespace pengine {
Lava::Lava() : Water(ParticleID::LAVA) {};
Rock::Rock() : Sand(ParticleID::ROCK) {};
void Lava::update(Grid *const g, int x, int y) {
Water::update(g,x,y);
}
void Rock::update(Grid *const g, int x, int y) {
Sand::update(g,x,y);
}
}

26
particles.h

@ -22,6 +22,7 @@ enum class ParticleID @@ -22,6 +22,7 @@ enum class ParticleID
WATER = 2,
STEAM = 3,
LAVA = 4,
ROCK = 5
};
class PixelColour {
@ -43,10 +44,22 @@ class PixelColour { @@ -43,10 +44,22 @@ class PixelColour {
PixelColour(SDL_Color c);
};
enum class State {
SOLID,
LIQUID,
GAS
};
struct particle_data {
double density;
bool liquid;
double temperature;
double boiling_point;
double melting_point;
double freezing_point;
ParticleID gas_state;
ParticleID liquid_state;
ParticleID solid_state;
};
class Particle;
@ -71,6 +84,7 @@ class Grid { @@ -71,6 +84,7 @@ class Grid {
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);
void replace_particle(int x, int y, Particle *new_particle);
// std::vector<Particle *> get_particles_near(int x, int y);
};
@ -90,6 +104,9 @@ class Particle @@ -90,6 +104,9 @@ class Particle
class BasicParticle : public Particle
{
protected:
bool update_temperature(Grid * const g, int x, int y);
State get_state();
public:
BasicParticle();
BasicParticle(ParticleID id);
@ -104,6 +121,7 @@ class Sand:public BasicParticle { @@ -104,6 +121,7 @@ class Sand:public BasicParticle {
public:
void update(Grid *const, int x, int y) override;
Sand() : BasicParticle(ParticleID::SAND){};
Sand(ParticleID id) : BasicParticle(id) {};
};
class Water:public BasicParticle {
@ -121,11 +139,15 @@ class Steam:public BasicParticle { @@ -121,11 +139,15 @@ class Steam:public BasicParticle {
class Lava:public Water {
public:
void update(Grid *const, int x, int y) override;
Lava();
};
}
class Rock: public Sand {
public:
void update(Grid *const, int x, int y) override;
Rock();
};
}
#endif

Loading…
Cancel
Save