斩断自己的退路,才能更好地赢得出路。在很多时候,我们都需要一种斩断自己退路的勇气。
SKAction简介
在先前的博客中就说过,动作是一个游戏中不可缺少的,比如移动,形状的变换等等.比如"超级马里奥"中的马里奥的移动,以及蘑菇,怪兽的移动都是需要动作的支持的.
在SpriteKit框架中是用SKAction类来实现动作.一个SKAction实例是一个动作,通过SKScene场景中的节点来执行。动作可以绑定到节点上,用以改变节点的结构和内容,有时也可以改变场景。当场景处理其子节点的时候,与这些节点相关联的动作将被计算。由于SKAction动作类型过多,所以我就先用下图进行了分类.
SKAction分类
准备工作
下面所有的动作前提准备都是一样的,我们就以微信打飞机的场景为实例,具体代发如下
-(instancetype)initWithSize:(CGSize)size{
if (self = [super initWithSize:size]) {
self.backgroundColor = [SKColor whiteColor];
}
return self;
}
-(void)didMoveToView:(SKView *)view{
[super didMoveToView:view];
[self backgroundNode];
[self planeNode];
}
#pragma mark ----创建背景----
-(void)backgroundNode{
SKSpriteNode *backgroundNode = [SKSpriteNode spriteNodeWithImageNamed:@"bg_02.jpg"];
backgroundNode.position = CGPointZero;
backgroundNode.zPosition = 0;
backgroundNode.anchorPoint = CGPointZero;
backgroundNode.size = self.size;
[self addChild:backgroundNode];
}
#pragma mark ---- 创建飞船 ----
-(void)planeNode{
SKSpriteNode *planeNode = [SKSpriteNode spriteNodeWithImageNamed:@"飞机.png"];
planeNode.position = CGPointMake(self.size.width/2, self.size.height/2);
planeNode.anchorPoint = CGPointMake(0.5, 0.5);
planeNode.zPosition = 1;
planeNode.name = @"plane";
[self addChild:planeNode];
}
场景示意图
移动动作
移动动作在一个游戏中是最常见的动作了.移动动作主要分为以点的形式移动和以偏移量的形式移动.且听我慢慢道来.
其中以点的形式移动的主要有三个SKAction类方法来创建.
+ (SKAction *)moveTo:(CGPoint)location duration:(NSTimeInterval)sec;
location: 用来指定节点移动到的位置.
sec:用来指定移动动作所需要的时间.
+ (SKAction *)moveToX:(CGFloat)x duration:(NSTimeInterval)sec;
x: 用来指定节点的x轴上移动到的位置.节点的y轴上的值不变化.
sec:用来指定移动动作所需要的时间.
+ (SKAction *)moveToY:(CGFloat)y duration:(NSTimeInterval)sec;
y: 用来指定节点的y轴上移动到的位置.节点的x轴上的值不变化.
sec:用来指定移动动作所需要的时间.
以偏移量的形式移动主要有两种两种类方法.
+ (SKAction *)moveBy:(CGVector)delta duration:(NSTimeInterval)sec;
delta:是一个矢量,用力啊指定偏移量,类型为CGVector,CGVector是一个很简单的结构体,有dx和dy组成.dx表示x轴上的偏移量,dy表示y轴上的偏移量.结构体形式如下.
struct CGVector {
CGFloat dx;
CGFloat dy;
};
sec:用来指定移动动作所需要的时间.
+ (SKAction *)moveByX:(CGFloat)deltaX y:(CGFloat)deltaY duration:(NSTimeInterval)sec;
deltaX:表示在x轴上的偏移量.
deltaY:表示在y轴上的偏移量.
sec:用来指定移动动作所需要的时间.
示例:
#pragma mark ---- 以点的形式移动飞船 ----
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint position = [touch locationInNode:self];
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
SKAction * moveAction = [SKAction moveTo:position duration:1];
[planeNode runAction:moveAction];
}
#pragma mark ---- 以偏移量的形式移动飞船 ----
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
SKAction * moveAction = [SKAction moveBy:CGVectorMake(50, 50) duration:1];
[planeNode runAction:moveAction];
}
上面的分别以点的形式和偏移量的形式做出了示例,我们看一下效果图.当我们每一次点击屏幕的时候触发移动动作,下面我们就看一下两种形式的效果图有何不同.
旋转动作
游戏中的物体的旋转大多需要用的旋转动作,旋转动作的创建方法只有一种,如下所示.
+ (SKAction *)rotateByAngle:(CGFloat)radians duration:(NSTimeInterval)sec;
sec:用来指定旋转动作所需要的时间.
radians:用来指定精灵或者其他节点的旋转量,以弧度为单位;下面所示的常用的角度(框架自带).
#define M_PI 3.14159265358979323846264338327950288 /* 180度 */
#define M_PI_2 1.57079632679489661923132169163975144 /* 90度 */
#define M_PI_4 0.785398163397448309615660845819875721 /* 45度 */
旋转示例:
#pragma mark --- 添加旋转动作 ---
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
SKSpriteNode *windmillNode = (SKSpriteNode *)[self childNodeWithName:@"windmillNode"];
//删除所有的动作
[windmillNode removeAllActions];
SKAction *rotateAction = [SKAction rotateByAngle:M_PI*2 duration:0.3];
[windmillNode runAction:rotateAction];
}
上面是以一个风车的精灵为例,做旋转动作,每当点击屏幕,精灵就会旋转360度.效果图如下.
路径动作
在游戏过程中,经常会遇到一些怪物,它们会按照一定的路劲轨迹不断的行走,在SKAciton中就有对路径动作的创建形式,其常用语法形式如下
+ (SKAction *)followPath:(CGPathRef)path duration:(NSTimeInterval)sec;
path:用来指定一个CGPathRef路径,这个路径就是精灵的移动路径.
sec:指定这个路径动作完成所需要的时间.
相比于上面比较常用的方式之外,下面的语法形式则应该算的上他的增强版,其中包括对其路径的点相对性,以及Z轴的旋转属性都可以进行设置操作.
+ (SKAction *)followPath:(CGPathRef)path asOffset:(BOOL)offset orientToPath:(BOOL)orient duration:(NSTimeInterval)sec;
路径示例:
下面就以一个矩形路径为示例,给节点添加路径动作,让其进行移动.
#pragma mark ---- 以路径的形式移动飞船 ----
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
CGRect createRect = CGRectMake(0, 0, 100, 100);
CGPathRef path = CGPathCreateWithRect(createRect, nil);
SKAction * moveAction = [SKAction followPath:path duration:2];
[planeNode runAction:moveAction];
}
通过下面的效果图我们就可以知道路径的点是相对路径.而且节点Z轴在旋转的时候属性也是发生改变的.
下面的则是完整版的路径动作创建.然后我们通过修改Offset(是否是相对路径),以及orientToPath(节点Z轴在旋转的时候属性是否发生改变).这两属性看看效果各有什么不同.
#pragma mark ---- 以路径的形式移动飞船 ----
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
CGRect createRect = CGRectMake(0, 0, 100, 100);
CGPathRef path = CGPathCreateWithRect(createRect, nil);
SKAction * moveAction = [SKAction followPath:path asOffset:YES orientToPath:YES duration:2];
[planeNode runAction:moveAction];
}
在 *** + (SKAction *)followPath:(CGPathRef)path duration:(NSTimeInterval)sec; ** 这个方法中默认的offset是YES,orient也是YES,也就是说如果上面的代码执行的话,是跟最常用的方法的效果图一样的,现在我们就先只修改offset的值为NO.会发现节点是以绝对路径进行运动的,也就是一节点的父类坐标系为基准,进行动作的执行.
接下来我们只修改orient的值为NO,其他不变,我们会发现节点Z轴是没有发生任何改变的.
反向动作
反向动作就是场景中的节点原来往一个方向进行移动,但是在运行时这些节点却向相反的防线进行了运动,如果想要实现反向运动,就需要使用到反向运动,反向运动的创建方法为对象方法,是使用一个动作调用- (SKAction *)reversedAction;
返回动作就会说这个动作的反向动作. 其语法形式如下所示.
- (SKAction *)reversedAction;
反向示例:
就那上面的路径动作为例,我们创建它的反向动作,为了更加生动形象,我给动作的触发设置了一个BOOL,具体的示例代码如下.
#pragma mark ---- 以反向形式移动飞船 ----
BOOL isReversed = YES;//设置监控反向的BOOL值.
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
isReversed = ! isReversed;
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
CGRect createRect = CGRectMake(0, 0, 100, 100);
CGPathRef path = CGPathCreateWithRect(createRect, nil);
SKAction * moveAction = [SKAction followPath:path duration:2];
SKAction *reversedAction = [moveAction reversedAction];
if (isReversed) {
[planeNode runAction:moveAction];
}else{
[planeNode runAction:reversedAction];
}
}
如下图所示,这就是反向动作的效果图
速度动作
速度动作一般是配合着别的位置动作使用的,其实不但有速度动作还有速度属性,我们可以给定一定的速度值来改变场景中节点执行动作的速度.速度动作一个有两个创建方式,一个是设置一个恒定的速度,加速度为0.一个是设置恒定的加速度.即速度增量.语法形式如下.
</b>
+ (SKAction *)speedTo:(CGFloat)speed duration:(NSTimeInterval)sec;
speed:指定节点运动的速度.
sec:指定完成动作所需要的时间
+ (SKAction *)speedBy:(CGFloat)speed duration:(NSTimeInterval)sec;
speed:指定节点运动的加速度.即速度增量
sec:指定完成动作所需要的时间
速度示例:
首先是恒定的速度的代码示例,不过在此之前,+ (SKAction *)group:(NSArray<SKAction*> *)actions;
要做一下接下,这是个组动作,可以把两个动作放在一起执行,主要的是两个动作是同时执行.下面我们会说到这个动作的.这里需要引用一下这个动作.
#pragma mark ---- 移动飞船 ----
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint position = [touch locationInNode:self];
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
SKAction * moveAction = [SKAction moveTo:position duration:3];
SKAction *speedAction = [SKAction speedTo:5 duration:1];
SKAction *groupAction = [SKAction group:@[
moveAction,
speedAction
]];
[planeNode runAction:groupAction];
}
我们看一下效果图,发现节点整体都是以一个恒定的速度做完每一次移动的.
接下来是以恒定的速度增量来来运动.示例代码如下
#pragma mark ---- 移动飞船 ----
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint position = [touch locationInNode:self];
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
SKAction * moveAction = [SKAction moveTo:position duration:3];
SKAction *speedAction = [SKAction speedBy:5 duration:1];
SKAction *groupAction = [SKAction group:@[
moveAction,
speedAction
]];
[planeNode runAction:groupAction];
}
下面的这效果图和上面的效果图一对比,发现,节点的速度是不断增加的.
组动作
组动作,我们在上面的移动操作的示例中已经做了简单的示例,组合动作其实就是吧两个或者两个以上的动作放在一起同时执行,组合动作最大的特点就是同时性,不管几个动作都是同时执行的.其语法形式如下:
+ (SKAction *)group:(NSArray<SKAction*> *)actions;
actions:是一个数组类型,数组中的元素是SKAction.
组动作示例:
组动作示例的示例代码就不多解释了,大家就参考着上面的速度动作的示例代码就可以了,当然了,组动作是可以其他的动作配合使用的.
序列动作
序列动作跟组动作一样,是一个组合动作,序列动作从字面上来看,最大的特点就是顺序.序列动作的使用场景是多个动作需要一个一个顺序执行,这时候就需要用到序列动作.
+ (SKAction *)sequence:(NSArray<SKAction*> *)actions;
actions:是一个数组类型,数组中的元素是SKAction.
序列动作示例:
序列动作的示例,我就用两个移动动作,当我点击屏幕的时候,飞船会飞到点击出,然后在回到初始位置.代码如下
#pragma mark ---- 移动飞船 ----
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint position = [touch locationInNode:self];
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
SKAction * moveAction = [SKAction moveTo:position duration:1];
SKAction *moveZeroAction = [SKAction moveTo:CGPointMake(self.size.width/2, self.size.height/2) duration:1];
SKAction *groupAction = [SKAction sequence:@[
moveAction,
moveZeroAction
]];
[planeNode runAction:groupAction];
}
效果图如下
重复动作
重复动作及一个动作运行多次或者无数次,其中重复动作分为无限重复和具有一定次数的重复.其中两种语法形式如下.
//无限重复
+ (SKAction *)repeatActionForever:(SKAction *)action;
//具有一定次数的重复
+ (SKAction *)repeatAction:(SKAction *)action count:(NSUInteger)count;
action:用来指定重复的动作.
count:用来指定重复的次数.
重复动作示例:
我们就拿上面的示例序列动作示例来添加在重复动作的中.如下代码所示.
#pragma mark ---- 移动飞船 ----
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint position = [touch locationInNode:self];
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
SKAction * moveAction = [SKAction moveTo:position duration:1];
SKAction *moveZeroAction = [SKAction moveTo:CGPointMake(self.size.width/2, self.size.height/2) duration:1];
SKAction *groupAction = [SKAction sequence:@[
moveAction,
moveZeroAction
]];
SKAction * repeatAction = [SKAction repeatActionForever:groupAction];
[planeNode runAction:repeatAction];
}
效果图如下,当我们点击屏幕的一个位置的时候,飞船会不断的来回移动.
组合动作注意事项:
上面叙述的组动作,序列动作,重复动作是以子动作的方式包含其他动作:
一个序列动作中有多个子动作,序列中的每一个动作在前一个动作结束之前开始。
一个组动作中有多个子动作,动作组中的所有动作同时开始执行。
一个重复动作中只有一个子动作,当重复动作中的子动作完成时,重复动作将重新开始执行。
上面三种动作可以嵌套使用,这种使动作结合起来的能力可以帮你为节点添加非常复杂的动作。
块动作
块动作其实就是把动作的整个执行过程放到一个Block块中,其中语法形式主要有两种,一种是常用的,另外一种是带有线程的.其语法形式如下.
+ (SKAction *)runBlock:(dispatch_block_t)block;
带有GCD线程相关的语法形式如下.
+ (SKAction *)runBlock:(dispatch_block_t)block queue:(dispatch_queue_t)queue;
block:指定执行的block块的系列动作
queue:指定GCD线程
块动作示例代码
接在在上面的重复动作的示例代码基础上来开发,效果图就如上了,但是实际的实现过程是有区别的,示例代码如下.
#pragma mark ---- 移动飞船 ----
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint position = [touch locationInNode:self];
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
SKAction *blockAction = [SKAction runBlock:^{
SKAction * moveAction = [SKAction moveTo:position duration:1];
SKAction *moveZeroAction = [SKAction moveTo:CGPointMake(self.size.width/2, self.size.height/2) duration:1];
SKAction *groupAction = [SKAction sequence:@[
moveAction,
moveZeroAction
]];
SKAction * repeatAction = [SKAction repeatActionForever:groupAction];
[planeNode runAction:repeatAction];
}];
[planeNode runAction:blockAction];
}
透明度动作
透明度动作就是指定节点的透明度的动作,虽然看起来比较简单,但是语法形式比较多,下面就注意的说明各个语法形式.
下面的两个语法是不用指定alpha值的,一个alpha值为1,一个为0,我们只需要设定两者的动作时间就可以了.
//alpha值为1
+ (SKAction *)fadeInWithDuration:(NSTimeInterval)sec;
//alpha值为0
+ (SKAction *)fadeOutWithDuration:(NSTimeInterval)sec;
下面的语法是需要指定alpha值的.
+ (SKAction *)fadeAlphaTo:(CGFloat)alpha duration:(NSTimeInterval)sec;
下面的语法是需要指定alpha值的增量.
+ (SKAction *)fadeAlphaBy:(CGFloat)factor duration:(NSTimeInterval)sec;
透明度动作的示例
我就以简单的不用指定的透明度的动作为示例.
#pragma mark ---- 飞船的透明度 ----
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
SKAction *alphaInAction = [SKAction fadeInWithDuration:1];
SKAction *alphaOutAction = [SKAction fadeOutWithDuration:1];
SKAction *repeatAction = [SKAction repeatActionForever:[SKAction sequence:@[
alphaOutAction,
alphaInAction
]]];
[planeNode runAction:repeatAction];
}
当我们点击屏幕的时候,效果图如下.
隐藏/显示动作
隐藏/显示动作和整体效果看起来和透明度的整体效果差不多,但是还是有一些区别的,透明度只是改变的是透明度,节点还是存在在场景上的,而隐藏/显示动作是真的隐藏了,节点是不存在与场景之中的.其语法形式如下.
//显示节点
+ (SKAction *)hide;
//隐藏节点
+ (SKAction *)unhide;
隐藏/显示动作示例:
isHide是我设置的一个监控的显示/隐藏的BOOL值.不多说,直接上代码.
#pragma mark ---- 隐藏/显示飞船 ----
BOOL isHide = YES;
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
isHide = !isHide;
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
SKAction *hideAction = [SKAction hide];
SKAction *unhideAction = [SKAction unhide];
if (isHide) {
[planeNode runAction:unhideAction];
}else{
[planeNode runAction:hideAction];
}
}
效果图如下所示,每当我点屏幕的时候,飞船的显示和隐藏状态就会发生改变.
尺寸动作
尺寸动作就是用来修改节点的尺寸的.其语法形式有以下几种,分别是以目标值调整尺寸,单独调节目标节点的高度或者宽度,以增量的形式调节整体的尺寸.具体语法形式如下.
以目标值调整尺寸
+ (SKAction *)resizeToWidth:(CGFloat)width height:(CGFloat)height duration:(NSTimeInterval)duration;
单独调节目标节点的高度或者宽度的两种形式语法如下
//调整宽度
+ (SKAction *)resizeToWidth:(CGFloat)width duration:(NSTimeInterval)duration;
//调整高度
+ (SKAction *)resizeToHeight:(CGFloat)height duration:(NSTimeInterval)duration;
以增量的形式调节整体的尺寸.
+ (SKAction *)resizeByWidth:(CGFloat)width height:(CGFloat)height duration:(NSTimeInterval)duration;
尺寸动作示例:
废话不多说,直接上代码.以以目标值调整尺寸为例.
#pragma mark ---- 改变尺寸飞船 ----
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
SKAction *sizeAction = [SKAction resizeToWidth:200 height:200 duration:0.5];
[planeNode runAction:sizeAction];
}
效果图如下.
缩放动作
缩放动作就是对节点进行缩放操作.其语法形式与尺寸动作类似,一共有三种,语法形式如下.
以缩放倍数缩放如下.
+ (SKAction *)scaleTo:(CGFloat)scale duration:(NSTimeInterval)sec;
//对宽和高以不同的缩放比例缩放.
+ (SKAction *)scaleXTo:(CGFloat)xScale y:(CGFloat)yScale duration:(NSTimeInterval)sec;
单独对宽和高进行缩放.
//宽度缩放
+ (SKAction *)scaleXTo:(CGFloat)scale duration:(NSTimeInterval)sec;
//高度缩放
+ (SKAction *)scaleYTo:(CGFloat)scale duration:(NSTimeInterval)sec;
以增量值进行缩放.
+ (SKAction *)scaleBy:(CGFloat)scale duration:(NSTimeInterval)sec;
//对宽和高以不同的缩放比例增量值缩放.
+ (SKAction *)scaleXBy:(CGFloat)xScale y:(CGFloat)yScale duration:(NSTimeInterval)sec;
缩放动作示例:
下面就一最简单的缩放形式进行缩放,其他的缩放类似
#pragma mark ---- 缩放飞船 ----
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
SKAction *sizeAction = [SKAction scaleTo:2 duration:1];
[planeNode runAction:sizeAction];
}
效果图如下
颜色动作
颜色动作其实是改变节点的颜色以及混合因子,语法形式总共有两种,一种是只改变混合因子,另外一种是改变颜色和混合因子,对于混合因子,类型为CGFloat类型,可以理解为颜色的深浅度.具体的语法形式如下.
只改变混合因子
+ (SKAction *)colorizeWithColorBlendFactor:(CGFloat)colorBlendFactor duration:(NSTimeInterval)sec;
同时改变混合因子和颜色
+ (SKAction *)colorizeWithColor:(SKColor *)color colorBlendFactor:(CGFloat)colorBlendFactor duration:(NSTimeInterval)sec;
颜色动作示例:
下面以只改变混合因子为示例.
#pragma mark ---- 改变飞船的颜色 ----
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
SKAction *sizeAction = [SKAction colorizeWithColorBlendFactor:0.66 duration:1];
[planeNode runAction:sizeAction];
}
效果图如下.通过效果图我们会发现飞机整体的颜色会变浅.
改变纹理的动作
改变纹理的动作,这个动作其实可以理解为是让一个游戏物体动起来,我们看到很多游戏都是这样的,例如下面的爆炸效果图.对于这个动作其实是要结合这纹理集进行实现的,改变纹理的动作也是比较常用的一个动作,具体内容查看SpriteKit框架之SKTextureAtlas这篇文章.
(重要等级:⭐️⭐️⭐️⭐️⭐️)
等待动作
等待动作也叫延时动作.也是在游戏中经常使用的一个动作,经常也其他动作配合使用.其语法形式一共有两种,比较特殊的哪一种形式是可以用力啊指定演示时间的范围的.代码如下.
这一种延时动作只能指定延时的时间
+ (SKAction *)waitForDuration:(NSTimeInterval)sec;
这一种延时动作是可以用来指定延时时间的范围.
+ (SKAction *)waitForDuration:(NSTimeInterval)sec withRange:(NSTimeInterval)durationRange;
sec:指定延时的时间.
durationRange:指定延时时间的范围.
等待动作示例:
我们就以上面的改变飞创的颜色的动作为基础进行等待动作的添加,代码如下.
#pragma mark ---- 改变飞船的颜色 ----
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
SKAction *sizeAction = [SKAction colorizeWithColorBlendFactor:0.66 duration:5];
SKAction *waitAction = [SKAction waitForDuration:1];
[planeNode runAction:[SKAction sequence:@[
waitAction,
sizeAction
]]];
}
我们看一下效果图,当我点击完屏幕之后,移开鼠标,等待5秒之后.改变颜色动作才会执行.
自定义动作
如果系统的动作还不能满足我们的需求怎么办?这时候,我们可以自定义动作,自定义出我们想要实现的效果.其语法形式如下.
+ (SKAction *)customActionWithDuration:(NSTimeInterval)seconds actionBlock:(void (^)(SKNode *node, CGFloat elapsedTime))block;
seconds:指定自定义动作完成所需要的时间
block:block块内指定自定义动作的内容.
自定义动作示例:
废话不多说,直接上代码
#pragma mark ---- 改变飞船的坐标 ----
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint position = [touch locationInNode:self];
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
SKAction *myMoveAction = [SKAction customActionWithDuration:1 actionBlock:^(SKNode * _Nonnull node, CGFloat elapsedTime) {
SKSpriteNode *plane= (SKSpriteNode *)node;
plane.position= CGPointMake(position.x, position.y);
}];
[planeNode runAction: myMoveAction];
}
效果图如下.
删除动作.
删除动作就是删除动作,当我们不需要节点的时候,我们可以使用删除动作删除节点.其语法形式如下.
+ (SKAction *)removeFromParent;
删除动作示例:
废话不多说,直接上代码,效果图不就添加了,就是直接删除飞船了.
#pragma mark ---- 删除飞船 ----
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];
[planeNode runAction: [SKAction removeFromParent]];
}
最后说两句
SpriteKit所有的动作都在这了,SKAction创建形式比较多.所以博客篇幅较长,这也没有办法,建议学习的时候每一个方法都测试一下,因为只有测试之后,你才能知道他的用途和注意事项,建议本篇博客学习时间为3天.好了,SKAction动作相关创建方式就说这么多了!如果您觉得这篇博客对你有所帮助就点赞支持一下呗,没帮助就不要点了,毕竟没帮到您是我最大的失败~~😂