ios - 停止一个永远运行的动作,运行另一个动作并在 SpriteKit 中恢复停止的动作
问题描述
我正在为一个班级项目复制 Chrome 恐龙游戏,我遇到了一个问题,当恐龙跳跃时我很难阻止它运行。
我在 SKTextureAtlas 中有三个纹理:walk_1、walk_2 和 jump,我希望恐龙在 walk_1 和 walk_2 之间不断切换,所以它看起来像在走路。当我触摸屏幕时,恐龙会跳跃,停止行走,纹理设置为跳跃,直到它再次落在地面上,然后它又开始行走。
但是,当我触摸屏幕时,恐龙确实会跳跃,但纹理并没有改变,它一直在行走。
我已经尝试了各种解决方案,例如结合 removeAction 和 run,将 moveSpeed 设置为 0 和 1,并在 touchesBegan 中简单地运行跳转序列,而无需任何其他设置,但以上都不起作用。
我的同学告诉我使用 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 中的 SKAction 在运行时具有内置的完成处理程序。所以不需要调度队列。
我已将动作分解为变量以便于阅读,并且我认为跳下应该比跳起来更快
要访问 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")
}
}
推荐阅读
- node-red - 我如何保持 FRED 节点连接
- python - 具有多个属性的 find_all
- android - 无法移动到主要活动
- c# - C# SDK 中 AWS Lambda 的 callbackWaitsForEmptyEventLoop
- reactjs - 在 React Native 中将值传递给新屏幕
- c# - 递归获取类的字段和属性类型
- sql - impala 中的长度小于 8 位数
- python - 要求用户输入他们的用户名和密码并将其存储在文件中,如何添加包含哈希密码的字典?
- c# - 更新面板中的 C# 动态单选按钮在第一次单击时未触发?
- javascript - 如何在javascript中的字符串中添加反斜杠?