Swift 如何在操作期间替换SKSpriteNode的图像,然后将其返回到它';原始纹理图集循环

Swift 如何在操作期间替换SKSpriteNode的图像,然后将其返回到它';原始纹理图集循环,swift,sprite-kit,ios9,texture-atlas,Swift,Sprite Kit,Ios9,Texture Atlas,我正在尝试用SpriteKit做一个基本的跑步和跳跃游戏 加载视图时,我希望使用纹理图集中的图像运行sprite节点。这是我设法做到的 触摸屏幕时,我希望此图像更改为纹理图集中名为跳跃的另一图像 当角色返回地面时,我希望它返回到原始纹理图集循环 到目前为止,我已经编写了以下代码: import UIKit import SpriteKit class Level1: SKScene { var Hero : SKSpriteNode! //Creates an object f

我正在尝试用SpriteKit做一个基本的跑步和跳跃游戏

加载视图时,我希望使用纹理图集中的图像运行sprite节点。这是我设法做到的

触摸屏幕时,我希望此图像更改为纹理图集中名为
跳跃的另一图像

当角色返回地面时,我希望它返回到原始纹理图集循环

到目前为止,我已经编写了以下代码:

import UIKit
import SpriteKit

class Level1: SKScene {
    var Hero : SKSpriteNode!
    //Creates an object for the Hero character.

    let textureAtlas = SKTextureAtlas(named:"RunImages.atlas")
    //Specifies the image atlas used.

    var spriteArray = Array<SKTexture>();
    //Creates a variable for the image atlas of him running.

    var HeroBaseLine = CGFloat (0)
    //This is where the Hero character sits on top of the ground.

    var onGround = true
    //Creates a variable to specify if Hero is on the ground.

    var velocityY = CGFloat (0)
    //Creates a variable to hold a three decimal point specification for velocity in the Y axis.

    let gravity = CGFloat (0.6)
    //Creates a non variable setting for gravity in the scene.

    let movingGround = SKSpriteNode (imageNamed: "Ground")
    //Creates an object for the moving ground and assigns the Ground image to it.

    var originalMovingGroundPositionX = CGFloat (0)
    //Sets a variable for the original ground position before it starts to move.

    var MaxGroundX = CGFloat (0)
    //Sets a variable for the maximum

    var groundSpeed = 4
    //Sets the ground speed.  This number is how many pixels it will move the ground to the left every frame.

    override func didMoveToView(view: SKView) {
        //Misc setup tasks.

        backgroundColor = (UIColor.blackColor())
        //Sets the background colour when the view loads.

        //Ground related tasks.

        self.movingGround.anchorPoint = CGPointMake(0, 0.5)
        //Positions the Ground image hard left in the X axis.

        self.movingGround.position = CGPointMake(CGRectGetMinX(self.frame), CGRectGetMinY(self.frame) + (self.movingGround.size.height / 2))
        //Positions the Ground image at the bottom of the screen relative to half the height of the image.

        self.addChild(self.movingGround)
        //Creates an instance of the Ground image that follows the parameters set in the lines above when the view loads.

        self.originalMovingGroundPositionX = self.movingGround.position.x
        //Sets the starting position for the ground image in the x before it start to move.

        self.MaxGroundX = self.movingGround.size.width - self.frame.size.width
        //Sets the maximum ground size minus the width of the screen to create the loop point in the image.

        self.MaxGroundX *= -1
        //This multiplies the size of the ground by itself and makes the max ground size a negative number as the image is moving towards the left in x which is negative.

        //Hero related tasks.

        spriteArray.append(textureAtlas.textureNamed("Run1"));
        spriteArray.append(textureAtlas.textureNamed("Run2"));
        spriteArray.append(textureAtlas.textureNamed("Run3"));
        spriteArray.append(textureAtlas.textureNamed("Run2"));

        Hero = SKSpriteNode(texture:spriteArray[0]);

        self.HeroBaseLine = self.movingGround.position.y + (self.movingGround.size.height / 2) + 25

        //self.Hero.position = CGPointMake(CGRectGetMinX(self.frame) + 50, self.HeroBaseLine)

        self.Hero.position = CGPointMake(CGRectGetMinX(self.frame) + 50, self.HeroBaseLine)
        //Sets where the character will appear exactly.

        self.Hero.xScale = 0.15
        self.Hero.yScale = 0.15

        addChild(self.Hero);
        //Adds an instance of Hero to the screen.

        let animateAction = SKAction.animateWithTextures(self.spriteArray, timePerFrame: 0.15);
        let moveAction = SKAction.moveBy(CGVector(dx: 0,dy: 0), duration: 0.0);
        //Although currently set to 0, the above line controls the displacement of the character in the x and y axis if required.
        let group = SKAction.group([ animateAction,moveAction]);
        let repeatAction = SKAction.repeatActionForever(group);
        self.Hero.runAction(repeatAction);
        //Animation action to make him run.  Here we can affect the frames and x, y movement, etc.
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if self.onGround {
            self.velocityY = -18
            self.onGround = false
        }
    }
    //This block specifies what happens when the screen is touched.

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if self.velocityY < -9.0 {
            self.velocityY = -9.0
        }
    }
    //This block prevents Hero from jumping whilst already jumping.

    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */

        if self.movingGround.position.x <= MaxGroundX {
            self.movingGround.position.x = self.originalMovingGroundPositionX
        }
        //This is how the ground is positioned at the beginning of each update (each frame refresh)

        movingGround.position.x -= CGFloat (self.groundSpeed)
        //This is how the ground is moved relative to the ground speed variable set at the top.  The number in the variable is how many pixels the frame is being moved each frame refresh.

        self.velocityY += self.gravity
        self.Hero.position.y -= velocityY

        if self.Hero.position.y < self.HeroBaseLine {
            self.Hero.position.y = self.HeroBaseLine
            velocityY = 0.0
            self.onGround = true
        }
        //This is the code for making Hero jump in accordance to the velocity and gravity specified at the top of the class in relation to the base line.
    }
}
}

