Debugging waves with onPaint()
The highlighted comment was created in this revision.
I've had a problem vexing me for some time....
From what I know by reading this amazing wiki, bots fire bullets the tick after fire()/setFire() are called. (assuming one never calls them until the gun is cool) However, if I make a wave (a wave that I'm firing for targeting purposes, not a wave fired at me) with a launchTime = getTime()+1 and then draw it, my wave reliably gets drawn one tick behind the bullet on the robocode screen.. doesn't begin to break (my waves change color when they begin the breaking process) till a tick after the bullet visually hits the opposing bot.
Everything lines up perfectly on screen if I just have launchTime be this tick.. but that's supposed to be off. I don't think I'm off in my wave radius calculation:
radius = velocity*(getTime()-launchTime)
Does a Bullet move its first step on the same tick it is created?
Are you doing your calculating in run() or in onScannedRobot()? IIRC they happen on different sides of the getTime() update.
It's happening in onScannedRobot()
Generally speaking, can I use onPaint() as a guide to having my picture of the battlefield properly placed? I guess that question boils down to "Do Robocode's own graphics and onPaint() happen at substantially the same time relative to the bots/bullets progressing from tick to tick?" If so, then proper alignment of my debug graphics with the screen means I'm getting things created/updated at the right times.
When my onPaint() draws my waves, breaking waves display their current min/max precise intersection angles. It was a beautiful moment when I saw that happening, and it looked accurate right down to the pixel (or as close as the naked eye gets) on the bot's bounding box. I'm just hoping that moment of "huzzah!!" wasn't in vain. ;)
Two important things here:
- The bullet's fire time is the tick you call fire/setFire/setFireBullet. The following tick the bullet appears and has traveled forward by its speed once from the location you were when you fired it. The tick after you call fire is the first tick the enemy can see that you've fired a bullet. And the tick before you called fire is the last info you could use to aim, since on the firing tick, the bullet is fired before the gun is turned.
- The order of operations is: (all other events), onScannedRobot, onPaint, run(), time increments. So if you fire from onScannedRobot, your graphics will line up. But if you fire from run(), things might look a tick behind, because they won't be painted until next tick's onPaint.
Re: "But if you fire from run(), things might look a tick behind"
Unless of course your bot is using a trick like making your "run()" code happen at the start of onPaint when onPaint is called, effectively re-ordering the "run()" code to be before "onPaint()" :-)
If you fire from run(), graphics can still line up if you also paint from that same run().
The way I do:
(all events), put all event data in a custom queue, execute() returns, cache battle state to avoid 1000 calls, process event queue and everything else in the order I want: radar, retrieve data from teammates, movement, fire gun, energy management, turn gun, send data to teammates, graphical debugging.
I assume you're referring to if you use the "getGraphics()" call instead of implementing "onPaint()" right?
At least personally I don't care for that approach because then either your bot will spend CPU time on the painting when painting is disabled, or you have to check if onPaint is called anyway.