Eventos
Como o robô reage
Um evento é um aviso do jogo: "olha, aconteceu isso com você". Você escreve o que o robô deve fazer ao receber cada aviso. É aqui que um robô deixa de ser um boneco andando e vira um competidor.
Os onze eventos precisam existir no seu robô, mesmo vazios. Se o jogo tentar avisar o seu robô de algo e não encontrar o evento (ou se o seu código der erro dentro dele), o programa inteiro fecha no meio da partida, para todas as equipes. Comece sempre do RoboMinimo, que já vem com todos.
Os três que sempre rodam
init(self)
Quando: uma única vez, no momento em que o robô entra na arena.
É o lugar de escolher cores, formato de radar, travas de arma e radar, e de guardar informações que não mudam, como o tamanho da arena.
def init(self):
self.setColor(66, 185, 193)
self.arena = self.getMapSize() # guarda para usar depois
self.lockRadar("gun")
self.setRadarField("thin")
self.radarVisible(True)
run(self)
Quando: toda vez que a fila de comandos do robô esvazia.
É o cérebro. Aqui você decide para onde andar e para onde girar. Lembre que ele
não roda a cada instante: se você mandar andar 200 pixels, o
run() só é chamado de novo quando esses 200 pixels terminarem.
def run(self):
self.move(80)
self.gunTurn(20) # anda e varre o radar ao mesmo tempo
self.stop()
sensors(self)
Quando: a cada quadro, o tempo todo, mesmo com a fila cheia.
Serve para observar. É o único lugar que roda de forma contínua, então é onde se acompanha algo que muda rápido, como quantos adversários restam. Evite colocar comandos de movimento aqui: como ele roda muitas vezes por segundo, a fila entope.
def sensors(self):
self.adversarios = len(self.getEnemiesLeft()) - 1
Quando o robô bate em alguma coisa
onHitWall(self)
Quando: o robô encosta numa das paredes da arena.
O jogo já tira 1 de vida, empurra o robô um pouco para trás e joga
fora a fila de comandos. Cabe a você decidir para onde ir agora. Se não fizer nada, o
robô volta ao run() e provavelmente bate de novo, e de novo.
def onHitWall(self):
self.reset()
self.move(-60) # da re
self.turn(90) # e vira, tudo ao mesmo tempo
onRobotHit(self, robotId, robotName)
Quando: o seu robô trombou em outro.
Recebe o número de identificação e o nome do robô em que você bateu. Os dois perdem 1 de vida.
onHitByRobot(self, robotId, robotName)
Quando: outro robô trombou no seu.
Mesmos dados, ponto de vista contrário. Numa trombada, os dois eventos acontecem, cada um no seu robô.
onRobotHit = eu bati.
onHitByRobot = bateram em mim.
O By no nome é quem indica que a ação veio de fora.
Quando envolve tiro
onTargetSpotted(self, botId, botName, botPos)
Quando: o radar do seu robô enxergou um inimigo.
É o evento mais importante do jogo. Você recebe três informações:
- botId
- o número de identificação do robô avistado
- botName
- o nome dele
- botPos
- onde ele está. Use
botPos.x()ebotPos.y().
A versão simples é atirar direto, o que funciona bem se o radar estiver travado na arma, porque aí o que o radar vê já está na mira:
def onTargetSpotted(self, botId, botName, botPos):
self.fire(3)
A versão caprichada calcula o ângulo exato até o inimigo antes de atirar:
def onTargetSpotted(self, botId, botName, botPos):
eu = self.getPosition()
dx = botPos.x() - eu.x()
dy = botPos.y() - eu.y()
# angulo ate o inimigo, na bussola do jogo
angulo_do_inimigo = math.degrees(math.atan2(dy, dx)) - 90
erro = angulo_do_inimigo - (self.getGunHeading() % 360)
while erro < -180:
erro = erro + 360
while erro > 180:
erro = erro - 360
self.gunTurn(erro)
self.stop()
self.fire(3)
onHitByBullet(self, bulletBotId, bulletBotName, bulletPower)
Quando: o seu robô levou um tiro.
Você recebe quem atirou (número e nome) e a potência do tiro. O dano
que você levou é 3 × bulletPower.
Reagir aqui é uma das melhores decisões que um robô pode tomar: se você levou um tiro, alguém está mirando em você e vai atirar de novo no mesmo lugar. Sair do lugar resolve.
def onHitByBullet(self, bulletBotId, bulletBotName, bulletPower):
self.rPrint("Levei " + str(3 * bulletPower) + " de dano")
self.reset()
self.move(100) # sai da linha de tiro
self.turn(45)
onBulletHit(self, botId, bulletId)
Quando: um tiro seu acertou alguém.
Além do dano no adversário, você recupera vida. E se acertou uma vez, o alvo provavelmente ainda está por perto, então vale insistir na mesma direção.
onBulletMiss(self, bulletId)
Quando: um tiro seu saiu da arena sem acertar ninguém.
A energia gasta no disparo foi perdida. Um robô que recebe muitos
onBulletMiss está atirando à toa e sangrando energia.
Quando acaba
onRobotDeath(self)
Quando: a vida do seu robô chegou a zero.
Não dá mais para fazer nada, porque o robô já saiu da arena. Serve para deixar uma mensagem de despedida no painel, o que às vezes ajuda a entender o que deu errado.
def onRobotDeath(self):
self.rPrint("Eliminei " + str(self.getKills()) + " antes de cair")
Resumo
| Evento | Dispara quando | Efeito na vida |
|---|---|---|
init | o robô entra na arena | nenhum |
run | a fila de comandos esvazia | nenhum |
sensors | a cada quadro | nenhum |
onHitWall | bateu na parede | −1 |
onRobotHit | eu bati em outro robô | −1 nos dois |
onHitByRobot | outro robô bateu em mim | −1 nos dois |
onHitByBullet | levei um tiro | −3 × potência |
onBulletHit | meu tiro acertou | +2 × potência |
onBulletMiss | meu tiro saiu da arena | nenhum |
onTargetSpotted | o radar viu alguém | nenhum |
onRobotDeath | minha vida zerou | nenhum |