我正在为一个课堂项目复制Chrome恐龙游戏,我遇到了一个问题,当恐龙跳跃时,我很难阻止它运行。
我在SKTextureAtlas中有三个纹理:walk_1、walk_2和跳跃,我希望恐龙一直在walk_1和walk_2之间切换,这样它看起来就像在行走。当我触摸屏幕时,恐龙会跳跃,停止行走,纹理被设置为跳跃,直到它再次落在地上,它又开始行走。
然而,当我触摸屏幕时,恐龙确实跳了起来,但纹理没有改变,它一直在走。
我试过各种解决方法,比如把removeAction和run结合起来,把moveSpeed设置为0和1,以及干脆在touchchesBegan中运行跳跃序列,而不做任何额外的设置,但以上都没有用。
我的同学告诉我使用DispatchQueue.main.asyncAfter,竟然成功了! 但是我不太清楚为什么能成功,想知道有没有其他的解决方案可以达到同样的目的。
import SpriteKit
class GameScene: SKScene {
var dinoTexture:SKTextureAtlas!
var dinosaur:SKSpriteNode!
var walkForever:SKAction!
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(size: CGSize) {
super.init(size: size)
dinoTexture = SKTextureAtlas(named: "dinosaur")
}
override func didMove(to view: SKView) {
let walkOnce = SKAction.animate(with: [dinoTexture.textureNamed("walk_1.png"), dinoTexture.textureNamed("walk_2.png")], timePerFrame: 0.1)
walkForever = SKAction.repeatForever(walkOnce)
dinosaur = SKSpriteNode(texture: dinoTexture.textureNamed("walk_2.png"))
dinosaur.run(walkForever, withKey: "dinosaurWalk")
self.addChild(dinosaur)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
dinosaur.removeAction(forKey: "dinosaurWalk")
dinosaur.run(SKAction.sequence([SKAction.setTexture(dinoTexture.textureNamed("jump.png")), SKAction.moveBy(x: 0, y: 150, duration: 0.5), SKAction.moveBy(x: 0, y: -150, duration: 0.5), SKAction.setTexture(dinoTexture.textureNamed("walk_2.png"))]))
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.dinosaur.run(self.walkForever, withKey: "dinosaurWalk")
}
}
Spritekit中的SKActions在运行时有一个内置的完成处理程序,所以不需要调度队列。
我已经将动作分解为变量,以便于阅读,在我看来,向下跳应该比向上跳更快。
要访问一个SKAction的完成情况,请在运行命令后的方括号中加入你的后续代码。
self.run(someAction) {
//run some code after someAction has run
}
你所要做的就是
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
coco.removeAction(forKey: "cocoWalk")
let setJumpTexture = SKAction.setTexture(SKTexture(imageNamed: "coco_jump.png"))
let setWalkTexture = SKAction.setTexture(SKTexture(imageNamed: "coco_walk2.png"))
let jumpUp = SKAction.moveBy(x: 0, y: 150, duration: 0.5)
let jumpDown = SKAction.moveBy(x: 0, y: -150, duration: 0.25)
coco.run(SKAction.sequence([setJumpTexture, jumpUp, jumpDown, setWalkTexture])) {
self.coco.run(self.walkForever, withKey: "cocoWalk")
}
}