[Home]Nfwu/Painter

Robo Home | Nfwu | Changes | Preferences | AllPages

Showing revision 1
Something new I wrote to help with my debugging. Feel free to use, with or without giving credit.

package nfwu;



import robocode.*;

import java.util.Vector;

import java.util.Iterator;

import java.awt.Color;

import java.awt.Graphics2D;

import java.awt.event.KeyEvent;



// Credit goes to David Alves for basic structure from DrawingBot.

// Added multiple layers for drawing on.

//Event Handlers to call from bot...

/*
	public void run(){
		//I want 2 layers
		Painter.init(2);
		//Register first layer to key '1'

		Painter.setupLayer(0, "Enemy Position", java.awt.event.KeyEvent.VK_1); 
		//Register second layer to key 'w'

		Painter.setupLayer(1, "Waves", java.awt.event.KeyEvent.VK_W);

	//other stuff

	}

	public void onKeyPressed(java.awt.event.KeyEvent e){

		if (Painter.onKeyPressed(e)) return;

		// other stuff

	}

	public void onKeyReleased(java.awt.event.KeyEvent e){

		if (Painter.onKeyReleased(e)) return;

		// other stuff

	}

	public void onPaint(java.awt.Graphics2D g){ Painter.onPaint(g); }

*/

// Interactive Display Controls:

//   Holding "key" displays the relevant layer until the key is released.

//   Typing Shift+"key" toggles permanent display of a layer.

//   Holding "H" shows a list of layer names and their keycodes.



public class Painter {

	public final static int HELP_KEY = KeyEvent.VK_H; //The 'h' key.

	public final static float MAGIC_FONT_HEIGHT_VALUE = 12.0f;

	static boolean isDisplayingHelpMessage = true;

	static boolean isDisplayingLayersList = false;

	static boolean isShiftPressed = false;



//Setup stuff
	public static void init(int numberOfLayers){//Call before every round

		System.out.println("This bot has debugging graphics.");

		System.out.println("Hold the '"+KeyEvent.getKeyText(HELP_KEY)+"' key with Paint enabled for help.");

		overlays = new DebugOverlay[numberOfLayers];

		isDisplayingLayersList = false;

		isShiftPressed = false;

	}

	public static void setupLayer(int oid, String name, int key, boolean defaultDisp){ //key must be a valid VK_ code!!!

		overlays[oid] = new DebugOverlay(name, key, defaultDisp);

	}

	public static void setupLayer(int oid, String name, int key){

		setupLayer(oid, name, key, false);

	}



//Draw Stuff (oid = the layer id)

	public static void drawObject(int oid, Renderable r){

		overlays[oid].renderables.add(r);

	}



	public static void drawLineRect(int oid, Color color, double x1, double y1, double x2, double y2){ //Rectangular Coords as input

		drawObject(oid, new Line(x1, y1, x2, y2, color)); 

	}



	public static void drawLinePol(int oid, Color color, double x1, double y1, double len, double ang){ //Relative polar Coords as input

		double x2 = x1 + Math.sin(ang) * len; //NOTE: Robocode Angles... www

		double y2 = y1 + Math.cos(ang) * len; 

		drawObject(oid, new Line(x1, y1, x2, y2, color));

	}

	

	public static void drawCircle(int oid, Color color, double x, double y, double radius){

		drawObject(oid, new Circle(x, y, radius, color));

	}

	

	public static void drawPoint(int oid, Color color, double x, double y){

		drawObject(oid, new Dot(x, y, color));

	}

	

	public static void drawText(int oid, Color color, double x, double y, String text){

		drawObject(oid, new Text(text, x, y, color));

	}


//Handler Stuff
	public static boolean onKeyPressed(KeyEvent e) {

		switch (e.getKeyCode()) {

		case KeyEvent.VK_SHIFT:

			isShiftPressed = true;

			return true;

		case HELP_KEY:

			if (isShiftPressed) isDisplayingHelpMessage = false;

			else isDisplayingLayersList = true;

			return true;

		}

		if (isShiftPressed) return false;

		for (int i=0;i<overlays.length;++i){

			if (overlays[i].key == e.getKeyCode()){

				overlays[i].displayed = true;

				return true;

			}

		}

		return false;

	}



