我正在用Swift和SpriteKit试验一些东西。
我有4张硬币图片。 (coin1,coin2,...)。我想在屏幕上的随机位置产生随机硬币并让它淡出。我想每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)
}
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个硬币。标签放在这三个硬币中的一个上,它甚至没有正确说出硬币的名称。这是新代码:
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)
}
}
你可以帮我解开这个谜吗?提前谢谢。
答案 0 :(得分:2)
问题是您在spawnAndFadeCoins
中再次致电spawnAndFadeLabels
:
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)
}
我认为这是你想要的。