public void deleteParticle(Particle p) { if (p != null) { p.Dead = true; particleField[(int)p.position.X, (int)p.position.Y] = null; deleteList.Add(p); } }
public void moveSwapParticle(Particle p, int newX, int newY) { if (p.Dead) return; if (newX < 0 || newX >= width || newY < 0 || newY >= height) { particleField[(int)p.position.X, (int)p.position.Y] = null; p.Dead = true; deleteList.Add(p); return; } Particle old = particleField[newX, newY]; old.position = new Vector2(p.position.X, p.position.Y); particleField[(int)p.position.X, (int)p.position.Y] = old; particleField[newX, newY] = p; p.position = new Vector2(newX, newY); }
/// <summary> /// Call to change the location of a particle. DO NOT set the position manually /// </summary> /// <param name="p"></param> /// <param name="newX"></param> /// <param name="newY"></param> public void moveParticle(Particle p, int newX, int newY) { if (p.Dead) return; particleField[(int)p.position.X, (int)p.position.Y] = null; if (newX < 0 || newX >= width || newY < 0 || newY >= height) { p.Dead = true; deleteList.Add(p); return; } var prev = particleField[newX, newY]; if (prev != null) { prev.Dead = true; deleteList.Add(prev); } particleField[newX, newY] = p; p.position = new Vector2(newX, newY); }
private bool isColliding(Particle pOrig, Particle collider) { pOrig.velocity = new Vector2(pOrig.velocity.X, 0); return true; }
private bool checkCollisions(Particle colP) { IEnumerable<Particle> collQuery = from p in particles where p.position.X - colP.position.X == 0 && p.position.Y - colP.position.Y == 1// && p.type == Particle_Type.Wall select p; foreach (Particle p in collQuery) { //if (p.position.Y - colP.position.Y <= 1 && p.position.Y - colP.position.Y >= -1 && // p.position.X - colP.position.X <= 1 && p.position.X - colP.position.X >= -1) { isColliding(colP, p); return true; } } return true; }
public bool newParticle(Particle p) { if (!(p.position.X < 0 || p.position.X >= width || p.position.Y < 0 || p.position.Y >= height) && particles.Count < maxParticles) { if (particleField[(int)p.position.X, (int)p.position.Y] == null) { particleField[(int)p.position.X, (int)p.position.Y] = p; //particles.Add(p); addList.Add(p); } // addList.Add(p); return true; } return false; }
private bool surrounded(Particle colP) { if (particleStorage.particleAt((int)colP.position.X, (int)colP.position.Y + 1) != null && particleStorage.particleAt((int)colP.position.X, (int)colP.position.Y + 1) != null &&//beleow particleStorage.particleAt((int)colP.position.X, (int)colP.position.Y - 1) != null && particleStorage.particleAt((int)colP.position.X, (int)colP.position.Y - 1) != null &&//above particleStorage.particleAt((int)colP.position.X + 1, (int)colP.position.Y) != null && particleStorage.particleAt((int)colP.position.X + 1, (int)colP.position.Y) != null && //right particleStorage.particleAt((int)colP.position.X - 1, (int)colP.position.Y) != null && particleStorage.particleAt((int)colP.position.X - 1, (int)colP.position.Y) != null)//left return true; else return false; }
private bool isColliding(Particle pOrig, Particle collider) { //pOrig.velocity.Y = 0; return true; }
private bool handleFire(Particle p) { Vector2[] positionList = new Vector2[8]; positionList[0] = new Vector2(p.position.X, p.position.Y - 1);//Right above first positionList[1] = new Vector2(p.position.X -1, p.position.Y - 1);//Then top corners positionList[2] = new Vector2(p.position.X + 1, p.position.Y - 1); positionList[3] = new Vector2(p.position.X - 1, p.position.Y);//Left and Right positionList[4] = new Vector2(p.position.X + 1, p.position.Y - 1); positionList[5] = new Vector2(p.position.X, p.position.Y + 1);//Right Below positionList[6] = new Vector2(p.position.X - 1, p.position.Y + 1);//Bottom corners positionList[7] = new Vector2(p.position.X + 1, p.position.Y + 1); bool nearParticle = false; int tempRand = rnd.Next(10); bool isRemoved = false; foreach (Vector2 pos in positionList) if (/*!isRemoved &&*/ particleStorage.particleAt((int)pos.X, (int)pos.Y) != null) { nearParticle = true; Particle other = particleStorage.particleAt((int)pos.X, (int)pos.Y); //double random = rnd.NextDouble(); if (other.type == Particle_Type.Water) { p.velocity = Vector2.Zero; p.dontMove = true; particleStorage.deleteParticle(p); particleStorage.deleteParticle(other); isRemoved = true; } else if (other.type == Particle_Type.Plant) { p.velocity = Vector2.Zero; p.dontMove = true; if (rnd.Next(10) == 0)//10% chance to delete plant { particleStorage.deleteParticle(other); if (rnd.Next(10) < 9)//90% chance to propagate addParticle(other.position, Vector2.Zero, Particle_Type.Fire, false, true); } } else if (other.type == Particle_Type.Wall || other.type == Particle_Type.Sand) { p.velocity = Vector2.Zero; p.dontMove = true; if (rnd.Next(10) == 0)//10% chance to delete wall { particleStorage.deleteParticle(other); if (rnd.Next(4) == 0) //25% chance to propagate addParticle(other.position, Vector2.Zero, Particle_Type.Fire, false, true); } } } else p.dontMove = false; if (!p.dontMove) { if (tempRand == 0 && p.velocity.X != 1) p.velocity = new Vector2(1, -1); else if (tempRand == 1 && p.velocity.X != -1) p.velocity = new Vector2(-1, -1); else p.velocity = new Vector2(0, -1); } return true; }
private void checkTurnToPlant(Particle colP) { if (colP.type != Particle_Type.Water) return; int deleteSize = particleStorage.particleDeleteCount(); if (particleStorage.particleAt((int)colP.position.X, (int)colP.position.Y + 1) != null)//beleow { if (particleStorage.particleAt((int)colP.position.X, (int)colP.position.Y + 1).type == Particle_Type.Plant && rnd.Next(10) == 0) { Vector2 tempPos = colP.position; particleStorage.deleteParticle(colP); addParticle(tempPos, new Vector2(0), Particle_Type.Plant, false, true); } } if (particleStorage.particleAt((int)colP.position.X, (int)colP.position.Y - 1) != null && deleteSize == particleStorage.particleDeleteCount()) //above { if (particleStorage.particleAt((int)colP.position.X, (int)colP.position.Y - 1).type == Particle_Type.Plant && rnd.Next(10) == 0) { Vector2 tempPos = colP.position; particleStorage.deleteParticle(colP); addParticle(tempPos, new Vector2(0), Particle_Type.Plant, false, true); } } if (particleStorage.particleAt((int)colP.position.X + 1, (int)colP.position.Y) != null && deleteSize == particleStorage.particleDeleteCount()) //right { if (particleStorage.particleAt((int)colP.position.X + 1, (int)colP.position.Y).type == Particle_Type.Plant && rnd.Next(6) == 0) { Vector2 tempPos = colP.position; particleStorage.deleteParticle(colP); addParticle(tempPos, new Vector2(0), Particle_Type.Plant, false, true); } } if (particleStorage.particleAt((int)colP.position.X - 1, (int)colP.position.Y) != null && deleteSize == particleStorage.particleDeleteCount()) //left { if (particleStorage.particleAt((int)colP.position.X - 1, (int)colP.position.Y).type == Particle_Type.Plant && rnd.Next(6) == 0) { Vector2 tempPos = colP.position; particleStorage.deleteParticle(colP); addParticle(tempPos, new Vector2(0), Particle_Type.Plant, false, true); } } }
private bool checkCollisions(Particle colP) { // these are used as flags for checking the first dip and checking for a wall which would block a particle bool checkLeft = false; bool leftObstacle = false; bool checkRight = false; bool rightObstacle = false; int counter = 1; //used for incrementing where dips are checked // List<Particle> collList = particleStorage.withinIndexExcludeSource((int)colP.position.X, (int)colP.position.Y);// new List<Particle>(); checkTurnToPlant(colP); if (particleStorage.particleAt((int)colP.position.X, (int)colP.position.Y + 1) != null) { //if particle is sand, and water is below, switch to cause sand to fall in water if (colP.type == Particle_Type.Sand && particleStorage.particleAt((int)colP.position.X, (int)colP.position.Y + 1).type == Particle_Type.Water) { //BAD, me no likey: colP.position = new Vector2(colP.position.X, colP.position.Y + 1); particleStorage.moveSwapParticle(colP, (int)colP.position.X, (int)colP.position.Y + 1); colP.velocity = Vector2.Zero; } else { colP.velocity = new Vector2(colP.velocity.X, 0); //future acid particle interaction? //if (colP.type == Particle_Type.Acid && rnd.Next(2) == 0) //{ // Vector2 tempPos = particleStorage.particleAt((int)colP.position.X, (int)colP.position.Y + 1).position; // particleStorage.deleteParticle(particleStorage.particleAt((int)colP.position.X, (int)colP.position.Y + 1)); // addParticle(tempPos, new Vector2(0), Particle_Type.Plant); //} //turns water into plant. if (particleStorage.particleAt((int)colP.position.X - 1, (int)colP.position.Y + 1) != null) //there is a particle to the bottom left { if (particleStorage.particleAt((int)colP.position.X + 1, (int)colP.position.Y + 1) == null) //there is no particle to the right { colP.velocity = new Vector2(1, 1); } //used to make particles behave more liquidlike and less powder like else if (!surrounded(colP)) //if the particle is surrounded by other particles, it shouldn't check while ((!checkLeft && !checkRight) && (!rightObstacle || !leftObstacle)) //if the bottom three particle spaces check all exist, loop until we find the first dip UNLESS both end in a wall { //if there is an obstacle in line with the particle, it will stop checking that side for a dip if (particleStorage.particleAt((int)colP.position.X + counter, (int)colP.position.Y) != null) //if(particleStorage.particleAt((int)colP.position.X + counter, (int)colP.position.Y).type == Particle_Type.Wall) //this drastically slows performance but speeds up liquid behavior rightObstacle = true; if (particleStorage.particleAt((int)colP.position.X - counter, (int)colP.position.Y) != null) //if(particleStorage.particleAt((int)colP.position.X - counter, (int)colP.position.Y).type == Particle_Type.Wall) //this drastically slows performance but speeds up liquid behavior leftObstacle = true; if (particleStorage.particleAt((int)colP.position.X + counter, (int)colP.position.Y + 1) == null && !rightObstacle) { checkRight = true; break; } if (particleStorage.particleAt((int)colP.position.X - counter, (int)colP.position.Y + 1) == null && !leftObstacle) { checkLeft = true; break; } counter++; } if (checkRight) colP.velocity = new Vector2(3, 0); if (checkLeft) colP.velocity = new Vector2(-3, 0); } else if (particleStorage.particleAt((int)colP.position.X + 1, (int)colP.position.Y + 1) != null) //there is a particle to the right { if (particleStorage.particleAt((int)colP.position.X - 1, (int)colP.position.Y + 1) == null) //there is no particle to the left { colP.velocity = new Vector2(-1, 1); } } else if (particleStorage.particleAt((int)colP.position.X, (int)colP.position.Y + 1) != null) //there is a particle directly underneath, but no particles to either side underneath (solves pillar problem) { if (rnd.Next(1) == 0) colP.velocity = new Vector2(1, 1); else colP.velocity = new Vector2(-1, 1); } } } //foreach (Particle p in collList) //{ // isColliding(colP, p); // if ((colP.position.Y - 1) - p.position.Y < -epsilon)//colP is above p // { // } //} return true; }