	public static boolean onKeyReleased(KeyEvent e) {

		switch (e.getKeyCode()) {

		case KeyEvent.VK_SHIFT:

			isShiftPressed = false;

			return true;

		case HELP_KEY:

			if (isShiftPressed) isDisplayingHelpMessage = false;

			else isDisplayingLayersList = false;

			return true;

		}

		//Toggle whether or not shift is pressed

		for (int i=0;i<overlays.length;++i){

			if (overlays[i].key == e.getKeyCode()){

				overlays[i].displayed = !overlays[i].displayed;

				return true;

			}

		}

		return false;

	}



	public static void onPaint(Graphics2D g){

		g.setColor(Color.WHITE);

		if (isDisplayingHelpMessage) g.drawString("Hold the '"+KeyEvent.getKeyText(HELP_KEY)+"' key for help.", 0.0f, 0.0f);

		else if (isDisplayingLayersList) g.drawString("List of avaliable debug graphics layers:", 0.0f, 0.0f);

		for (int j=0;j<overlays.length;++j){

			if (isDisplayingLayersList){

				g.setColor(Color.WHITE);

				g.drawString((overlays[j].displayed?"*":"  ")+"["+KeyEvent.getKeyText(overlays[j].key)+"]: "+overlays[j].name, 0.0f, (j+1)*MAGIC_FONT_HEIGHT_VALUE);

			}

			if (!overlays[j].displayed) continue;

			Iterator i = overlays[j].renderables.iterator();

			while(i.hasNext()){

				Renderable r = (Renderable) i.next();

				r.render(g);

			}

			overlays[j].renderables.clear();

		}

		if (isDisplayingLayersList){

			g.setColor(Color.WHITE);

			g.drawString("Holding the key in brackets displays the layer", 0.0f, (overlays.length+1)*MAGIC_FONT_HEIGHT_VALUE);

			g.drawString("Typing Shift+key toggles permanent display of a layer", 0.0f, (overlays.length+2)*MAGIC_FONT_HEIGHT_VALUE);

		}

	}



//Implementation

	static DebugOverlay[] overlays;



	private static class DebugOverlay {

		DebugOverlay(String name, int key, boolean defaultDisp){

			this.name = name;

			this.key = key;

			this.displayed = defaultDisp;

		}

		Vector renderables = new Vector();

		boolean displayed;

		int key; //Keycode to toggle display mode

		String name;

	}



	public static abstract class Renderable {

		public abstract void render(Graphics2D g);

	}

	

	private static class Circle extends Renderable {

		double x, y, radius;

		Color color;

		public Circle(double x, double y, double radius, Color color){

			this.x = x; this.y = y; this.radius = radius;

			this.color = color;

		}

		public void render(Graphics2D g) {

			g.setColor(color);

			g.drawOval((int)Math.round(x - radius), (int)Math.round(y - radius),

				   (int)Math.round(2 * radius), (int)Math.round(2 * radius));

		}

	}

	

	private static class Dot extends Circle {

		public Dot(double x, double y, Color color){

			super(x, y, 2, color); //super(x, y, 2, colour);

		}

	}

	

	private static class Line extends Renderable {

		double x1, y1, x2, y2;

		Color color;

		public Line(double x1, double y1, double x2, double y2, Color color){

			this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2;

			this.color = color;

		}

		public void render(Graphics2D g) {

			g.setColor(color);

			g.drawLine((int)Math.round(x1), (int)Math.round(y1), (int)Math.round(x2), (int)Math.round(y2));

		}

	}

	

	private static class Text extends Renderable {

		String text;

		double x, y;

		Color color;

		public Text(String text, double x, double y, Color color){

			this.text = text;

			this.x = x; this.y = y;

			this.color = color;

		}

		public void render(Graphics2D g) {

			g.setColor(color);

			g.drawString(text, (float)x, (float)y);

		}

	}

}

Robo Home | Nfwu | Changes | Preferences | AllPages
Edit revision 1 of this page | View other revisions | View current revision
Edited September 6, 2008 1:33 EST by Nfwu (diff)
Search: