iPhone色つなぎ

同じ色の六角形を繋いで消して。という感じの色つなぎiPhoneアプリのサンプルコードを描いてみます。

動かすとこんな感じです

サンプルコード

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

#define hexsize 40

@interface ColorHexScene : SKScene

@property (nonatomic, strong) NSMutableArray *selectedNodes;

@property (nonatomic, strong) NSValue *touchPoint;

@end

@implementation ColorHexScene

– (void)didMoveToView:(SKView *)view

{

    [self createSceneContents];

}

– (void)createSceneContents

{

    self.backgroundColor = [self color:0];

    [self createWall];

    [self fill];

}

– (void)fill

{

    for (int j=0; j<6; j++) {

        

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

            float x = hexsize * i + 20;

            float y = 300 + j * 60;

            SKNode *hex = [self colorHex];

            [self addChild:hex];

            hex.position = CGPointMake(x, y);

        }

        

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

            float x = hexsize * i + 40;

            float y = 340 + j * 60;

            SKNode *hex = [self colorHex];

            [self addChild:hex];

            hex.position = CGPointMake(x, y);

        }

    }

}

– (SKNode*)colorHex

{

    float dAngle = M_PI / 3.0;

    float r = hexsize / 2.0;

    UIBezierPath *path = [UIBezierPath bezierPath];

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

        if (i == 0)

            [path moveToPoint:CGPointMake(r * cos(dAngle * i), r * sin(dAngle * i))];

        [path addLineToPoint:CGPointMake(r * cos(dAngle * i), r * sin(dAngle * i))];

    }

    [path closePath];

    

    SKShapeNode *node = [SKShapeNode node];

    node.name = @”hex”;

    node.path = path.CGPath;

    node.strokeColor = [self color:(arc4random() % 4) + 1];

    node.fillColor = node.strokeColor;

    

    node.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:path.CGPath];

    node.physicsBody.friction = 0;

    node.physicsBody.restitution = 0;

    

    return node;

}

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

{

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

    

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

        if ([node containsPoint:p]) {

            self.selectedNodes = [NSMutableArray array];

            [self.selectedNodes addObject:node];

        }

    }];

}

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

{

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

    self.touchPoint = [NSValue valueWithCGPoint:p];

    

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

        if ([node containsPoint:p]) {

            SKShapeNode *a= (SKShapeNode *)node;

            SKShapeNode *b = (SKShapeNode *)self.selectedNodes.lastObject;

            float distance = hypotf(a.position.x – b.position.x, a.position.y – b.position.y);

            if ([a.fillColor isEqual:b.fillColor]

                && ![self.selectedNodes containsObject:node]

                && distance < hexsize * 1.1) {

                [self.selectedNodes addObject:node];

            }

        }

    }];

}

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

{

    for (SKNode *n in self.selectedNodes) {

        [n removeFromParent];

    }

    self.selectedNodes = nil;

    self.touchPoint = nil;

}

– (void)didSimulatePhysics

{

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

    if (!annotationNode) {

        annotationNode = [SKShapeNode node];

        annotationNode.name = @”annotationNode”;

        annotationNode.strokeColor = [SKColor whiteColor];

        annotationNode.lineWidth = 2;

        [self addChild:annotationNode];

    }

    

    UIBezierPath *linePath = [UIBezierPath bezierPath];

    

    SKNode *previousNode = nil;

    for (SKNode *node in self.selectedNodes) {

        if (previousNode) {

            [linePath addLineToPoint:node.position];

        }

        [linePath appendPath:[UIBezierPath bezierPathWithArcCenter:node.position radius:4 startAngle:0 endAngle:2.0*M_PI clockwise:NO]];

        [linePath moveToPoint:node.position];

        

        previousNode = node;

    }

    

    if (self.touchPoint) {

        [linePath addLineToPoint:[self.touchPoint CGPointValue]];

    }

    

    

    annotationNode.path = linePath.CGPath;

}

– (void)createWall

{

    CGPoint p[] = {

        CGPointMake(CGRectGetMidX(self.frame), 0),

        CGPointMake(0, CGRectGetMidY(self.frame)),

        CGPointMake(CGRectGetMaxX(self.frame), CGRectGetMidY(self.frame)),

    };

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

        float w = i == 0 ? CGRectGetMaxX(self.frame) : 40;

        float h = i > 0 ? CGRectGetMaxY(self.frame) : 40;

        SKSpriteNode *wall = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:CGSizeMake(w, h)];

        wall.position = p[i];

        [self addChild:wall];

        

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

        wall.physicsBody.dynamic = NO;

    }

}

#define ColorHex(rgbValue) [SKColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:0.8]

– (SKColor*)color:(int)i

{

    switch (i) {

        case 0:

            return ColorHex(0xE8E9EE);

        case 1:

            return ColorHex(0xA5D7D0);

        case 2:

            return ColorHex(0xFBC987);

        case 3:

            return ColorHex(0xF09777);

        case 4:

            return ColorHex(0xDA5859);

        default:

            break;

    }

    return nil;

}

@end

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

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

    [self.view addSubview:spriteView];

    

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

    [spriteView presentScene:scene];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end