iPhone回転タンク

頭をくるくる回転させて弾を打ち出すiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

@interface TankScene : SKScene

@property (nonatomic) CGPoint touchPoint;

@property (nonatomic) int turnHead;

@property (nonatomic, strong) NSMutableArray *timer;

@end

@implementation TankScene

– (void)didMoveToView:(SKView *)view

{

    self.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1];

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

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

    [self createTank];

    [self createTurnButton];

    

    self.timer = [NSMutableArray array];

}

– (void)createTank

{

    SKNode *tank = [SKNode node];

    tank.name = @”tank”;

    tank.position = CGPointMake(160, 80);

    [self addChild:tank];

    

    SKSpriteNode *body = [SKSpriteNode spriteNodeWithColor:[SKColor colorWithRed:0 green:0.4 blue:0 alpha:1] size:CGSizeMake(80, 48)];

    [tank addChild:body];

    

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

        SKSpriteNode *tire = [SKSpriteNode spriteNodeWithColor:[SKColor darkGrayColor] size:CGSizeMake(85, 15)];

        tire.position = CGPointMake(0, i ? –33 : 33);

        [tank addChild:tire];

    }

    

    SKNode *head = [SKNode node];

    head.name = @”head”;

    [tank addChild:head];

    

    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:30 startAngle:0 endAngle:2.0*M_PI clockwise:NO];

    SKShapeNode *circle = [SKShapeNode node];

    circle.path = path.CGPath;

    circle.fillColor = [UIColor colorWithRed:0 green:0.6 blue:0 alpha:1];

    [head addChild:circle];

    

    SKSpriteNode *port = [SKSpriteNode spriteNodeWithColor:[SKColor colorWithRed:0 green:0.6 blue:0 alpha:1] size:CGSizeMake(15, 40)];

    port.position = CGPointMake(0, 40);

    [head addChild:port];

    

    tank.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:body.size];

}

– (void)createTurnButton

{

    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:70 startAngle:0 endAngle:2.0 * M_PI clockwise:NO];

    SKShapeNode *btn = [SKShapeNode node];

    btn.position = CGPointMake(320, 0);

    btn.fillColor = [SKColor colorWithRed:0.3 green:0.6 blue:0.6 alpha:1];

    btn.path = path.CGPath;

    [self addChild:btn];

    btn.name = @”turn”;

}

– (void)tick

{

    int count = self.timer.count;

    if (count > 60) {

        [self.timer enumerateObjectsUsingBlock:^(SKNode *n, NSUInteger idx, BOOL *stop) {

            [n removeFromParent];

        }];

        

        [self shoot];

        [self.timer removeAllObjects];

    } else {

        SKSpriteNode *n = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(30, 5)];

        n.position = CGPointMake(300, 100 + 5 * count);

        [self addChild:n];

        [self.timer addObject:n];

    }

}

– (void)shoot

{

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

    SKNode *head = [tank childNodeWithName:@”head”];

    

    SKSpriteNode *ball = [SKSpriteNode spriteNodeWithColor:[UIColor blackColor] size:CGSizeMake(10, 10)];

    float angle = head.zRotation + M_PI * 0.5;

    float x = tank.position.x + 70 * cos(angle);

    float y = tank.position.y + 70 * sin(angle);

    ball.position = CGPointMake(x, y);

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

    [self addChild:ball];

    

    [ball.physicsBody applyImpulse:CGVectorMake(cos(angle), sin(angle))];

}

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

{

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

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

    if ([btn containsPoint:p]) {

        btn.alpha = (btn.alpha == 1.0) ? 0.7 : 1.0;

        self.turnHead = (self.turnHead + 1) % 4;

        return;

    }

    

    self.touchPoint = p;

}

– (void)update:(NSTimeInterval)currentTime

{

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

    float dx = tank.position.xself.touchPoint.x;

    if (dx != 0 && !CGPointEqualToPoint(self.touchPoint, CGPointZero)) {

        tank.physicsBody.velocity = CGVectorMake(dx > 0 ? –10 : 10, 0);

    }

    

    SKNode *head = [tank childNodeWithName:@”head”];

    if (self.turnHead % 2 == 1) {

        head.zRotation += (self.turnHead==1) ? 0.01 : –0.01;

    }

    

    [self tick];

}

@end

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

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

    [self.view addSubview:spriteView];

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

    [spriteView presentScene:scene];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end