MonoGame + TiledSharp碰撞

时间:2016-09-14 17:02:43

标签: collision-detection monogame tiled

我正在使用Tiled(http://www.mapeditor.org)生成我的地图和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();   

我认为,我需要的一切都在那里,我只是错过了一个简单的步骤来比较玩家&#39;目标位置及其属性的位置:(

任何建议或示例都将不胜感激。 (也许只需要用一种简单的方法自己计算......)

2 个答案:

答案 0 :(得分:1)

想出来,实际上非常简单:

首先,在我的班级管理我的地图时,我用碰撞对象设置了一个List。

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()方法中,我从map-class中调用一个简单的helper-method检查交集:

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

    return false;
}

成品。

撰写此帖子比实际实施更多努力^^

答案 1 :(得分:0)

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

我的班级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类中调用所有函数