/// <summary> /// Checks for collision between a projectile and current tanks. /// </summary> /// <param name="position"></param> /// <param name="hitTank"></param> /// <returns></returns> private bool CheckProjectileTankCollision(Vector2D position, out Tank hitTank) { lock (world) { foreach (Tank t in world.GetTanks()) { if ((position - t.location).Length() <= 30) { hitTank = t; return(true); } } } hitTank = null; return(false); }
/// <summary> /// This method is invoked when the DrawingPanel needs to be re-drawn /// </summary> protected override void OnPaint(PaintEventArgs e) { //Makes sure world is null, since it is null while loading game if (theWorld != null) { //Locks world since it accesses info from it lock (theWorld) { //Get player's tank to center view Tank player; if (theWorld.GetTank(PlayerID, out player)) { double playerX = player.location.GetX(); double playerY = player.location.GetY(); double ratio = (double)ViewSize / (double)theWorld.GetSize(); int halfSizeScaled = (int)(theWorld.GetSize() / 2.0 * ratio); double inverseTranslateX = -WorldSpaceToImageSpace(theWorld.GetSize(), playerX) + halfSizeScaled; double inverseTranslateY = -WorldSpaceToImageSpace(theWorld.GetSize(), playerY) + halfSizeScaled; e.Graphics.TranslateTransform((float)inverseTranslateX, (float)inverseTranslateY); } //Draw background e.Graphics.DrawImage(Background, new Rectangle(0, 0, theWorld.GetSize(), theWorld.GetSize())); // Draw the tanks foreach (Tank tank in theWorld.GetTanks()) { //Draw tank, turret, and info if tank is alive and ingame if (!tank.died && !tankTimer.ContainsKey(tank) && tank.hitPoints > 0) { DrawObjectWithTransform(e, tank, theWorld.GetSize(), tank.location.GetX(), tank.location.GetY(), tank.orientation.ToAngle(), TankDrawer); DrawObjectWithTransform(e, tank, theWorld.GetSize(), tank.location.GetX(), tank.location.GetY(), tank.aiming.ToAngle(), TurretDrawer); DrawObjectWithTransform(e, tank, theWorld.GetSize(), tank.location.GetX(), tank.location.GetY(), 0, InfoDrawer); } //Otherwise, add tank to tank timer, increment tank timer, or remove tank from tank timer if it is alive else { //If tank is a live again, remove from tank timer if (tank.hitPoints > 0) { tankTimer.Remove(tank); break; } //If tank is already in tank timer, decrement tank timer or remove tank from timer if (tankTimer.ContainsKey(tank)) { if (tankTimer[tank] < 200) { tankTimer[tank]++; } else { tankTimer.Remove(tank); } } //Add tank to timer if not in timer yet else { tankTimer.Add(tank, 0); } } } // Draw the walls foreach (Wall w in theWorld.GetWalls()) { Vector2D location = GetWallLocation(w); DrawObjectWithTransform(e, w, theWorld.GetSize(), location.GetX(), location.GetY(), 0, WallDrawer); } //Draw beams if existed for less than 60 frames List <Beam> beams = new List <Beam>(beamsTimer.Keys); foreach (Beam b in beams) { if (beamsTimer[b] > 60) { beamsTimer.Remove(b); } //Increments beamsTimer and draws beams else { beamsTimer[b]++; DrawObjectWithTransform(e, b, theWorld.GetSize(), b.origin.GetX(), b.origin.GetY(), b.direction.ToAngle(), BeamDrawer);; } } // Draw the powerups if not dead foreach (Powerup pow in theWorld.GetPowerups()) { if (!pow.died) { DrawObjectWithTransform(e, pow, theWorld.GetSize(), pow.location.GetX(), pow.location.GetY(), 0, PowerupDrawer); } } //Draw projectiles if not dead foreach (Projectile p in theWorld.GetProjectiles()) { if (!p.died) { DrawObjectWithTransform(e, p, theWorld.GetSize(), p.location.GetX(), p.location.GetY(), p.orientation.ToAngle(), ProjectileDrawer); } } //Draw tank explosions with tanks in tankTimer List <Tank> tanks = new List <Tank>(tankTimer.Keys); foreach (Tank t in tanks) { DrawObjectWithTransform(e, t, theWorld.GetSize(), t.location.GetX(), t.location.GetY(), 0, ExplosionDrawer); } } } // Do anything that Panel (from which we inherit) needs to do base.OnPaint(e); }
/// <summary> /// This method is invoked when the DrawingPanel needs to be re-drawn /// </summary> protected override void OnPaint(PaintEventArgs e) { //Gets the world based on the world of the controller world = controller.GetWorld(); //Gets the playerNum based on the controller's player number playerNum = controller.GetPlayerNum(); //Only attempts to draw if the world contains the tanks if (world.GetTanks().Count > 0) { //Locks the thread with the world as the key to draw everything in one thread to avoid changes while drawing lock (world) { //Locks the player's view in the center based on ther user's controlled tank, if the tank is not dead if (world.GetTanks().TryGetValue(playerNum, out Tank tank) && !tank.GetDead()) { //Sets the player's X and Y coordinate playerX = tank.GetLocation().GetX(); playerY = tank.GetLocation().GetY(); //Centers the player's view double ratio = (double)viewSize / (double)world.Size; int halfSizeScaled = (int)(world.Size / 2.0 * ratio); double inverseTranslateX = -WorldSpaceToImageSpace(world.Size, playerX) + halfSizeScaled; double inverseTranslateY = -WorldSpaceToImageSpace(world.Size, playerY) + halfSizeScaled; e.Graphics.TranslateTransform((float)inverseTranslateX, (float)inverseTranslateY); } else { //If the tank is not dead, then it sets the location as the last place of death of the tank and center's the player's view double ratio = (double)viewSize / (double)world.Size; int halfSizeScaled = (int)(world.Size / 2.0 * ratio); double inverseTranslateX = -WorldSpaceToImageSpace(world.Size, playerX) + halfSizeScaled; double inverseTranslateY = -WorldSpaceToImageSpace(world.Size, playerY) + halfSizeScaled; e.Graphics.TranslateTransform((float)inverseTranslateX, (float)inverseTranslateY); } //Doesn't draw anything if the world size is less than equal to 0 if (world.Size <= 0) { return; } //Draws the background DrawObjectWithTransform(e, null, world.Size, 0, 0, 0, BackgroundDrawer); //Draws all the walls in the world foreach (Wall w in world.GetWalls().Values.ToList()) { for (double i = w.GetStartingPoint().GetX(); i <= w.GetEndingPoint().GetX(); i = i + 50) { for (double j = w.GetStartingPoint().GetY(); j <= w.GetEndingPoint().GetY(); j = j + 50) { //Draws all the walls in the condition that the starting point is smaller than ending points of the walls DrawObjectWithTransform(e, w, world.Size, i, j, 0, WallDrawer); } } for (double i = w.GetEndingPoint().GetX(); i <= w.GetStartingPoint().GetX(); i = i + 50) { for (double j = w.GetEndingPoint().GetY(); j <= w.GetStartingPoint().GetY(); j = j + 50) { //Draws all the walls in the condition that the starting point is greater than ending points of the walls DrawObjectWithTransform(e, w, world.Size, i, j, 0, WallDrawer); } } } //Draws all the powerups foreach (Powerups p in world.GetPowerups().Values) { //Draws the outside and inside circle for the powerups DrawObjectWithTransform(e, p, world.Size, p.GetLocation().GetX(), p.GetLocation().GetY(), 0, PowerupDrawer); DrawObjectWithTransform(e, p, world.Size, p.GetLocation().GetX(), p.GetLocation().GetY(), 0, PowerupDrawerInsideCircle); } //Draws all the tanks in the world foreach (Tank t in world.GetTanks().Values) { //Draws the tank DrawObjectWithTransform(e, t, world.Size, t.GetLocation().GetX(), t.GetLocation().GetY(), t.GetOrientation().ToAngle(), TankDrawer); //Draws the turret DrawObjectWithTransform(e, t, world.Size, t.GetLocation().GetX(), t.GetLocation().GetY(), t.GetAiming().ToAngle(), TurretDrawer); //Draws the name DrawObjectWithTransform(e, t, world.Size, t.GetLocation().GetX(), t.GetLocation().GetY() + 60, 0, NameDrawer); //Draws the health DrawObjectWithTransform(e, t, world.Size, t.GetLocation().GetX(), t.GetLocation().GetY() - 40, 0, HealthDrawer); } //Draws all the projectiles in the world foreach (Projectile p in world.GetProjectile().Values.ToList()) { //Draws the projectile DrawObjectWithTransform(e, p, world.Size, p.GetLocation().GetX(), p.GetLocation().GetY(), p.GetOrientation().ToAngle(), ProjectileDrawer); } //Draws all the beams in the world foreach (Beams b in world.GetBeams().Values.ToList()) { //Draws the beams DrawObjectWithTransform(e, b, world.Size, b.GetOrigin().GetX(), b.GetOrigin().GetY(), b.GetDirection().ToAngle(), BeamDrawer); //Removes the beams after 20 iterations beamFrameCount++; if (beamFrameCount == 20) { world.GetBeams().Remove(b.GetBeamID()); beamFrameCount = 0; } } } } //Calls the base base.OnPaint(e); }
/// <summary> /// Draws a projectile /// </summary> private void ProjectileDrawer(object o, PaintEventArgs e) { //Converts the object to a projectile Projectile p = o as Projectile; //Sets the width to 30 int width = 30; //Doesn't smoothen the projectile drawing e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None; using (System.Drawing.SolidBrush blueBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Blue)) using (System.Drawing.SolidBrush yellowBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Yellow)) using (System.Drawing.SolidBrush darkBlueBrush = new System.Drawing.SolidBrush(System.Drawing.Color.DarkBlue)) using (System.Drawing.SolidBrush greenBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Green)) using (System.Drawing.SolidBrush lightGreenBrush = new System.Drawing.SolidBrush(System.Drawing.Color.LightGreen)) using (System.Drawing.SolidBrush redBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Red)) using (System.Drawing.SolidBrush orangeBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Orange)) using (System.Drawing.SolidBrush purpleBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Purple)) { //Centers the projectile Rectangle r = new Rectangle(-(width / 2), -(width / 2), width, width); Color c = new Color(); foreach (int id in world.GetTanks().Keys) { //Sets the color based on the tank's color Tank t = world.GetTanks()[id]; if (t.GetID() == p.GetOwnerID()) { c = t.GetColor(); } } //Draws the projectile based on what the tank's color is if (c == Color.Red) { e.Graphics.DrawImage(redShot, r); } else if (c == Color.Yellow) { e.Graphics.DrawImage(yellowShot, r); } else if (c == Color.Blue) { e.Graphics.DrawImage(blueShot, r); } else if (c == Color.DarkBlue) { e.Graphics.DrawImage(whiteShot, r); } else if (c == Color.Purple) { e.Graphics.DrawImage(purpleShot, r); } else if (c == Color.Orange) { e.Graphics.DrawImage(brownShot, r); } else if (c == Color.Green) { e.Graphics.DrawImage(greenShot, r); } else if (c == Color.LightGreen) { e.Graphics.DrawImage(greyShot, r); } } }
/// <summary> /// Process any buffered messages separated by '\n' /// Then inform the view /// </summary> /// <param name="state"></param> private void ReceiveWorld(SocketState state) { //Gets the data from the state and splits it by a new line string totalData = state.GetData(); string[] parts = Regex.Split(totalData, @"(?<=[\n])"); // Loop until we have processed all messages. // We may have received more than one. //Gets the player number, which should only be once int playerNumber = 0; havePlayerNum = int.TryParse(parts[0], out playerNumber); parts[0] = ""; if (playerNumber != 0) { playerNum = playerNumber; } //Gets the dimensions of the world that should only happen once int dim = 0; haveDimension = int.TryParse(parts[1], out dim); parts[1] = ""; if (dim != 0) { worldDimension = dim; world = new World(worldDimension); } //Iterates through all the data given by the server foreach (string p in parts) { // Ignore empty strings added by the regex splitter if (p.Length == 0) { continue; } // The regex splitter will include the last string even if it doesn't end with a '\n', // So we need to ignore it if this happens. if (p[p.Length - 1] != '\n') { break; } //Locks with a world so that we process information in a single thread lock (world) { //Parses the object with the JSON JObject jObject = JObject.Parse(p); //Converts the JSON object to a token based on the name of the string JToken projToken = jObject["proj"]; JToken beamToken = jObject["beam"]; JToken tankToken = jObject["tank"]; JToken wallToken = jObject["wall"]; JToken powerToken = jObject["power"]; //If the projToken is not null, i.e. if the JSON string passed was a projectile, then it goes in this condition if (projToken != null) { //Deserializes the string and converts it to a projectile Projectile proj = JsonConvert.DeserializeObject <Projectile>(p); //Adds the projectile to the world world.SetProjectile(proj.GetID(), proj); //If projectile is dead, removes the projectile from the world if (proj.GetDead() == true) { world.GetProjectile().Remove(proj.GetID()); } } //If the beamToken is not null, i.e. if the JSON string passed was a beam, then it goes in this condition if (beamToken != null) { //Deserializes the string and converts it to a beam Beams b = JsonConvert.DeserializeObject <Beams>(p); //Adds the beam in the world's beam dictionary world.SetBeams(b.GetBeamID(), b); } //If the tankToken is not null, i.e. if the JSON string passed was a tank, then it goes in this condition if (tankToken != null) { //Deserializes the string and converts it to a tank Tank t = JsonConvert.DeserializeObject <Tank>(p); //Sets the color of the tank based on the tank's ID t.SetColor(t.GetID()); //Adds the tank to the world's tank dictionary world.SetTanks(t.GetID(), t); //If the hitpoints of the tank are 0, then it remove it from the dictionary if (t.GetHitPoints() == 0) { world.GetTanks().Remove(t.GetID()); } //If the tank gets disconnected, then it remove it from the dictionary if (t.GetDisconnected()) { world.GetTanks().Remove(t.GetID()); } //If the tank is dead, then it remove it from the dictionary if (t.GetDead()) { world.GetTanks().Remove(t.GetID()); } } //If the wallToken is not null, i.e. if the JSON string passed was a wall, then it goes in this condition if (wallToken != null) { //Deserializes the string and converts it to a wall Wall w = JsonConvert.DeserializeObject <Wall>(p); //Adds the wall to the world's wall dictionary world.SetWalls(w.GetID(), w); } //If the powerToken is not null, i.e. if the JSON string passed was a powerup, then it goes in this condition if (powerToken != null) { //Deserializes the string and converts it to a powerup Powerups power = JsonConvert.DeserializeObject <Powerups>(p); //Adds the powerup to the world's powerup dictionary world.SetPowerups(power.GetID(), power); //If the powerup is dead, then it removes it from the dictionary if (power.GetDead()) { world.GetPowerups().Remove(power.GetID()); } } } // Then remove it from the SocketState's growable buffer state.RemoveData(0, p.Length); } if (UpdateArrived != null) { // inform the view to redraw UpdateArrived(); } //Inform the server Process(); }