Created
May 4, 2014 04:28
-
-
Save aclissold/6f90bf2f3deae8d65820 to your computer and use it in GitHub Desktop.
Simple SpriteKit Slingshot
This file contains 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
// | |
// SlingScene.m | |
// | |
// Demonstrates a simple slingshot mechanism. | |
// | |
// Created by Andrew Clissold on 5/3/14. | |
// Copyright (c) 2014 Andrew Clissold. All rights reserved. | |
// | |
/* Contents of SlingScene.h: | |
#import <SpriteKit/SpriteKit.h> | |
@interface SlingScene : SKScene | |
@end */ | |
#import "SlingScene.h" | |
@interface SlingScene () | |
@property (nonatomic, strong) SKAction *slingAction; | |
@end | |
@implementation SlingScene | |
- (instancetype)initWithSize:(CGSize)size { | |
self = [super initWithSize:size]; | |
if (self) { | |
CGPoint center = CGPointMake(self.size.width/2.0, self.size.height/2.0); | |
self.slingAction = [SKAction sequence: | |
@[[SKAction waitForDuration:0.1], | |
[SKAction runBlock: | |
^{ | |
[self.physicsWorld removeAllJoints]; | |
} | |
]]]; | |
// Create a square, which will be slung by the spring | |
SKSpriteNode *square = | |
[SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] | |
size:CGSizeMake(60.0, 60.0)]; | |
square.position = CGPointMake(center.x, center.y - 2*square.size.height); | |
square.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:square.size]; | |
square.physicsBody.collisionBitMask = 0; | |
square.name = @"square"; | |
// Create a post to anchor the square to | |
SKShapeNode *post = [SKShapeNode node]; | |
post.path = CGPathCreateWithEllipseInRect( | |
CGRectMake(0.0, 0.0, 60.0, 60.0), NULL); | |
post.fillColor = [SKColor brownColor]; | |
post.strokeColor = [SKColor brownColor]; | |
post.position = CGPointMake(center.x-30.0, center.y-30.0); | |
post.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:60.0 center:center]; | |
// Give the post a near-infinite mass so the square won't tug at it | |
// and move it around | |
post.physicsBody.mass = 1000000; | |
post.physicsBody.affectedByGravity = NO; | |
// Set their collision bit masks to the same value to allow them to pass | |
// through each other | |
post.physicsBody.collisionBitMask = 0; | |
square.physicsBody.collisionBitMask = 0; | |
// Add them to the scene | |
[self addChild:post]; | |
[self addChild:square]; | |
// Connect them via a spring | |
SKPhysicsJointSpring *spring = | |
[SKPhysicsJointSpring jointWithBodyA:post.physicsBody | |
bodyB:square.physicsBody | |
anchorA:center | |
anchorB:square.position]; | |
spring.damping = 0.4; | |
spring.frequency = 1.0; | |
[self.physicsWorld addJoint:spring]; | |
// Lower gravity from default {0.0, -9.8} to allow the | |
// square to be slung farther | |
self.physicsWorld.gravity = CGVectorMake(0.0, -4.0); | |
} | |
return self; | |
} | |
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { | |
// Move the square to the touch position | |
SKSpriteNode *square = (SKSpriteNode *)[self childNodeWithName:@"square"]; | |
CGPoint location = [[touches anyObject] locationInNode:self]; | |
[square runAction:[SKAction moveTo:location duration:0.1]]; | |
} | |
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { | |
// Sling the square by | |
// 1. allowing the spring to accelerate it, and | |
// 2. removing the spring altogether | |
[self runAction:self.slingAction]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This can easily be played around with in an existing SpriteKit app: