今回は、シーンのdidSimulatePhysicsメソッドを試してみます。
ぴぽやさんの画像素材を使っています。
1フレームで行われるシーンの処理は次のような流れになります。
- シーンの更新
- アクションの更新
- didEvaluateActionsメソッド呼び出し
- 物理シミュレーション処理
- didSimulatePhysicsメソッド呼び出し
- シーンの描画
didSimulatePhysicsメソッドを使う例として、あるNodeをシーンの真ん中に持ってくる処理を作ってみます。
使用する画像は、こちらです。
シーンの構成はこのようになっています。
キャラクタはシーンの真ん中でアニメーションするだけなので、WorldではなくSceneの子にしておきました。
CameraをSceneの真ん中に移動することにより、マップスクロールを実現します。
ソースコードはこのようになります。
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"];
}
実行結果はこのようになります。
今回はここまで。