Ejemplo n.º 1
0
        /// <summary>
        /// Processes the message received from the server. If it is a json object, it updates the world accordingly.
        /// Otherwise, it is either the player id or world size, and thus sets those accordingly.
        /// </summary>
        private void ProcessMessage(SocketState state)
        {
            if (state.ErrorOccured)
            {
                return;
            }

            //Gets data and parts from data
            string totalData = state.GetData();

            string[] parts = Regex.Split(totalData, @"(?<=[\n])");

            foreach (string s in parts)
            {
                //If the part has a length of 0, then it is not a complete message
                if (s.Length <= 0)
                {
                    continue;
                }

                //If the part does not end with newline, then the message is incomplete
                if (s[s.Length - 1] != '\n')
                {
                    break;
                }
                //If the part is a json, deserialize
                if (s[0] == '{')
                {
                    lock (world)
                    {
                        //Get the json object out of the part
                        JObject obj = JObject.Parse(s);
                        JToken  type;

                        //Wall is not loaded
                        if (!world.WallsLoaded)
                        {
                            type = obj["wall"];
                            if (type != null)
                            {
                                Wall w = JsonConvert.DeserializeObject <Wall>(s);
                                world.AddWall(w.ID, w.p1, w.p2);
                            }
                            else
                            {
                                //As soon as we reach a JSON that isn't a wall, the walls are loaded
                                world.LoadWalls();
                                WorldLoaded();
                            }
                        }

                        //If it a tank, update the world
                        type = obj["tank"];
                        if (type != null)
                        {
                            Tank t = JsonConvert.DeserializeObject <Tank>(s);
                            world.UpdateTank(t.ID, t.location, t.orientation, t.aiming, t.name, t.hitPoints, t.score, t.died, t.disconnected);
                        }

                        //Projectile
                        type = obj["proj"];
                        if (type != null)
                        {
                            Projectile p = JsonConvert.DeserializeObject <Projectile>(s);
                            world.UpdateProjectile(p.ID, p.location, p.orientation, p.owner, p.died);
                        }

                        //Powerup
                        type = obj["power"];
                        if (type != null)
                        {
                            Powerup p = JsonConvert.DeserializeObject <Powerup>(s);
                            world.UpdatePowerup(p.ID, p.location, p.died);
                        }

                        //Beam
                        type = obj["beam"];
                        if (type != null)
                        {
                            Beam b = JsonConvert.DeserializeObject <Beam>(s);
                            BeamFired(b);
                        }
                    }
                }
                //If it is not a json object, then it must be the world size or player id
                else
                {
                    //If player id is not set, then the part is the player id
                    if (PlayerID < 0)
                    {
                        PlayerID = Int32.Parse(s);
                        IDLoaded();
                    }
                    //Otherwise, the part must be the world
                    else
                    {
                        world = new World(Int32.Parse(s));
                    }
                }

                lock (state)
                {
                    //Remove the processed part
                    state.RemoveData(0, s.Length);
                }

                //If OnUpdate is set, call it
                if (OnUpdate != null)
                {
                    OnUpdate();
                }
            }
        }
Ejemplo n.º 2
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());
            }
        }