Область применения NSTimer()
Моя проблема: NSTimer(), объявленный в одной функции, влияет на другую.
Я делаю простую ролевую игру, которая позволяет двум игрокам сражаться друг с другом. В игре есть текстовое поле, в котором отображаются односекундные сообщения, например, "Первый игрок атакует" и т. Д. После завершения игры в текстовом поле предполагается напечатать победителя и оставить сообщение в текстовом поле. Для решения первой части (показать сообщение, через одну секунду показать пустую строку) я сделал следующий код:
func printEmpty() {
textToDisplayLabel.text = ""
}
func announcer(player: Character) {
var timer = NSTimer()
textToDisplayLabel.text = "\(player.name) attacks"
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "printEmpty", userInfo: nil, repeats: false)
}
Для решения второй части (показать информацию о победителе и оставить ее в текстовом поле) я использовал:
func hideAfterAPlayerHasWon(winner: Character) {
leftPlayerAttackButton.hidden = true
rightPlayerAttackButton.hidden = true
leftPlayerHpLabel.hidden = true
rightPlayerHpLabel.hidden = true
leftPlayerNameLabel.hidden = true
rightPlayerNameLabel.hidden = true
if winner.side == Character.playerSide.left {
soldierMain.hidden = true
let centerXConst = NSLayoutConstraint(item: orcMain, attribute: .CenterX, relatedBy: .Equal, toItem: self.view, attribute: .CenterX, multiplier: 1, constant: 1)
let centerYConst = NSLayoutConstraint(item: orcMain, attribute: .CenterY, relatedBy: .Equal, toItem: self.view, attribute: .CenterY, multiplier: 1, constant: 1)
self.view.addConstraint(centerXConst)
self.view.addConstraint(centerYConst)
textToDisplayLabel.text = "\(leftPlayer.name) has won"
} else {
orcMain.hidden = true
let centerXConst = NSLayoutConstraint(item: soldierMain, attribute: .CenterX, relatedBy: .Equal, toItem: self.view, attribute: .CenterX, multiplier: 1, constant: 1)
let centerYConst = NSLayoutConstraint(item: soldierMain, attribute: .CenterY, relatedBy: .Equal, toItem: self.view, attribute: .CenterY, multiplier: 1, constant: 1)
self.view.addConstraint(centerXConst)
self.view.addConstraint(centerYConst)
textToDisplayLabel.text = "\(rightPlayer.name) has won"
}
}
Проблема в том, что при запуске игры отображается информация о действиях, например, "атаках игроков" и т. Д., И они скрываются через одну секунду, как я хочу, но информация о победителе ведет себя так же, как о действиях, даже если бы они думали таймер был объявлен только в функции извещателя. Таким образом, у меня возник вопрос: какова область применения NSTimer () и как мне решить эту проблему?
РЕДАКТИРОВАТЬ: Вот функция, где вызывается диктор (а также hideAfter...)
@IBAction func onLeftPlayerAttackPressed(sender: UIButton) {
if leftPlayer.type == Character.charType.orc {
playOrcSlash()
}
if leftPlayer.type == Character.charType.soldier {
playSoldierSlash()
}
announcer(leftPlayer)
updateHp(leftPlayer, defender: rightPlayer)
disableButton(leftPlayerAttackButton)
if !(rightPlayer.isAlive) {
hideAfterAPlayerHasWon(leftPlayer)
}
}
2 ответа
какова сфера применения NSTimer()
У него нет "объема". Как только вы запланировали это, он принадлежит NSRunLoop, который владеет им и отвечает за его запуск. Если это неповторяющийся таймер, он исчезает после срабатывания.
Это не имеет ничего общего с вашей проблемой. У вас есть элементарная логическая ошибка:
onLeftPlayerAttackPressed
устанавливает таймер (announcer(leftPlayer)
) и звонкиhideAfterAPlayerHasWon
,затем
hideAfterAPlayerHasWon
ставит "игрок выиграл" на этикетке.Затем таймер срабатывает и снова очищает этикетку!
Действительно, ваш таймер срабатывает после обновления ярлыка, что вы можете сделать:
Задержка вызова вашей функции hideAfterAPlayerHasWon
на одну или две секунды, так что вы уверены, что ваш таймер уже сработал.
if !(rightPlayer.isAlive) {
let yourDelayTime = (Int64(NSEC_PER_SEC) * NUMBER_SECOND_DELAY)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, yourDelayTime), dispatch_get_main_queue(), { () -> Void in
self.hideAfterAPlayerHasWon(leftPlayer)
})
}