Swift Button acts like a sensor when finger passes on - ios

I'm trying to make an app something like this but i couldn't find out how to do it. i have tried many things but it didn't work or i couldn't make it work since i'm very new on swift.
this is the video reference: https://youtu.be/6cCV_YsbUq0?t=2s
Thanks for your time

i am not sure , but you can try with x and y position of screen touched, to find x and y position follow this code.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let position = touch.location(in: self.view)
print(position.x)
print(position.y)
}
}

Related

SpriteKit: How to make touchesBegan work for node not on the highest zPosition

I am making a SpriteKit game that has a button node that is at the highest zPosition. I am overriding the touchesBegan function to add functionality to the button. It works because that button is at the highest position in the z dimension. The .zPosition is set to the highest amount compared to any other nodes. I need to have another button in the scene but it needs to have a lower .zPosition because it needs to be covered by another node at one point. When I have a .zPosition that is lower than another node, the touchesBegan method does not trigger. It works if I have a higher .zPosition but that makes the other button node not work. How can I make the touchesBegan method work regardless of what the .zPosition is? Please ask me for more clarification. Thanks!
Once you get the point in touchesBegan did you try to test if the button node contains the point :
func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) -> Bool {
if touches.count == 1 {
if let touch = touches.first {
let location = touch.location(in: self)
if myButtonNode.contains(location) {
...
You want to use the nodes(at:) method. This is an array of all nodes at a particular point, the point being where you touch.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches {
let location = t.location(in: self)
let touchedNodes = self.nodes(at: location) // Array of all nodes at the point
for node in touchedNodes { // Iterate through all nodes in the touchedNode array
if node.name == "your button node" {
... // Add your button code here
}
}
}
}

Defining my spaceship movement in spritekit game in Swift

Hi I am new to Xcode and Swift, right now I am trying to design a game that involves a spaceship as player with alien spaceships.
I ran into a little problem where I am trying to differentiate the movement of the spaceship from the firing of the spaceship.
Basically I used touchesBegan() function to run the function which my spaceship fires, and touchesMoved() function to move the spaceship's x-position.
These are the code:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
pShoot()
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches{
let location = touch.location(in: self)
spaceship.run(SKAction.moveTo(x: location.x, duration: 0.5))
}
}
What I am trying to do is to differentiate the clicking or touching indicator and pressed and move indicator, in other words I dont want the spaceship to fire when I am pressed and move on the screen, and I do not want the spaceship to move when I am clicking constantly but at different position. ( touchesMoved() detects changes in touch positions so if I am clicking at different positions spaceship will move which I dont want)
I would like to know what would be the best way of implementing this, thank you.
You could try checking the area that the user pressed and deciding whether or not to move the spaceship depending on the origin of the touch.

How to replicate iOS home screen behaviour?

I am currently working on a game in SpriteKit, where I need to move a sprite in response to touch (i.e when user swipes or pans anywhere in SKView.
I want to get the direction of pan (for swipe I know how to do it),so that the sprite will move according to pan (I have a path defined for the sprite if user pans or according to swipe if user swipes), the way touch in iOS appdrawer works i.e it responds to slightest of swipes and also pans (i.e when you pan forwards or backwards, it makes a decision whether you want to move to the next screen or not).
Is there any documentation or so? (I have gone through the UIGestureRecognizer documentation, but I haven't been able to find a way to implement it.)
I use something similar on my MenuScene, I have 3 pages setup that the user can scroll through to get various game data. But I don't want the slightest touch to move the screen, it would be to jarring for the user. So I just watch the finger movements in the Touches functions and check if the movement is greater that an amount I designate as the minimum move amount and if it is greater than I scroll the page. In your case you could handle it as; if it is greater than the minimum move amount treat as a pan else treat it as a swipe
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch: UITouch = touches.first!
initialTouch = touch.location(in: self.view!)
moveAmtY = 0
moveAmtX = 0
initialPosition = menuScroller.position
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch: UITouch = touches.first!
let movingPoint: CGPoint = touch.location(in: self.view!)
moveAmtX = movingPoint.x - initialTouch.x
moveAmtY = movingPoint.y - initialTouch.y
//their finger is on the page and is moving around just move the scroller and parallax backgrounds around with them
//Check if it needs to scroll to the next page when they release their finger
menuScroller.position = CGPoint(x: initialPosition.x + moveAmtX, y: initialPosition.y)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
//they havent moved far enough so just reset the page to the original position
if fabs(moveAmtX) > 0 && fabs(moveAmtX) < minimum_detect_distance {
resetPages()
}
//the user has swiped past the designated distance, so assume that they want the page to scroll
if moveAmtX < -minimum_detect_distance {
moveLeft()
}
else if moveAmtX > minimum_detect_distance {
moveRight()
}
}

Swift, Spritekit Rotating sprites swift 3

I am trying to rotate a sprite using swift, IOS 10 and the touchesmoved function, the code I have works in the fact it moves the sprite but in not the right way, the wrong directions etc.
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
guard let touch=touches.first{
return
}
let touchLocation = touch.location(in: self)
self.zRotation=CGFloat(atan2(Double(touchLocation.y), Double(touchLocation.x)))
}
does anyone know the correct way to rotate a sprite using zRotation and touchesMoved?
Thank you
I think you've probably overlooked the wonderful power of constraints in SpriteKit. Easy enough to do, Apple does a terrible job of promoting, presenting and educating those considering using SpriteKit.
Constraints allow you to say "go here", or "look at this".
In your case, the "look at this" is ideal, from the docs:
Orientation Constraints
A common use for orientation constraints is to make a look-at
constraint. For example, you may create a look-at constraint to make a
pair of eyes follow a moving object or to have a rocket point in the
direction of its target.
More specifically, you can use these in your touchesMoved:
https://developer.apple.com/reference/spritekit/skconstraint/1519627-orient
thanks for all the suggestions. Yes my explanation of the problem was not too great. so will add the full code here and it seems to be working apart from occasionally moving by 90 degrees on its own when i stop dragging and start dragging again
What I was trying to do was rotate a sprite around another sprite for example a cannon barrel around its wheel... When the wheel is loaded from the scene it calls this class and adds a child node (the barrel) which should be able to be moved around its wheel
import SpriteKit
class WheelNode: SKSpriteNode, CustomNodeEvent{
private var tubeNode=SKSpriteNode(imageNamed: "cannon-barrel")
var previousPoint:CGPoint!
var touchLocation:CGPoint!
func didMoveToScene() {
guard let scene=scene else{
return
}
isUserInteractionEnabled=true
tubeNode.anchorPoint=CGPoint(x:0, y:0)
tubeNode.position=position
self.addChild(tubeNode)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch=touches.first{
previousPoint=touch.location(in: scene!)
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
if let touch=touches.first{
touchLocation=touch.location(in: scene!)
var angle=atan2(touchLocation.y-previousPoint.y, touchLocation.x-previousPoint.x)
self.zRotation=angle
}
}
}

SKLabelNode will disappear but is still clickable

I am making a game using SpriteKit and Swift, running Xcode 6. I have an SKLabelNode, let's call it myLabelNode for this example. When I call myLabelNode.removeFromParent() it removes the node from the scene, as it should. The node count drops by 1, and it isn't visible anywhere on the screen. However, when I click the spot where myLabelNode previously was, my program will still call out the function that should only happen when myLabelNode is touched. I also tried combining myLabelNode.removeFromParent() with myLabelNode.hidden = true, but it is still touchable, and calls the function even though it shouldn't. How should I fix this? Is there a different method I should be using? Is this supposed to happen?
Edit:
let lemonadeLabel = SKLabelNode(fontNamed: "Optima-ExtraBlack")
override func didMoveToView(view: SKView) {
lemonadeLabel.text = "Lemonade Stand"
lemonadeLabel.fontSize = 24
lemonadeLabel.fontColor = SKColor.yellowColor()
lemonadeLabel.position = CGPoint(x: size.width/2, y: size.height*0.66)
lemonadeLabel.zPosition = 2.0
addChild(lemonadeLabel)
}
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
let touch = touches.anyObject() as UITouch
let location = touch.locationInNode(self)
if lemonadeLabel.containsPoint(location) {
println("lemonadeLabel pressed")
lemonadeLabel.removeFromParent()
/*lemonadeLabel is now be removed,
however if I click the area where it
used to be, "lemonadeLabel pressed"
will print to the console*/
}
}
You are trying to determine if the constrainPoints' location are being touched. Even if you remove the label from the scene, it is still an object in memory, i.e: you could re-ad it later.. it still has all it's properties including position, etc..
I would try this instead:
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
for touch: AnyObject in touches {
if nodeAtPoint(touch.locationInNode(self)) == lemonadeLabel {
println("lemonadeLabel pressed")
lemonadeLabel.removeFromParent()
}
}
}
You basically determine if the lemonadeLabel is the node at that position, if yes you remove it. Since you compare with the added node in the scene, if it's gone, it will not be there for comparison ;)
Your labelNode may not be inside the SKScene anymore. This does not mean that it will not respond to the containsPoint function. The labelNode still has a position assigned to it and it can calculate if a point falls inside it using containsPoint function.
Instead you can try this.
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
let touch = touches.anyObject() as UITouch
let location = touch.locationInNode(self)
if self.nodeAtPoint(location) === lemonadeLabel {
println("lemonadeLabel pressed")
lemonadeLabel.removeFromParent()
}
}

Resources