Coca ColaKit框架之最全动作介绍

</b>

Coca Cola Kit 是iOS
7开头添加的一个新内置框架。首要用以支付2D游戏。协理内容包涵天使、各样特效(摄像、滤镜遮罩),继承了物理引擎等许多内容。

斩断投机的后路,才能更好地获取出路。在重重时候,大家都亟待一种斩断投机退路的胆略。

图片 1

</b>

timg-2.jpeg

</br>

Pepsi-ColaKit常用的类:

SKSpriteNode —– 用于绘制精灵的纹路
SKVideoNod —– 用于广播摄像
SKLabelNode —– 用于渲染文本
SKShapeNode —– 用于渲染基于Core Graphics 路径的形制
SKEmitterNode —– 用于创立和渲染粒子系统
SKCropNode —– 用于选取遮罩来裁剪子节点
SKEffectNode —– 用于接纳遮罩来裁剪子节点

简短介绍一下Coca ColaKit,上边介绍起来spriteKit 中基础类的拔取。

SKAction简介


在原先的博客中就说过,动作是三个玩耍中不可缺失的,比如移动,形状的变换等等.比如”一流马里奥”中的马里奥的移位,以及蘑菇,怪兽的移动都以索要动作的支撑的.

在SpriteKit框架中是用SKAction类来贯彻动作.2个SKAction实例是二个动作,通过SKScene场景中的节点来施行。动作可以绑定到节点上,用以改变节点的布局和内容,有时也可以改变风貌。当场景处理其子节点的时候,与那么些节点相关联的动作将被统计。由于SKAction动作类型过多,所以小编就先用下图举办了分类.

</br>

SKScene 场景

行使SKScene以前先说一下SKView,SKView 类是特意用来表现Coca Cola Kit的View,在这么些类中得以渲染和治本壹个SKScene,每种Scene中可以加载多少个机智,Scene可以管理天使的作为。

导入SpriteKit 创建SKScene:

func createScene() {
        let skView = SKView.init(frame: self.view.bounds)
        if(skView.scene == nil){
            skView.showsFPS = true
            skView.showsNodeCount = true
            let scene = GameScene(size: skView.bounds.size)
            skView.presentScene(scene)
        }
        self.view.addSubview(skView)
    }

在动用时,一般会将Scene子类化,在子类中装置它的质量。在打闹中都会有几个场景,就会有气象切换,单纯的景观切换会显得相当生硬,所以Coca ColaKit中提供了过度动画。

crossFadeWithDuration 交叉淡入淡出过渡动画
doorsCloseHorizontalWithDuration 从左右两边水平关闭
doorsCloseVerticalWithDuration 从上下两边垂直关闭
doorsOpenHorizontalWithDuration 从中路向左右两边水平打开
doorsOpenVerticalWithDuration 从中路向左右两边垂直打开
doorwayWithDuration 从中间向两边开拓,新现象从后方向显示器靠近
fadeWithColor 淡入淡出的衔接动画,先成为钦定颜色,再变成目的场景
fadeWithDuration 淡入淡出的连片动画,先成为蛋青,再变成内定颜色
flipHorizontalWithDuration 以水平中轴线垂直翻转
flipVerticalWithDuration 以垂直中中轴线水平翻转
movenInWithDirection 新景色从内定方向移入
pushWithDirection 新情景从内定方向推入
revealWithDirection 旧场景向钦命方向移除,新现象在旧场景下边
使用:skView.presentScene(scene, transition:SKTransition)

SKAction分类


</b>

SKSpriteNode 精灵

敏感分为有纹理天使和无纹理天使,纹理天使是常用的,是大家把插图放加入景中的方法,像娱乐中的职分角色和背景等。

有备无患干活

下边全部的动作前提准备都以一样的,大家就以微信手淫的场地为实例,具体代发如下

-(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];

}

</br>

境况示意图

</br>

行使方法,创立天使:
let KScreenWidth = UIScreen.main.bounds.width
let KScreenHeight = UIScreen.main.bounds.height
func addNode() {
        let texture = SKTexture.init(imageNamed: "ao.jpg")  // 纹理
        let splash = SKSpriteNode.init(texture: texture)
//        let splash = SKSpriteNode.init(imageNamed: "ao.jpg")
        splash.size = CGSize.init(width: KScreenWidth, height: KScreenHeight)
        splash.position = CGPoint.init(x: KScreenWidth/2, y: KScreenHeight/2)
        // 设置锚点
//        splash.anchorPoint = CGPoint.init(x: 0.0, y: 0.0)
        // 精灵着色
        splash.color = SKColor.green
        splash.colorBlendFactor = 0.3   // 颜色混合因子0~1
        splash.setScale(2)  // 缩放 放大两倍
//        splash.xScale = 2   // 单独缩放x
        splash.zRotation = CGFloat(Double.pi)/2  // 旋转
        splash.alpha = 0.5
        splash.isHidden = false
        self.addChild(splash)

//        splash.removeFromParent()
//        removeAllChildren()
    }

内部的锚点可以依照下边的图明白

图片 2

B2588466-9F89-4209-9EB8-BC732A1F1935.png

可以明白为将图纸订在墙上,锚点相当于钉子钉的职位,暗中认可是(0.5, 0.5)。

移动动作

挪动动作在二个游玩中是最普遍的动作了.移动动作根本分为以点的款型活动和以偏移量的样式移动.且听自身逐步道来.
</br>

  • ##### 其中以点的款式活动的主要有多少个SKAction类方法来创建.

+ (SKAction *)moveTo:(CGPoint)location duration:(NSTimeInterval)sec;

