How to position objects on a map?

I’ve got a map with four wall objects on it I’m running using C#, Monogame, Extended and Tiled. You can see them in the image and (hopefully) the small dots that denotes the first point selected as outlined in the Tiled docs.

When it renders the object layer in game though that first point of each object is rendered at tile coordinate 1,1. Is that expected behaviour? Do I have to render each object in context of world space individually or have I got that wrong?

Not sure if the image below makes that clearer or not! It’s where the four objects are rendering.

Thanks.

I’m having a hard time reading your map and diagram, but if they’re rendering in a different location in your game than in Tiled, that means you’re rendering them incorrectly.

Object coordinates are in world space, correct, and the coordinates in the map file are in pixels. However, you need to keep rotations in mind, they may change the position of the object significantly since they’re done about the top left corner. However, if you rotate an object 180 degrees, this “top left corner” is visually the bottom right corner xP Your render location may need to take this into account of transformations are done differently in-engine than in Tiled.

Hello Eishiya.

I’ve drawn the objects as they are in Tiled on the screenshot. The image with the white background is how they are when I run the game. The first point of the blue object is the bottom left of the polygon. I’ve checked the figures in the property window and X/Y are accurate in regards to the world position (0, 3360).
They’re all rotated properly and the right size. Just all the objects locate their first position at 70,70 in the world.

Thanks for the colour coding, that helped me a lot in understanding your earlier drawing!

Just to be clear, when I say “world space” I mean map space, not the World feature in Tiled. Every map’s top left corner is 0,0 in this space.

I also think I may have accidentally misled you earlier: when I said “object coordinates”, I meant the X and Y properties on the object itself. The points within a polygon or polyline are in local space to the object, so you’ll need to add the object’s x and y properties to each point’s coordinates if you need them to be in map space. If possible, however, you should keep the points in local space and transform the entire object using your engine’s transform functions to position and rotate it, so that any runtime changes to the object are more predictable and consistent with Tiled’s behaviour. That may also give you more accurate collision detection, depending on how that’s implemented.

X/Y properties are all correct in Tiled for the world coordinates of the first points of the polygon objects.

Haven’t really done anything with the map in game.

Load.

        // Map
        tiledMap = Content.Load<TiledMap>("LevelBasement");
        tiledMapRenderer = new TiledMapRenderer(GraphicsDevice, tiledMap);
        // Map Objects
        objLayer = tiledMap.GetLayer<TiledMapObjectLayer>("Objects");
        tileset = tiledMap.Tilesets[0];

        // Sprite
        spriteLocation = new Rectangle(GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2, 123, 126);
        spriteTexture = this.Content.Load<Texture2D>("penguin");

        // Camera
        //var viewportadapter = new BoxingViewportAdapter(Game.Window, GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height);
        //camera = new OrthographicCamera(viewportadapter);
        camera = new OrthographicCamera(GraphicsDevice);

Some debug info in Update.

                float x = cameraPosition.X;
                float y = cameraPosition.Y;

                var polyObj = obj as TiledMapPolygonObject;
                if(GameMain.ContainsPoint(polyObj.Points, new Vector2(x, y)))
                {
                    if(obj.Type == "Wall")
                        strText += "Wall (" + obj.Name + "), ";
                }
                else
                {
                    strText += "Not Wall, ";
                }

…and Draw.

            // Draw Map
            tiledMapRenderer.Draw(tiledMap.GetLayer("Ground"), camera.GetViewMatrix());

            // Set source of sprite
            spriteSource = new Rectangle(nSpriteX, nSpriteY, 41, 42);
            // Set height of joystick
            int nJoystickY = GraphicsDevice.Viewport.Height - 500;

            // Draw Sprite
            Game.spriteBatch.Begin();
            Game.spriteBatch.Draw(spriteTexture,
                spriteLocation,
                spriteSource,
                Color.White);
            Game.spriteBatch.End();

            tiledMapRenderer.Draw(tiledMap.GetLayer("Higher"), camera.GetViewMatrix());

            // Draw Joystick
            Game.spriteBatch.Begin();
            Game.spriteBatch.Draw(Game.joystickTexture,
                new Rectangle(50, nJoystickY, 450, 450),
                Game.joystickSource,
                Color.White);
            Game.spriteBatch.End();

Just checking…

My last response was removed as spam!

All the X/Y coordinates for the objects are correct.

I opened the tmx file and the contents are below. Should the objects render at x/y or the position of point[0]?

<objectgroup id="3" name="Objects">
  <object id="6" name="North Outer" type="Wall" x="0" y="0">
   <polygon points="0,0 7000,0 7000,3360 6930,3360 6930,210 70,210 70,3360 0,3360"/>
  </object>
  <object id="10" name="South Outer" type="Wall" x="0" y="3640">
    <polygon points="0,0 70,0 70,3290 6930,3290 6930,0 7000,0 7000,3360 0,3360"/>
  </object>
 <object id="11" name="West Outer" type="Wall" x="280" y="420">
     <polygon points="0,0 3080,0 3080,70 70,70 70,6230 3080,6230 3080,6300 0,6300"/>
 </object>
 <object id="12" name="East Outer" type="Wall" x="3640" y="420">
     <polygon points="0,0 3080,0 3080,6300 0,6300 0,6230 3010,6230 3010,70 0,70"/>
 </object>
</objectgroup>

I’m not sure how to answer your question because I don’t know how your object rendering system is set up.

The objects should be rendered at x, y, which should mean that each point within the object is at its given coordinates plus the x, y. As I mentioned in my previous post, the x, y coordinates should ideally be applied as a transform on the whole object, rather than being manually added to the raw positions of each point.

Using Monogame.Extended.Tiled.Renderers as they come out of the box. I pass it the GraphicsDevice and TiledMap.
Sorry, out of my depth here and not sure what else I can give you.

Thanks for your help BTW.

Tried it previously using a rectangle for the object and it’s largely the same code and it placed that properly in the world space. Changed to polygons and it doesn’t appear to read the x,y anymore.

I’m not familiar with Monogame so I can’t give specific advice, but looking at the code for the Monogame.Extended.Tiled stuff, it looks like when Polygons are created, they take the points (unchanged from the TMX) and the x, y as a separate position parameter. So, you should not need to worry about doing anything with the points, you should be able to just position the object according to its x, y properties, and Monogame handles the transformations. The position and points are part of the object when it’s created (i.e. when it’s read in from the TMX), and not passed in to the renderers. So, it’s likely not your rendering code, but your initial reading code where the issue lies.

It looks that way looking at the xml that makes up the tmx file. The object nodes have the correct x/y values. The code below loads the map object. Using a breakpoint I’ve stepped through these few lines and the objLayer has the map objects with the x/y data from the file. Just doesn’t use it when locating them in the world.

        // Map
        tiledMap = Content.Load<TiledMap>("LevelBasement");
        tiledMapRenderer = new TiledMapRenderer(GraphicsDevice, tiledMap);
        // Map Objects
        objLayer = tiledMap.GetLayer<TiledMapObjectLayer>("Objects").Objects;

This sounds like an issue to bring up in the Monogame community if you haven’t already, there are more likely to be people there who are familiar with this issue.

I did try but no luck.

Thanks anyway Eishiya.

It was flagged by the system, I’ve unflagged it now.