I'm busy with a C# XNA 4.0 2d rpg game and have the following problem. To detect collesion i loop through all my TileStore objects stored in a List
TileStore is an object that holds:
- Rectangle
- Bool walkable
- Bool pickable
But after some collesion detection and movement my character gets very slow
To show this in code. In the class GameplayScreen i handle everything for the gameplay field (movement, draw, collesion dection)
When i press right arrow key the following code will be executed in the update method
public void update(KeyboardState keyboard, KeyboardState oldKeyboard, GameTime gameTime)
{
// Update this after every game tick -> GameTIme
elapsed += (int)gameTime.ElapsedGameTime.TotalMilliseconds;
if (elapsed >= delay)
{
if (frames >= 8)
{
frames = 0;
}
else
{
frames++;
}
elapsed = 0;
}
/*******************************************************************
* RIGHT KEY CHECK (collesion, out off screen, Movement en animation) *
*******************************************************************/
// Walk right if there is no collision
if (collisionRight == false)
{
// Check out of screen
if (character.pos.X <= screenWidth - 64)
{
if (Keyboard.GetState().IsKeyDown(Keys.Right))
{
// Determine which sprite to load
character.charSprite.Y = 704;
// Character animation
character.charSprite.X = 64 * frames;
// Move character by increase x pos by 1
character.pos.X += 1;
// Check to walk left again
if (intersect(character.pos) == false && collisionRight == false)
{
collisionLeft = false;
}
else
// Else intersect disable movement right
{
collisionRight = true;
}
}
}
}
}
and my intersect (collision) method looks like this
public bool intersect(Rectangle player)
{
// Loop through the tileobject list defined in Tile class
for (int i = 0; i < Tile.tileObject.Count; i++)
{
// Check if tileObject is not walkable
if (Tile.tileObject[i].walkable == false)
{
// Collesion => Intersects c#
if (Tile.tileObject[i].Rectangle.Intersects(player))
{
return true;
}
}
}
return false;
}
So everytime i press the key RIGHT,BOTTOM,LEFT,UP there's a check for intersects. I think that after playing serval minutes the for loop is calling to much what will cause the slow playing/movement character.
Are there people who has experienced this problem also?
And how could a do intersect without making my movement after serval minutes very slow.
Edit show complete code
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.IO;
using Microsoft.Xna.Framework.Storage;
using System.Xml.Serialization;
using System.Xml.Linq;
using System.Diagnostics;
namespace Quester
{
public class GameplayScreen
{
// Scherm grenzen / borders
private int screenWidth;
private int screenHeight;
// Texture
private Texture2D creditsLogo;
private Texture2D background;
// Sprite class
private Tile tile;
private Character character;
// Vector
private Vector2 logoPosition;
private Vector2 backgroundPosition;
// Spritefont
public SpriteFont mainFont;
// Walking Delay
float elapsed;
float delay = 175f;
int frames = 0;
int counter = 0;
// Collission
bool collisionLeft = false;
bool collisionRight = false;
bool collisionTop = false;
bool collisionBottom = false;
// Constructor
public GameplayScreen(SpriteBatch spriteBatch, Texture2D creditsLogo, int screenWidth, int screenHeight, SpriteFont mainFont, Texture2D background, Texture2D mainCharacter, ContentManager Content)
{
this.creditsLogo = creditsLogo;
this.screenWidth = screenWidth;
this.screenHeight = screenHeight;
this.mainFont = mainFont;
this.background = background;
//sprite = new Sprite(tileSet, new Vector2(0, 0), spriteBatch, screenWidth, screenHeight);
//sprite2 = new Sprite(tileSet2, new Vector2(0, 0), spriteBatch, screenWidth, screenHeight);
tile = new Tile(spriteBatch, screenWidth, screenHeight, Content);
character = new Character(mainCharacter, spriteBatch);
}
public void Initialize()
{
// Background position
backgroundPosition = new Vector2(0, 0);
// Logo positioneren
logoPosition = new Vector2((screenWidth / 2) - (creditsLogo.Width / 2), (screenHeight / 8));
}
public void update(KeyboardState keyboard, KeyboardState oldKeyboard, GameTime gameTime)
{
// Update dit naar elke game tick -> gameTime
elapsed += (int)gameTime.ElapsedGameTime.TotalMilliseconds;
if (elapsed >= delay)
{
if (frames >= 8)
{
frames = 0;
}
else
{
frames++;
}
elapsed = 0;
}
// Druk op Spatie om naar het menu te gaan!
if (Keyboard.GetState().IsKeyDown(Keys.Space))
{
playScreenSelected = true; // Zet splashScreenSelected op true, zodat je wordt doorgestuurd naar het menu
}
/*******************************************************************
* DOWN KEY CHECK (collesion, uit het scherm, bewegen en animatie) *
*******************************************************************/
// Je kan alleen naar beneden lopen als en geen collision is
if (collisionTop == false)
{
// Checken als character niet uit het scherm loopt.
if (character.pos.Y <= screenHeight - 64)
{
if (Keyboard.GetState().IsKeyDown(Keys.Down))
{
// Bepalen welke sprite wordt ingeladen
character.charSprite.Y = 640;
// Character animeren door middel van frames
character.charSprite.X = 64 * frames;
// Verhoog positie met 1
character.pos.Y += 1;
// Check om weer naar beneden te kunnen lopen
if (intersect(character.pos) == false && collisionTop == false)
{
collisionBottom = false;
}
// Check als en een intersect plaats vindt disable naar beneden lopen
else
{
collisionTop = true;
}
}
}
}
/*******************************************************************
* UP KEY CHECK (collesion, uit het scherm, bewegen en animatie) *
*******************************************************************/
// Je kan alleen naar boven lopen als en geen collision is
if (collisionBottom == false)
{
// Checken als character niet uit het scherm loopt.
if (character.pos.Y >= 0)
{
// Walk up
if (Keyboard.GetState().IsKeyDown(Keys.Up))
{
// Bepalen welke sprite wordt ingeladen
character.charSprite.Y = 512;
// Character animeren door middel van frames
character.charSprite.X = 64 * frames;
// Verlaag positie met 1
character.pos.Y -= 1;
// Check om weer naar boven te kunnen lopen
if (intersect(character.pos) == false && collisionBottom == false)
{
collisionTop = false;
}
// Check als en een intersect plaats vindt disable naar boven lopen
else
{
collisionBottom = true;
}
}
}
}
/*******************************************************************
* LEFT KEY CHECK (collesion, uit het scherm, bewegen en animatie) *
*******************************************************************/
// Je kan alleen links lopen als en geen collision is
if (collisionLeft == false)
{
// Checken als character niet uit het scherm loopt.
if (character.pos.X >= 0)
{
// Walk left
if (Keyboard.GetState().IsKeyDown(Keys.Left))
{
// Bepalen welke sprite wordt ingeladen
character.charSprite.Y = 576;
// Character animeren door middel van frames
character.charSprite.X = 64 * frames;
// Verlaag positie met 1
character.pos.X -= 1;
// Check om weer naar rechts te kunnen lopen
if (intersect(character.pos) == false && collisionLeft == false)
{
collisionRight = false;
}
// Check als en een intersect plaats vindt disable naar Links lopen
else
{
collisionLeft = true;
}
}
}
}
/*******************************************************************
* RIGHT KEY CHECK (collesion, uit het scherm, bewegen en animatie) *
*******************************************************************/
// Je kan alleen rechts lopen als en geen collision is
if (collisionRight == false)
{
// Checken als character niet uit het scherm loopt.
if (character.pos.X <= screenWidth - 64)
{
if (Keyboard.GetState().IsKeyDown(Keys.Right))
{
// Bepalen welke sprite wordt ingeladen
character.charSprite.Y = 704;
// Character animeren door middel van frames
character.charSprite.X = 64 * frames;
// Verhoog positie met 1
character.pos.X += 1;
// Check om weer naar Links te kunnen lopen
if (intersect(character.pos) == false && collisionRight == false)
{
collisionLeft = false;
}
else
// Check als en een intersect plaats vindt disable naar Rechts lopen
{
collisionRight = true;
Tile.tileObject.Clear();
}
}
}
}
}
/// <summary>
/// Kijken of player met object intersect
/// </summary>
/// <param name="player">Player rectangle</param>
/// <returns></returns>
public bool intersect(Rectangle player)
{
for (int i = 0; i < Tile.tileObject.Count; i++)
{
if (Tile.tileObject[i].walkable == false)
{
if (Tile.tileObject[i].Rectangle.Intersects(player))
{
return true;
}
}
}
//// Loop door alle tiles heen
//foreach (TileStorage tiles in tile.tileObject)
//{
// // Check of tile walkable is
// if (tiles.walkable == false)
// {
// // Check of er een collission detectie is tussen player en tile
// if (tiles.Rectangle.Intersects(player))
// {
// return true;
// }
// }
// counter++;
//}
//counter = 0;
return false;
}
// DRAW
public void Draw(SpriteBatch spriteBatch, GameTime gameTime)
{
spriteBatch.Begin();
// Draw the map => param tile size
tile.Draw(128);
spriteBatch.DrawString(mainFont, "Y Position: " + character.pos.Y, new Vector2(10, 100), Color.Black);
spriteBatch.DrawString(mainFont, "X Position: " + character.pos.X, new Vector2(400, 100), Color.Black);
spriteBatch.DrawString(mainFont, "Tiles dection : " + Tile.tileObject.Count, new Vector2(800, 100), Color.Black);
// Draw the character
character.Draw();
// Weergave van het logo
//spriteBatch.Draw(creditsLogo, logoPosition, Color.White);
spriteBatch.End();
}
// bool splashScreenSelected (GET & SET)
public bool playScreenSelected { get; set; }
}
}
- Class: GameplayScreen (the playfield)
- Link: hostcode.sourceforge.net/view/3092
- Class: Tile (Loop through map to generate field and draw it
- Link: hostcode.sourceforge.net/view/3093
- Class: TileStorage (object for tiles)
- Link: hostcode.sourceforge.net/view/3094
- Class: Character (Draw character)
- Link: hostcode.sourceforge.net/view/3095
- Class: Map (Create map with rows/columns)
- Link: hostcode.sourceforge.net/view/3096