回転している三角にボールをぶつけて跳ね返すiPhoneアプリのサンプルコードです。
動かすとこんな感じ
サンプルコード
#import “ViewController.h”
#import <SpriteKit/SpriteKit.h>
#define StartPoint CGPointMake(CGRectGetMidX(self.frame), 120)
@interface ReflectScene : SKScene
@property BOOL contentCreated;
@property (weak, nonatomic) SKNode *selected;
@property (weak, nonatomic) SKShapeNode *sling;
@end
@implementation ReflectScene
– (void)didMoveToView:(SKView *)view
{
if (!self.contentCreated) {
[self createSceneContents];
self.contentCreated = YES;
}
}
– (void)createSceneContents
{
self.physicsWorld.gravity = CGVectorMake(0, 0);
[self setupBaseBody];
[self createReflector];
[self createCatapult];
[self createWall];
[self createBall];
}
– (void)setupBaseBody
{
self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.size];
self.physicsBody.categoryBitMask = 0x2;
self.physicsBody.collisionBitMask = 0x2;
self.physicsBody.dynamic = NO;
}
– (void)createReflector
{
UIBezierPath *path = [UIBezierPath bezierPath];
float r = 80;
float angle[] = {0, 2.0 * M_PI/3.0, 4.0 * M_PI/3.0};
[path moveToPoint:CGPointMake(r * cos(angle[0]), r * sin(angle[0]))];
[path addLineToPoint:CGPointMake(r * cos(angle[1]), r * sin(angle[1]))];
[path addLineToPoint:CGPointMake(r * cos(angle[2]), r * sin(angle[2]))];
[path closePath];
SKShapeNode *reflector = [SKShapeNode node];
reflector.name = @”reflector”;
reflector.fillColor = [SKColor whiteColor];
reflector.path = path.CGPath;
reflector.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMaxY(self.frame)-40);
[self addChild:reflector];
reflector.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:path.CGPath];
reflector.physicsBody.categoryBitMask = 0x1;
reflector.physicsBody.collisionBitMask = 0x1;
SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:reflector.physicsBody bodyB:self.physicsBody anchor:reflector.position];
[self.physicsWorld addJoint:pin];
}
– (void)createCatapult
{
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(-25, 30)];
[path addLineToPoint:CGPointMake(0, 10)];
[path addLineToPoint:CGPointMake(25, 30)];
[path moveToPoint:CGPointMake(0, 10)];
[path addLineToPoint:CGPointMake(0, –30)];
SKShapeNode *catapult = [SKShapeNode node];
catapult.position = CGPointMake(CGRectGetMidX(self.frame), 80);
catapult.path = path.CGPath;
[self addChild:catapult];
}
– (void)createWall
{
float p[] = {50, 300, 270, 300};
for (int i=0; i<2; i++) {
SKSpriteNode *wall = [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] size:CGSizeMake(100, 10)];
wall.position = CGPointMake(p[2 * i], p[2 * i + 1]);
[self addChild:wall];
wall.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:wall.size];
wall.physicsBody.dynamic = NO;
}
}
– (void)createBall
{
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-15, –15, 30, 30)];
SKShapeNode *ball = [SKShapeNode node];
ball.name = @”ball”;
ball.path = path.CGPath;
ball.position = StartPoint;
ball.fillColor = [SKColor whiteColor];
[self addChild:ball];
ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:15];
ball.physicsBody.categoryBitMask = 0x1;
ball.physicsBody.collisionBitMask = 0x1;
ball.physicsBody.restitution = 1.0;
ball.physicsBody.dynamic = NO;
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self];
SKNode *node = [self childNodeWithName:@”ball”];
if ([node containsPoint:p]) {
self.selected = node;
}
}
– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
self.selected.position = [[touches anyObject] locationInNode:self];
}
– (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (self.selected) {
CGPoint p = [[touches anyObject] locationInNode:self];
CGVector v = CGVectorMake((StartPoint.x – p.x) / 10.0, (StartPoint.y – p.y) / 10.0);
self.selected.name = @”ball0″;
self.selected.physicsBody.dynamic = YES;
[self.selected.physicsBody applyImpulse:v];
self.selected = nil;
[self performSelector:@selector(createBall) withObject:nil afterDelay:0.5];
}
}
– (void)update:(NSTimeInterval)currentTime
{
SKNode *reflecor = [self childNodeWithName:@”reflector”];
reflecor.physicsBody.angularVelocity = 1;
}
– (void)didSimulatePhysics
{
if (!self.sling) {
SKShapeNode *s = [SKShapeNode node];
s.strokeColor = [SKColor lightGrayColor];
[self addChild:s];
self.sling = s;
}
if (self.selected) {
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(StartPoint.x – 22, StartPoint.y – 5)];
[path addLineToPoint:self.selected.position];
[path moveToPoint:CGPointMake(StartPoint.x + 22, StartPoint.y – 5)];
[path addLineToPoint:self.selected.position];
self.sling.path = path.CGPath;
} else {
self.sling.path = nil;
}
[self enumerateChildNodesWithName:@”ball0″ usingBlock:^(SKNode *node, BOOL *stop) {
if (![self containsPoint:node.position]) {
[node removeFromParent];
}
}];
}
@end
@interface ViewController ()
@end
@implementation ViewController
– (void)viewDidAppear:(BOOL)animated
{
SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:spriteView];
SKScene *scene = [[ReflectScene alloc] initWithSize:spriteView.frame.size];
[spriteView presentScene:scene];
}
@end