Example #1
0
        /// <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);
        }
Example #2
0
        /// <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();
        }
Example #3
0
        /// <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);
        }
Example #4
0
        /// <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());
            }
        }