2D Tiling碰撞检测不会检测到

时间:2013-11-15 13:51:41

标签: c# xna collision-detection 2d-games tiling

情况:在我的游戏中,我有一些与检测到的玩家碰撞的牌,然而当我碰撞碰撞时发生事件时,什么都不会发生。

问题:我目前在每个tile类中都有一个Collision类。在tile类中,我有一个方法,它使用参数传递播放器矩形(x,y,width和height)。然后我调用了瓷砖碰撞类检查碰撞方法。经过一些测试,我发现当我检查每个tile(使用foreach)并在每个tile类中调用update方法时,我的tileMap类(保存Tile类的2D数组)中的碰撞被识别出来了,只有第一个瓷砖碰撞。没别了。

enter image description here

这是我的代码:

瓷砖:

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

namespace Project
{
    class Tile
    {              
        Texture2D tileTexture;
        Rectangle tileRect;
        public Collision collision;
        private Vector2 pos;
        public int tileNumber;
        private SpriteFont tileT;
        bool box;
        public enum tileCollision
        {
            passable,
            nonpassable,
            trigger,
        }

        public tileCollision tileValue;

        public Tile(string tileType,int number, Rectangle newTileRect, ContentManager Content)
        {                
            tileTexture = Content.Load<Texture2D>(tileType);
            tileT = Content.Load<SpriteFont>("TimesNewRoman");
            tileRect = newTileRect;
            tileNumber = number;

            pos.X = tileRect.X;
            pos.Y = tileRect.Y;

            //check if tile is within draw block 
            if (tileNumber >= 9 && tileNumber <= 13)
            {
                tileValue = tileCollision.passable;    
            }

            if (tileNumber >= 0 && tileNumber <= 8 )
            {                    
                tileValue = tileCollision.nonpassable;
                System.Console.WriteLine("NON PASSABLE TILE: " + " x: " + tileRect.X + " y: " + tileRect.Y);
            }                

            collision = new Collision(tileRect.X, tileRect.Y, tileRect.Width, tileRect.Height);
        }

        public void update(Rectangle rect)
        {
            //System.Console.WriteLine(playerRect.X, playerRect.Y);    
            if (collision.boundingBoxCollisionCheck(rect.X, rect.Y, rect.Width, rect.Height))
            {
                //if (tileValue == tileCollision.nonpassable)
                //{
                //    System.Console.WriteLine("COLLISION!!!!!");
                //}

                box = true;                    
            }
            if (box == true)
            {
                System.Console.WriteLine("COLLISION!!!!! at x: " + tileRect.X + "y: " + tileRect.Y );
            }    
        }

        public void draw(SpriteBatch spritebatch)
        {
            //if tile is within draw block then draw
            spritebatch.Draw(tileTexture, tileRect, Color.White);                                
            spritebatch.DrawString(tileT, pos.X.ToString(), pos, Color.White);               
        }
    }
}

tilemap的:

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

namespace Project
{
    class TileMap
    {

        //public Tile[,] tile = new Tile[10,10];
        public List<Tile> tiles = new List<Tile>();
        int width;
        int height;    

        string[] tileType = { "Tiles/BrickGrassTile1", "Tiles/BrickGrassTile2", "Tiles/BrickGrassTile3", "Tiles/BrickGrassTile4", 
                                "Tiles/BrickGrassTile5", "Tiles/BrickRoofTile1", "Tiles/BrickRoofTile2", "Tiles/BrickRoofTile3",
                                "Tiles/BrickTile1", "Tiles/GrassPuddleTile1", "Tiles/GrassRockTile1", "Tiles/WallTile1", "Tiles/GrassTile1", "Tiles/GrassTile2", "Tiles/BrickDoor1" };

        public void generateMap(int [,]map, int size, ContentManager content)
        {               
            for (int x = 0; x < map.GetLength(1); x++)
            {
                for (int y = 0; y < map.GetLength(0); y++)
                {
                    int number = map[y, x];

                    if (number >= 0)
                    {
                            tiles.Add(new Tile(tileType[number],number, new Rectangle(x * size, y * size, size, size), content));
                    }

                    width = (x + 1) * size;
                    height = (y + 1) * size;
                }
            }
        }

        public void update(Rectangle playerRect)
        {
            foreach (Tile tile in tiles)
            {    
                tile.update(playerRect);                    
            }
        }

        public void draw(SpriteBatch spritebatch)
        {
            foreach (Tile tile in tiles)
            {
                tile.draw(spritebatch);
            }    
        }          
    }
}

1 个答案:

答案 0 :(得分:0)

... each tile (using foreach) and call the update method within each tile class, only the first tile collides. Nothing else.

我怀疑你的玩家矩形小于你的一个牌,这就是为什么你只有1次碰撞。

修改

您的逻辑现在的工作方式,一旦您与某个项目发生碰撞,它就会永久地说您正在与该项目发生碰撞。这是不正确的。使用此:

public void update(Rectangle rect)
{
    //System.Console.WriteLine(playerRect.X, playerRect.Y);    
    if (collision.boundingBoxCollisionCheck(rect.X, rect.Y, rect.Width, rect.Height))
    {
        System.Console.WriteLine("COLLISION!!!!! at x: " + tileRect.X + "y: " + tileRect.Y );                  
    }  
}