iOS_SpriteKit_03_精靈平移拖動
阿新 • • 發佈:2019-01-04
效果圖:
標頭檔案:
#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