location: 用来内定节点移动到的地方.
sec:用来钦点移动动作所需求的时间.
</br>

+ (SKAction *)moveToX:(CGFloat)x duration:(NSTimeInterval)sec;

x: 用来钦赐节点的x轴上运动到的地方.节点的y轴上的值不变化.
sec:用来钦点移动动作所须要的时间.
</br>

+ (SKAction *)moveToY:(CGFloat)y duration:(NSTimeInterval)sec;

y: 用来指定节点的y轴上移步到的地方.节点的x轴上的值不变化.
sec:用来钦点移动动作所急需的时间.
</br>
</br>

  • ##### 以偏移量的样式活动主要有两种两系列方法.

+ (SKAction *)moveBy:(CGVector)delta duration:(NSTimeInterval)sec;

delta:是3个矢量,用力啊钦定偏移量,类型为CGVector,CGVector是多少个很不难的结构体,有dx和dy组成.dx表示x轴上的偏移量,dy表示y轴上的偏移量.结构体格局如下.

struct CGVector {
    CGFloat dx;
    CGFloat dy;
};

sec:用来钦赐移动动作所急需的时间.
</br>

+ (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];


}

</b>
地点的分级以点的款型和偏移量的款型做出了演示,我们看一下功效图.当大家每一次点击屏幕的时候接触移动动作,下边我们就看一下两种样式的成效图有什么分歧.

以点花样活动效果图

以偏移量情势活动效果图

</br>

删除天使
splash.removeFromParent()
removeAllChildren()

旋转动作

娱乐中的物体的旋转大多要求用的旋转动作,旋转动作的始建方法唯有一种,如下所示.

+ (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度.效果图如下.

旋转效果图

</br>

SKLightNode

为了让天使更有着真实感,百事可乐Kit提供了SKLightNode作为光源节点。

SKLightNode
可以定义光源的颜料、阴影和衰减程度。继承于SKNode。为了在SKCoca ColaNode的意义尤其活龙活现,SKPepsi-ColaNode
提供了normalTexture 属性,用来储存原贴图的觉察贴图NormalMap。

SKLightNode常用属性:

enabled 光源的开关
ambientColor 环境颜色,暗中同意深褐(无)
lightColor 光的水彩,默许金黄
shadowColor 被天使物体遮挡爆发的黑影颜色
falloff 光源强度的衰减比率
categoryBitMask 光的档次,3几个人整数。SKSpriteNode的
lightingBItMask(被何种光照亮)、shadowedBitMask(被何种光爆发阴影)、shadowCastBitMask(遮挡何种光线并爆发阴影)
存储着光的品类。

途径动作

在游玩进度中,平常会遇到某个怪物,它们会按部就班一定的路劲轨迹不断的行动,在SKAciton中就有对路线动作的成立格局,其常用语法形式如下

+ (SKAction *)followPath:(CGPathRef)path duration:(NSTimeInterval)sec;

path:用来钦点1个CGPathRef路径,那几个路子就是灵动的移位路径.
sec:指定这么些路子动作形成所急需的时间.
</br>

比较于地点比较常用的方法之外,上面的语法方式则应该算的上他的增强版,其中囊括对其路径的点相对性,以及Z轴的旋转属性都得以开展设置操作.

+ (SKAction *)followPath:(CGPathRef)path asOffset:(BOOL)offset orientToPath:(BOOL)orient duration:(NSTimeInterval)sec;

</br>

  • ##### 路径示例:

上面就以三个矩形路径为示范,给节点添加路径动作,让其进展移动.

#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];

}

</b>
由此下边的出力图大家就可以精通路径的点是相持路径.而且节点Z轴在打转的时候属性也是发出变动的.

</br>

上面的则是一体化版的不二法门动作创立.然后大家通过修改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];


}

</b>
在 *** + (SKAction *)followPath:(CGPathRef)path
duration:(NSTimeInterval)sec; **
那几个方法中暗中同意的offset是YES,orient也是YES,也等于说假设上边的代码执行的话,是跟最常用的法子的效应图一律的,今后我们就先只修改offset的值为NO.会发现节点是以相对路径举行移动的,相当于一节点的父类坐标系为尺度,举行动作的执行.

offset的值为NO

</b>
接下去大家只修改orient的值为NO,其余不变,我们会发觉节点Z轴是从未有过暴发其他改变的.

</br>

SKLightNode使用:
func addLightNode() {
        backgroundColor = SKColor.black
        // 创建精灵
        let spriNode = SKSpriteNode.init(color: UIColor.white, size: CGSize.init(width: 300, height: 300))
        spriNode.position = CGPoint.init(x: KScreenWidth/2, y: KScreenHeight/2)
        self.addChild(spriNode)
        // 添加光源
        let nodeNormMap = spriNode.texture?.generatingNormalMap()
        spriNode.normalTexture = nodeNormMap
        spriNode.lightingBitMask = 1    // 被何种光照
        spriNode.name = "SprNOde"
        let lightSprite = SKLightNode() //实例化光源
        lightSprite.position = CGPoint.init(x: KScreenWidth/2 + 60, y: KScreenHeight/2) // 关照位置
        lightSprite.name = "LightSptite"
        lightSprite.categoryBitMask = 1 // 光的种类
        self.addChild(lightSprite)
    }

运维结果截图:

图片 3

C9C46872B5421D98C7940C17C21B4D3C.png

反向动作

