1. 程式人生 > >iOS_SpriteKit_03_精靈平移拖動

iOS_SpriteKit_03_精靈平移拖動

效果圖:

標頭檔案:

#import <SpriteKit/SpriteKit.h>

@interface MainScene : SKScene
// 新增背景
- (void)addBgImgWithName:(NSString *)imgName;
// 新增人物
- (void)addBoyWithImgName:(NSString *)imgName;
@end


M檔案

#import "MainScene.h"
static NSString * const kAnimalNodeName = @"constant_boy";
@interface MainScene()
{
    BOOL _isContentCreated;
    
}
@property (nonatomic, strong) SKSpriteNode *currentNode;
@end
@implementation MainScene

- (void)willMoveFromView:(SKView *)view
{
    DLog(@"即將從View:%@ 移除",view);
}
// 每當檢視呈現場景時,didMoveToView:方法都會被呼叫
- (void)didMoveToView: (SKView *) view
{
    DLog(@"didMoveToView:%@",view);
    if (!_isContentCreated)
    {
        [self initSceneContents];
        _isContentCreated = YES;

    }
    // 給self 場景 所在的view新增平移手勢
    [self addPanReco];
}
- (void)addPanReco
{
    UIPanGestureRecognizer *gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGuestRecoed:)];
    [[self view] addGestureRecognizer:gestureRecognizer];
}

- (void)initSceneContents
{
    self.backgroundColor = [SKColor blueColor];
    
    self.scaleMode = SKSceneScaleModeAspectFit;
    [self addChild: [self newHelloNode]];
}

- (SKLabelNode *)newHelloNode
{
    SKLabelNode *helloNode = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
    helloNode.text = @"Hello, Beyond!";
    // 類似於tag
    helloNode.name = @"HelloBeyond";
    
    helloNode.fontSize = 32;
    helloNode.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame));
    return helloNode;
}




// 根據圖片名,新增背景圖片精靈
- (void)abstract_addBgSpriteNodeNamed:(NSString *)imgName
{
        SKSpriteNode *bgSprite = [SKSpriteNode spriteNodeWithImageNamed:imgName];
        bgSprite.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame));
        bgSprite.size = self.size;
        [self addChild:bgSprite];
}

// 根據圖片名,新增人物精靈
- (void)abstract_addBoySpriteNamed:(NSString *)imgName
{
    SKSpriteNode *boy = [SKSpriteNode spriteNodeWithImageNamed:imgName];
    boy.name = kAnimalNodeName;
    boy.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame));
    

    [self addChild:boy];
    
}

// 另一種方法新增背景
- (void)addBgImgWithName:(NSString *)imgName
{
    [self abstract_addBgSpriteNodeNamed:imgName];
}

- (void)addBoyWithImgName:(NSString *)imgName
{
    [self abstract_addBoySpriteNamed:imgName];
}


#pragma mark - 新增平移手勢
- (void)panGuestRecoed:(UIPanGestureRecognizer *)recognizer {
    if (recognizer.state == UIGestureRecognizerStateBegan) {
        NSLog(@"手勢開始");
        CGPoint touchLocation = [recognizer locationInView:recognizer.view];
        // 列印
        DLog(@"sg__%@",NSStringFromCGPoint(touchLocation));
        
        touchLocation = [self convertPointFromView:touchLocation];
        // 列印
        DLog(@"sg__%@",NSStringFromCGPoint(touchLocation));
        
        // 找出點選的目標,並且_currentNode記住
        [self selectNodeForTouch:touchLocation];
        
        
    } else if (recognizer.state == UIGestureRecognizerStateChanged) {
        NSLog(@"手勢進行...");
        
        CGPoint translation = [recognizer translationInView:recognizer.view];
        // 列印
        DLog(@"手勢進行...sg__%@",NSStringFromCGPoint(translation));
        
        translation = CGPointMake(translation.x, -translation.y);
        
        [self panForTranslation:translation];
        
        [recognizer setTranslation:CGPointZero inView:recognizer.view];
        
    } else if (recognizer.state == UIGestureRecognizerStateEnded) {
        NSLog(@"手勢結束");
        
    }
}

- (void)panForTranslation:(CGPoint)translation {
    CGPoint position = [_currentNode position];
    if([[_currentNode name] isEqualToString:kAnimalNodeName]) {
        
        // 更新boy的座標
        [_currentNode setPosition:CGPointMake(position.x + translation.x, position.y + translation.y)];
    }
}
// 根據位置, 選擇出當前的Node
- (void)selectNodeForTouch:(CGPoint)touchLocation {
    //1
    SKSpriteNode *touchedNode = (SKSpriteNode *)[self nodeAtPoint:touchLocation];
    
    //2 點了新的 Node
    if(![_currentNode isEqual:touchedNode]) {
        
        [_currentNode removeAllActions];
        [_currentNode runAction:[SKAction rotateToAngle:0.0f duration:0.1]];
        
        _currentNode = touchedNode;
        
        
        
        //3
        if([[touchedNode name] isEqualToString:kAnimalNodeName]) {
            SKAction *sequence = [SKAction sequence:@[[SKAction rotateByAngle:degToRad(-4.0f) duration:0.1],
                                                      [SKAction rotateByAngle:0.0 duration:0.1],
                                                      [SKAction rotateByAngle:degToRad(4.0f) duration:0.1]]];
            [_currentNode runAction:[SKAction repeatActionForever:sequence]];
        }
        
        
    }
    
}
// 選中後,搖擺
float degToRad(float degree) {
    return degree / 180.0f * M_PI;
}

#pragma mark - 觸屏事件
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    // 當前Node停止抖動
    [_currentNode removeAllActions];
}
#pragma mark - 觸控事件
- (void)touchesBegan2:(NSSet *) touches withEvent:(UIEvent *)event
{
    SKNode *helloNode = [self childNodeWithName:@"HelloBeyond"];
    
    if (helloNode != nil)
    {
        // 為了防止Node 重複響應 touch事件,程式碼會清除節點的名稱。
        // To prevent the node from responding to repeated presses, the code clears the node’s name.
        helloNode.name = nil;
        SKAction *moveUp = [SKAction moveByX: 0 y: 100.0 duration: 0.5];
        SKAction *zoom = [SKAction scaleTo: 2.0 duration: 0.25];
        SKAction *pause = [SKAction waitForDuration: 0.5];
        SKAction *fadeAway = [SKAction fadeOutWithDuration: 0.25];
        SKAction *remove = [SKAction removeFromParent];
        SKAction *moveSequence = [SKAction sequence:@[moveUp, zoom, pause, fadeAway, remove]];
        //        [helloNode runAction: moveSequence];
        
        [helloNode runAction: moveSequence completion:^{
            return;
            //            ShipScene *shipScene  = [[ShipScene alloc] initWithSize:self.size];
            //            SKTransition *doorTransition = [SKTransition doorsOpenVerticalWithDuration:0.5];
            //            [self.view presentScene:shipScene transition:doorTransition];
        }];
        
    }
}
@end