iPhoneびよびよView

Viewを引っ張るとびよびよするようなiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SpriteKit;

@interface ViewController () <SKSceneDelegate>

@property (nonatomic, weak) SKView *spriteView;

@property (nonatomic, weak) UIView *gumView;

@property (nonatomic, weak) SKNode *touched;

@property (nonatomic) CGPoint touchPoint;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    self.view.backgroundColor = [self color:0];

    

    [self createGumView];

}

– (void)createGumView {

    UIView *baseView = [[UIView alloc] initWithFrame:self.view.bounds];

    baseView.backgroundColor = [self color:1];

    baseView.center = CGPointMake(CGRectGetMidX(self.view.bounds), –CGRectGetMaxY(self.view.bounds) * 0.2);

    baseView.layer.masksToBounds = NO;

    [self.view addSubview:baseView];

    self.gumView = baseView;

    

    SKView *sv = [[SKView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.view.bounds) – 200, CGRectGetMaxX(self.view.bounds), 400)];

    sv.allowsTransparency = YES;

    [baseView addSubview:sv];

    SKScene *scene = [SKScene sceneWithSize:sv.frame.size];

    scene.backgroundColor = [UIColor clearColor];

    scene.physicsWorld.gravity = CGVectorMake(0, 0);

    scene.delegate = self;

    [sv presentScene:scene];

    self.spriteView = sv;

    

    

    float dx = CGRectGetMaxX(self.view.bounds) / 20.0;

    SKNode *previous = nil;

    for (int i=0; i<20; i++) {

        SKShapeNode *n = [SKShapeNode shapeNodeWithCircleOfRadius:dx/2.0];

        n.name = @”myobj”;

        n.fillColor = [[self color:2] colorWithAlphaComponent:0.5];

        n.strokeColor = [self color:4];

        n.position = CGPointMake((i + 0.5) * dx, 200);

        [scene addChild:n];

        n.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:dx/2.0];

        

        SKSpriteNode *anchorNode = [SKSpriteNode spriteNodeWithColor:[UIColor clearColor] size:CGSizeMake(1, 1)];

        anchorNode.position = CGPointMake(n.position.x, n.position.y + 100);

        [scene addChild:anchorNode];

        anchorNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:anchorNode.size];

        anchorNode.physicsBody.dynamic = NO;

        

        SKPhysicsJointSpring *sp = [SKPhysicsJointSpring jointWithBodyA:n.physicsBody bodyB:anchorNode.physicsBody anchorA:n.position anchorB:anchorNode.position];

        sp.frequency = 3;

        sp.damping = 0.1;

        [scene.physicsWorld addJoint:sp];

        

        if (previous) {

            SKPhysicsJointSpring *sp2 = [SKPhysicsJointSpring jointWithBodyA:n.physicsBody bodyB:previous.physicsBody anchorA:n.position anchorB:previous.position];

            [scene.physicsWorld addJoint:sp2];

        }

        

        // light (left) side -> stop

        if (i==0 || i==19) {

            n.name = @””;

            n.physicsBody.dynamic = NO;

        }

        

        previous = n;

    }

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    CGPoint p = [[touches anyObject] locationInNode:self.spriteView.scene];

    SKNode *node = [self.spriteView.scene nodeAtPoint:p];

    if ([node.name isEqual:@”myobj”]) {

        self.touched = node;

        node.physicsBody.dynamic = NO;

        self.touchPoint = [[touches anyObject] locationInView:self.view];

    }

}

– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

{

    CGPoint p = [[touches anyObject] locationInNode:self.spriteView.scene];

    if (self.touched) {

        self.touched.position = p;

        self.touchPoint = [[touches anyObject] locationInView:self.view];

    }

}

– (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

{

    if (self.touched) {

        self.touched.physicsBody.dynamic = YES;

        self.touched = nil;

    }

}

– (void)update:(NSTimeInterval)currentTime forScene:(SKScene *)scene

{

    __block float lasty = 0;

    [scene enumerateChildNodesWithName:@”myobj” usingBlock:^(SKNode *node, BOOL *stop) {

            lasty = node.position.y;

    }];

    CGPoint p = [scene.view convertPoint:CGPointMake(0, lasty) fromScene:scene];

    p = [self.view convertPoint:p fromView:scene.view];

    self.gumView.layer.position = CGPointMake(CGRectGetMidX(self.view.bounds), p.yCGRectGetMidY(self.view.bounds));

    

    if (self.touched) {

        CGPoint tp = [self.view convertPoint:self.touchPoint toView:scene.view];

        tp = [scene.view convertPoint:tp toScene:scene];

        self.touched.position = tp;

    }

}

#define ColorHex(rgb) [UIColor colorWithRed:((rgb & 0xFF0000) >> 16)/255.0 green:((rgb & 0xFF00) >> 8)/255.0 blue:(rgb & 0xFF)/255.0 alpha:1]

– (UIColor *)color:(int)i {

    switch (i) {

        case 0: return ColorHex(0xFF5335);

        case 1: return ColorHex(0xB29C85);

        case 2: return ColorHex(0x306E73);

        case 3: return ColorHex(0x3B424C);

        case 4: return ColorHex(0x1D181F);

    }

    return nil;

}

@end