3

I am currently working on a project in which I need the user to press on a node to make an action occur. So currently I am working with some code that will allow this to happen but only if the user touches the screen.

I want it to work when the user touches and holds a specific node. Any help is appreciated! My code is in a picture below.

Thank You! The Code

Balaach
  • 125
  • 1
  • 6

1 Answers1

4

Since you already know how to do the gesture the rest is easy:

All we are going to do is take the point from the view, convert it to scene coordinates, and grab 1/all node(s) from the scene.

@IBAction func TELE(_ gestureRecognizer : UILongPressGestureRecognizer) {

    if gestureRecognizer.state == .began{
         var touchPoint = gestureRecognizer.location(in: view)
         var touchPointInScene = view.scene.convertPoint(fromView:touchPoint)

         //use atPoint for the deepest node, node(:at) for all nodes)
         var node = view.scene.atPoint(touchPointInScene)
         var nodes = view.scene.nodes(at:touchPointInScene)

    }
}
Knight0fDragon
  • 16,609
  • 2
  • 23
  • 44
  • So is this the touch and hold function? or is this the function that will turn the node into the view of the scene? Will I still need to use my gesture code that I have provided above? – Balaach Jul 14 '17 at 20:15
  • Do you not know how gestures work? You should already be doing this, I just filled in the meat and potatoes for you. – Knight0fDragon Jul 14 '17 at 20:16
  • btw @IBAction was a force of habit, you only need that if you plan on using the interface builder to setup your gesture – Knight0fDragon Jul 14 '17 at 20:19
  • Sorry I am a bit new to gestures, I was just using the above code with things like double tap and the hold feature. – Balaach Jul 14 '17 at 20:19
  • when you setup your gesture you should have created the TELE method, otherwise your gesture will not work. This code is what happens after the gesture is fired. The .began means the beginning of your gesture, .ended is used when the gesture ends. So in your code, after you hold onto the screen for 2 seconds, this event will fire, then grab the node at the point you are touching. If you have a node there, process it, otherwise skip and move on. – Knight0fDragon Jul 14 '17 at 20:21
  • Ok so it seems that I may have mad a mistake in explaining my situation, the node is not in the scene it is a node, which is made to act as a button and is added into the scene. The node is used to move the player right. So what I need is for the node to be touched and held which will then move the player as long as the node is held. Otherwise it will stop. The node is also going to stay in the camera view at all times. Thank you for the help please let me know if you would like me to clarify anything more. – Balaach Jul 14 '17 at 20:29
  • I want you to think about what you said: `the node is not in the scene`. If a node is not on a scene, then a node is not on the screen, so you can't poke it – Knight0fDragon Jul 14 '17 at 20:30
  • If you need to create a new node, then you use `touchPointInScene` as the position of your new node – Knight0fDragon Jul 14 '17 at 20:33
  • if you want your node to be on the camera, then you need to convert from scene to camera using `camera.convert(touchPointInScene, from:scene)` – Knight0fDragon Jul 14 '17 at 20:35
  • Haha sorry for my wording let me try to correct myself again, the node is in the scene. It is a Node which will follow the camera and will be visible at all times. This node is a button used to make an action happen. Like the pause button in many IOS games it is visible at all times, however it is used to control the player. – Balaach Jul 14 '17 at 20:36
  • I just want to know how I can make the gesture code I presented in the original question above work with a node instead of working with the screen, so i dont want to tap and hold the screen, i want to specifically tap and hold this node. – Balaach Jul 14 '17 at 20:37
  • 1
    already gave you that answer, you have to tap and hold the screen, there is no getting around this. If you want to use gestures, you need to do the work because SpriteKit does not have special gestures built for it. If you want to do the gesture made for SpriteKit yourself so that SpriteKit does the conversions I listed in my answer automatically, you are going to have to write your own handler, subclass the node, and override the touchesBegan. The method I gave you is a lot less work than having to do all of this. – Knight0fDragon Jul 14 '17 at 20:41
  • Ok thanks for the help it seems like i will have to look into other methods of controlling the character for my project. – Balaach Jul 14 '17 at 20:44
  • I think he didnt' try the code :) @Knight0fDragon He thinks that your code is run no matter where do you tap on screen. I mean it will run, but that is where atPoint and convertPoint comes into action...Hopefully, he will just try it :) – Whirlwind Jul 14 '17 at 21:35
  • @Knight0fDragon So I have tried your code and it does not work. I have placed the touch in the button(node) required for the touch to work, but it seems to work anywhere I touch the screen. Any suggestions? – Balaach Jul 14 '17 at 21:48
  • @Balaach Check if `node` is your button . You need to add one if statement. – Whirlwind Jul 14 '17 at 21:54
  • @Whirlwind I dont understand, what do you mean? Like the node in the code? should it be equal to the node on screen? – Balaach Jul 14 '17 at 21:58
  • 1
    Yes, you need to either check if node is your button or check all the nodes at the touch location to see if button is in it. If multiple nodes are overlaying each other, it will grab the node at the deepest branch of your tree ( do not confuse this with the highest z position) – Knight0fDragon Jul 14 '17 at 21:59
  • I dont know how you are doing your node, if you are subclassing then it is easy as (node as? MyNodeButton).pressedFunction() – Knight0fDragon Jul 14 '17 at 22:04