MonoGame + TiledSharp 碰撞

MonoGame + TiledSharp Collision

我正在使用 Tiled (http://www.mapeditor.org) to generate my maps and TiledSharp (https://github.com/marshallward/TiledSharp) 来加载和绘制我的地图。

到目前为止一切顺利。地图绘制正确(在正确的图层中)并且英雄移动正确。

我没有得到什么。如何检查玩家和物体之间的碰撞?

在我的 Update() 中,我有类似的东西

if (ks.IsKeyDown(Keys.W))
{
    playerMovement += new Vector2(0, -2);
    curAnimation = "Walk_North";
}

...

if (playerMovement.Length() != 0)
    player.MoveBy(playerMovement);

检查地图的 .tmx 文件,有我的组和我可以碰撞的对象:

 <objectgroup name="Collision">
  <properties>
   <property name="collision" type="bool" value="true"/>
  </properties>
  <object id="1" x="1089" y="1118" width="62" height="65"/>
  <object id="2" x="801" y="1026" width="61" height="60"/>
 </objectgroup>

我现在要找的是

If(tileAt(player.Position + playerMovement).Properties.Collision)
    playerMovement = Vector2.Zero();   

我想,我需要的一切都在那里,我只是缺少一个简单的步骤来比较玩家的位置与目标位置及其 属性 :(

如有任何建议或示例,我们将不胜感激。 (可能需要自己用简单的方法计算一下...)

想通了,其实很简单:

首先,在我的 class 管理我的地图时,我用我的碰撞对象设置了一个列表。

foreach(var o in curMap.ObjectGroups["Collision"].Objects)
    collisionObjects.Add(new Rectangle((int)o.X, (int)o.Y, (int)o.Width, (int)o.Height));

在我的 UpdateGame() 方法中,我从我的地图中调用了一个简单的辅助方法-class 检查交叉点:

public bool IsCollisionTile(Rectangle player)
{
    foreach (Rectangle rect in collisionObjects)
        if (rect.Intersects(player))
           return true;

    return false;
}

完成。

写这篇文章比实际实施更费力^^

我已经测试了你的代码,但是当我启动我的游戏时他不工作,在 foreach 中显示一个异常他说在字典中找不到密钥

这是我的class MapLoader

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

using System;
using System.Collections.Generic;

using TiledSharp;

namespace TestMapLoader
{
    public class MapLoader
    {
        private TmxMap _map;
        private Texture2D _tileset;
        private int _tileWidth;
        private int _tileHeight;
        private int _mapWidth;
        private int _mapHeight;
        private int _tilesetTilesWide;
        private int _tilesetTilesHigh;
        private List<Rectangle> _collisionObject;

        public MapLoader()
        {
        }

        public void LoadContent(ContentManager content, string path)
        {
            _collisionObject = new List<Rectangle>();

            _map = new TmxMap(path);
            _tileset = content.Load<Texture2D>(_map.Tilesets[0].Name.ToString());

            _tileWidth = _map.Tilesets[0].TileWidth;
            _tileHeight = _map.Tilesets[0].TileHeight;

            _tilesetTilesWide = _tileset.Width / _tileWidth;
            _tilesetTilesHigh = _tileset.Height / _tileHeight;

            _mapWidth = _map.Width;
            _mapHeight = _map.Height;
        }

        public void Update()
        {
        }

        public void Draw(SpriteBatch spriteBatch ,int nbLayer)
        {
            spriteBatch.Begin();

            for (int nLayer = 0; nLayer < nbLayer; nLayer++)
            {
                for (var i = 0; i < _map.Layers[nLayer].Tiles.Count; i++)
                {
                    int gid = _map.Layers[nLayer].Tiles[i].Gid;

                    if (gid != 0)
                    {
                        int tileFrame = gid - 1;
                        int column = tileFrame % _tilesetTilesWide;
                        int row = (int)Math.Floor((double)tileFrame / (double)_tilesetTilesWide);

                        int mapRow = (int)(i / _mapWidth);
                        int mapColumn = i % _mapWidth;

                        float x = (i % _map.Width) * _map.TileWidth;
                        float y = (float)Math.Floor(i / (double)_map.Width) * _map.TileHeight;

                        Rectangle tilesetRec = new Rectangle(_tileWidth * column, _tileHeight * row, _tileWidth, _tileHeight);

                        spriteBatch.Draw(_tileset, new Rectangle((int)x, (int)y, _tileWidth, _tileHeight), tilesetRec, Color.White);
                    }
                }
            }

            spriteBatch.End();
            foreach(var o in _map.ObjectGroups["Collision"].Objects)
            {
                this._collisionObject.Add(new Rectangle((int)o.X, (int)o.Y, (int)o.Width, (int)o.Height));
            }
        }

        public bool IsCollisionTile(Rectangle player)
        {
            foreach(Rectangle rect in this._collisionObject)
            {
                if (rect.Intersects(player))
                {
                    return true;
                }
            }
            return false;
        }

        public TmxMap getMap()
        {
            return _map;
        }
    }
}

我调用了 Game1 中的所有函数 class