2013-10-10 17 views
6

Bu benim ilk gönderiim ve Apple'ın SpriteKit çerçevesini kullanmaya çalışıyorum.SpriteKit'i Anlamak: Sprite'ları Taşıma

Çerçeveleri kullanarak sprite nasıl taşınacağını yanlış anladığımı düşünüyorum. Ben "kahraman" konumuna karşılık gelen bir musluk yeri temel basit UP, DOWN, LEFT, RIGHT yönde bir hero taşımak istiyoruz basit bir örnek var. Kahraman bir block isabet ettiğinde, "kahraman" durmalıdır.

Test amaçlı olarak, sadece ekranın üstündeki blokların duvarına çarpıp "kahraman" a dokunmaya çalışıyorum. Sonra çarpışmadan sonra, "kahraman" ın altına dokunun. "Kahramanın" alt sıradaki blokların duvarına doğru hareket etmesini bekliyordum; Ancak, "kahraman" ın yukarı ve üst duvar boyunca ilerlemeye devam ettiği görülmektedir. Eminim ki temel bir kusur yapıyorum, herhangi bir yardım için minnettar olurum.

İşte
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 
+0

sona devre dışı/kaldırmak gerekir, bu deneyin:

Teşekkür İşte

Yazdığım örnek sahnesi: //stackoverflow.com/questions/19172140/skaction-move-forward/19172574#19172574 – DogCoffee

+0

@Smick harika. Teşekkürler –

+0

@Smick Cevap için size kredi vermek istiyorum. Bunu yapmanın en iyi yolu nedir? Üzgünüm, burada yeniyim. –

cevap

5

size dokunur yanı

bu http yardımcı olacaktır
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 

for (UITouch *touch in touches) { 

    for (UITouch *touch in touches) { 

     CGPoint location = [touch locationInNode:self]; 

     CGPoint diff = CGPointMake(location.x - self.hero.position.x, location.y - self.hero.position.y); 

     CGFloat angleRadians = atan2f(diff.y, diff.x); 

     [self.hero runAction:[SKAction sequence:@[ 
                [SKAction rotateToAngle:angleRadians duration:1.0], 
                [SKAction moveByX:diff.x y:diff.y duration:3.0] 
                ]]]; 
    } 
} 
}