LoginSignup
2
2

More than 5 years have passed since last update.

SpriteKit入門 -25-

Posted at

今回は、シーンのdidSimulatePhysicsメソッドを試してみます。
ぴぽやさんの画像素材を使っています。

1フレームで行われるシーンの処理は次のような流れになります。

  1. シーンの更新
  2. アクションの更新
  3. didEvaluateActionsメソッド呼び出し
  4. 物理シミュレーション処理
  5. didSimulatePhysicsメソッド呼び出し
  6. シーンの描画

didSimulatePhysicsメソッドを使う例として、あるNodeをシーンの真ん中に持ってくる処理を作ってみます。

使用する画像は、こちらです。

マップ用。
pipo-map001.png

キャラクタ用。
pipo-charachip001.png

シーンの構成はこのようになっています。
キャラクタはシーンの真ん中でアニメーションするだけなので、WorldではなくSceneの子にしておきました。
CameraをSceneの真ん中に移動することにより、マップスクロールを実現します。

spritekit_25_01.png

ソースコードはこのようになります。

HelloScene.m
@interface HelloScene()
{
    SKNode *_world;
    SKNode *_camera;
}
@property BOOL contentCreated;
@end

@implementation HelloScene

- (void)didMoveToView:(SKView *)view
{
    if (! self.contentCreated) {
        [self createSceneContents];
        self.contentCreated = YES;
    }
}

- (void)createSceneContents
{
    self.backgroundColor = [SKColor blackColor];
    self.scaleMode = SKSceneScaleModeAspectFit;
    self.anchorPoint = CGPointMake(0.5, 0.5);

    _world = [SKNode node];
    [self addChild:_world];

    _camera = [SKNode node];
    _camera.name = @"camera";
    [_world addChild:_camera];

    _camera.position = CGPointMake(1000, 1000);

    int x = 10;
    int y = 10;
    SKTexture *mapTexture = [SKTexture textureWithImageNamed:@"pipo-map001.png"];
    SKTexture *mapchipTextureBase = [SKTexture textureWithRect:CGRectMake(0.0/MAPFILE_WIDTH, (MAPFILE_HEIGHT-MAPCHIP_HEIGHT-0.0)/MAPFILE_HEIGHT, MAPCHIP_WIDTH/MAPFILE_WIDTH, MAPCHIP_HEIGHT/MAPFILE_HEIGHT) inTexture:mapTexture];
    for (y=0; y < MAPCHIP_Y_MAX; y++) {
        for (x=0; x < MAPCHIP_X_MAX; x++) {
            @autoreleasepool {
                SKSpriteNode *mapchipBase = [SKSpriteNode spriteNodeWithTexture:mapchipTextureBase];
                mapchipBase.position = CGPointMake(x*MAPCHIP_WIDTH, y*MAPCHIP_HEIGHT);
                [_world addChild:mapchipBase];

                int mapchipType = s_map[MAPCHIP_Y_MAX-y-1][x];
                if (mapchipType > 0) {
                    CGFloat mapchipX = (mapchipType % MAPFILE_X_MAX) * MAPCHIP_WIDTH;
                    CGFloat mapchipY = (mapchipType / MAPFILE_X_MAX) * MAPCHIP_HEIGHT;
                    SKTexture *mapchipTexture = [SKTexture textureWithRect:CGRectMake(mapchipX/MAPFILE_WIDTH, (MAPFILE_HEIGHT-MAPCHIP_HEIGHT-mapchipY)/MAPFILE_HEIGHT, MAPCHIP_WIDTH/MAPFILE_WIDTH, MAPCHIP_HEIGHT/MAPFILE_HEIGHT) inTexture:mapTexture];
                    SKSpriteNode *mapchip = [SKSpriteNode spriteNodeWithTexture:mapchipTexture];
                    mapchip.position = CGPointMake(x*MAPCHIP_WIDTH, y*MAPCHIP_HEIGHT);
                    [_world addChild:mapchip];
                }
            }
        }
    }

    SKTexture *charTexture = [SKTexture textureWithImageNamed:@"pipo-charachip001.png"];
    SKTexture *charTextureBase = [SKTexture textureWithRect:CGRectMake(0.0/CHARFILE_WIDTH, (CHARFILE_HEIGHT-CHARCHIP_HEIGHT-0.0)/CHARFILE_HEIGHT, CHARCHIP_WIDTH/CHARFILE_WIDTH, CHARCHIP_HEIGHT/CHARFILE_HEIGHT) inTexture:charTexture];
    SKSpriteNode *charSprite = [SKSpriteNode spriteNodeWithTexture:charTextureBase];
    [self addChild:charSprite];
    SKTexture *charAnim1 = [SKTexture textureWithRect:CGRectMake(0*CHARCHIP_WIDTH/CHARFILE_WIDTH, (CHARFILE_HEIGHT-CHARCHIP_HEIGHT-0.0)/CHARFILE_HEIGHT, CHARCHIP_WIDTH/CHARFILE_WIDTH, CHARCHIP_HEIGHT/CHARFILE_HEIGHT) inTexture:charTexture];
    SKTexture *charAnim2 = [SKTexture textureWithRect:CGRectMake(1*CHARCHIP_WIDTH/CHARFILE_WIDTH, (CHARFILE_HEIGHT-CHARCHIP_HEIGHT-0.0)/CHARFILE_HEIGHT, CHARCHIP_WIDTH/CHARFILE_WIDTH, CHARCHIP_HEIGHT/CHARFILE_HEIGHT) inTexture:charTexture];
    SKTexture *charAnim3 = [SKTexture textureWithRect:CGRectMake(2*CHARCHIP_WIDTH/CHARFILE_WIDTH, (CHARFILE_HEIGHT-CHARCHIP_HEIGHT-0.0)/CHARFILE_HEIGHT, CHARCHIP_WIDTH/CHARFILE_WIDTH, CHARCHIP_HEIGHT/CHARFILE_HEIGHT) inTexture:charTexture];
    SKTexture *charAnim4 = [SKTexture textureWithRect:CGRectMake(1*CHARCHIP_WIDTH/CHARFILE_WIDTH, (CHARFILE_HEIGHT-CHARCHIP_HEIGHT-0.0)/CHARFILE_HEIGHT, CHARCHIP_WIDTH/CHARFILE_WIDTH, CHARCHIP_HEIGHT/CHARFILE_HEIGHT) inTexture:charTexture];
    SKAction *charAction = [SKAction animateWithTextures:@[charAnim1, charAnim2, charAnim3, charAnim4] timePerFrame:0.2];
    [charSprite runAction:[SKAction repeatActionForever:charAction]];
}

- (void) didSimulatePhysics
{
    [self centerOnNode:[self childNodeWithName:@"//camera"]];
}

- (void) centerOnNode:(SKNode *)node
{
    CGPoint cameraPositionInScene = [node.scene convertPoint:node.position fromNode:node.parent];
    node.parent.position = CGPointMake(node.parent.position.x - cameraPositionInScene.x, node.parent.position.y - cameraPositionInScene.y);
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:_world];
    CGFloat distance = sqrtf((_camera.position.x - location.x)*(_camera.position.x - location.x)+(_camera.position.y - location.y)*(_camera.position.y - location.y));
    SKAction *cameraAction = [SKAction moveTo:location duration:distance/100.0];
    [_camera runAction:cameraAction withKey:@"move"];
}

実行結果はこのようになります。

spritekit_25_02.png

今回はここまで。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2