1 Replies - 1104 Views - Last Post: 24 November 2013 - 09:39 PM Rate Topic: -----

#1 crapmyster  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 77
  • Joined: 12-October 11

Jumping Sprite With 2D Collision Detection Bug. XNA

Posted 24 November 2013 - 08:05 AM

Hello,

Basically, I'm using XNA to create a platformer game. I'm trying to implement collision detection with my sprite with a tile map. Collision Detection works for when the sprite collides with a tile left and right. However, when I jump for example and hit a tile from above or below, the sprite will stop moving all together and the sprite won't be able to move left or right or anywhere. I've posted the code below. Can someone point me in the right direction.

Thank You.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Sheriff_Fatman
{
    public class Character : Sprite
    {
        public Vector2 velocity, oldPosition;
        public Rectangle rectangle, characterBounds;
        private int currentFrame, frameHeight, frameWidth;
        private float timer, interval, moveSpeed, jumpSpeed;
        private const float gravity = 1;
        private bool hasJumped;
        public int baseHeight = 415, jumpHeight = 300;

        public Character(Texture2D texture, Vector2 position, SpriteBatch spriteBatch, int newFrameHeight, int newFrameWidth)
            : base(texture, position, spriteBatch)
        {
            hasJumped = false;
            frameHeight = 32;
            frameWidth = 32;
            interval = 70;
            jumpSpeed = 10.0f;
            moveSpeed = 6.0f;
        }

        public void Update(GameTime gameTime)
        {
            UpdatePosition(gameTime);
            UpdateMovement(gameTime);
        }

        private void UpdateMovement(GameTime gameTime)
        {
            KeyboardState keyboardState = Keyboard.GetState();
            if (Keyboard.GetState().IsKeyDown(Keys.Left))
            {
                velocity.X = -moveSpeed;
                leftAnimation(gameTime);
            }
            else if (Keyboard.GetState().IsKeyDown(Keys.Right))
            {
                velocity.X = moveSpeed;
                rightAnimation(gameTime);
            }
            else
                velocity.X = 0f;


            if (Keyboard.GetState().IsKeyDown(Keys.Space) && hasJumped == false)
            {
                velocity.Y = -jumpSpeed;
            }

            if (Position.Y < jumpHeight)
            {
                velocity.Y = (velocity.Y + gravity);
                hasJumped = true;
            }

            if (Position.Y == baseHeight && hasJumped == true)
            {
                velocity.Y = 0f;
                hasJumped = false;
            }

            rectangle = new Rectangle(currentFrame * frameWidth, 0, frameWidth, frameHeight);
        }

        private void UpdatePosition(GameTime gameTime)
        {
            oldPosition = Position;
            Position += velocity * (float)gameTime.ElapsedGameTime.TotalMilliseconds / 15;
            characterBounds = new Rectangle((int)Position.X, (int)Position.Y, 32, 32);
            Position = Board.CurrentBoard.Collision(oldPosition, Position, characterBounds);
        }

        private void rightAnimation(GameTime gameTime)
        {
            timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            if (timer > interval)
            {
                currentFrame++;
                timer = 0;
                if (currentFrame > 3)
                    currentFrame = 0;
            }
        }

        private void leftAnimation(GameTime gameTime)
        {
            timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            if (timer > interval)
            {
                currentFrame++;
                timer = 0;
                if (currentFrame > 7 || currentFrame < 4)
                    currentFrame = 4;
            }
        }

        private void jumpAnimation(GameTime gameTime)
        {
            timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            if (timer > interval)
            {
                if (currentFrame > 5 || currentFrame < 3)
                    currentFrame = 4;
            }
        }

        public override void Draw()
        {
            SpriteBatch.Draw(Texture, Position, rectangle, Color.White);
        }
    }
}



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Sheriff_Fatman
{
    public class Board
    {
        public Tile[,] Tiles { get; set; }
        public int[,] Map;
        public int Columns { get; set; }
        public int Rows { get; set; }
        public Texture2D TileTexture { get; set; }
        private SpriteBatch SpriteBatch { get; set; }
        public static Board CurrentBoard { get; private set; }
        public const int Width = 32;
        public const int Height = 32;



        public Board(SpriteBatch spritebatch, Texture2D tileTexture, int columns, int rows)
        {
            Columns = columns;
            Rows = rows;
            TileTexture = tileTexture;
            SpriteBatch = spritebatch;
            Tiles = new Tile[columns, rows];
            Map = new int[columns, rows];
            Board.CurrentBoard = this;
            readInFile();
            LoadLevel();
        }

        public Vector2 Collision(Vector2 oldPosition, Vector2 Position, Rectangle characterBounds)
        {
            int leftTile = (int)Math.Floor((float)characterBounds.Left / Width);
            int rightTile = (int)Math.Ceiling(((float)characterBounds.Right / Width)) - 1;
            int topTile = (int)Math.Floor((float)characterBounds.Top / Width);
            int bottomTile = (int)Math.Ceiling(((float)characterBounds.Bottom / Width)) - 1;

            for (int y = topTile; y <= bottomTile; ++y)
            {
                for (int x = leftTile; x <= rightTile; ++x)
                {   
                    //left
                    if (Map[leftTile, topTile + 1] == 1)
                    {
                        Position = new Vector2(oldPosition.X, oldPosition.Y);
                        Console.WriteLine("Left"+Position);
                        return Position;
                    }
                    //right
                    if (Map[rightTile, topTile + 1] == 1)
                    {
                        Position = new Vector2(oldPosition.X, oldPosition.Y);
                        Console.WriteLine("Right"+Position);
                        return Position;
                    }
                    //top
                    if (Map[rightTile - 1, topTile] == 1)
                    {
                        Position = new Vector2(oldPosition.X, oldPosition.Y);
                        Console.WriteLine("Top"+Position);
                        return Position;
                    }
                    //bottom
                    if (Map[rightTile - 1, bottomTile] == 1)
                    {
                        Position = new Vector2(oldPosition.X, oldPosition.Y);
                        Console.WriteLine("Bottom"+Position);  
                        return Position;
                    }
                 }
            }
            return Position;
        }

        private void LoadLevel()
        {
            for (int x = 0; x < Columns; x++)
            {
                for (int y = 0; y < Rows; y++)
                {
                    //Console.WriteLine(Map[x, y]);
                    if (Map[x, y] == 1)
                    {
                        Vector2 tilePosition = new Vector2(x * TileTexture.Width, y * TileTexture.Height);
                        Tiles[x, y] = new Tile(TileTexture, tilePosition, SpriteBatch, true);
                    }
                    else
                    {
                        Vector2 tilePosition = new Vector2(x * TileTexture.Width, y * TileTexture.Height);
                        Tiles[x, y] = new Tile(TileTexture, tilePosition, SpriteBatch, false);
                    }
                }
            }
        }

        /*
         * Draws the map to the screen 
         */
        public void Draw()
        {
            for (int x = 0; x < Columns; x++)
            {
                for (int y = 0; y < Rows; y++)
                {
                    var tile = Tiles[x, y];
                    tile.Draw();
                }
            }
        }

        /*
         * A method to read in textfile (the map)
         */
        public void readInFile()
        {
            string file = @"content/map.txt";
            try
            {
                if (System.IO.File.Exists(file))
                {
                    using (StreamReader sr = new StreamReader("content/map.txt"))
                    {
                        string line;
                        int x = 0, y = 0;
                        while ((line = sr.ReadLine()) != null)
                        {
                            foreach (char ch in line)
                            {
                                double temp = Char.GetNumericValue(ch);
                                int result = Convert.ToInt32(temp);
                                Map[x, y] = result;
                                x++;
                            }
                            y++;
                            x = 0;
                        }
                    }
                }
                else
                {
                    throw new FileNotFoundException(file + " could not be found");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("The file could not be read");
                Console.WriteLine(e.Message);
            }

            //Used for Debugging
            for (int j = 0; j < 15; j++)
            {
                for (int i = 0; i < 25; i++)
                {
                    //Console.Write(Map[i, j]);
                }
                //Console.WriteLine("");
            }
        }
    }
}



Is This A Good Question/Topic? 0
  • +

Replies To: Jumping Sprite With 2D Collision Detection Bug. XNA

#2 Rhino1111  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 99
  • View blog
  • Posts: 228
  • Joined: 28-August 13

Re: Jumping Sprite With 2D Collision Detection Bug. XNA

Posted 24 November 2013 - 09:39 PM

Have you even attempted to debug the code? Obviously something is going wrong in the up/down collisions as you've said, so set breakpoints at the start of those methods/code blocks and run through what is happening. Set breakpoints on anything related to up/down collision.

These are vital skills to have as a developer. Not many people will sift through 300 lines of code to find logic errors for you, Let alone when your working with much larger systems.

I haven't glanced over the code but it seems like you enter an infinite collision in these scenario's, which is why the character gets stuck where it is, and any key presses likely register positive for collisions, so you can't move.

This post has been edited by Rhino1111: 24 November 2013 - 09:48 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1