Finding which Tile is touched in a Orthogonal TileMap

I have a tilemap that I created using Tiled and I have it loaded into my game. Now I want to try to detect which of the tiles has been touched by a user. Is that possible? I have only seen examples using CCSprite and ContainsPoint. I just want to use a TileMap and try to figure out which tile was tapped instead of having to calculate the size of every tile, the location in the world, and then trying to figure out if where the user tapped was somewhere inside one of the tiles. All tiles are 100x100 and there are 9 total tiles in a 300x300 grid so a standard 3x3 grid.

Also, the documentation for CocosSharp Forms is incredibly sparse and not very thorough except for some very basic use cases which generally don't apply to many scenarios. I have looked through what is out there but basically if there are any courses or tutorials other than the ones Microsoft released I would love to look those over. Thanks!

protected override void AddedToScene()
{
base.AddedToScene();

        tileMap = new CCTileMap("TileMaps/Board.tmx");

        tileMap.Antialiased = false;

        tileMap.Position = new CCPoint(ContentSize.Width / 2 - 150, ContentSize.Height / 2);

        this.AddChild(tileMap);

}

I want to figure out if the user touched a tile

    private void OnTouchesBegan(List<CCTouch> touches, CCEvent touchEvent)
    {
        if (touches.Count > 0)
        {
            isTapping = true;
            CCPoint touchLoc = touches[0].Location;
           //Did the user touch one of the tiles and if yes which tile?
        }
    }

If you can point me in the right direction that would be great.

Tagged:

Best Answer

  • KenMyersKenMyers US ✭✭
    Accepted Answer

    Okay it is not pretty but I have an answer here ... Basically when I add the tileMap I am noting the position where it gets added and then building out an array of Rects that will complete my 3x3. Then I can just check to see on a touch if the touch point is contained by any of the Rects in my tileMapLocations array. Seems to work! I still don't really get why the built in methods don't work but I'm moving on as I have what I need now.

Answers

  • KenMyersKenMyers USMember ✭✭

    This seems to be not possible. I have tried every combination that I can find to no avail.

    CCPoint location = layer.WorldToParentspace(touchLocation);
    CCPoint loc = layer.ConvertToWorldspace(touch.Location);
    CCPoint loc2 = layer.ScreenToWorldspace(touch.Location);
    CCPoint loc3 = ScreenToWorldspace(touch.Location);
    CCPoint loc4 = WorldToScreenspace(touch.Location);

    None of the attempts to translate the touch event to the tileMap tiles seems to be working correctly.

  • KenMyersKenMyers USMember ✭✭

    I should mention that I am using cocossharp forms (maybe I should not be ha). Anyway, nothing seems to be working properly. I would love to see a real thorough online course on this and/or documentation that stepped you through more scenarios. It's somewhat there for native iOS and native Droid but XF users are out of luck.

  • KenMyersKenMyers USMember ✭✭

    Here is a more complete piece of code that is still not providing the correct tile coordinates:

    using System;
    using System.Collections.Generic;
    using CocosSharp;
    using System.Linq;
    using System.Diagnostics;
    
    namespace TicTacToe
    {
    
        public class GameLayer : CCLayerColor
        {
    
            CCTileMap tileMap;
    
            bool isTapping = false;
    
            public GameLayer() : base(new CCColor4B(0, 0, 0)) //This color is to match the sky background we will use for the parallax scrolling effect
            {
                //Nothing here
            }
    
            protected override void AddedToScene()
            {
                base.AddedToScene();
    
                tileMap = new CCTileMap("TileMaps/Board.tmx");
                tileMap.Position = new CCPoint(ContentSize.Width / 2 - 150, ContentSize.Height / 2);
                AddChild(tileMap);
    
                // Register for touch events
                var touchListener = new CCEventListenerTouchAllAtOnce();
                touchListener.OnTouchesEnded = OnTouchesEnded;
                touchListener.OnTouchesBegan = OnTouchesBegan;
                AddEventListener(touchListener, this);
    
            }
    
            void EndGame()
            {
                CCScene gameOverScene = new CCScene(GameView);
                var transitionToGameOver = new CCTransitionRotoZoom(1.0f, gameOverScene);
                gameOverScene.AddLayer(new GameOverLayer(10 / 2));
                Director.ReplaceScene(transitionToGameOver);
            }
    
            private void OnTouchesBegan(List<CCTouch> touches, CCEvent touchEvent)
            {
    
                isTapping = true;
    
                CCTouch touch = touches.FirstOrDefault();
                var layer = tileMap.LayerNamed("Board");
                var location = layer.WorldToParentspace(touch.LocationOnScreen);
    
                // HERE IS THE PROBLEM tileCoordinates is incorrect I want to know if it is 0,0 or 1,0 or 1,1, etc.
                var tileCoordinates = layer.ClosestTileCoordAtNodePosition(location);
    
            }
    
            void OnTouchesEnded(List<CCTouch> touches, CCEvent touchEvent)
            {
                if (touches.Count > 0)
                {
                    isTapping = false;
                }
            }
    
        }
    }
    
    
    
  • KenMyersKenMyers USMember ✭✭

    Just as a refresher this is a 3x3 map 100px x 100px

  • KenMyersKenMyers USMember ✭✭

    I should also point out that this tileMap is in the center of the screen and since it is 300x300 it does not take up the full screen. I am wondering if that is why none of the conversion methods work properly?

  • KenMyersKenMyers USMember ✭✭
    Accepted Answer

    Okay it is not pretty but I have an answer here ... Basically when I add the tileMap I am noting the position where it gets added and then building out an array of Rects that will complete my 3x3. Then I can just check to see on a touch if the touch point is contained by any of the Rects in my tileMapLocations array. Seems to work! I still don't really get why the built in methods don't work but I'm moving on as I have what I need now.

Sign In or Register to comment.