6
これは私の最初の投稿であり、AppleのSpriteKit
フレームワークを使用しようとしています。SpriteKitの理解:スプライトの移動
フレームワークを使用してスプライトを移動する方法について私が誤解していると思います。私はシンプルな例を持っています。ここでは、 "ヒーロー"の位置に応じて、UP
、DOWN
、LEFT
、RIGHT
の方向に、hero
を簡単に移動したいと考えています。ヒーローがblock
にヒットしたら、「ヒーロー」が止まるはずです。
テスト目的のために、私はちょうど "ヒーロー"の上のタップを画面の上部にあるブロックの壁に当てようとしています。その後、衝突が発生した後、「ヒーロー」の下をタップします。私は "ヒーロー"が一番下の行のブロックの壁に向かって移動することを期待していました。しかし、それは "英雄"が上の壁を介して上を移動し続けているようだ。私は根本的な欠陥を作っていると確信しています。私は助けていただければ幸いです。
ここstatic inline CGPoint CGPointSubtract(const CGPoint a, const CGPoint b)
{
return CGPointMake(a.x - b.x, a.y - b.y);
}
typedef enum DIRECTION_e
{
UP,
DOWN,
LEFT,
RIGHT
} DIRECTION_t;
typedef NS_OPTIONS(uint32_t, CNPhysicsCategory)
{
PhysicsCategoryBlock = 1 << 0,
PhysicsCategoryHero = 1 << 1
};
@interface LevelScene()
@property (nonatomic) SKSpriteNode * hero;
@property (nonatomic) BOOL inMotion;
@end
@implementation LevelScene
-(id) initWithSize:(CGSize)size
{
if (self = [super initWithSize:size])
{
self.physicsWorld.gravity = CGVectorMake(0,0);
self.physicsWorld.contactDelegate = self;
[self createLevel];
[self createHero];
self.inMotion = NO;
}
return self;
}
- (void) createHero
{
[self addHeroAtRow:5 column:2];
}
- (void) createLevel
{
self.backgroundColor = [SKColor blackColor];
self.scaleMode = SKSceneScaleModeAspectFit;
[self addBlockAtRow:1 column:1];
[self addBlockAtRow:1 column:2];
[self addBlockAtRow:1 column:3];
[self addBlockAtRow:10 column:1];
[self addBlockAtRow:10 column:2];
[self addBlockAtRow:10 column:3];
}
- (void) addBlockAtRow:(NSInteger)row column:(NSInteger)column
{
SKSpriteNode *block = [[SKSpriteNode alloc] initWithColor:[SKColor brownColor] size:CGSizeMake(64,64)];
block.position = CGPointMake(32 + (column * 64), 32 + ((11-row) * 64));
block.name = @"block";
block.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:block.size];
block.physicsBody.dynamic = NO;
block.physicsBody.categoryBitMask = PhysicsCategoryBlock;
block.physicsBody.collisionBitMask = PhysicsCategoryBlock | PhysicsCategoryHero;
block.physicsBody.contactTestBitMask = PhysicsCategoryBlock | PhysicsCategoryHero;
[self addChild:block];
}
- (void) addHeroAtRow:(NSInteger)row column:(NSInteger)column
{
self.hero = [[SKSpriteNode alloc] initWithColor:[SKColor redColor] size:CGSizeMake(64,64)];
self.hero.position = CGPointMake(32 + (column * 64), 32 + ((11-row) * 64));
self.hero.name = @"hero";
self.hero.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(self.hero.size.width/2, self.hero.size.height/2)];
self.hero.physicsBody.usesPreciseCollisionDetection = YES;
self.hero.physicsBody.dynamic = YES;
self.hero.physicsBody.categoryBitMask = PhysicsCategoryHero;
self.hero.physicsBody.collisionBitMask = PhysicsCategoryHero | PhysicsCategoryBlock;
self.hero.physicsBody.contactTestBitMask = PhysicsCategoryHero | PhysicsCategoryBlock;
[self addChild:self.hero];
NSLog(@"ADDING HERO: %f, %f", self.hero.position.x, self.hero.position.y);
}
- (void)didBeginContact:(SKPhysicsContact *)contact
{
if (contact.bodyA.categoryBitMask == PhysicsCategoryBlock && contact.bodyB.categoryBitMask == PhysicsCategoryHero)
{
[self.hero removeAllActions];
self.hero.position = contact.bodyB.node.position;
NSLog(@"COLLISION: %f, %f", self.hero.position.x, self.hero.position.y);
self.inMotion = NO;
}
else if (contact.bodyB.categoryBitMask == PhysicsCategoryBlock && contact.bodyA.categoryBitMask == PhysicsCategoryHero)
{
[self.hero removeAllActions];
self.hero.position = contact.bodyA.node.position;
NSLog(@"COLLISION: %f, %f", self.hero.position.x, self.hero.position.y);
self.inMotion = NO;
}
}
- (void) moveHeroTowardDirection:(DIRECTION_t)direction
{
CGPoint location;
switch (direction)
{
case UP:
{
location = CGPointMake(self.hero.position.x, self.hero.position.y + 600);
}
break;
case DOWN:
{
location = CGPointMake(self.hero.position.x, self.hero.position.y + -600);
}
break;
case LEFT:
{
location = CGPointMake(self.hero.position.x + -600, self.hero.position.y);
}
break;
case RIGHT:
{
location = CGPointMake(self.hero.position.x + 600, self.hero.position.y);
}
break;
default: return;
}
NSLog(@"MOVE POSITION: %f, %f", location.x, location.y);
SKAction *action = [SKAction moveTo:location duration:10];
[self.hero runAction:action];
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (self.inMotion)
return;
self.inMotion = YES;
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
CGPoint diff = CGPointSubtract(self.hero.position, touchLocation);
NSLog(@"TOUCH POSITION: %f, %f", touchLocation.x, touchLocation.y);
NSLog(@"HERO POSITION: %f, %f", self.hero.position.x, self.hero.position.y);
NSLog(@"DIFF POSITION: %f, %f", diff.x, diff.y);
//
// Magnitude to find out which direction is dominate
//
if (abs(diff.x) > abs(diff.y))
{
if (touchLocation.x > self.hero.position.x)
{
NSLog(@"LEFT");
[self moveHeroTowardDirection:LEFT];
}
else
{
NSLog(@"RIGHT");
[self moveHeroTowardDirection:RIGHT];
}
}
else
{
if (touchLocation.y < self.hero.position.y)
{
NSLog(@"UP");
[self moveHeroTowardDirection:UP];
}
else
{
NSLog(@"DOWN");
[self moveHeroTowardDirection:DOWN];
}
}
}
@end
終了無効/削除する必要があり、これを試してみてください。
おかげでここ
は、私が書いたサンプルシーンです。 //stackoverflow.com/questions/19172140/skaction-move-forward/19172574#19172574 – DogCoffee@Smick wonderful。ありがとうございます –
@Smick私はあなたに答えのクレジットを与えたいと思います。それをする最善の方法は何ですか?申し訳ありません、私はここで新しいです。 –