反向动作就是气象中的节点原来往1个趋势进行运动,不过在运维时这个节点却向相反的防线举行了活动,如若想要落成反向运动,就要求运用到反向运动,反向运动的制造方法为对象方法,是行使2个动作调用- (SKAction *)reversedAction;再次来到动作就会说这一个动作的反向动作.
其语法方式如下所示.

- (SKAction *)reversedAction;

</br>

  • ##### 反向示例:

就那上边的路径动作为例,我们创造它的反向动作,为了尤其绘身绘色形象,作者给动作的触发设置了1个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];

    }

}

</br>

如下图所示,那就是反向动作的成效图

反向效率图.gif

</br>

SKAction 动作

SKAction是玩玩中很关键的一部分,内容很多啊,会写的相比长。首先预览下内容,动作的分类:动作属性、移动动作、种类动作、重复动作、延迟动作、缩放动作、旋转动作、调整尺寸的动作、组合动作、改变反射率的动作、改变颜色的动作、以动画片的花样改变纹理的动作、路径动作、反向运动、速度动作、突显或躲藏动作、块动作、自定义动作、删除动作。

进程动作

进程动作一般是匹配着其余地点动作使用的,其实不唯有速度动作还有速度属性,大家可以给定一定的速度值来改变风貌中节点执行动作的进度.速度动作二个有七个成立情势,三个是设置二个一定的快慢,加快度为0.2个是设置一定的增速度.即速度增量.语法格局如下.
</b>

+ (SKAction *)speedTo:(CGFloat)speed duration:(NSTimeInterval)sec;

speed:钦命节点运动的速度.
sec:内定完毕动作所急需的时日

+ (SKAction *)speedBy:(CGFloat)speed duration:(NSTimeInterval)sec;

speed:钦点节点运动的增速度.即速度增量
sec:内定达成动作所须要的年华

</br>

  • ##### 速度示例:

首先是一直的进度的代码示例,然而在此之前,+ (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];
}

</b>
我们看一下功效图,发现节点全部都是以1个定点的速度做完每四次活动的.

效果图.gif

</br>
接下去是以固定的快慢增量来来运动.示例代码如下

#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];
}

上面的那成效图和上边的效率图一相对而言,发现,节点的进程是绵绵追加的.

</br>

始建动作方法
let spriteMoveUp = SKAction.moveBy(x: 300, y: 0, duration: 1.0) // X方向向右移100

组动作

组动作,大家在下边的运动操作的以身作则中曾经做了简要的言传身教,组合动作其实就是吗多个可能八个以上的动作放在一起同时实施,组合动作最大的特点就是同时性,不管几个动作都以还要推行的.其语法格局如下:

</b>

+ (SKAction *)group:(NSArray<SKAction*> *)actions;

actions:是一个数组类型,数组中的元素是SKAction.

</br>

  • ##### 组动作演示:

组动作示例的示范代码就不多解释了,我们就参照着地点的速度动作的示范代码就足以了,当然了,组动作是可以其余的动作合作使用的.

</br>

一 、移动动作

回顾以点的不二法门移动和 以偏移量的情势移动

func nodeAction() {
        let texture = SKTexture.init(imageNamed: "field")  // 纹理
        let background = SKSpriteNode.init(texture: texture)
        background.position = CGPoint.init(x: KScreenWidth/2, y: KScreenHeight/2)
        background.size = CGSize.init(width: KScreenWidth, height: KScreenHeight)
        self.addChild(background)

        let ball = SKSpriteNode.init(imageNamed: "soccer")
        ball.position = CGPoint.init(x: KScreenWidth/2, y: KScreenHeight/2)
        ball.setScale(1.05) // 缩放
        ball.size = CGSize.init(width: 50, height: 50)
        self.addChild(ball)

        // 动作   以点的方式移动
        let spriteMoveUp = SKAction.moveBy(x: 300, y: 0, duration: 1.0) // X方向向右移100
        // ball.run(spriteMoveUp)
        // 动作  以偏移量的方式移动
        let negDelta = CGVector.init(dx: -300, dy: -100)
        let actionMove = SKAction.move(by: negDelta, duration: 2)
        ball.run(actionMove)
    }

队列动作

队列动作跟组动作一样,是三个结合动作,体系动作从字面上来看,最大的特点就是顺序.连串动作的利用境况是几个动作要求贰个二个相继执行,那时候就须求用到行列动作.

+ (SKAction *)sequence:(NSArray<SKAction*> *)actions;

actions:是3个数组类型,数组中的成分是SKAction.

</br>

  • ##### 种类动作演示:

队列动作的示范,小编就用多个活动动作,当自家点击屏幕的时候,飞船会飞到点击出,然后在回去初阶地点.代码如下

#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];
}

</b>
效益图如下

效果图.gif

</br>

二 、动作属性

speed 速度
duration 时间
timingMode 曲线格局

双重动作

再次动作及一个动作运维往往依旧无多次,其中重复动作分为无限重复和持有自然次数的重复.其中三种语法格局如下.

//无限重复
+ (SKAction *)repeatActionForever:(SKAction *)action;

//具有一定次数的重复
+ (SKAction *)repeatAction:(SKAction *)action count:(NSUInteger)count;

action:用来指定重复的动作.
count:用来内定重复的次数.

</br>

  • ##### 重复动作演示:

大家就拿地方的以身作则队列动作演示来添加在重复动作的中.如下代码所示.

#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];
}

功效图如下,当大家点击显示器的一个职位的时候,飞船会不断的来往移动.

</br>

