/// <summary> /// Method to be called when mouse moves. Calls controller's aiming method with normalized vector2D of mouse location /// </summary> private void Aim(Object sender, MouseEventArgs e) { Vector2D aim = new Vector2D(e.X - 450, e.Y - 450); aim.Normalize(); controller.Aiming(aim); }
//Set ControlCommand aiming to current mouse relative to mid of drawing panel public void MoveMouseRequest(Point point) { Vector2D aiming = new Vector2D(point.X - 450, point.Y - 450); aiming.Normalize(); command.Aiming = aiming; }
/// <summary> /// Compute the clockwise angle of the vector pointing from b to a /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static float AngleBetweenPoints(Vector2D a, Vector2D b) { Vector2D bToA = a - b; bToA.Normalize(); return(bToA.ToAngle()); }
/// <summary> /// A constructor that sets the data according to the way the user would like to send it including a Vector they would like to /// pass, normalizing the vector created /// </summary> public ControlCommands(string movingDir, string fireType, Vector2D vector) { moving = movingDir; fire = fireType; direction = new Vector2D(vector); direction.Normalize(); }
/// <summary> /// A constructor that sets the data according to the way the user would like to send it including the x and y coordinates, /// to create a new vector and then normalizing the vector created /// </summary> public ControlCommands(string movingDir, string fireType, double xCoordinate, double yCoordinate) { moving = movingDir; fire = fireType; direction = new Vector2D(xCoordinate, yCoordinate); direction.Normalize(); }
/// <summary> /// Method for calculating the tank turret direction based on the mouse location in order to send /// to the server. /// </summary> /// <param name="x">X location of the mouse</param> /// <param name="y">Y location of the mouse</param> public void ProcessMouseMove(double x, double y) { Vector2D loc = new Vector2D(x - Constants.ViewSize / 2, y - Constants.ViewSize / 2); loc.Normalize(); commands.aiming = new Vector2D(loc.GetX(), loc.GetY()); }
/// <summary> /// Processes a MouseMove event by updating the TurretDirection of the ControlCommand of theWorld /// </summary> public void ProcessMouseMove(double posX, double posY) { Vector2D newTurretDirection = new Vector2D(posX, posY); newTurretDirection.Normalize(); lock (theWorld) { tankControlCommand.TurretDirection = newTurretDirection; } }
/// <summary> /// Handle the mouse movement via centering x and y at our tank center. /// We then normalize and set the Turret direction. /// </summary> /// <param name="sender"></param> /// <param name="mousePoint"></param> public void HandleMouseMovement(object sender, Vector2D mousePoint) { // x,y to be centered at our tank double x = mousePoint.GetX() - 450; double y = mousePoint.GetY() - 450; mousePoint = new Vector2D(x, y); mousePoint.Normalize(); commands.SetTDIR(mousePoint); }
/// <summary> /// A constructor where the playerName and ID be set according /// </summary> public Tank(string playerName, int playerID) { name = playerName; ID = playerID; location = new Vector2D(-463.92, -199.00); orientation = new Vector2D(1, 0); orientation.Normalize(); aiming = new Vector2D(0, -1); aiming.Normalize(); hitPoints = 3; died = false; disconnected = false; joined = true; }
public Projectile(Vector2D currentLocation, Vector2D direction, int owner) { //Sets the ID ID = NextID; NextID++; //Sets the location, orientation, and owner. Also normalizes the orientation and calculates the velocity Location = currentLocation; Orientation = direction; Orientation.Normalize(); Velocity = Orientation * Constants.ProjectileSpeed; OwnerID = owner; }
/// <summary> /// Method for drawing a tank explosion for some tank t. If the particles haven't been created yet, it spawns them at /// a random angle some distance away from the tank. Then when this method is called next it increases the distance so /// those particles appear to move outward. It also keeps track of the amount of frames the particles have been out and /// if that exceeds the tank frames constant it gets rid of the particles. /// </summary> /// <param name="t">Tank that died</param> /// <param name="e">Graphics for drawing the particles</param> private void DrawExplosion(Tank t, PaintEventArgs e) { Dictionary <int, TankExplosion> explosionDictionary = TheController.TheWorld.TankExplosions; Random rnd = new Random(); //Creates a new explosion if it doesn't exist yet if (!explosionDictionary.ContainsKey(t.ID)) { explosionDictionary[t.ID] = new TankExplosion(); } //Gets rid of the particles after a certain amount of frames if (explosionDictionary[t.ID].tankFrames > Constants.TankParticleFrameLength) { if (explosionDictionary[t.ID].tankParticles.Count > 0) { explosionDictionary[t.ID].tankParticles.Clear(); } return; } Dictionary <int, Vector2D> TankParticlesDictionary = explosionDictionary[t.ID].tankParticles; for (int i = 0; i < Constants.TankParticleCount; i++) { if (TankParticlesDictionary.ContainsKey(i)) { //Creates a direction vector and moves the particle in that direction Vector2D direction = new Vector2D(TankParticlesDictionary[i]); direction.Normalize(); TankParticlesDictionary[i] += direction * Constants.TankParticleSpeed; } else { //Creates a random angle and spawns the particle at that location double Angle = rnd.NextDouble() * 2 * Math.PI; TankParticlesDictionary[i] = new Vector2D(Constants.TankParticleSpawnRadius * Math.Cos(Angle), Constants.TankParticleSpawnRadius * Math.Sin(Angle)); } using (SolidBrush redBrush = new SolidBrush(Color.Red)) e.Graphics.FillEllipse(redBrush, (int)TankParticlesDictionary[i].GetX(), (int)TankParticlesDictionary[i].GetY(), Constants.TankParticleRadius, Constants.TankParticleRadius); } TheController.TheWorld.ExplosionIncrementFrames(explosionDictionary[t.ID]); }
/// <summary> /// This method receives the mouse position and /// translates it to the tank's turret movement. /// The turret will always point in the direction of the mouse /// </summary> /// <param name="mousePos"></param> public void TurretMouseAngle(Point mousePos) { //Calculate the vector between mouse position and tank //425 is half of the view screen size. Since tank is centered on the panel, that //describes tank location as a fixed point double mouseWorldXPosition = mousePos.X - 425; double mouseWorldYPosition = mousePos.Y - 425; //Get the vector points between mouse and tank location Vector2D newAim = new Vector2D(mouseWorldXPosition, mouseWorldYPosition); //Normalize vector and set tank aim direction to this new vector newAim.Normalize(); selfTank.AimDirection = newAim; //Update the tank SendTankUpdate(selfTank); }
/// <summary> /// For server to create a new tank when a client first connect /// </summary> /// <param name="id"></param> /// <param name="name"></param> public Tank(int id, string name, int hp, int sincelastshot, Vector2D loc) { ID = id; Name = name; Orientation = new Vector2D(0, -1); Died = false; Disconnected = false; Joined = true; Score = 0; HitPoints = hp; Location = loc; Alts = 0; FramesInCeasedShooting = sincelastshot; FramesInRespawn = 0; //Create arbitrary unit tdir vector Random rng = new Random(); Vector2D aim = new Vector2D(rng.Next(-10, 10), rng.Next(-10, 10)); aim.Normalize(); Aiming = aim; }
/// <summary> /// Sets the turret direction associated with the tank by changing it's control command /// </summary> public void SetDirection(Vector2D vector) { //Sets the direction and normalizes it direction = new Vector2D(vector); direction.Normalize(); }
/// <summary> /// Gets the turret direction associated with the tank's control command /// </summary> public Vector2D GetDirection() { //Has the direction normalized and returns the direction direction.Normalize(); return(direction); }
/// <summary> /// Updates the world based off of commands and game logic. /// </summary> private void updateWorld() { lock (world) { //Powerup logic if (powerUpTimer == 0 && new List <Powerup>(world.GetPowerups()).Count < world.maxPowers) { Random r = new Random(); Vector2D RandLoc = new Vector2D(r.Next(-world.GetSize() / 2 + 16, world.GetSize() / 2 - 16), r.Next(-world.GetSize() / 2 + 16, world.GetSize() / 2 - 16)); while (CheckPowerupWallCollision(RandLoc)) { RandLoc = new Vector2D(r.Next(-world.GetSize() / 2 + 16, world.GetSize() / 2 - 16), r.Next(-world.GetSize() / 2 + 16, world.GetSize() / 2 - 16)); } world.UpdatePowerup(powerupCount++, RandLoc, false); resetPowerupTimer(); } else if (powerUpTimer != 0) { powerUpTimer--; } //Tank logic foreach (Tank t in new List <Tank>(tanksFired.Keys)) { int temp = tanksFired[t]; if (temp > 1) { tanksFired[t]--; } else { tanksFired.Remove(t); } } foreach (Tank t in new List <Tank>(tanksRespawning.Keys)) { if (t.died) { world.UpdateTank(t.ID, t.location, t.orientation, t.aiming, t.name, t.hitPoints, t.score, false, t.disconnected); } int temp = tanksRespawning[t]; if (temp > 1) { tanksRespawning[t]--; } else { tanksRespawning.Remove(t); Random r = new Random(); Vector2D RandLoc = new Vector2D(r.Next(-world.GetSize() / 2 + 16, world.GetSize() / 2 - 16), r.Next(-world.GetSize() / 2 + 16, world.GetSize() / 2 - 16)); while (CheckTankWallCollision(RandLoc)) { RandLoc = new Vector2D(r.Next(-world.GetSize() / 2 + 16, world.GetSize() / 2 - 16), r.Next(-world.GetSize() / 2 + 16, world.GetSize() / 2 - 16)); } t.beams = 0; world.UpdateTank(t.ID, RandLoc, new Vector2D(0, 1), new Vector2D(0, 1), t.name, 3, t.score, t.died, t.disconnected); } } foreach (Tank t in new List <Tank>(world.GetTanks())) { if (t.disconnected == true) { world.UpdateTank(t.ID, new Vector2D(0, 0), new Vector2D(0, 1), new Vector2D(0, 1), t.name, t.hitPoints, 0, t.died, t.disconnected); } } //Disconnect logic foreach (SocketState s in new List <SocketState>(users.Keys)) { if (s.ErrorOccured) { if (world.GetTank(users[s], out Tank t)) { t.setDisconnected(); } } } //Control command logic foreach (int i in new List <int>(controls.Keys)) { if (world.GetTank(i, out Tank t)) { if (t.hitPoints != 0 && !tanksRespawning.ContainsKey(t)) { ControlCommand c = controls[i]; Vector2D orientation = new Vector2D(1, 0); switch (c.moving) { case "none": orientation = t.orientation; t.velocity = new Vector2D(0, 0); break; case "up": orientation = new Vector2D(0, -1); t.velocity = new Vector2D(0, -world.tankSpeed); break; case "down": orientation = new Vector2D(0, 1); t.velocity = new Vector2D(0, world.tankSpeed); break; case "left": orientation = new Vector2D(-1, 0); t.velocity = new Vector2D(-world.tankSpeed, 0); break; case "right": orientation = new Vector2D(1, 0); t.velocity = new Vector2D(world.tankSpeed, 0); break; } Vector2D loc = t.location + t.velocity; if (CheckTankWallCollision(loc)) { loc = t.location; } loc = TankWraparound(loc); orientation.Normalize(); c.direction.Normalize(); world.UpdateTank(t.ID, loc, orientation, c.direction, t.name, t.hitPoints, t.score, t.died, t.disconnected); if (c.fire == "main" && !tanksFired.ContainsKey(t)) { world.UpdateProjectile(projCount++, t.location, c.direction, t.ID, false); tanksFired.Add(t, world.projectileDelay); } else if (c.fire == "alt" && t.beams > 0) { world.AddBeam(beamCount++, t.location, c.direction, t.ID); t.beams--; } controls.Remove(i); } } } //beam logic beams = new List <Beam>(world.GetBeams()); foreach (Beam b in new List <Beam>(world.GetBeams())) { List <Tank> temp = CheckBeamTankCollision(b); foreach (Tank hitTank in temp) { if (hitTank.ID != b.owner && !tanksRespawning.ContainsKey(hitTank)) { if (world.GetTank(b.owner, out Tank t)) { world.UpdateTank(hitTank.ID, hitTank.location, hitTank.orientation, hitTank.aiming, hitTank.name, 0, hitTank.score, true, t.disconnected); tanksRespawning.Add(hitTank, world.respawnTime); t.kill(); } } } world.RemoveBeam(b.ID); } //projectile logic foreach (Projectile p in new List <Projectile>(world.GetProjectiles())) { Vector2D loc = p.location + p.orientation * world.projectileSpeed; world.UpdateProjectile(p.ID, loc, p.orientation, p.owner, p.died); if (!p.died) { if (CheckProjectileWallCollision(loc)) { p.setDied(); } else if (CheckProjectileTankCollision(loc, out Tank hitTank)) { if (hitTank.ID != p.owner && !tanksRespawning.ContainsKey(hitTank)) { p.setDied(); hitTank.hit(); if (world.GetTank(p.owner, out Tank t) && hitTank.hitPoints == 0) { world.UpdateTank(hitTank.ID, hitTank.location, hitTank.orientation, hitTank.aiming, hitTank.name, hitTank.hitPoints, hitTank.score, true, t.disconnected); tanksRespawning.Add(hitTank, world.respawnTime); t.kill(); } } } } } //powerup logic foreach (Powerup p in new List <Powerup>(world.GetPowerups())) { world.UpdatePowerup(p.ID, p.location, p.died); if (!p.died) { if (CheckProjectileTankCollision(p.location, out Tank hitTank)) { if (!tanksRespawning.ContainsKey(hitTank)) { p.setDied(); hitTank.beams++; } } } } //create lists for send (beams is done before these) tanks = new List <Tank>(world.GetTanks()); projs = new List <Projectile>(world.GetProjectiles()); powerups = new List <Powerup>(world.GetPowerups()); } }
/// <summary> /// Method that informs the server /// </summary> public void Process() { lock (world) { String movingDir = ""; //If the keyPressed was up, then it sets moving dir to up if (keyPressedUp) { movingDir = "up"; } //If the keyPressed was left, then it sets moving dir to left if (keyPressedLeft) { movingDir = "left"; } //If the keyPressed was right, then it sets moving dir to right if (keyPressedRight) { movingDir = "right"; } //If the keyPressed was down, then it sets moving dir to down if (keyPressedDown) { movingDir = "down"; } //If the keyPressed was not pressed, then it sets moving dir to none if (!keyPressedLeft && !keyPressedDown && !keyPressedRight && !keyPressedUp) { movingDir = "none"; } String fireType = ""; //If the left mouse was pressed, sets fireType to main if (leftMousePressed) { fireType = "main"; } //If the right mouse was pressed, sets fireType to alt else if (rightMousePressed) { fireType = "alt"; } //If the left mouse and right mouse were not pressed, sets fireType to none else if (!leftMousePressed && !rightMousePressed) { fireType = "none"; } //Creates a new vector with the xCoord, and yCoord and normalizes the new vector created vec = new Vector2D(xCoord, yCoord); vec.Normalize(); //Passes this information in a ControlCommands ControlCommands c = new ControlCommands(movingDir, fireType, vec); //Serializes the control commands string serializedString = JsonConvert.SerializeObject(c); //If the server is open, then it passes the serialized string to the server if (theServer != null) { Networking.Send(theServer.TheSocket, serializedString + "\n"); } } }