|
|
|
@ -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); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|