Last active
January 23, 2017 04:45
-
-
Save densmoe/7fb22ef64f7a142d4050 to your computer and use it in GitHub Desktop.
[Swift/SpriteKit] Game demo with multiple touch panning gestures
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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