结合动作注意事项:
上面叙述的组动作,系列动作,重复动作是以子动作的章程蕴涵其余动作:
三个行列动作中有多少个子动作,连串中的每3个动作在前三个动作截止以前开首。
多个组动作中有四个子动作,动作组中的全数动作同时开班实施。
二个双重动作中唯有一个子动作,当再一次动作中的子动作达成时,重复动作将再一次开始施行。
下边三种动作可以嵌套使用,那种使动作结合起来的能力能够帮您为节点添加卓殊复杂的动作。

</br>

曲线情势包涵八种:

SKAction提姆ingLinear 平均分布
SKActionTimingEaseIn 起先较慢,再加速
SKActionTimingEaseOut 开始快,再变慢
SKActionTimingEaseInEaseOut 开端慢,再加速至中间,再变慢
let spriteMoveUp = SKAction.moveBy(x: 300, y: 0, duration: 1.0)

spriteMoveUp.speed = 1.3  // 速度
spriteMoveUp.timingMode = SKActionTimingMode.easeInEaseOut  // 曲线方式
print(ball.speed)  // 获取并输出动作所需时间

块动作

块动作其实就是把动作的上上下下实施进程置于贰个Block块中,其中语法情势首要有二种,一种是常用的,别的一种是带有线程的.其语法方式如下.

+ (SKAction *)runBlock:(dispatch_block_t)block;

饱含GCD线程相关的语法格局如下.

+ (SKAction *)runBlock:(dispatch_block_t)block queue:(dispatch_queue_t)queue;

block:钦定执行的block块的一而再串动作
queue:指定GCD线程

</br>

  • ##### 块动作演示代码

接在在地点的再次动作的以身作则代码基础上来支付,效果图就好像上了,可是事实上的落到实处进程是有分其他,示例代码如下.

#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];
}

</br>

叁 、 体系动作

运用sequence()
方法完毕。以地点移动动作为例,将spriteMoveUp、actionMove作为一个种类动作然后实施。

let sequence = SKAction.sequence([spriteMoveUp, actionMove])
ball.run(sequence)

反射率动作

发光度动作就是钦定节点的折射率的动作,纵然看起来相比较不难,不过语法格局比较多,上面就注意的辨证种种语法方式.

</b>

上边的八个语法是决不内定阿尔法值的,1个阿尔法值为1,一个为0,大家只要求设定两者的动作时间就可以了.

//alpha值为1
+ (SKAction *)fadeInWithDuration:(NSTimeInterval)sec;

//alpha值为0
+ (SKAction *)fadeOutWithDuration:(NSTimeInterval)sec;

</b>

上面的语法是亟需钦点阿尔法值的.

+ (SKAction *)fadeAlphaTo:(CGFloat)alpha duration:(NSTimeInterval)sec;

</b>

上面的语法是内需钦命阿尔法值的增量.

+ (SKAction *)fadeAlphaBy:(CGFloat)factor duration:(NSTimeInterval)sec;

</br>

  • ##### 反射率动作的示范

本身就以简练的绝不内定的反射率的动作为示例.

#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];
}

当大家点击显示器的时候,效果图如下.

</br>

肆 、重复动作

重复动作分为无限重复和有次数的重新,使用格局:

let sequence = SKAction.sequence([spriteMoveUp, actionMove])
//        let runForever = SKAction.repeatForever(sequence)  // 无限重复
let runRepeat = SKAction.repeat(sequence, count: 2)  // 重复两次(执行两次)
ball.run(runRepeat)

隐藏/突显动作

潜伏/展现动作和一体化效果看起来和光滑度的完好效用差不离,但是照旧有部分区其他,光滑度只是改变的是折射率,节点依然存在在场所上的,而藏身/显示动作是真正隐藏了,节点是不设有与场景之中的.其语法格局如下.

//显示节点
+ (SKAction *)hide;

//隐藏节点
+ (SKAction *)unhide;

</br>

  • ##### 隐藏/突显动作示例.

</b>
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];

    }
}

成效图如下所示,每当我点屏幕的时候,飞船的呈现和潜伏状态就会生出改变.

</br>

五 、延迟动作

行使waitForDuration()方法完结。以体系动作为例,在连串中插入3个延迟动作。

let wait = SKAction.wait(forDuration: 1.0)   // 延迟动作(延迟1s)
let sequence = SKAction.sequence([spriteMoveUp, wait, actionMove])
ball.run(sequence)

尺寸动作

尺寸动作就是用来修改节点的尺码的.其语法方式有以下二种,分别是以目的值调整尺寸,单独调节目的节点的可观或然增幅,以增量的款式调节全部的尺寸.具体语法格局如下.

以目的值调整尺寸

+ (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;

</br>

  • ##### 尺寸动作示例:

废话不多说,直接上代码.以以目标值调整尺寸为例.

#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];
}

职能图如下.

</br>

⑥ 、缩放动作

缩放动作分为:以缩放倍数缩放(scaleTo()、scaleXTo())、以增量值缩放(scaleBy()、scaleXBy())

func scaleAction() {
        let ball = SKSpriteNode.init(imageNamed: "soccer")
        ball.position = CGPoint.init(x: KScreenWidth/2, y: KScreenHeight/2)
        ball.size = CGSize.init(width: 50, height: 50)  // 设置初始大)
        self.addChild(ball)

        // 以缩放倍数缩放
        let shrink = SKAction.scale(to: 0.1, duration: 0.5) // 缩小
        let zoom = SKAction.scale(to: 10, duration: 2) // 放大
        // 对宽高进行缩放
//        let shrink = SKAction.scaleX(to: 0.1, duration: 3) // 缩小
//        let zoom = SKAction.scale(to: 1, duration: 3) // 放大
        let sequence = SKAction.sequence([shrink, zoom])
        let runForever = SKAction.repeatForever(sequence)
//        ball.run(runForever)

        // 以增量值缩放
        let scaleZoom = SKAction.scale(by: 1, duration: 0.2)    // 放大
        let scaleShrink = SKAction.scale(by: -1, duration: 0.2) // 缩小
//        let scaleZoom = SKAction.scaleX(by: 1, duration: 0.2)    // 放大
//        let scaleShrink = SKAction.scaleX(by: -1, duration: 0.2) // 缩小
        let scaleSequence = SKAction.sequence([scaleZoom, scaleShrink])
        let scaleForever = SKAction.repeatForever(scaleSequence)
        ball.run(scaleForever)
    }

