iPhone三角跳ね返り

回転している三角にボールをぶつけて跳ね返す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.x22, StartPoint.y5)];

        [path addLineToPoint:self.selected.position];

        [path moveToPoint:CGPointMake(StartPoint.x + 22, StartPoint.y5)];

        [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