//使他运行的动画函数。在这里,我们可以影响帧和x、y移动等。
func run(){
让animateAction=SKAction.animateWithTextures(self.spriteArray,timePerFrame:0.15);
//尽管当前设置为0,但如果需要,上面的行控制角色在x轴和y轴上的位移。
让moveAction=SKAction.moveBy(CGVector(dx:0,dy:0),持续时间:0.0);
让group=SKAction.group([animateAction,moveAction]);
让repeatAction=SKAction.repeatActionForever(组);
self.Hero.runAction(重复动作);
}
//动画功能使他跳跃。
func jump(){
self.velocityY=-18
self.onGround=false
让jumpAnimation=SKAction.animateWithTextures(jumpArray,timePerFrame:0.15)
self.Hero.runAction(SKAction.repeatActionForever(jumpAnimation))
}
覆盖功能触摸开始(触摸:设置,withEvent事件:UIEvent?){
//此块指定触摸屏幕时发生的情况。
如果你在附近{
跳转()
}
}
覆盖func touchesEnded(触摸:设置,withEvent事件:UIEvent?){
//这个方块可以防止英雄在已经跳跃的时候跳跃。
如果self.velocityY<-9.0{
self.velocityY=-9.0
}
}
覆盖函数更新(currentTime:CFTimeInterval){
/*在渲染每个帧之前调用*/
//这是每次更新(每次帧刷新)开始时地面的定位方式

如果self.movingGround.position.x因为你已经让你的精灵跑了,跳转不是一件难事。只需在适当的位置用跳转动画的纹理替换跑步动画的纹理即可

首先,我将运行动画的代码包装起来,以便以后重用

func run() {
    let animateAction = SKAction.animateWithTextures(self.spriteArray, timePerFrame: 0.15);
    let moveAction = SKAction.moveBy(CGVector(dx: 0,dy: 0), duration: 0.0);
    let group = SKAction.group([animateAction,moveAction]);
    let repeatAction = SKAction.repeatActionForever(group);
    self.Hero.runAction(repeatAction);
}
下一步是制作
Jump
的纹理图集。对于演示,我只添加了一帧跳跃动画。在创建
textureAtlas
spriteArray
以运行
后添加这些线条

var jumpArray = Array<SKTexture>()
let jumpAtlas = SKTextureAtlas(named:"JumpImages.atlas")
jumpArray.append(jumpAtlas.textureNamed("Jump"))
最后但并非最不重要的一点是,在
update
中返回地面后继续运行动画

override func update(currentTime: CFTimeInterval) {
    ...

    if self.Hero.position.y < self.HeroBaseLine {
        self.Hero.position.y = self.HeroBaseLine
        velocityY = 0.0
        if self.onGround == false {
            self.onGround = true
            println("on the ground")

            run()
        }
    }
}
覆盖函数更新(currentTime:CFTimeInterval){
...
如果self.Hero.position.y
现在你应该得到下面的结果。如果你对代码有任何问题,请告诉我


在编写代码之前写注释更为传统。谢谢,我也做了更改。我稍后会看一看。@Fiducial13您在编辑的代码中的
update
方法中遗漏了两行。它们是
self.velocityY+=self.gravity
self.Hero.position.y-=velocityY
,它们使精灵跳跃。
var jumpArray = Array<SKTexture>()
let jumpAtlas = SKTextureAtlas(named:"JumpImages.atlas")
jumpArray.append(jumpAtlas.textureNamed("Jump"))
func jump() {
    self.velocityY = -18
    self.onGround = false
    println("jump over ground")

    let jumpAnimation = SKAction.animateWithTextures(jumpArray, timePerFrame: 0.15)
    self.Hero.runAction(SKAction.repeatActionForever(jumpAnimation))
}

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent?) {
    if self.onGround {
        jump()
    }
}
override func update(currentTime: CFTimeInterval) {
    ...

    if self.Hero.position.y < self.HeroBaseLine {
        self.Hero.position.y = self.HeroBaseLine
        velocityY = 0.0
        if self.onGround == false {
            self.onGround = true
            println("on the ground")

            run()
        }
    }
}