我正在用 Swift 和 SpriteKit 做一些实验。
我有 4 张硬币图片。 (硬币 1,硬币 2,...)。我想在屏幕上的随机位置生成一个随机硬币并让它淡出。我想每 3 秒重复一次这个 Action 。这是代码,它运行良好。
class GameScene: SKScene {
// creating a playable area
let gameArea: CGRect
override init(size: CGSize) {
let maxAspectRatio: CGFloat = 16.0/9.0
let playableWidth = size.height / maxAspectRatio
let gameAreaMargin = (size.width - playableWidth)/2
gameArea = CGRect(x: gameAreaMargin, y: 270, width: playableWidth, height: size.height - 270)
super.init(size: size)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func random() -> CGFloat {
return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}
func random(min: CGFloat, max: CGFloat) -> CGFloat {
return random() * (max-min) + min
}
func spawnAndFadeCoins() -> SKSpriteNode{
let randNum = arc4random()%4 + 1
let coin = SKSpriteNode(imageNamed: "coin\(randNum)")
if randNum == 4 {
coin.zPosition = 10
}
else {
coin.zPosition = 5
}
coin.name = "coin\(randNum)"
let randomX = random(min: gameArea.minX + coin.size.width/2,
max: gameArea.maxX - coin.size.width/2)
let randomY = random(min: gameArea.minY + coin.size.height/2,
max: gameArea.maxY - coin.size.height/2)
coin.position = CGPoint(x: randomX, y: randomY)
let disappear = SKAction.fadeOut(withDuration: 1.0)
coin.run(SKAction.repeatForever(disappear))
self.addChild(coin)
return(coin)
}
override func didMove(to view: SKView) {
let background = SKSpriteNode(imageNamed:"bg")
background.size = self.size
background.position = CGPoint(x:self.frame.size.width/2, y: self.frame.size.height/2)
background.zPosition = 0
self.addChild(background)
var _ = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(GameScene.spawnAndFadeCoins), userInfo: nil, repeats: true)
}
}
但是,当我为每个硬币添加一个指定其名称的标签时,奇怪的事情发生了:每 3 秒后,3 个硬币同时出现在屏幕上。标签贴在这 3 枚硬币中的一枚上,它甚至没有正确说出硬币的名称。这是新代码:
class GameScene: SKScene {
// creating a playable area
let gameArea: CGRect
override init(size: CGSize) {
let maxAspectRatio: CGFloat = 16.0/9.0
let playableWidth = size.height / maxAspectRatio
let gameAreaMargin = (size.width - playableWidth)/2
gameArea = CGRect(x: gameAreaMargin, y: 270, width: playableWidth, height: size.height - 270)
super.init(size: size)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func random() -> CGFloat {
return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}
func random(min: CGFloat, max: CGFloat) -> CGFloat {
return random() * (max-min) + min
}
func spawnAndFadeCoins() -> SKSpriteNode{
let randNum = arc4random()%4 + 1
let coin = SKSpriteNode(imageNamed: "coin\(randNum)")
if randNum == 4 {
coin.zPosition = 10
}
else {
coin.zPosition = 5
}
coin.name = "coin\(randNum)"
let randomX = random(min: gameArea.minX + coin.size.width/2,
max: gameArea.maxX - coin.size.width/2)
let randomY = random(min: gameArea.minY + coin.size.height/2,
max: gameArea.maxY - coin.size.height/2)
coin.position = CGPoint(x: randomX, y: randomY)
let disappear = SKAction.fadeOut(withDuration: 1.0)
coin.run(SKAction.repeatForever(disappear))
self.addChild(coin)
return(coin)
}
func spawnAndFadeLabels() -> SKLabelNode{
let label = SKLabelNode()
label.text = "\(spawnAndFadeCoins().name)"
label.zPosition = 15
label.color = SKColor.white()
label.fontSize = 60
label.position = spawnAndFadeCoins().position
let disappear2 = SKAction.fadeOut(withDuration: 1.0)
label.run(SKAction.repeatForever(disappear2))
self.addChild(label)
return(label)
}
override func didMove(to view: SKView) {
let background = SKSpriteNode(imageNamed:"bg")
background.size = self.size
background.position = CGPoint(x:self.frame.size.width/2, y: self.frame.size.height/2)
background.zPosition = 0
self.addChild(background)
var _ = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(GameScene.spawnAndFadeCoins), userInfo: nil, repeats: true)
var _ = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(GameScene.spawnAndFadeLabels), userInfo: nil, repeats: true)
}
}
你能帮我解开这个谜团吗?提前致谢。
最佳答案
问题是您在 spawnAndFadeLabels
中调用了 spawnAndFadeCoins
两次:
func spawnAndFadeLabels() -> SKLabelNode{
let label = SKLabelNode()
label.text = "\(spawnAndFadeCoins().name)" <-- here!
label.zPosition = 15
label.color = SKColor.white()
label.fontSize = 60
label.position = spawnAndFadeCoins().position <-- and here!
let disappear2 = SKAction.fadeOut(withDuration: 1.0)
label.run(SKAction.repeatForever(disappear2))
self.addChild(label)
return(label)
}
我认为你可以做的一件事是:
只有一个定时器:
runAction(SKAction.repeatForever(SKAction.sequence([SKAction.wait(forDuration: 3), SKAction.run(spawnAndFadeCoins)])))
我这里使用了SKAction
,因为在spritekit中不推荐使用Timer
。
现在只有 spawnAndFadeCoins
每三秒调用一次。然后,将 spawnAndFadeLabels
更改为:
func spawnAndFadeLabels(of node: SKSpriteNode) -> SKLabelNode{
let label = SKLabelNode()
label.text = "\(node.name)"
label.zPosition = 15
label.color = SKColor.white()
label.fontSize = 60
label.position = node.position
let disappear2 = SKAction.fadeOut(withDuration: 1.0)
label.run(SKAction.repeatForever(disappear2))
self.addChild(label)
return(label)
}
将 spawnAndFadeCoins
更改为:
func spawnAndFadeCoins() -> SKSpriteNode{
let randNum = arc4random()%4 + 1
let coin = SKSpriteNode(imageNamed: "coin\(randNum)")
if randNum == 4 {
coin.zPosition = 10
}
else {
coin.zPosition = 5
}
coin.name = "coin\(randNum)"
let randomX = random(min: gameArea.minX + coin.size.width/2,
max: gameArea.maxX - coin.size.width/2)
let randomY = random(min: gameArea.minY + coin.size.height/2,
max: gameArea.maxY - coin.size.height/2)
coin.position = CGPoint(x: randomX, y: randomY)
let disappear = SKAction.fadeOut(withDuration: 1.0)
coin.run(SKAction.repeatForever(disappear))
self.addChild(coin)
spawnAndFadeLabels(of: coin) <-- This line is added!
return(coin)
}
我想这就是你想要的。
关于swift - 我在 SpriteKit 上的 scheduledTimer 有问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41607025/