Edit: Click the screen to play
Hi all, so I came across this webpage detailing a basic wave simulator in C# and was blown away at all the code, Wave Simulator with C# - CodeProject, figured there had to be an easier way so spent the afternoon playing around with vectors and came up with this instead, thought id share in case anyone wanted to tinker with it and see if you can improve it, mine was under 100 lines of code until the comments to make it easier to understand whats happening.
Would love feedback either way on how you could improve it
int count = 200;
Cell[][] grid = new Cell[count][count];
Cell[][] next = new Cell[count][count];
float w;
boolean paused = true;
void setup() {
size(1000, 1000);
colorMode(HSB);
surface.setVisible(true);
w = (float)width/count;
//GENERATE CELLS
for (int y = 0; y < count; y++) {
for (int x = 0; x < count; x++) {
grid[x][y] = new Cell(x, y);
next[x][y] = new Cell(x, y);
}
}
//INITIALIZE WALLS
for (int x = 0; x < count; x++) {
if (x >= 80 && x <= 90 || x >= 110 && x <= 120) continue;
grid[x][50].water = false;
}
}
void draw() {
surface.setTitle(str(int(frameRate)));
//GENERATE WAVE
if (!paused) {
for (int x = 0; x < count; x++) {
grid[x][2].pos.z = map(sin(frameCount/3f), -1, 1, 0, 255);
}
}
//CALCULATE SHOW FRAME AND CALCULATE NEXT FRAME
for (int y = 1; y < count; y++) {
for (int x = 0; x < count; x++) {
grid[x][y].show();
if (grid[x][y].water && !paused) {
grid[x][y].update();
}
}
}
//TRANSFER NEXT FRAME TO CURRENT
for (int y = 0; y < count; y++) {
for (int x = 0; x < count; x++) {
grid[x][y].pos.set(next[x][y].pos);
}
}
}
void mousePressed() {
paused = !paused;
}
//CALCULATE AVERAGE HEIGHT AROUND CELL
float averageHeight(int x, int y) {
float sum = 0;
for (int j = -1; j <= 1; j++) {
for (int i = -1; i <= 1; i++) {
if (i == 0 && j == 0) continue;
sum += grid[(x+i+count)%count][(y+j+count)%count].pos.z;
}
}
return sum/8f;
}
class Cell {
PVector pos, vel, acc;
PVector force = new PVector();
PVector neighbor = new PVector();
int x, y;
boolean water = true;
Cell(int _x, int _y) {
x = _x;
y = _y;
pos = new PVector(x*w, y*w, 127);
vel = new PVector();
acc = new PVector();
}
void update() {
//SET VECTOR TO AVERAGE HEIGHT OF NEIGHBORS AND APPLY FORCE TO NEXT GRID
neighbor.set(0, 0, averageHeight(x,y));
force = PVector.sub(neighbor, pos);
force.x = 0;
force.y = 0;
acc.set(force);
vel.add(acc);
vel.mult(0.98);
next[x][y].pos.add(vel);
}
void show() {
noStroke();
fill(water ? color(map(pos.z, 50, 150, 130, 160), 200, 255) : 0);
rect(pos.x, pos.y, w, w);
}
}