缩放动作

缩放动作就是对节点开展缩放操作.其语法情势与尺寸动作类似,一共有两种,语法格局如下.

以缩放倍数缩放如下.

+ (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;

</br>

  • ##### 缩放动作演示:

上边就一最简易的缩放情势开展缩放,其余的缩放类似

#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];
}

成效图如下

</br>

柒 、旋转动作

利用rotateByAngle()方法落成。

   let rotate = SKAction.rotate(byAngle: CGFloat(Double.pi)*2, duration: 3)
   ball.run(rotate)

颜色动作

水彩动作其实是改变节点的颜色以及混合因子,语法方式总共有三种,一种是只变动混合因子,其它一种是改变颜色和交集因子,对于混合因子,类型为CGFloat类型,可以清楚为颜色的浓度度.具体的语法格局如下.

只改变混合因子

+ (SKAction *)colorizeWithColorBlendFactor:(CGFloat)colorBlendFactor duration:(NSTimeInterval)sec;

而且更改混合因子和颜料

+ (SKAction *)colorizeWithColor:(SKColor *)color colorBlendFactor:(CGFloat)colorBlendFactor duration:(NSTimeInterval)sec;

</br>

  • ##### 颜色动作演示:

下边以只变动混合因子为示例.

#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];
}

功用图如下.通过效用图大家会意识飞机全部的颜料会变浅.

</br>

捌 、调整尺寸的动作

调整尺寸的动作包涵:以目的值调整尺寸、以增量调整尺寸

let resizeWidth = SKAction.resize(toWidth: 100, height: 100, duration: 2)  // 以目标值调整尺寸
ball.run(resizeWidth)
let resize = SKAction.resize(byWidth: 200, height: 200, duration: 2)  // 以增量调整尺寸
ball.run(resize)

改变纹理的动作

更改纹理的动作,这些动作其实可以掌握为是让多少个游戏物体动起来,大家看来不少游戏都以那般的,例如上面的爆炸效果图.对于那些动作其实是要结成那纹理集进行落实的,改变纹理的动作也是相比较常用的1个动作,具体内容查看SpriteKit框架之SKTextureAtlas那篇小说.
(紧要阶段:⭐️⭐️⭐️⭐️⭐️)

</br>

玖 、组合动作

不畏同时对五个及以上的动作举行实施。使用group()方法完结。

func groupAction() {
        backgroundColor = SKColor.black

        let star = SKSpriteNode.init(imageNamed: "star.jpg")
        star.position = CGPoint.init(x: KScreenWidth/2, y: KScreenHeight/2)
        star.size = CGSize.init(width: 300, height: 300)
        self.addChild(star)

        let zoom = SKAction.scale(to: 1, duration: 0.2)
        let shrink = SKAction.scale(to: 0.1, duration: 0.2)
        let sequence = SKAction.sequence([zoom, shrink])
        let rotate = SKAction.rotate(byAngle: CGFloat(Double.pi)*2, duration: 1.5)

        let group = SKAction.group([sequence, rotate])  // 组合动画
        let runForever = SKAction.repeatForever(group)
        star.run(runForever)
    }

等待动作

伺机动作也叫延时动作.也是在玩耍中平时接纳的壹个动作,常常也其余动作相当使用.其语法格局一共有三种,比较奇特的哪个种类样式是可以努力啊钦赐演示时间的限量的.代码如下.

这一种延时动作不得不指定延时的时刻

+ (SKAction *)waitForDuration:(NSTimeInterval)sec;

这一种延时动作是足以用来指定延时时间的范围.

+ (SKAction *)waitForDuration:(NSTimeInterval)sec withRange:(NSTimeInterval)durationRange;

sec:钦赐延时的时间.
durationRange:钦定延时时间的范围.

</br>

  • ##### 等待动作演示:

大家就以地方的改观飞创的水彩的动作为根基举行等待动作的丰硕,代码如下.

#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秒之后.改变颜色动作才会执行.

</br></br>

十 、改变反射率的动作

有二种,分别是不必要内定阿尔法值和指定阿尔法值(以目标值钦点、以增量值钦赐)。

// 不需要指定alpha值
let fadeOut = SKAction.fadeOut(withDuration: 0.25)
let fadeIn = SKAction.fadeIn(withDuration: 0.25)
// 指定alpha值
let fadeOutAlpha = SKAction.fadeAlpha(to: 0, duration: 0.2) // 以目标值指定
let fadeInAlpha = SKAction.fadeAlpha(to: 1, duration: 0.2)
let hide = SKAction.fadeAlpha(by: -1, duration: 0.2)    // 以增量值指定
let show = SKAction.fadeAlpha(by: 1, duration: 0.2)

自定义动作

一旦系统的动作还不可以满意大家的需求如何是好?那时候,我们得以自定义动作,自定义出大家想要完成的职能.其语法格局如下.

