梯子積み

iPhone梯子

梯子を積み上げてあそぶiPhoneアプリのサンプルを描いてみます。

動かすとこんな感じです

サンプルコード

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

@interface LadderScene : SKScene

@property (nonatomic, strong) NSValue *touched;

@end

@implementation LadderScene

– (void)didMoveToView:(SKView *)view

{

    [self createGround];

    [self createLadderStartPoint:CGPointMake(CGRectGetMidX(self.frame), 0) endPoint:CGPointMake(CGRectGetMidX(self.frame), 100)];

}

– (void)createGround

{

    SKSpriteNode *ground = [SKSpriteNode spriteNodeWithColor:[SKColor brownColor] size:CGSizeMake(320, 30)];

    ground.position = CGPointMake(160, 15);

    [self addChild:ground];

    

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

    ground.physicsBody.dynamic = NO;

}

– (void)createLadderStartPoint:(CGPoint)start endPoint:(CGPoint)end

{

    float hue = arc4random() % 10 * 0.1;

    SKColor *color = [SKColor colorWithHue:hue saturation:0.5 brightness:1.0 alpha:1.0];

    

    UIBezierPath *linePath = [UIBezierPath bezierPath];

    [linePath moveToPoint:start];

    [linePath addLineToPoint:end];

    

    UIBezierPath *barPath = [UIBezierPath bezierPath];

    float dx = end.x – start.x;

    float dy = end.y – start.y;

    float distance= hypotf(dx, dy);

    CGVector normal = CGVectorMake(dy/distance, -dx/distance);

    

    float c = 14.0;

    CGPoint pa = CGPointMake(start.x + c * normal.dx, start.y + c * normal.dy);

    CGPoint pb = CGPointMake(end.x + c * normal.dx, end.y + c * normal.dy);

    CGPoint pc = CGPointMake(start.x – c * normal.dx, start.y – c * normal.dy);

    CGPoint pd = CGPointMake(end.x – c * normal.dx, end.y – c * normal.dy);

    [barPath moveToPoint:pa];

    [barPath addLineToPoint:pb];

    [barPath moveToPoint:pc];

    [barPath addLineToPoint:pd];

    

    SKShapeNode *bar = [SKShapeNode node];

    bar.path = barPath.CGPath;

    bar.lineWidth = 2;

    bar.strokeColor = color;

    [self addChild:bar];

    

    UIBezierPath *physicsPath = [UIBezierPath bezierPath];

    [physicsPath moveToPoint:pa];

    [physicsPath addLineToPoint:pb];

    [physicsPath addLineToPoint:pd];

    [physicsPath addLineToPoint:pc];

    [physicsPath closePath];

    bar.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:physicsPath.CGPath];

    

    SKShapeNode *dot = [SKShapeNode node];

    dot.lineWidth=30;

    CGFloat pattern[2]; pattern[0]=2; pattern[1]=20;

    // SKShapeNode dash path

    dot.path = CGPathCreateCopyByDashingPath(linePath.CGPath, NULL, 2, pattern, 2);

    dot.strokeColor = color;

    [bar addChild:dot];

}

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

{

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

    self.touched = [NSValue valueWithCGPoint:p];

}

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

{

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

    

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

    if (!guide) {

        guide = [SKShapeNode node];

        guide.name = @”guide”;

        guide.lineWidth=3;

        guide.strokeColor = [SKColor whiteColor];

        [self addChild:guide];

    }

    

    UIBezierPath *linePath = [UIBezierPath bezierPath];

    [linePath moveToPoint:[self.touched CGPointValue]];

    [linePath addLineToPoint:p];

    CGFloat pattern[2]; pattern[0]=5; pattern[1]=10;

    guide.path = CGPathCreateCopyByDashingPath(linePath.CGPath, NULL, 0, pattern, 2);

}

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

{

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

    [self createLadderStartPoint:[self.touched CGPointValue] endPoint:p];

    self.touched = nil;

    

    SKNode *guide = [self childNodeWithName:@”guide”];

    SKAction *fade = [SKAction fadeOutWithDuration:0.5];

    [guide runAction:fade completion:^{

        [guide 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 = [[LadderScene alloc] initWithSize:spriteView.frame.size];

    [spriteView presentScene:scene];

}

@end