I have managed to implement a screen state system which I use to access the game. When the the character has collided with an enemy tile the game ends by going to a seperate game over screen. After being re-directed to the start screen the player can choose to start a new game. However the old level is still loaded and the old player character is still in contact with the enemy tile and the game over screen is loaded instantly.
How can I reload the level as new rather than load the previous game?
I have included the main game class below, Thanks
using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using FarseerPhysics.DebugViews;
using FarseerPhysics.HelloWorld.Physics;
using System.Collections.Generic;
using FarseerPhysics.HelloWorld.GameObjects;
using TiledLib;
using System;
namespace FarseerPhysics.HelloWorld
{
/// <summary>
/// This is the main class for our game, most of the work ealier on in the project will
/// be done in this class but we should move some of the work into level classes.
/// </summary>
public class Sum :Game
{
//Graphics
private GraphicsDeviceManager graphics;
//Sprite Batch- used to draw texture2D to the screen
private SpriteBatch spriteBatch;
//Holds the previous input state
private KeyboardState oldKeyState;
private GamePadState oldPadState;
//For drawing text to the screen, mainly debug info
private SpriteFont gameFont;
public float playerSpeed;
public float jumpHeight;
public int jumpTimes;
public float gravity;
private int count = 0;
private int count2 = 0;
public float friction;
public float bounce;
public float velocity;
//World, this is the physics simulation, we will use this to add
//remove objects from the physics
private World world;
// Simple camera controls
private Matrix view;
private Vector2 cameraPosition;
private Vector2 screenCenter;
//Physics debug overlay, shows what has been added to the simulation
private DebugViewXNA debugPhysicsView;
private Matrix debugProjection;
private Matrix debugView;
//Holds every game sprite on the screen, this has been loaded by us and
//not from the map
List<GameSprite> displayList;
//The Sprite we are controlling, is there a better way to control something
GameSprite playerSprite;
MenuComponent menuComponent;
KeyboardState keyboardState;
KeyboardState oldKeyboardState;
GameScreen activeScreen;
StartScreen startScreen;
ActionScreen actionScreen;
OptionsScreen optionsScreen;
PopUpScreen quitScreen;
public bool game = false;
public bool gameEnds = false;
public bool playerDead = false;
//The Tiled Map we are using at the moment
Map gameMap;
GameSprite movingPlatform;
//If we are not on the XBOX360 platform
#if !XBOX360
//Some instruction text to show
const string Text = "Press A or D to rotate the ball\n" +
"Press Space to jump\n" +
"Press Shift + W/S/A/D to move the camera"+
"Press F1 to enable/disable physics debug";
#else
const string Text = "Use left stick to move\n" +
"Use right stick to move camera\n" +
"Press A to jump\n"+
"Press Back to enable/disable physics debug";
#endif
/// <summary>
///
/// </summary>
public void VariableChanger()
{
string[] lines = System.IO.File.ReadAllLines("Content/TextEditor.txt");
foreach (string line in lines)
{
string[] chart = line.Split('=');
if (chart[0].ToLower() == "playerspeed")
{
playerSpeed = float.Parse(chart[1]);
}
if (chart[0] == "jumpHeight")
{
jumpHeight = float.Parse(chart[1]);
}
if (chart[0] == "jumpTimes")
{
jumpTimes = int.Parse(chart[1]);
}
if (chart[0] == "gravity")
{
gravity = float.Parse(chart[1]);
}
if (chart[0] == "friction")
{
friction = float.Parse(chart[1]);
}
if (chart[0] == "bounce")
{
bounce = float.Parse(chart[1]);
}
if (chart[0] == "velocity")
{
velocity = float.Parse(chart[1]);
}
}
}
public Sum()
{
VariableChanger();
//Initialise the graphics system
graphics = new GraphicsDeviceManager(this);
//Width and Height of the screen
graphics.PreferredBackBufferWidth = 1200;
graphics.PreferredBackBufferHeight = 880;
//The root directory for all assets
Content.RootDirectory = "Content";
//This holds sprites that are loaded by us and not from the tiled Map
displayList = new List<GameSprite>();
//Create Physics Simulation with Gavity of 9.8. We should load this
//value from a text file
world = new World(new Vector2(0, gravity));
}
public void LoadGame()
{
VariableChanger();
// Initialize camera controls
view = Matrix.Identity;
cameraPosition = Vector2.Zero;
//Calculate screen centre
screenCenter = new Vector2(graphics.GraphicsDevice.Viewport.Width / 2f, graphics.GraphicsDevice.Viewport.Height / 2f);
//Create Sprite batch for drawing our sprites later
//batch = new SpriteBatch(GraphicsDevice);
//load font from drawing text
gameFont = Content.Load<SpriteFont>("font");
//Create our debug physics view
debugPhysicsView = new DebugViewXNA(world);
debugPhysicsView.Enabled = true;
debugPhysicsView.LoadContent(GraphicsDevice, Content);
debugPhysicsView.DebugPanelPosition = new Vector2(600.0f, 0.0f);
debugPhysicsView.AppendFlags(DebugViewFlags.Shape);
debugPhysicsView.AppendFlags(DebugViewFlags.Joint);
debugPhysicsView.AppendFlags(DebugViewFlags.DebugPanel);
debugPhysicsView.AppendFlags(DebugViewFlags.ContactPoints);
debugPhysicsView.AppendFlags(DebugViewFlags.AABB);
debugPhysicsView.AppendFlags(DebugViewFlags.PolygonPoints);
debugPhysicsView.AppendFlags(DebugViewFlags.CenterOfMass);
//Load our game map, we should probably load the level name(map) from
//a text file
gameMap = Content.Load<Map>("Test Map");
//we have loaded the map, we need to add Physics Objects
//to represent this. We have decided that layer called Game
//will have physics
TileLayer tileLayer = gameMap.GetLayer("Main Level Layer") as TileLayer;
int xindex = 0;
int yindex = 0;
//Start position of tiles
float xPos = 0f;
float yPos = 0f;
//Nested for loop to go through every tile in the layer
for (int y = 0; y < tileLayer.Height; y++)
{
for (int x = 0; x < tileLayer.Width; x++)
{
//if we have a tile at position x, y
if (tileLayer.Tiles[x, y] != null)
{
//Retrieve that tile
Tile currentTile = tileLayer.Tiles[x, y];
//Grab the propery called tile type from the tile, this was
//created in Tiled editor
int tileType = (int)currentTile.Properties["TileType"];
//Retrieve the size of the tile
Vector2 size = new Vector2(currentTile.Source.Width,
currentTile.Source.Height);
//Get the position
Vector2 pos = new Vector2(xPos, yPos);
//We need to offset the position to the center of the tile
pos += size / 2;
//create the body for the tile
Body b = BodyFactory.CreateRectangle(world, PhysicsUtils.ConvertToPhysicsUnits(size.X),
PhysicsUtils.ConvertToPhysicsUnits(size.Y), 1f, PhysicsUtils.ConvertToPhysicsUnits(pos));
//Make the body static, pinned in place
b.BodyType = BodyType.Static;
//set the user type of the body, this allows us to associate some kind of data with
//the body and
b.UserData = tileType;
if (tileType == 3)
{
//Create Game Sprite
movingPlatform = new GameSprite();
//Load the texture and asign it to the texture property of the the new sprite
movingPlatform.Texture = Content.Load<Texture2D>("Test Sprite"); // 40 x 40 - 1m x 1m
//Convert screen center from pixels to meters, we could grab this position
//from a tile
movingPlatform.Position = PhysicsUtils.ConvertToPhysicsUnits(screenCenter) + new Vector2(-1.5f, -1.5f);
//Create the RigidBody of the player, we could change this to some other kind
//rigid body or a combination of rigid bodies
movingPlatform.RigidBody = b;
//Under simulation control
movingPlatform.RigidBody.BodyType = BodyType.Dynamic;
movingPlatform.RigidBody.OnCollision += new OnCollisionEventHandler(platform_OnCollision);
movingPlatform.RigidBody.IgnoreGravity = true;
movingPlatform.RigidBody.LinearVelocity = new Vector2(-10.0f, 0.0f);
movingPlatform.RigidBody.FixedRotation = true;
movingPlatform.RigidBody.Mass = 1000f;
//sprite.RigidBody.LinearVelocity = new Vector2(0,0);
//// Give it some bounce and friction
//movingPlatform.RigidBody.Restitution = bounce;
//movingPlatform.RigidBody.Friction = friction;
//Register a collision handler for the moving sprite
//movingPlatfrom.RigidBody.OnCollision += new OnCollisionEventHandler(RigidBody_OnCollision);
// sprite.RigidBody.FixedRotation = true;
//Add it to the display list
displayList.Add(movingPlatform);
//xindex = x;
//yindex = y;
tileLayer.Tiles[x, y] = null;
}
}
//Move the new position to the next tile position on the x
xPos += PhysicsUtils.MeterInPixels;
}
//reset back to the starting x position
xPos = 0f;
//Move the new position to the next tile position on the y
yPos += PhysicsUtils.MeterInPixels;
}
tileLayer.Tiles[xindex, yindex] = null;
//Create Game Sprite
GameSprite sprite = new GameSprite();
//Load the texture and asign it to the texture property of the the new sprite
sprite.Texture = Content.Load<Texture2D>("Test Sprite"); // 40 x 40 - 1m x 1m
//Convert screen center from pixels to meters, we could grab this position
//from a tile
sprite.Position = PhysicsUtils.ConvertToPhysicsUnits(screenCenter) + new Vector2(-1.5f, -1.5f);
//Create the RigidBody of the player, we could change this to some other kind
//rigid body or a combination of rigid bodies
sprite.RigidBody = BodyFactory.CreateCircle(world, PhysicsUtils.MeterInPixels
/ PhysicsUtils.ConvertToGraphicsUnits(2f),
1f, sprite.Position);
//Under simulation control
sprite.RigidBody.BodyType = BodyType.Dynamic;
//sprite.RigidBody.LinearVelocity = new Vector2(0,0);
//// Give it some bounce and friction
sprite.RigidBody.Restitution = bounce;
sprite.RigidBody.Friction = friction;
//Register a collision handler for the moving sprite
sprite.RigidBody.OnCollision += new OnCollisionEventHandler(RigidBody_OnCollision);
// sprite.RigidBody.FixedRotation = true;
//Add it to the display list
displayList.Add(sprite);
////this is the sprite we are controlling
playerSprite = sprite;
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content. We might change this later on when we
/// need to load a level at a time
/// </summary>
protected override void LoadContent()
{
//string[] menuItems = { "Start", "Options", "Quit"};
spriteBatch = new SpriteBatch(GraphicsDevice);
startScreen = new StartScreen(this, spriteBatch, Content.Load<SpriteFont>("menufont"), Content.Load<Texture2D>("image1"));
Components.Add(startScreen);
startScreen.Hide();
actionScreen = new ActionScreen(this, spriteBatch, Content.Load<Texture2D>("image4"));
Components.Add(actionScreen);
actionScreen.Hide();
optionsScreen = new OptionsScreen(this, spriteBatch, Content.Load<SpriteFont>("menufont"), Content.Load<Texture2D>("image2"));
Components.Add(optionsScreen);
optionsScreen.Hide();
quitScreen=new PopUpScreen(this, spriteBatch, Content.Load<SpriteFont>("menufont"), Content.Load<Texture2D>("image3"));
Components.Add(quitScreen);
quitScreen.Hide();
activeScreen = startScreen;
activeScreen.Show();
//menuComponent = new MenuComponent(this, spriteBatch, Content.Load<SpriteFont>("menufont"), menuItems);
//Components.Add(menuComponent);
}
public void movePlatform()
{
//movingPlatform.RigidBody.ApplyLinearImpulse(new Vector2(-1000.0f, 0.0f));
//movingPlatform.RigidBody.Position = new Vector2(movingPlatform.RigidBody.Position.X - 0.02f, movingPlatform.RigidBody.Position.Y);
/*count++;
if (count > 0 && count < 120)
{
movingPlatform.RigidBody.Position = new Vector2(movingPlatform.RigidBody.Position.X - 0.02f, movingPlatform.RigidBody.Position.Y);
}
count++;
if (count > 120 && count < 241)
{
movingPlatform.RigidBody.Position = new Vector2(movingPlatform.RigidBody.Position.X + 0.02f, movingPlatform.RigidBody.Position.Y);
}
if (count > 241)
{
count = 0;
}*/
//movingPlatform.BodyType = BodyType.Dynamic;
//movingPlatform.IgnoreGravity = true;
//movingPlatform.FixedRotation = true;
//movingPlatform.ApplyForce(new Vector2(-5f,0f));
}
/// <summary>
/// The Collision handler
/// </summary>
/// <param name="fixtureA">The fixture(contains body) which is on the left side of +=</param>
/// <param name="fixtureB">The fixture(contains body) which has been collided by the above</param>
/// <param name="contact">Extra contact information</param>
/// <returns></returns>
bool RigidBody_OnCollision(Fixture fixtureA, Fixture fixtureB, Dynamics.Contacts.Contact contact)
{
//Cast the user data from fixture B's body and check it
if ((int)fixtureB.Body.UserData == 3)
{
//this.Exit();
playerSprite.Position = new Vector2(movingPlatform.Position.X, movingPlatform.Position.Y);
}
if ((int)fixtureB.Body.UserData == 2)
{
//need to write code to destroy playersprite here
displayList.Remove(playerSprite);
playerSprite.RigidBody.IgnoreCollisionWith(fixtureB.Body);
playerDead = true;
gameEnds = true;
count2 = 10;
}
else
{
count2 = 0;
}
return true;
}
bool platform_OnCollision(Fixture fixtureA, Fixture fixtureB, Dynamics.Contacts.Contact contact)
{
if (fixtureB.Body != playerSprite.RigidBody)
{
float xvel = movingPlatform.RigidBody.LinearVelocity.X;
xvel *= -1;
movingPlatform.RigidBody.LinearVelocity = new Vector2(xvel,0.0f);
//return true;
}
return true;
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
keyboardState = Keyboard.GetState();
if (activeScreen == startScreen)
{
HandleStartScreen();
}
if (activeScreen == optionsScreen)
{
HandleOptionsScreen();
}
if (activeScreen == quitScreen)
{
HandleQuitScreen();
}
if (activeScreen == actionScreen)
{
HandleActionScreen();
}
if (game == true)
{
if (CheckKey(Keys.Escape))
{
activeScreen.Enabled = false;
activeScreen = quitScreen;
activeScreen.Show();
}
//Call to deal with game pad controls
HandleGamePad();
//Call to deal with keyboard controls
HandleKeyboard();
movePlatform();
//Update physics first, never lest than 30 FPS
world.Step(Math.Min((float)gameTime.ElapsedGameTime.TotalSeconds, (1f / 30f)));
}
if (gameEnds == true)
{
game = false;
activeScreen = actionScreen;
activeScreen.Show();
}
base.Update(gameTime);
oldKeyboardState = keyboardState;
//HandleKeyboard();
}
private void HandleActionScreen()
{
if (CheckKey(Keys.Enter))
{
actionScreen.Hide();
activeScreen = startScreen;
startScreen.Show();
gameEnds = false;
}
}
private void HandleStartScreen()
{
if (CheckKey(Keys.Enter))
{
if (startScreen.SelectedIndex == 0)
{
activeScreen.Hide();
//activeScreen = actionScreen;
//activeScreen.Show();
LoadGame();
game = true;
}
if (startScreen.SelectedIndex == 1)
{
activeScreen = optionsScreen;
startScreen.Hide();
optionsScreen.Show();
}
if (startScreen.SelectedIndex == 2)
{
this.Exit();
}
}
}
private void HandleOptionsScreen()
{
if (CheckKey(Keys.Enter))
{
if (optionsScreen.SelectedIndex == 0)
{
}
if (optionsScreen.SelectedIndex == 1)
{
}
if (optionsScreen.SelectedIndex == 2)
{
optionsScreen.Hide();
startScreen.Show();
activeScreen = startScreen;
//selected index has to be changed to allow user to change between menus
optionsScreen.SelectedIndex = 1;
}
}
}
private void HandleQuitScreen()
{
if (CheckKey(Keys.Enter))
{
if (quitScreen.SelectedIndex == 0)
{
activeScreen.Hide();
activeScreen = startScreen;
activeScreen.Show();
game = false;
}
if (quitScreen.SelectedIndex == 1)
{
activeScreen.Hide();
}
}
}
private bool CheckKey(Keys theKey)
{
return keyboardState.IsKeyUp(theKey) && oldKeyboardState.IsKeyDown(theKey);
}
/// <summary>
/// This is used to update the joypad state
/// </summary>
private void HandleKeyboard()
{
if (playerDead == false)
{
//Get the current keyboard state
KeyboardState state = Keyboard.GetState();
// Switch between player and camera control
if (state.IsKeyDown(Keys.LeftShift) || state.IsKeyDown(Keys.RightShift))
{
// Move camera
if (state.IsKeyDown(Keys.A))
cameraPosition.X += 1.5f;
if (state.IsKeyDown(Keys.D))
cameraPosition.X -= 1.5f;
if (state.IsKeyDown(Keys.W))
cameraPosition.Y += 1.5f;
if (state.IsKeyDown(Keys.S))
cameraPosition.Y -= 1.5f;
view = Matrix.CreateTranslation(new Vector3(cameraPosition - screenCenter, 0f)) *
Matrix.CreateTranslation(new Vector3(screenCenter, 0f));
}
else
{
// We make it possible to rotate the circle body
if (state.IsKeyDown(Keys.A))
playerSprite.RigidBody.ApplyLinearImpulse(new Vector2(-playerSpeed, 0f));
if (state.IsKeyDown(Keys.D))
playerSprite.RigidBody.ApplyLinearImpulse(new Vector2(playerSpeed, 0f));
if (state.IsKeyUp(Keys.A) && oldKeyState.IsKeyDown(Keys.A))
{
//playerSprite.RigidBody.LinearVelocity = new Vector2(velocity, playerSprite.RigidBody.LinearVelocity.Y);
}
if (state.IsKeyUp(Keys.D) && oldKeyState.IsKeyDown(Keys.D))
{
//playerSprite.RigidBody.LinearVelocity = new Vector2(velocity, playerSprite.RigidBody.LinearVelocity.Y);
}
if (state.IsKeyDown(Keys.Space) && oldKeyState.IsKeyUp(Keys.Space))
{
if (count2 < jumpTimes)
{
playerSprite.RigidBody.LinearVelocity = new Vector2(playerSprite.RigidBody.LinearVelocity.X, 0f);
playerSprite.RigidBody.ApplyForce(new Vector2(0, -jumpHeight * 75));
count2++;
}
}
if (!(state.IsKeyDown(Keys.A)) && !(state.IsKeyDown(Keys.D)))
{
playerSprite.RigidBody.LinearVelocity = new Vector2(playerSprite.RigidBody.LinearVelocity.X / 2 * friction, playerSprite.RigidBody.LinearVelocity.Y);
}
if (state.IsKeyDown(Keys.F1) && oldKeyState.IsKeyUp(Keys.F1))
debugPhysicsView.Enabled = !debugPhysicsView.Enabled;
if (playerSprite.RigidBody.LinearVelocity.X > playerSpeed)
{
playerSprite.RigidBody.LinearVelocity = new Vector2(playerSpeed, playerSprite.RigidBody.LinearVelocity.Y);
}
if (playerSprite.RigidBody.LinearVelocity.X < -playerSpeed)
{
playerSprite.RigidBody.LinearVelocity = new Vector2(-playerSpeed, playerSprite.RigidBody.LinearVelocity.Y);
}
}
// if (state.IsKeyDown(Keys.Escape))
// Exit();
oldKeyState = state;
//oldKeyboardState = keyboardState;
}
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
//Clear the screen
GraphicsDevice.Clear(Color.CornflowerBlue);
//Begin a sprite batch
//batch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, view);
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null);
spriteBatch.End();
base.Draw(gameTime);
if (game == true)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, view);
//draw map
gameMap = Content.Load<Map>("Test Map");
gameMap.Draw(spriteBatch);
//Cycle through game sprites
foreach (GameSprite s in displayList)
{
// Convert physics position (meters) to screen coordinates (pixels)
Vector2 pos = PhysicsUtils.ConvertToGraphicsUnits(s.RigidBody.Position);
Vector2 origin = new Vector2(s.Texture.Width / 2f, s.Texture.Height / 2f);
float rotation = 0;
//Draw sprite
spriteBatch.Draw(s.Texture, pos, null, Color.White, rotation, origin, 1f, SpriteEffects.None, 0f);
}
spriteBatch.End();
//Draw debug display
debugView = Matrix.CreateTranslation(new Vector3(PhysicsUtils.ConvertToPhysicsUnits(cameraPosition - screenCenter), 0f)) *
Matrix.CreateTranslation(new Vector3(PhysicsUtils.ConvertToPhysicsUnits(screenCenter), 0f)); ;
debugProjection = Matrix.CreateOrthographicOffCenter(0, PhysicsUtils.ConvertToPhysicsUnits(GraphicsDevice.Viewport.Width),
PhysicsUtils.ConvertToPhysicsUnits(GraphicsDevice.Viewport.Height), 0, 0, 1f);
debugPhysicsView.RenderDebugData(ref debugProjection, ref debugView);
//Begin Sprite batch
spriteBatch.Begin();
// Display instructions
spriteBatch.DrawString(gameFont, Text, new Vector2(14f, 14f), Color.Black);
spriteBatch.DrawString(gameFont, Text, new Vector2(12f, 12f), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
public GameSprite sprite { get; set; }
}
}