+ (SKAction *)customActionWithDuration:(NSTimeInterval)seconds actionBlock:(void (^)(SKNode *node, CGFloat elapsedTime))block;

seconds:钦赐自定义动作一挥而就所必要的时光
block:block块内钦点自定义动作的内容.

</br>

  • ##### 自定义动作演示:

废话不多说,直接上代码

#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];

}

效率图如下.

</br></br>

1一 、改变颜色的动作

分为两种:改变混合因子、改变颜色和交集因子。

// 改变混合因子
let color1 = SKAction.colorize(withColorBlendFactor: 0.8, duration: 0.5)
let color2 = SKAction.colorize(withColorBlendFactor: 0.0, duration: 0.5)
// 改变颜色和混合因子
let color = SKAction.colorize(with: SKColor.green, colorBlendFactor: 0.7, duration: 2)

除去动作.

剔除动作就是去除动作,当大家不须要节点的时候,我们可以行使删除动作删除节点.其语法方式如下.

+ (SKAction *)removeFromParent;

</br>

1二 、以卡通的方式改变纹理的动作

利用animateWithTextures()方法完结

func animateTexturesAction() {
        // 加载动画纹理
        let textures = NSMutableArray.init()
        for index in 4...13 {
            let texture = SKTexture.init(imageNamed: "frame-\(index)")
            textures.add(texture)
        }

        let playerSprite = SKSpriteNode.init(texture: textures.firstObject as? SKTexture)
        playerSprite.position = CGPoint.init(x: KScreenWidth/2, y: KScreenHeight/2)
        self.addChild(playerSprite)

        let runRightAction = SKAction.animate(with: textures as! [SKTexture], timePerFrame: 0.1)
        let runForever = SKAction.repeatForever(runRightAction)
        playerSprite.run(runForever)
    }

删除动作演示:

废话不多说,直接上代码,效果图不就添加了,就是间接删除飞船了.

#pragma mark ---- 删除飞船 ----


-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{


    SKSpriteNode *planeNode = (SKSpriteNode *)[self childNodeWithName:@"plane"];


    [planeNode runAction: [SKAction removeFromParent]];

}

</br>
</br>

1③ 、路径动作

运用followPath()方法完结。方法中的属性:

path 用来指定三个CGPathRef路径
offset
用来内定路线中的点是或不是为相对坐标,true(相对坐标),false(相对坐标)
orient 指定Z轴在打转时属性是或不是改变
sec 动作时间

func pathAction() {
        let background = SKSpriteNode.init(imageNamed: "field")
        background.position = CGPoint.init(x: KScreenWidth/2, y: KScreenHeight/2)
        background.size = CGSize.init(width: KScreenWidth, height: KScreenHeight)
        self.addChild(background)

        let ball = SKSpriteNode.init(imageNamed: "soccer")
        ball.position = CGPoint.init(x: KScreenWidth/2, y: KScreenHeight/2)
        ball.size = CGSize.init(width: 50, height: 50)
        self.addChild(ball)

        let circle = CGPath.init(roundedRect: CGRect.init(x: 200, y:100 , width: 200, height: 200), cornerWidth: 100, cornerHeight: 100, transform: nil)
        let follow = SKAction.follow(circle, asOffset: false, orientToPath: false, duration: 5)
        let runRepeat = SKAction.repeatForever(follow)
        // 反向运动
        let reverse = runRepeat.reversed()
        // 速度动作
        let speedaction = SKAction.speed(to: 15, duration: 1.0)
        let group = SKAction.group([speedaction, reverse])
        ball.run(group)

    }

说到底说两句


</b>

1肆 、反向运动
let spriteMoveUp = SKAction.moveBy(x: 300, y: 0, duration: 1.0)
let reverse = spriteMoveUp.reversed()  // 反向运动

雪碧Kit全数的动作都在那了,SKAction创设格局相比多.所以博客篇幅较长,那也从不主意,指出学习的时候每三个办法都测试一下,因为唯有测试之后,你才能知道她的用处和注意事项,指出本篇博客学习时光为3天.好了,SKAction动作相关创建方式就说这么多了!如若您觉得那篇博客对你持有支持就点赞协助一下嘛,没帮助就无须点了,终究没帮到您是本人最大的破产~~😂

1五 、速度动作

使用 speedTo() 或者 speedBy() 实现。

let speedaction = SKAction.speed(to: 5, duration: 1.0)
1陆 、呈现或隐藏动作

运用 hide() 和unhide()方法完结

let hide = SKAction.hide()      // 显示动作
let show = SKAction.unhide()    // 隐藏动作
17、块动作

采用runBlock()方法已毕,异步调用动作的艺术,可钦定执行的线程。

func blockAction() {
        let ball = SKSpriteNode.init(imageNamed: "soccer")
        ball.position = CGPoint.init(x: KScreenWidth/2, y: KScreenHeight/2)
        ball.size = CGSize.init(width: 80, height: 80)
        self.addChild(ball)

        // 创建块动作
        let blockAction = SKAction.run { 
            let rotate = SKAction.rotate(byAngle: CGFloat(Double.pi*2), duration: 3)
            let runRepeat = SKAction.repeatForever(rotate)
            ball.run(runRepeat)
        }
        ball.run(blockAction)
    }

设置动作执行的线程:

SKAction.run({
}, queue: DispatchQueue)
1捌 、自定义动作

使用customActionWithDuration()实现

