Skip to content

Instantly share code, notes, and snippets.

@densmoe
Last active January 23, 2017 04:45
Show Gist options
  • Save densmoe/7fb22ef64f7a142d4050 to your computer and use it in GitHub Desktop.
Save densmoe/7fb22ef64f7a142d4050 to your computer and use it in GitHub Desktop.
[Swift/SpriteKit] Game demo with multiple touch panning gestures
//http://stackoverflow.com/questions/31928324/how-to-drag-a-skspritenode-without-touching-it-with-swift/31930669?noredirect=1#comment51852474_31930669
import SpriteKit
class GameScene: SKScene {
var leftShape:ConfinedShape!
var rightShape:ConfinedShape!
override func didMoveToView(view: SKView) {
let radius:CGFloat = 15.0
let halfFrameSize = CGSizeMake(frame.width / 2, frame.height)
//creates the shapes to be moved
leftShape = ConfinedShape(circleOfRadius: radius)
leftShape.position = CGPointMake(frame.width / 4, frame.midY)
leftShape.strokeColor = UIColor.blueColor()
leftShape.bounds = CGRect(origin: CGPointZero, size: halfFrameSize)
leftShape.zPosition = 1
addChild(leftShape)
rightShape = ConfinedShape(circleOfRadius: radius)
rightShape.position = CGPointMake(frame.width * 3 / 4, frame.midY)
rightShape.strokeColor = UIColor.redColor()
rightShape.bounds = CGRect(origin: CGPointMake(frame.midX, frame.minY), size: halfFrameSize)
rightShape.zPosition = 1
addChild(rightShape)
let leftBoundsRect = SKShapeNode(rect: leftShape.bounds) //indicates touch area for left node
leftBoundsRect.fillColor = leftShape.strokeColor
leftBoundsRect.alpha = 0.1
addChild(leftBoundsRect)
let rightBoundsRect = SKShapeNode(rect: rightShape.bounds)
rightBoundsRect.fillColor = rightShape.strokeColor
rightBoundsRect.alpha = 0.1
addChild(rightBoundsRect)
//sets up gesture recognizer
let pan = UIPanGestureRecognizer(target: self, action: "panned:")
pan.maximumNumberOfTouches = 1
//view.addGestureRecognizer(pan)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch in touches {
if let touch = touch as? UITouch {
let location = touch.locationInNode(self) //gets touchlocation within the scene
//detects touch within bounds & makes sure that shape is not already selected / associated with touch
if leftShape.bounds.contains(location) && leftShape.associatedTouchID == nil {
leftShape.associatedTouchID = touch.hashValue //hashvalue = unique identifier of touch
} else if rightShape.bounds.contains(location) && rightShape.associatedTouchID == nil {
rightShape.associatedTouchID = touch.hashValue
}
}
}
}
override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch in touches {
if let touch = touch as? UITouch {
let translate = touch.locationInNode(self) - touch.previousLocationInNode(self) //calculate delta x and delta y of finger
if leftShape.associatedTouchID == touch.hashValue {
leftShape.setPositionWithinBounds(leftShape.position + CGPointMake(translate.x, 0)) //assign new position to shape
leftShape.fillColor = leftShape.strokeColor //simple animation to indicate touch in progress
} else if rightShape.associatedTouchID == touch.hashValue {
rightShape.setPositionWithinBounds(rightShape.position + CGPointMake(translate.x, 0))
rightShape.fillColor = rightShape.strokeColor
}
}
}
}
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch in touches {
if let touch = touch as? UITouch {
let translate = touch.locationInNode(self) - touch.previousLocationInNode(self)
if leftShape.associatedTouchID == touch.hashValue {
leftShape.associatedTouchID = nil //when touch has ended, delete association with it from node
leftShape.fillColor = SKColor.clearColor()
} else if rightShape.associatedTouchID == touch.hashValue {
rightShape.associatedTouchID = nil
rightShape.fillColor = SKColor.clearColor()
}
}
}
}
}
class ConfinedShape:SKShapeNode {
var associatedTouchID:Int?
var bounds:CGRect!
func setPositionWithinBounds (pos:CGPoint) {
if let bounds = bounds { //unwrap optional
let radius = self.frame.width / 2
if CGRectInset(bounds, radius, 0).contains(pos) { //check if new position is within bounds, taking radius into account
self.position = pos //assign new pos
}
}
}
}
//handy little helper functions to easily add up CGPoints coordinates
func +(lhs:CGPoint, rhs:CGPoint) -> CGPoint {
return CGPointMake(lhs.x + rhs.x, lhs.y + rhs.y)
}
func -(lhs:CGPoint, rhs:CGPoint) -> CGPoint {
return CGPointMake(lhs.x - rhs.x, lhs.y - rhs.y)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment