/// <summary>
        /// Draws the gameplay screen.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {
            frames++;
            frameTimer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            if (frameTimer > 1000)
            {
                fps = frames;
                frameTimer = 0f;
                frames = 0;
            }

            // This game has a blue background. Why? Because!
            ScreenManager.GraphicsDevice.Clear(ClearOptions.Target,
                                               Color.CornflowerBlue, 0, 0);
            camera.Zoom = 1f;
            Matrix proj = camera.SimProjection;
            Matrix view = camera.SimView;

            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;

            //Begins spriteBatch with the default sort mode, alpha blending on sprites, and a camera.
            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, camera.View);

            // Draws the game background.
            skyLayer.Draw(spriteBatch);

            leftWall.Draw(spriteBatch);
            rightWall.Draw(spriteBatch);
            ground.Draw(spriteBatch);

            if (player != null)
            {
                player.Draw(spriteBatch);
            }
            foreach (CompositeCharacter p in playerMap.Values)
            {
                p.Draw(spriteBatch);
            }

            //checks to see if a player is firing through their own input, creates a projectile associated with that player.
            if (player.canFire)
            {
                //Yellow weapon selected
                if (player.Weapon == Character.WeaponSelect.Yellow)
                {
                    if (player.Mana >= YellowProjectile.manaCost)
                    {
                        Vector2 cPos = ConvertUnits.ToDisplayUnits(camera.ConvertScreenToWorld(playerHUD.cursorPos));
                        Projectile projectile = new YellowProjectile(world, player.Position, projectileTexYellow, new Vector2(10.0f, 10.0f), cPos, player, SendModifyTerrainMessage);
                        projectile.id = projectileId;
                        player.Mana -= YellowProjectile.manaCost;
                        player.fireDelay = projectile.delay;
                        writeStream.Position = 0;
                        writer.Write((byte)Protocol.FireProjectile);
                        writer.Write((byte)0);
                        writer.Write((byte)projectileId);
                        writer.Write(cPos.X);
                        writer.Write(cPos.Y);
                        writer.Write(projectile.Position.X);
                        writer.Write(projectile.Position.Y);
                        lock (client.GetStream())
                        {
                            SendData(GetDataFromMemoryStream(writeStream));
                        }
                        projectiles.Add(projectile);
                        projectileId = (byte)((projectileId + 1) % 100);
                    }
                }
                //Red weapon selected
                else if (player.Weapon == Character.WeaponSelect.Red)
                {
                    if (player.Mana >= RedProjectile.manaCost)
                    {
                        Vector2 cPos = ConvertUnits.ToDisplayUnits(camera.ConvertScreenToWorld(playerHUD.cursorPos));
                        Projectile projectile = new RedProjectile(world, player.Position, projectileTexRed, new Vector2(10.0f, 10.0f), cPos, player, SendModifyTerrainMessage);
                        projectile.id = projectileId;
                        player.Mana -= RedProjectile.manaCost;
                        player.fireDelay = projectile.delay;
                        writeStream.Position = 0;
                        writer.Write((byte)Protocol.FireProjectile);
                        writer.Write((byte)1);
                        writer.Write((byte)projectileId);
                        writer.Write(cPos.X);
                        writer.Write(cPos.Y);
                        writer.Write(projectile.Position.X);
                        writer.Write(projectile.Position.Y);
                        lock (client.GetStream())
                        {
                            SendData(GetDataFromMemoryStream(writeStream));
                        }
                        projectiles.Add(projectile);
                        projectileId = (byte)((projectileId + 1) % 100);
                    }
                }
                //Blue weapon selected
                else if (player.Weapon == Character.WeaponSelect.Blue)
                {
                    if (player.Mana >= BlueProjectile.manaCost)
                    {
                        Vector2 cPos = ConvertUnits.ToDisplayUnits(camera.ConvertScreenToWorld(playerHUD.cursorPos));
                        Projectile projectile = new BlueProjectile(world, player.Position, projectileTexBlue, new Vector2(10.0f, 10.0f), cPos, player, SendModifyTerrainMessage);
                        projectile.id = projectileId;
                        player.Mana -= BlueProjectile.manaCost;
                        player.fireDelay = projectile.delay;
                        writeStream.Position = 0;
                        writer.Write((byte)Protocol.FireProjectile);
                        writer.Write((byte)2);
                        writer.Write((byte)projectileId);
                        writer.Write(cPos.X);
                        writer.Write(cPos.Y);
                        writer.Write(projectile.Position.X);
                        writer.Write(projectile.Position.Y);
                        lock (client.GetStream())
                        {
                            SendData(GetDataFromMemoryStream(writeStream));
                        }
                        projectiles.Add(projectile);
                        projectileId = (byte)((projectileId + 1) % 100);
                    }
                }

                player.canFire = false;
            }

            foreach (PhysicsObject projectile in projectiles)
            {
                projectile.Draw(spriteBatch);
            }
            //-----------------------

            spriteBatch.End();
            terrain.RenderTerrain(ref proj, ref view);

            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, null, null, null, null, camera.View);

            foreach (Explosion explosion in explosions)
            {
                explosion.Draw(spriteBatch);
            }

            spriteBatch.End();

            DebugView.RenderDebugData(ref proj, ref view);

            // If the game is transitioning on or off, fade it out to black.
            if (TransitionPosition > 0 || pauseAlpha > 0)
            {
                float alpha = MathHelper.Lerp(1f - TransitionAlpha, 1f, pauseAlpha / 2);

                ScreenManager.FadeBackBufferToBlack(alpha);
            }
        }
        private void ProcessData(byte[] data)
        {
            readStream.SetLength(0);
            readStream.Position = 0;//reset data

            readStream.Write(data, 0, data.Length);//read data
            readStream.Position = 0;
            Protocol p;
            while (readStream.Position != data.Length)
            {
                try
                {
                    p = (Protocol)reader.ReadByte();
                    /*if (GameScreen.isExiting)
                    {
                        System.Diagnostics.Debug.WriteLine
                    }*/
                    if (p == Protocol.Initialize)
                    {
                        id = reader.ReadByte();
                        //if (id == 0)
                        //    terrain.CreateRandomTerrain(new Vector2(0, 0));
                    }
                    else if (p == Protocol.Connected)
                    {
                        lock (client.GetStream())
                        {
                            terrainMaster = true;
                            foreach (byte otherID in playerMap.Keys)
                            {
                                if (otherID < this.id)
                                {
                                    terrainMaster = false;
                                    break;
                                }
                            }
                            //pindex++;
                            System.Diagnostics.Debug.WriteLine(pindex);
                            byte id = reader.ReadByte();
                            string ip = reader.ReadString();
                            ScreenManager.CharacterColor = Color.White;

                            CompositeCharacter newPlayer = new CompositeCharacter(world, new Vector2(ScreenManager.GraphicsDevice.Viewport.Width / 2.0f, ScreenManager.GraphicsDevice.Viewport.Height / 2.0f),
                                    Content.Load<Texture2D>("bean_ss1"), new Vector2(35.0f, 50.0f), ScreenManager.CharacterColor);
                            newPlayer.body.IgnoreGravity = true;
                            newPlayer.wheel.IgnoreGravity = true;
                            newPlayer.body.CollidesWith = Category.Cat24;
                            newPlayer.wheel.CollidesWith = Category.Cat24;
                            playerMap.Add(id, newPlayer);

                            writeStream.Position = 0;
                            writer.Write((byte)Protocol.AddCharacter);
                            writer.Write((byte)playerMap.Count);
                            SendData(GetDataFromMemoryStream(writeStream));
                            try
                            {
                                if (terrainMaster)
                                {
                                    writeStream.Position = 0;
                                    writer.Write((byte)Protocol.CreateTerrain);
                                    writer.Write(terrain.seed1);
                                    writer.Write(terrain.seed2);
                                    writer.Write(terrain.seed3);
                                    SendData(GetDataFromMemoryStream(writeStream));
                                }
                            }
                            catch (Exception e)
                            {

                            }
                        }
                    }

                    else if (p == Protocol.Disconnected)
                    {
                        //pindex--;
                        //System.Diagnostics.Debug.WriteLine(pindex);
                        byte id = reader.ReadByte();
                        string ip = reader.ReadString();
                        playerMap[id].Dispose();
                        playerMap.Remove(id);
                    }
                    else if (p == Protocol.Movement)
                    {
                        float px = reader.ReadSingle();
                        float py = reader.ReadSingle();
                        bool dead = reader.ReadBoolean();
                        Character.CharDirection dir = (Character.CharDirection)reader.ReadByte();
                        Character.CharState state = (Character.CharState)reader.ReadByte();
                        byte id = reader.ReadByte();
                        string ip = reader.ReadString();

                        playerMap[id].Dead = dead;
                        playerMap[id].Direction = dir;
                        playerMap[id].State = state;
                        playerMap[id].Position = new Vector2(px, py);
                    }
                    else if (p == Protocol.AddCharacter)
                    {
                        byte numPlayers = reader.ReadByte();
                        byte id = reader.ReadByte();
                        string ip = reader.ReadString();
                        CompositeCharacter newPlayer;
                        if (numPlayers != playerMap.Count)
                        {
                            newPlayer = new CompositeCharacter(world, new Vector2(ScreenManager.GraphicsDevice.Viewport.Width / 2.0f, ScreenManager.GraphicsDevice.Viewport.Height / 2.0f),
                                Content.Load<Texture2D>("bean_ss1"), new Vector2(35.0f, 50.0f), ScreenManager.CharacterColor);
                            newPlayer.body.IgnoreGravity = true;
                            newPlayer.wheel.IgnoreGravity = true;
                            newPlayer.body.CollidesWith = Category.Cat24;
                            newPlayer.wheel.CollidesWith = Category.Cat24;
                            playerMap.Add(id, newPlayer);
                        }
                    }
                    else if (p == Protocol.CreateTerrain)
                    {
                        if (!terrain.Created)
                        {
                            double s1 = reader.ReadDouble();
                            double s2 = reader.ReadDouble();
                            double s3 = reader.ReadDouble();
                            byte id = reader.ReadByte();
                            string ip = reader.ReadString();
                            terrain.CreateTerrain(new Vector2(0, 0), s1, s2, s3);
                        }
                    }
                    else if (p == Protocol.FireProjectile)
                    {
                        byte color = reader.ReadByte();
                        byte pId = reader.ReadByte();
                        float cx = reader.ReadSingle();
                        float cy = reader.ReadSingle();
                        float px = reader.ReadSingle();
                        float py = reader.ReadSingle();
                        byte id = reader.ReadByte();
                        string ip = reader.ReadString();
                        Projectile projectile;

                        switch (color)
                        {
                            case 0:
                                projectile = new YellowProjectile(world, new Vector2(px, py), projectileTexYellow,
                                    new Vector2(10f, 10f), new Vector2(cx, cy), playerMap[id]);
                                break;
                            case 1:
                                projectile = new RedProjectile(world, new Vector2(px, py), projectileTexRed,
                                    new Vector2(10f, 10f), new Vector2(cx, cy), playerMap[id]);
                                break;
                            case 2:
                                projectile = new BlueProjectile(world, new Vector2(px, py), projectileTexBlue,
                                    new Vector2(10f, 10f), new Vector2(cx, cy), playerMap[id]);
                                break;
                            default:
                                projectile = new Projectile(world, new Vector2(px, py), projectileTexYellow,
                                    new Vector2(10f, 10f), new Vector2(cx, cy), playerMap[id], null);
                                break;
                        }
                        projectile.id = ((id+1) * 100) + pId;
                        projectile.body.CollidesWith = Category.None;
                        projectiles.Add(projectile);
                    }

                    else if (p == Protocol.ModifyTerrain)
                    {
                        byte pId = reader.ReadByte();
                        float px = reader.ReadSingle();
                        float py = reader.ReadSingle();

                        byte id = reader.ReadByte();
                        string ip = reader.ReadString();

                        for (int i = 0; i < projectiles.Count; i++ )
                        {
                            if (projectiles[i].id == ((id + 1) * 100) + pId)
                            {
                                CheckCollision(projectiles[i]);
                                projectiles.RemoveAt(i);
                            }
                        }

                    }

                    oldP = p;
                }
                catch (Exception e)
                {

                }
            }
        }
        /// <summary>
        /// Draws the gameplay screen.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {
            frames++;
            frameTimer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            if (frameTimer > 1000)
            {
                fps = frames;
                frameTimer = 0f;
                frames = 0;
            }

            // This game has a blue background. Why? Because!
            ScreenManager.GraphicsDevice.Clear(ClearOptions.Target,
                                               Color.CornflowerBlue, 0, 0);
            camera.Zoom = 1f;
            Matrix proj = camera.SimProjection;
            Matrix view = camera.SimView;

            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;

            //Begins spriteBatch with the default sort mode, alpha blending on sprites, and a camera.
            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, camera.View);

            // Draws the game background.
            skyLayer.Draw(spriteBatch);

            leftWall.Draw(spriteBatch);
            rightWall.Draw(spriteBatch);

            player.Draw(spriteBatch);

            foreach (Enemy e in enemies)
            {
                e.Draw(spriteBatch);
            }

            //--------NEED TO REWORK--------
            //checks to see if a player is firing through their own input, creates a projectile associated with that player.
            /* TODO:
             * Need to add projectile types, this means that it will select a players selected weapon and pass it into projectile.
             * Based on this we can subtract the nessesary mana / damage / rate of fire
             * Change if statement to include players mana compared to selected spells requirement
             */
            if (player.canFire)
            {
                //Yellow weapon selected
                if (player.Weapon == Character.WeaponSelect.Yellow)
                {
                    if (player.Mana >= YellowProjectile.manaCost)
                    {
                        Projectile projectile = new YellowProjectile(world, player.Position, projectileTexYellow, new Vector2(10.0f, 10.0f), ConvertUnits.ToDisplayUnits(camera.ConvertScreenToWorld(playerHUD.cursorPos)), player, CheckCollision);
                        player.Mana -= YellowProjectile.manaCost;
                        player.fireDelay = projectile.delay;
                        projectiles.Add(projectile);
                    }
                }
                //Red weapon selected
                else if (player.Weapon == Character.WeaponSelect.Red)
                {
                    if (player.Mana >= RedProjectile.manaCost)
                    {
                        Projectile projectile = new RedProjectile(world, player.Position, projectileTexRed, new Vector2(10.0f, 10.0f), ConvertUnits.ToDisplayUnits(camera.ConvertScreenToWorld(playerHUD.cursorPos)), player, CheckCollision);
                        player.Mana -= RedProjectile.manaCost;
                        player.fireDelay = projectile.delay;
                        projectiles.Add(projectile);
                    }
                }
                //Blue weapon selected
                else if (player.Weapon == Character.WeaponSelect.Blue)
                {
                    if (player.Mana >= BlueProjectile.manaCost)
                    {
                        Projectile projectile = new BlueProjectile(world, player.Position, projectileTexBlue, new Vector2(10.0f, 10.0f), ConvertUnits.ToDisplayUnits(camera.ConvertScreenToWorld(playerHUD.cursorPos)), player, CheckCollision);
                        player.Mana -= BlueProjectile.manaCost;
                        player.fireDelay = projectile.delay;
                        projectiles.Add(projectile);
                    }
                }

                player.canFire = false;
            }

            foreach (PhysicsObject projectile in projectiles)
            {
                projectile.Draw(spriteBatch);
            }
            //-----------------------

            spriteBatch.End();
            terrain.RenderTerrain(ref proj, ref view);

            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, null, null, null, null, camera.View);

            foreach (Explosion explosion in explosions)
            {
                explosion.Draw(spriteBatch);
            }

            spriteBatch.End();

            DebugView.RenderDebugData(ref proj, ref view);

            // If the game is transitioning on or off, fade it out to black.
            if (TransitionPosition > 0 || pauseAlpha > 0)
            {
                float alpha = MathHelper.Lerp(1f - TransitionAlpha, 1f, pauseAlpha / 2);

                ScreenManager.FadeBackBufferToBlack(alpha);
            }
        }