2016-09-14 52 views
0

我使用Tiled(http://www.mapeditor.org)生成我的地图和TiledSharp(https://github.com/marshallward/TiledSharp)来加载和绘制我的地图。MonoGame + TiledSharp Collision

到目前为止这么好。地图绘制正确(正确的图层)和英雄运动是正确的。

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

在我的更新()我有类似

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(); 

我觉得,一切都是我需要的是有,我只是缺少一个SI多步骤比较球员的位置与目标位置及其属性:(

任何建议或例子,将不胜感激。 (也许只需要通过自己在一个简单的方法来计算的话...)

回答

1

想通了,其实很简单:

首先,在我的课堂管理我的地图我成立了我的collisionobjects的列表。

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()方法调用我一个简单的辅助法从我的地图级检查路口:

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

    return false; 
} 

成品。

更多精力写这个帖子不是实际执行^^

0

我测试你的代码,但是当我启动我的游戏一个例外显示在foreach他说,关键是不是在字典中找到他不工作

其班上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类

+0

首先,你不应该添加内绘制的foreach()。在这种情况下,您将每秒60次(@ 60FPS)添加所有collisionObjects,这是非常疯狂的;) 我已经在TileMap构造函数中添加了foreach,因为您需要每个地图只填充一次碰撞对象(假设您加载地图一次) 第二个: 请检查您的.tmx文件中的以下内容 等等 组是区分大小写的! –