2015年

6月

21日

Objective-C SpriteKit

ViewController.m

#import <CoreMotion/CoreMotion.h>

#import "ViewController.h"

#import "MyScene.h"


@interface ViewController() {

    

    // MotionManagerオブジェクト

    CMMotionManager *_cmm;

    

}


@end


@implementation ViewController


- (void)viewDidLoad

{

    [super viewDidLoad];


    // ビュー(SKView)の設定

    SKView * skView = (SKView *)self.view;

    skView.showsFPS = YES;

    skView.showsNodeCount = YES;

    skView.showsPhysics = YES;

    

//    CGSize gameSize;

//    gameSize.width=320;

//    

//    if (skView.frame.size.height>480){

//        //iPhone5以降

//        gameSize.height=568;

//    } else {

//        //iPhone4s

//        gameSize.height=480;

//    }

    

//    SKScene * scene = [MyScene sceneWithSize:gameSize];

    

    NSLog(@"高さ%f", skView.frame.size.height);

    

    // シーンの作成、設定

    SKScene * scene = [MyScene sceneWithSize:

                       skView.bounds.size];

    

    scene.scaleMode = SKSceneScaleModeAspectFill;

    

    // シーンのオープン

    [skView presentScene:scene];

    

    // 加速度センサー開始

    [self startAccelerometer:(MyScene *)scene];


}



// 画面回転の許可

- (BOOL)shouldAutorotate

{

    return NO; // 回転許可しない

}


// 画面回転方向の設定

- (NSUInteger)supportedInterfaceOrientations

{

    // iPhoneの場合は逆回転禁止

    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {

        return UIInterfaceOrientationMaskAllButUpsideDown;

    } else {

        return UIInterfaceOrientationMaskAll;

    }

}


- (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.

}



// 加速度センサーの開始

- (void)startAccelerometer:(MyScene *)scene {

    

    // MotionManagerオブジェクト生成

    _cmm = [CMMotionManager new];

    //  _cmm = [[CMMotionManager alloc] init];

    

    // 設定(加速度センサー値取得間隔(秒))

    _cmm.accelerometerUpdateInterval = 0.05;

    

    // 加速度センサー受信開始

    NSOperationQueue *que = [NSOperationQueue currentQueue];

    

    // 加速度センサー受信処理

    CMAccelerometerHandler hnd =

    ^(CMAccelerometerData *accelerometerData, NSError *error) {

        

        // センサー値の取得

        CMAcceleration ca = accelerometerData.acceleration;

        

        // 重力の変更

        [scene changeGravityWithDx:ca.x * 100

                                dy:ca.y * 100];

        

        

    };

    

    [_cmm startAccelerometerUpdatesToQueue:que

                               withHandler:hnd];

}


@end

MyScene.h

#import <SpriteKit/SpriteKit.h>


@interface MyScene : SKScene


-(void)changeGravityWithDx:(CGFloat)dx

                        dy:(CGFloat)dy;

@end

MyScene.m

#import "MyScene.h"


@interface MyScene () <SKPhysicsContactDelegate>


@end


@implementation MyScene


// イニシャライザ

-(id)initWithSize:(CGSize)size {    

    if (self = [super initWithSize:size]) {

        /* Setup your scene here */

        

        self.backgroundColor = [SKColor colorWithRed:0.15

                                               green:0.15

                                                blue:0.3

                                               alpha:1.0];

        

        // 物理枠の設定(シーンの物性)

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

        

        // 物理空間の重力 上に上昇

        //self.physicsWorld.gravity = CGVectorMake(0.0, -9.8); // -9.8 9.8

        

        

        // デリゲート設定

        self.physicsWorld.contactDelegate = self;

        

        

    

        // ノードの追加(ラベル)

        {

            SKLabelNode *myLabel = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];

            

            // Hello, World!

            myLabel.text = @"Hello, World!";

            myLabel.fontSize = 10;

            myLabel.position = CGPointMake(CGRectGetMidX(self.frame),

                                           CGRectGetMidY(self.frame));

            

            // 山小屋表示

            SKSpriteNode* iv;

            iv = [SKSpriteNode spriteNodeWithImageNamed:@"images.png"];

            

            iv.position = CGPointMake(160, 90);

            [self addChild:iv];

            

            // 物性(剛性)の設定

            myLabel.physicsBody =

                [SKPhysicsBody bodyWithRectangleOfSize:myLabel.frame.size];

            

            // 重力の影響の設定

            myLabel.physicsBody.dynamic = NO;

            

            [self addChild:myLabel];

            

        }

        

        // ノードの追加(エミッター)放射する

        {

            // パーティクルの参照

            NSBundle *bnd = [NSBundle mainBundle];

            NSString *pth = [bnd pathForResource:@"ParticleSnow" ofType:@"sks"];

            

            SKEmitterNode *nod = [NSKeyedUnarchiver unarchiveObjectWithFile:pth];

            

            nod.position = CGPointMake(CGRectGetMidX(self.frame),

                                       CGRectGetMaxY(self.frame));

            [self addChild:nod];

        }

    }

    return self;

}


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    /* Called when a touch begins */

    

    for (UITouch *touch in touches) {

        

        // タッチ位置の取得

        CGPoint location = [touch locationInNode:self];

        

        // ノードの追加(スプライト)

        {

            // ノードオブジェクト追加

            SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];

            sprite.position = location;

            

            // サイズの倍率

            sprite.xScale = 0.2;

            sprite.yScale = 0.2;

            

            // アンカーポイントの設定(いかり)

            sprite.anchorPoint = CGPointMake(0.5, 0.3);

            

            // 物性(剛性)の設定

            sprite.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:sprite.size.width / 2 * 0.8];

            

            // 衝突テストビットマップの設定

            sprite.physicsBody.contactTestBitMask = 1;

            

            [self addChild:sprite];

            

            // アクション設定(回転)

//            SKAction *action = [SKAction rotateByAngle:M_PI duration:1];

//            [sprite runAction:[SKAction repeatActionForever:action]];

            

            

        }

        

    }

}


// FPS(Frame Per Second)毎に実行

-(void)update:(CFTimeInterval)currentTime {

    /* Called before each frame is rendered */

}


#pragma mark - SKPhysicsContactDelegate Method


// 衝突終了後

-(void)didEndContact:(SKPhysicsContact *)contact {

    

    // 音の再生

    SKAction *act = [SKAction playSoundFileNamed:@"middle_punch2.mp3"

                               waitForCompletion:YES];

    

    

    [self runAction:act];

    

    // ノードの追加(エミッター)放射する

    {

        // パーティクルの参照

        NSBundle *bnd = [NSBundle mainBundle];

        NSString *pth = [bnd pathForResource:@"ParticleSpark" ofType:@"sks"];

        

        SKEmitterNode *nod = [NSKeyedUnarchiver unarchiveObjectWithFile:pth];

        

        nod.position = CGPointMake(CGRectGetMidX(self.frame),

                                   CGRectGetMaxY(self.frame));

        

        // パーティクル数

        nod.position = contact.contactPoint;

        

        nod.numParticlesToEmit = 10;

        

        [self addChild:nod];

    }

}

#pragma mark - Own Method

    

// 重力の変更

-(void)changeGravityWithDx:(CGFloat)dx

                        dy:(CGFloat)dy {

        // 物理空間の重力 上に上昇

        self.physicsWorld.gravity = CGVectorMake(dx, dy); // -9.8 9.8

        

    }


@end

※重要

上下、もしくは左右に黒いバーが出現する場合の解決策

Launch ImageをAsset Catalogより使うよう指定する。

GitHub SpriteKit02

  

目 次