2013-10-10 21 views
6

이것은 내 첫 번째 게시물이며 Apple의 SpriteKit 프레임 워크를 사용하려고합니다.SpriteKit 이해 : 스프라이트 이동

프레임 워크를 사용하여 스프라이트를 이동하는 방법에 대한 오해가 있다고 생각합니다. 나는 단순한 예를 들어 , DOWN, LEFT, RIGHT 방향의 "주인공"위치에 따라 을 간단하게 이동하려고합니다. 영웅이 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 
+0

종료/비활성화 제거해야하는이 시도 :

덕분에 여기

내가 쓴 샘플 장면입니다 : //stackoverflow.com/questions/19172140/skaction-move-forward/19172574#19172574 – DogCoffee

+0

@Smick wonderful. 감사합니다. –

+0

@Smick 답변에 대한 크레딧을드립니다. 그렇게하는 가장 좋은 방법은 무엇입니까? 죄송합니다. 여기 새로 왔습니다. –

답변

5

당신이 당신의 접촉뿐만 아니라

이 HTTP 도움이 될 것입니다
-(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] 
                ]]]; 
    } 
} 
}