func customAction() {
        let background = SKSpriteNode.init(imageNamed: "field")
        background.position = CGPoint.init(x: KScreenWidth/2, y: KScreenHeight/2)
        background.size = CGSize.init(width: KScreenWidth, height: KScreenHeight)
        self.addChild(background)

        let ball = SKSpriteNode.init(imageNamed: "soccer")
        ball.position = CGPoint.init(x: KScreenWidth/2, y: KScreenHeight/2)
        ball.size = CGSize.init(width: 50, height: 50)
        self.addChild(ball)

        let customAction = SKAction.customAction(withDuration: 2) { (node: SKNode, elapsedTime: CGFloat) in
            let fraction = CGFloat(elapsedTime) / 2.0
            let yOff = 100 * 4 * fraction * (1 - fraction)
            node.position = CGPoint.init(x: node.position.x, y: KScreenHeight/2 + CGFloat(yOff))
        }
        let runRepeat = SKAction.repeatForever(customAction)
        ball.run(runRepeat)

        // MARK: 删除动作
//        let remove = SKAction.removeFromParent()
    }
1⑨ 、删除动作

使用removeFromParent()方法完结。

let remove = SKAction.removeFromParent()

用户交互

1、触摸

出手是最广泛的用户交互之一。分为单拍、多拍触摸(touchesBegan),移动触摸(touchesMoved),截止和注销触摸(touchesEnded)。

在触摸中常用的事件处理:单拍和多拍触摸在一个办法中监听,所以须要开展区分

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let mytouches = touches as NSSet
        let touch: AnyObject? = mytouches.anyObject() as AnyObject
        if(touch?.tapCount == 1){
            // 单拍
        }
        if(touch?.tapCount == 2) {
            // 多拍
        }
    }

在运动触摸中得到当前点击的坐标地点

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        let mytouchs = touches as NSSet
        let touch = mytouchs.anyObject() as! UITouch
        let touchLocation = touch.location(in: self)
        print(touchLocation)
    }
2、手势

广泛的手势识别器:

