iPhone マップ9

画面の端まできたらマップ切り替えるようなiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SpriteKit;

@interface ViewController () <SKSceneDelegate>

@property (nonatomic, weak) SKScene *scene;

@property (nonatomic, strong) NSMutableArray *maps;

@property (nonatomic) int mapNo;

@property (nonatomic, weak) SKNode *currentMap;

@property (nonatomic) NSInteger direction;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor blackColor];

    

    [self setup];

    [self initMaps];

    self.direction = –1;

    [self showMap:self.mapNo direction:0];

    [self createPlayer];

    [self createButtons];

}

– (void)setup

{

    

    float w = CGRectGetMaxX(self.view.bounds);

    SKView *spriteView = [[SKView alloc] initWithFrame:CGRectMake(0, 0, w, w)];

    spriteView.center = CGPointMake(CGRectGetMidX(self.view.frame), CGRectGetMidY(self.view.frame));

    [self.view addSubview:spriteView];

    

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

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

    scene.backgroundColor = [UIColor colorWithRed:0.8 green:0.5 blue:0 alpha:1];

    scene.delegate = self;

    [spriteView presentScene:scene];

    

    self.scene = scene;

}

– (void)initMaps

{

    self.maps = [NSMutableArray array];

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

        NSMutableArray *points = [NSMutableArray array];

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

            int x = arc4random() % 7 + 2;

            int y = arc4random() % 7 + 2;

            [points addObject:[NSValue valueWithCGPoint:CGPointMake(x, y)]];

        }

        [self.maps addObject:points];

    }

    

    self.mapNo = 4;

}

– (void)showMap:(int)no direction:(int)direction

{

    float w = CGRectGetMaxX(self.view.frame);

    float bw = w / 10.0;

    

    SKNode *map = [SKNode node];

    [self.scene addChild:map];

    for (NSValue *p in self.maps[self.mapNo]) {

        SKSpriteNode *block = [SKSpriteNode spriteNodeWithColor:[SKColor brownColor] size:CGSizeMake(40, 40)];

        block.position = CGPointMake(p.CGPointValue.x * bw, p.CGPointValue.y * bw);

        [map addChild:block];

        

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

        block.physicsBody.dynamic = NO;

    }

    

    CGPoint move = CGPointZero;

    CGPoint playerMove = CGPointZero;

    SKNode *player = [self.scene childNodeWithName:@”player”];

    switch (direction) {

        case 1:

            move = CGPointMake(w * 1.5, 0);

            playerMove = CGPointMake(CGRectGetMaxX(self.view.bounds)-30, player.position.y);

            break;

        case 2:

            move = CGPointMake(0, w * 1.5);

            playerMove = CGPointMake(player.position.x, CGRectGetMaxX(self.view.bounds) – 30);

            break;

        case 3:

            move = CGPointMake(-w * 1.5, 0);

            playerMove = CGPointMake(30, player.position.y);

            break;

        case 4:

            move = CGPointMake(0, -w * 1.5);

            playerMove = CGPointMake(player.position.x, 30);

            break;

        default:

            break;

    }

    

    map.position = CGPointMake(-move.x, -move.y);

    

    [player runAction:[SKAction moveTo:playerMove duration:0.4]];

    

    __block SKNode *old = self.currentMap;

    [old runAction:[SKAction moveTo:move duration:0.5] completion:^{

        [old removeFromParent];

    }];

    

    [map runAction:[SKAction moveTo:CGPointZero duration:0.5] completion:^{

        self.currentMap = map;

        self.scene.physicsWorld.speed = 1.0;

    }];

}

– (void)createPlayer

{

    float w = CGRectGetMaxX(self.view.frame) / 10.0;

    SKSpriteNode *player = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(w, w)];

    player.name = @”player”;

    player.position = CGPointMake(w/2.0, w/2.0);

    [self.scene addChild:player];

    

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

}

– (void)createButtons

{

    CGPoint o = CGPointMake(CGRectGetMidX(self.view.frame), CGRectGetMaxY(self.view.bounds) – 60);

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

        float x = 40 * cos(M_PI_2 * i) + o.x;

        float y = 40 * sin(M_PI_2 * i) + o.y;

        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];

        btn.tag = i + 1;

        btn.frame = CGRectMake(0, 0, 40, 40);

        [btn setBackgroundColor:[UIColor lightGrayColor]];

        btn.center = CGPointMake(x, y);

        [self.view addSubview:btn];

        

        [btn addTarget:self action:@selector(touchDownButton:) forControlEvents:UIControlEventTouchDown];

        [btn addTarget:self action:@selector(touchUpButton:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchDragExit | UIControlEventTouchUpOutside];

    }

}

– (void)touchDownButton:(UIButton *)sender

{

    self.direction = sender.tag;

}

– (void)touchUpButton:(UIButton *)sender

{

    self.direction = 0;

}

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

{

    SKNode *player = [self.scene childNodeWithName:@”player”];

    switch (self.direction) {

        case 0:

            player.physicsBody.velocity = CGVectorMake(0, 0);

            break;

        case 1:

            player.physicsBody.velocity = CGVectorMake(100, 0);

            break;

        case 2:

            player.physicsBody.velocity = CGVectorMake(0, –100);

            break;

        case 3:

            player.physicsBody.velocity = CGVectorMake(-100, 0);

            break;

        case 4:

            player.physicsBody.velocity = CGVectorMake(0, 100);

            break;

        default:

            break;

    }

}

– (void)didSimulatePhysicsForScene:(SKScene *)scene

{

    if (self.scene.physicsWorld.speed == 0) {

        return;

    }

    

    SKNode *player = [self.scene childNodeWithName:@”player”];

    float max = CGRectGetMaxX(self.view.bounds);

    int nextMap = arc4random() % 10;

    if (player.position.x < 0) {

        self.scene.physicsWorld.speed = 0;

        [self showMap:nextMap direction:1];

    }

    else if (player.position.x > max) {

        self.scene.physicsWorld.speed = 0;

        [self showMap:nextMap direction:3];

    }

    else if (player.position.y < 0) {

        self.scene.physicsWorld.speed = 0;

        [self showMap:nextMap direction:2];

    }

    else if (player.position.y > max) {

        self.scene.physicsWorld.speed = 0;

        [self showMap:nextMap direction:4];

    }

}

– (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

}

@end