Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect click/touch on isometric texture

I am having a hard time trying to implement click handling in a simple isometric Sprite Kit game.

I have a Game Scene (SKScene) with a Map (SKNode) containing multiple Tile objects (SKSpriteNode).

Here is a screenshot of the map :

enter image description here

I want to be able to detect the tile the user clicked on, so I implemented mouseDown on the Tile object. Here is my mouseDown in Tile.m :

-(void)mouseDown:(NSEvent *)theEvent
{
    [self setColorBlendFactor:0.5];
}

The code seems to work fine but there is a glitch : the nodes overlap and the click event is detected on the transparent part of the node. Example (the rects have been added to illustrate the problem only. They are not used in the logic) :

enter image description here

As you can see, if I click on the top left corner of the tile 7, the tile 8 becomes transparent.

enter image description here

I tried something like getting all the nodes at click location and checking if click is inside a CGPath without success (I think there was something wrong in the coordinates).

So my question here is how to detect the click only on the texture and not on the transparent part? Or maybe my approach of the problem is wrong?

Any advice would be appreciated.

Edit : for anyone interested in the solution I finally used, see my answer here

like image 694
Heyfara Avatar asked Mar 22 '14 14:03

Heyfara


1 Answers

My solution for such a problem 'right now' is:

  • in your scene get all nodes which are in that position of your click, i.e.

    [myScene nodesAtPoint:[theEvent lactionInNode:myScene]]
    
  • don't forget to check if your not clicking the root of your scene something like that:

    if (![[myScene nodeAtPoint:[theEvent locationInNode:myScene]].name isEqual: @"MyScene"])
    

    then go through the Array of possible nodes and check the alpha of the Texture (NOT myNode.alpha)

  • if the alpha is 0.0f go to the next node of your Array
  • pick the first node which alpha is not 0.0f and return the nodes name
  • this way you can find your node (first) and save it, as the node you need, and kill the array, which you don't need anymore
  • than do what you want with your node
  • btw check if your new node you wish to use is nil after searching for its name. if thats true, just break out of your moveDown method

To get the alpha try this.

Mine looks something like that:

-(void)mouseDown:(NSEvent *)theEvent {
     /* Called when a mouse click occurs */
    if (![[self nodeAtPoint:[theEvent locationInNode:self]].name isEqual: self.name]]) {

        /* find the node you clicked */
        NSArray *clickedNodes = [self nodesAtPoint:[theEvent locationInNode:self]];

        SKNode *clickedNode = [self childNodeWithName:[clickedNodes getClickedCellNode]];

        clickedNodes = nil;

        /* call the mouseDown method of your Node you clicked to to node specific actions */
        if(clickedNode) {
           [clickedNode mouseDown:theEvent];
        }
        /* kill the pointer to your clicked node */
        clickedNode = nil;
    }
}
like image 135
Roboter Avatar answered Sep 29 '22 12:09

Roboter