2016-09-14 12 views
0

Я использую Tiled (http://www.mapeditor.org) для создания своих карт и TiledSharp (https://github.com/marshallward/TiledSharp) для загрузки и рисования моей карты.MonoGame + TiledSharp Collision

Пока все хорошо. Карта рисуется правильно (в правильных слоях), и движение героя верное.

То, что я не получаю. Как проверить конфликт между игроком и объектами?

В моем 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(); 

Я думаю, все, что мне нужно, есть, и мне просто не хватает си (

Любые предложения или примеры будут оценены по достоинству. (Может быть, нужно просто вычислить его самостоятельно в простой метод ...)

ответ

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

меня проверить свой код, но он не работает, когда я запускаю свою игру один дисплей исключения в Еогеаспе он говорит ключ не найден в словаре

Его мой класс 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

во-первых, вы должны не добавлять Еогеасп внутри Draw(). в этом случае вы добавляете все collisionObjects 60 раз в секунду (@ 60FPS), что совершенно безумно;) Я добавил foreach в конструктор TileMap, так как вам нужно заполнить объект столкновения только один раз на карту (при условии, что вы загружаете карту сразу) Второе: Проверьте .tmx файл для следующих <идентификатор объекта = "1" х = "96" у = "1054,67" ширина = "96" высота = «64.3333» /> <объект id = "2" x = "479" y = "1119,5" width = "68" height = "66.5" /> и т. Д. Название группа чувствительна к регистру! –