iPhone繋ぐ隣

一番近い四角を線でコネクトするiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

@interface NearScene : SKScene

@property (nonatomic, strong) NSMutableArray *blocks;

@end

@implementation NearScene

– (void)didMoveToView:(SKView *)view

{

    self.physicsWorld.gravity = CGVectorMake(0, –0.02);

    [self createWall];

    [self createButton];

    [self createBlocks];

    [self createLineCanvas];

}

– (void)createWall

{

    self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];

}

– (void)createBlocks

{

    self.blocks = [NSMutableArray array];

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

        SKSpriteNode *b = [SKSpriteNode spriteNodeWithColor:[SKColor colorWithHue:i * 0.1 saturation:0.6 brightness:0.9 alpha:1] size:CGSizeMake(30, 30)];

        b.name = @”block”;

        

        float x = (i % 3) * 80 + 80;

        float y = (i / 3) * 100 + 160;

        b.position = CGPointMake(x, y);

        [self addChild:b];

        

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

        b.physicsBody.restitution = 0.9;

        

        [self.blocks addObject:b];

    }

}

– (void)createLineCanvas

{

    SKShapeNode *n = [SKShapeNode node];

    n.name = @”canvas”;

    n.fillColor = [SKColor clearColor];

    n.strokeColor = [[SKColor whiteColor] colorWithAlphaComponent:0.7];

    n.lineWidth = 2;

    [self addChild:n];

}

– (void)update:(NSTimeInterval)currentTime

{

    UIBezierPath *path = [UIBezierPath bezierPath];

    for (SKNode *b0 in self.blocks) {

        float min = HUGE_VAL;

        SKNode *nearest;

        for (SKNode *b1 in self.blocks) {

            if (b1 == b0)

                continue;

            

            float r = hypotf(b0.position.x – b1.position.x, b0.position.y – b1.position.y);

            if (r < min) {

                nearest = b1;

                min = r;

            }

        }

        

        [path moveToPoint:b0.position];

        [path addLineToPoint:nearest.position];

    }

    

    SKShapeNode *canvas = (SKShapeNode *)[self childNodeWithName:@”canvas”];

    canvas.path = path.CGPath;

}

– (void)createButton

{

    SKSpriteNode *btn = [SKSpriteNode spriteNodeWithColor:[SKColor lightGrayColor] size:CGSizeMake(100, 50)];

    btn.position = CGPointMake(160, 25);

    btn.name = @”button”;

    [self addChild:btn];

    

    SKLabelNode *title = [SKLabelNode node];

    title.text = @”touch”;

    title.position = CGPointMake(0, –10);

    [btn addChild:title];

}

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

{

    CGPoint p = [[touches anyObject] locationInNode:self];

    SKNode *btn = [self childNodeWithName:@”button”];

    if ([btn containsPoint:p]) {

        for (SKNode *b in self.blocks) {

            float vx = (arc4random()) % 40 * 0.12;

            float vy = (arc4random()) % 20 * 0.1;

            [b.physicsBody applyImpulse:CGVectorMake(vx, vy)];

        }

    }

}

@end

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];

    [self.view addSubview:spriteView];

    SKScene *scene = [[NearScene alloc] initWithSize:spriteView.frame.size];

    [spriteView presentScene:scene];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end