/// <summary> /// Check if a unit is outside of the level /// </summary> /// <param name="unit">The unit to check</param> /// <returns>true if the unit is outside, otherwise false</returns> public bool IsOutsideLevel(Unit unit) { Vector2 position = unit.GetPosition(); //Don't bother getting an accurate size for the unit rectangle, //the level check doesn't require that much accuracy Rectangle rect = new Rectangle((int)position.X, (int)position.Y, 10, 10); //The level rectangle intersects with the unit's rectangle if (bounds.Intersects(rect)) { return false; } return true; }
public void removeFromObjects(Unit unit) { objectsInGame.Remove(unit); }
public void removeFromGame(Unit unit) { objectsInGame.Remove(unit); if (unit is SpaceShip) { redTeam.Remove(unit as SpaceShip); blueTeam.Remove(unit as SpaceShip); } else if (unit is IObstacle) { obstacles.Remove(unit as IObstacle); } }
// Adds to unit collection in game public void addToGame(Unit unit) { objectsInGame.Add(unit); }
/// <summary> /// Calculate own collision damage, check if colliding with an explosion /// Call OnDestroy/OnDeath and do blast damage (if applicable) /// </summary> /// <param name="unit"></param> protected void HandleCollision(Unit unit, GameTime gameTime) { if (health <= 0 && unit.getHealth() <= 0) return; // TODO: calulate ratio based on a fixed number and armor: double ratio = 1; double moveEnergy = 0.2; //The percentage of energy involved in movement double energyOther = (float)unit.getMass() * Math.Sqrt(Math.Pow(unit.getVelocity().X,2) + Math.Pow(unit.getVelocity().Y,2)); double energySelf = (float)getMass() * Math.Sqrt(Math.Pow(getVelocity().X,2) + Math.Pow(getVelocity().Y,2)); double _damageSelf = Math.Max(energyOther / 1000, 1); double _damageOther = Math.Max(energySelf / 1000, 1); Log.getLog().addEvent(unitID + " collision damage " + this.GetType() + ": " + _damageSelf); Log.getLog().addEvent(unit.getUnitID() + " collision damage " + unit.GetType() + ": " + _damageOther); damage(_damageSelf, gameTime, false); unit.damage(_damageOther, gameTime, false); if (health <= 0) { OnDestroy(gameTime, true); if (unit is ConcreteObstacle_Asteroid && this is SpaceShip) { if ((this as SpaceShip).GetOwner() != null) { IPlayer pl = (this as SpaceShip).GetOwner(); (pl as Human).IncreaseDeathsByAsteroid(); } } } if (unit.getHealth() <= 0) { unit.OnDestroy(gameTime, true); if (this is ConcreteObstacle_Asteroid && unit is SpaceShip) { if ((unit as SpaceShip).GetOwner() != null) { IPlayer pl = (unit as SpaceShip).GetOwner(); (pl as Human).IncreaseDeathsByAsteroid(); } } } Vector2 velocityUnit = unit.getVelocity(); Vector2 positionUnit = unit.GetPosition(); Rectangle unitRec = unit.getUnitRectangle(); double unitMass = unit.getMass(); Log.getLog().addEvent(unitID + " at (" + position.X + ", " + position.Y + ") collided with " + unit.getUnitID() + " at (" + positionUnit.X + ", " + positionUnit.Y + ")"); //From here starts calculations that will move the lightest unit out of the other unit's hitbox Vector2 difference = new Vector2(position.X - positionUnit.X, position.Y - positionUnit.Y); double distance = Math.Sqrt(Math.Pow(difference.X, 2) + Math.Pow(difference.Y, 2)); //Finds the vector that multiplies difference, but only reaches to the edge of the hitbox double rad = Math.Sqrt(Math.Pow(animationFrame.Width / 2, 2) + Math.Pow(animationFrame.Height / 2, 2)); double var = Math.Sqrt(Math.Pow(rad, 2) / (Math.Pow(difference.X, 2) + Math.Pow(difference.Y, 2))); Vector2 edge = new Vector2((float)var*difference.X, (float)var*difference.Y); edge = -edge; edge = downSize(edge, new Vector2(animationFrame.Width / 2, animationFrame.Height / 2)); //Finds the vector that multiplies difference, but only reaches to the edge of the other ship's hitbox rad = Math.Sqrt(Math.Pow(unitRec.Width / 2, 2) + Math.Pow(unitRec.Height / 2, 2)); var = Math.Sqrt(Math.Pow(rad, 2) / (Math.Pow(difference.X, 2) + Math.Pow(difference.Y, 2))); Vector2 edge2 = new Vector2((float)var * difference.X, (float)var * difference.Y); edge2 = downSize(edge2, new Vector2(unitRec.Width/2, unitRec.Height/2)); var = Math.Sqrt(1 / (Math.Pow(difference.X, 2) + Math.Pow(difference.Y, 2))); Vector2 unity = new Vector2((float)(difference.X * var), (float)(difference.Y * var)); //Moves the lightest ship Vector2 move; if (mass > unit.getMass()) { move = edge - edge2 - unity + difference; unit.setPosition(positionUnit + move); } else { move = edge2 + unity - edge - difference; setPosition(position + move); } //End of movement calculations /* double vel1x = (moveEnergy * velocity.X * (mass - unitMass) + 2 * unitMass * velocityUnit.X) / (mass + unitMass); double vel2x = (moveEnergy * velocityUnit.X * (unitMass - mass) + 2 * mass * velocity.X) / (mass + unitMass); double vel1y = (moveEnergy * velocity.Y * (mass - unitMass) + 2 * unitMass * velocityUnit.Y) / (mass + unitMass); double vel2y = (moveEnergy * velocityUnit.Y * (unitMass - mass) + 2 * mass * velocity.Y) / (mass + unitMass); */ double velx = ((mass * velocity.X + unitMass * velocityUnit.X) / (mass + unitMass)); double vely = ((mass * velocity.Y + unitMass * velocityUnit.Y) / (mass + unitMass)); setVelocity(new Vector2((float)velx, (float)vely)); unit.setVelocity(new Vector2((float)velx, (float)vely)); bool test = getUnitRectangle().Intersects(unit.getUnitRectangle()); }
/// <summary> /// The method that will called when this Unit collides with another. /// Usually, this method will only call HandleCollision. /// </summary> public void Collide(Unit unit, GameTime gameTime) { if (readyToCollide(gameTime) && unit.readyToCollide(gameTime)) { if (ableToCollide(unit) && unit.ableToCollide(this)) { HandleCollision(unit, gameTime); addCd(new CollisionCd(unit)); unit.addCd(new CollisionCd(this)); } } }
/// <summary> /// Check whether two units are ready to collide again /// </summary> /// <param name="unit"></param> /// <returns></returns> public bool ableToCollide(Unit unit) { foreach (CollisionCd cd in cooldowns) { if (cd.getUnit() == unit) { return false; } } return true; }