c# XNA collesion slows movement

77 Views Asked by At

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:

  1. Rectangle
  2. Bool walkable
  3. 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
0

There are 0 best solutions below