名称 功能
UITapGestureRecognizer 轻拍
UIPinchGestureRecognizer
UISwipeGestureRecognizer 滑动
UIRotationGestureRecognizer 旋转
UIPanGestureRecognizer 移动
UILongPressGestureRecognizer 长按
  • 轻拍
    分两步,添加手势、达成手势方法。

    func addGestureRecognizer() {
        let tapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(self.handleTap))
        self.view?.addGestureRecognizer(tapGestureRecognizer)
    }

    func handleTap() {
        backgroundColor = UIColor.yellow
    }

  • 捏 其实就是经过两个指头的张合,完结图片的放手和缩短。

    func addGestureRecognizer() {
        let pinchGestureRecognizer = UIPinchGestureRecognizer.init(target: self, action: #selector(handlepin(recognizer:)))
        self.view?.addGestureRecognizer(pinchGestureRecognizer)
    }

    var lastScale: CGFloat = 0.0
    func handlepin(recognizer: UIPinchGestureRecognizer) {
        self.view?.bringSubview(toFront: view!)
        // 复原
        if(recognizer.state == UIGestureRecognizerState.ended){
            lastScale = 1.0
            return
        }

        let scale: CGFloat = 1.0 - (lastScale - recognizer.scale)
        let current: CGAffineTransform = recognizer.view!.transform
        let newaa = current.scaledBy(x: scale, y: scale)
        recognizer.view?.transform = newaa
        lastScale = recognizer.scale
    }
  • 旋转
    通过旋转手势,多个指头旋转控制图片旋转。

    func addGestureRecognizer() {
        let rotationGestureRecognizer = UIRotationGestureRecognizer.init(target: self, action: #selector(handRotation(recognizer:)))
        self.view?.addGestureRecognizer(rotationGestureRecognizer)
    }
    // 旋转
    func handRotation(recognizer: UIRotationGestureRecognizer) {
        let rataion:CGFloat = recognizer.rotation
        sprite.zRotation = -rataion
    }
  • 移动
    和触摸中的touchesMoved类似功能,通过移动手势,可以使图片跟发轫指的移位手势移动。

    func addGestureRecognizer() {
        let panGestureRecognizer = UIPanGestureRecognizer.init(target: self, action: #selector(handPan(recognizer:)))
        self.view?.addGestureRecognizer(panGestureRecognizer)
    }
    // 移动
    func handPan(recognizer: UIPanGestureRecognizer) {
        let point = recognizer.location(in: self.view)
        let pointY = (self.view?.frame.size.height)! - point.y
        sprite.position = CGPoint.init(x: point.x, y: pointY)
    }
  • 滑动
    滑出手势:UISwipeGestureRecognizer。在应用时方可应用direction属性设置滑下手势滑动的大方向。

    func addGestureRecognizer() {
        let swipeLeftGestureRecognizer = UISwipeGestureRecognizer.init(target: self, action: #selector(handSwipeLeft))     // 向左滑动
        swipeLeftGestureRecognizer.direction = UISwipeGestureRecognizerDirection.left;
        self.view?.addGestureRecognizer(swipeLeftGestureRecognizer)

        let swipeRightGestureRecognizer = UISwipeGestureRecognizer.init(target: self, action: #selector(handSwipeRight))     // 向右滑动
        swipeRightGestureRecognizer.direction = UISwipeGestureRecognizerDirection.right;
        self.view?.addGestureRecognizer(swipeRightGestureRecognizer)
    }
    // 滑动
    func handSwipeLeft() {
        let actionMove = SKAction.move(to: CGPoint.init(x: sprite.size.width/2, y: KScreenHeight/2), duration: 1)
        sprite.run(actionMove)
    }
    func handSwipeRight() {
        let actionMove = SKAction.move(to: CGPoint.init(x: KScreenWidth - sprite.size.width/2, y: KScreenHeight/2), duration: 1)
        sprite.run(actionMove)
    }
  • 长按

    func addGestureRecognizer() {
        let longPressGestureRecognizer = UILongPressGestureRecognizer.init(target: self, action: #selector(handLongPress))
        self.view?.addGestureRecognizer(longPressGestureRecognizer)
    }
    // 长按
    func handLongPress() {
        backgroundColor = UIColor.gray
    }
三 、引力影响

动力感应事件又被称之为加快计事件,属于运动事件的一种。运动时间发出可以经过:倾斜、摇动设备等。这么些活动事件的检测基于设设备的加快计或陀螺仪。须求拜访那个多少,需求通过coreMotion那个框架,coreMotion有提供访问加快计和陀螺仪数据的接口。

导入coerMotion框架,实例化CMMotionManager()对象。
在应用引力感应前,须要判定设备是或不是协理引力感应:

import CoreMotion
var mManger:CMMotionManager = CMMotionManager()
override func didMove(to view: SKView) {
    if(!mManger.isAccelerometerAvailable){
        // 重力感应不可用
    }
}

在认清设备帮忙动力影响后。我们来做贰个小功效,使用动力影响来决定天使对象的运动。

步骤:

  • 壹 、创制场景。
  • ② 、判断引力影响是或不是可用。
  • 三 、添加物理引擎,添加物理体。
  • ④ 、获取引力感应accelerometer的多少。
  • 伍 、依据数据移动灵活。

代码:

import Foundation
import UIKit
import SpriteKit
import CoreMotion

var mManger:CMMotionManager = CMMotionManager()
class GravityScene: SKScene {

    var gravityBall = SKSpriteNode.init(imageNamed: "soccer")

    override func didMove(to view: SKView) {
        // 创建两个精灵对象,场景和移动体
        let background = SKSpriteNode.init(imageNamed: "field")
        background.position = CGPoint.init(x: KScreenWidth/2, y: KScreenHeight/2)
        background.size = CGSize.init(width: KScreenHeight, height: KScreenWidth)
        self.addChild(background)

        gravityBall.position = CGPoint.init(x: KScreenWidth/2, y: KScreenHeight/2)
        gravityBall.size = CGSize.init(width: 50, height: 50)
        self.addChild(gravityBall)

        // 判断重力感应是否可用
        if(!mManger.isAccelerometerAvailable){
            // 重力感应不可用
            let alert:UIAlertController = UIAlertController.init(title: "提示", message: "重力感应不可用", preferredStyle: UIAlertControllerStyle.alert)
            let cancel:UIAlertAction = UIAlertAction.init(title: "取消", style: UIAlertActionStyle.cancel, handler: nil)
            alert.addAction(cancel)

            self.getCurrentVC()?.present(alert, animated: true, completion: {
            })

        }else {
            mManger.startAccelerometerUpdates()
        }


        // 添加物理引擎,添加物理体
        self.physicsBody = SKPhysicsBody.init(edgeLoopFrom: self.frame)
        //创建矩形物理体
        self.gravityBall.physicsBody = SKPhysicsBody.init(rectangleOf: self.gravityBall.frame.size)
        self.gravityBall.physicsBody?.isDynamic = true  // 能承受碰撞和其他外力作用
        self.gravityBall.physicsBody?.affectedByGravity = false // 不承受重力影响
        self.gravityBall.physicsBody?.mass = 0.2    // 给物体任意质量,使移动就会显得自然

    }

    // 飞创移动的方法
    func ballUpdate() {
        let data:CMAccelerometerData? = mManger.accelerometerData
        // 获取accelerometer数据
        var value:Double? = data?.acceleration.x
        if(value == nil){
            value = 0
        }

        // 判断设备倾斜方向
        if(fabs(value!) > 0.2){
            let fvector = CGVector.init(dx: 40*CGFloat(value!), dy: 0)
            self.gravityBall.physicsBody?.applyForce(fvector)
        }
    }

    override func update(_ currentTime: TimeInterval) {
        ballUpdate()
    }

    // 当前控制器响应者
    func getCurrentVC()->UIViewController?{
        var result:UIViewController?
        var window = UIApplication.shared.keyWindow
        if window?.windowLevel != UIWindowLevelNormal{
            let windows = UIApplication.shared.windows
            for tmpWin in windows{
                if tmpWin.windowLevel == UIWindowLevelNormal{
                    window = tmpWin
                    break
                }
            }
        }

        let fromView = window?.subviews[0]
        if let nextRespnder = fromView?.next{
            if nextRespnder.isKind(of: UIViewController.classForCoder()){
                result = nextRespnder as? UIViewController
            }else{
                result = window?.rootViewController
            }
        }
        return result
    }
}

将此情形添加到控制器的视图上浮现即可。

    // 创建重力感应场景
    func createGravityScene() {
        let skView = SKView.init(frame: self.view.bounds)
        if(skView.scene == nil){
            skView.showsFPS = true
            skView.showsNodeCount = true
            let scene = GravityScene(size: skView.bounds.size)
            skView.presentScene(scene)
        }
        self.view.addSubview(skView)
    }

终极完结的听从是,场景中的ball天使会依照手机的左右歪斜方一直移动。

最终奉上前边全数内容的demo Sprite Kit
基础

参照:《iOS游戏框架 Pepsi-Cola Kit技术详解》

基础篇就那些了。接下来就是进阶部分了:Sprite Kit进阶(音频、摄像、粒子系统)。 还有最后的高等级:七喜 Kit高级(物理引擎、瓦片地图)。会不定期更新,有趣味的能够关切下哦。