Spritekit 通过 touchesBegan 暂停和恢复 SKSpriteNode 的动作
Posted
技术标签:
【中文标题】Spritekit 通过 touchesBegan 暂停和恢复 SKSpriteNode 的动作【英文标题】:Spritekit pause and resume SKSpriteNode's action by touchesBegan 【发布时间】:2014-11-02 20:48:00 【问题描述】:我有一个重复运动的 SKSpriteNode,我称之为 RunAction A,例如上升 - 下降。现在我想做一个动作,让我们称之为 RunAction B,左 - 中 - 右 - 中,由 touchesBegan。
在完成 RunAction B 后,RunAction A 应该会恢复。它应该从 RunAction B 开始和停止的位置开始。
如果我使用(注意伪语言。)
[sprite RunAction A]
[sprite setPaused: True]
[sprite RunAction B]
[sprite setPaused: False]
我可以看到,精灵从未暂停!
是否有可能让精灵恢复之前停止的动作?
谢谢
【问题讨论】:
[sprite runAction: A completion:^ [sprite setPaused: True] ]; 感谢您的回答;) 对不起...但这不会救我。让我再解释一下……我有一个 Sprite,它通过 Rect 中的 FollowPath/RepeatForever/RunAction 移动。形成A角到B角,从B到C,C-D再A-B...等。现在,如果检测到触摸,精灵应该停止在当前位置并开始新的运动,例如从 0 到 Pi*2 运行一个弧线,完成后,释放第一个动作,从最后一个当前位置开始,他被触摸停止...希望,这已经足够清楚了...:/请找到方法!谢谢,欢呼, 【参考方案1】:#import "GameScene.h"
@implementation GameScene
-(void)didMoveToView:(SKView *)view
/* Setup your scene here */
SKLabelNode *myLabel = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
myLabel.text = @"Hello, World!";
myLabel.fontSize = 65;
myLabel.position = CGPointMake(CGRectGetMidX(self.frame),
CGRectGetMidY(self.frame));
NSString *myParticlePath = [[NSBundle mainBundle] pathForResource:@"fireflies" ofType:@"sks"];
SKEmitterNode *myParticle = [NSKeyedUnarchiver unarchiveObjectWithFile:myParticlePath];
[self addChild:myParticle];
self.physicsWorld.gravity=CGVectorMake(0.0, -9);
self.physicsBody=[SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
self.physicsBody.linearDamping=0.0;
SKSpriteNode *rectNode=[SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(50, 50)];
rectNode.name=@"rect";
rectNode.position=CGPointMake(300, 300);
[self addChild:rectNode];
[self moveAction];
-(SKAction*)groupAction:(CGPoint)points
SKAction *A=[SKAction moveTo:CGPointMake(points.x+100, points.y+100) duration:1];
SKAction *B=[SKAction moveTo:CGPointMake(500, 100) duration:1];
SKAction *C=[SKAction moveTo:CGPointMake(100, 100) duration:1];
SKAction *s=[SKAction sequence:@[A,B,C]];
return s;
-(void)moveRect:(SKNode*)node
[node runAction:[SKAction repeatActionForever:[self groupAction:node.position]] withKey:@"moveAction"];
-(void)moveAction
[self enumerateChildNodesWithName:@"rect" usingBlock:^(SKNode *node, BOOL *stop)
[self moveRect:node];
];
-(void)clearAction
[self enumerateChildNodesWithName:@"rect" usingBlock:^(SKNode *node, BOOL *stop)
[node removeActionForKey:@"moveAction"];
];
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
/* Called when a touch begins */
for (UITouch *touch in touches)
CGPoint location = [touch locationInNode:self];
if(!_stop)
[self clearAction];
_stop=TRUE;
else
[self moveAction];
_stop=FALSE;
/*
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
sprite.physicsBody.allowsRotation=FALSE;
sprite.physicsBody=[SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(sprite.size.width, sprite.size.height)];
sprite.physicsBody.friction=0.0;
sprite.physicsBody.linearDamping=0.0;
sprite.physicsBody.restitution=1.0;
sprite.xScale = 0.5;
sprite.yScale = 0.5;
sprite.position = location;
[self addChild:sprite];
*/
-(void)update:(CFTimeInterval)currentTime
/* Called before each frame is rendered */
@end
查看此示例,我只使用了一个矩形,但您可以使用任意数量的对象,确保不同的操作组包含不同的名称,以便您在用户触摸屏幕并应用时轻松删除和暂停操作删除或暂停操作时对另一个对象的新操作组。
【讨论】:
非常感谢。我了解解决方案的原理。【参考方案2】:每个动作在 sprite kit 中都有一个完整的处理程序,因此您可以使用以下句子轻松获取动作完成或完成的时间
//action 一个完成,当action完成后做任何你想做的事情
[sprite runAction: A completion:^
[sprite setPaused: True]
];
【讨论】:
以上是关于Spritekit 通过 touchesBegan 暂停和恢复 SKSpriteNode 的动作的主要内容,如果未能解决你的问题,请参考以下文章
调用函数 touchesBegan 时 SpriteKit 游戏延迟
touchesBegan Swift 2 自定义 SpriteKit 节点
SpriteKit Objective-C:SKSpriteNode 类实例上的 touchesBegan()
Swift:Spritekit 中的多个场景,从第二个和第一个场景的不同 Sprite 节点类型调用 touchesBegan