User talk:Nat/DrawingBot
Complex Graphics Rendering
Because my wave painter was very complicated (~200 java code), I always doing paint in onPaint()
. If I need to paint data that aren't available globally, I'll make global variable(s) to store it. This isn't efficient I know, but it does save some skipped turns when I'm not painting (and I call nearly 10,000 trig operations for each wave in air, bot me and enemy if any)
Later when I make single Wave class that I use in many developing robots, I extract all painting code to class call WavePainter
. I still do all painting in onPaint()
.
Recently when I was about to release Samekh, I switch the graphics system to the one similar to this (refer to User:Nat/DrawingBot) and Nfwu's mixed. I used to set isPainting = false
and clear the renderables buffer in onScannedRobot() and set isPainting = true
in onPaint()
. This way I know if I need to calculate the graphics or not. That's when I realised something. I read somewhere:
“Complex graphics can to done by extend the Renderable abstract class.”
I then changed my WavePainter
class to extends Renderable
, create constructor, and I need not to check whatever I'm painting or not. If it isn't painting, then the render(Graphics2D)
in my WavePainter
won't be call. And if I put all calculation there I won't skipped turns due the calculation on the debug graphics.
When I look at some other robot's source that I know also do complex calculation in graphical debugging (although not as complex as mine), such as DrussGT and Diamond. For DrussGT he does painting in onPaint
directly. For Diamond, he does what I used to do. Not the same, but similar. He check the paint time to decide is the painting is on or not, which make code complicated.
Pros of this method is the code is a lot cleaner. Some example of my waves:
public void onPaint(Grapgics2D g) { for (Wave wave : waves) { // 200+ lines of wave painting } }
vs.
public void updateWave() { // notice this is in updateWave, not in onPaint for (Wave wave : waves) { wave.update(enemyLocation); graphics.draw(new WaveRenderer(wave)); } }
or in case of an arrow, which I first saw in Diamond, that I also use in my robots.
Diamond's code:
if (paintStatus()) { DiaWave w = firingWaves.get(x); Point2D.Double angleHead = DiaUtils.project(myNextLocation, xFiringAngle, Math.min(400, w.targetDistance - 55)); _renderables.add(RoboGraphic.drawLine(myNextLocation, angleHead, Color.red)); _renderables.addAll(Arrays.asList(RoboGraphic.drawArrowHead( angleHead, 10, xFiringAngle, Color.red))); }
versus my code:
for (Point2D pt : fireLocations) graphics.draw(new Arrow(myPosition, pt, Color.red));
Of course, it isn't comparable since it is under definitely different structure, but as you see my arrow drawing code is in separate class and only calculate when it is firing with need of the paintStatus()
thing. Before some of you argue that Diamond's has system that allow disable/enable of graphics layer, my approach can implement the same thing too (in fact, all of this are implemented in Samekh, take a look at package nat.gfx
if you like).
Comments? --Nat Pavasant 10:27, 11 October 2009 (UTC) Diamond's code above is under RWPCL. My code above I hereby make it public domain, although nothing much in it. I think we should define explicit license for all code in this site, even some code that won't worth copy at all.
- [View source↑]
- [History↑]
You cannot post new threads to this discussion page because it has been protected from new threads, or you do not currently have permission to edit.