The Canvas
, to which the mansion is drawn.
Create the MansionCanvas
class
file.
Import the required classes.
package com.nokia.mid.mansion; import javax.microedition.lcdui.*;
Set the MansionCanvas
to
extend Canvas
. Define the objects, constants and variables
used by the application and create the constructor.
/** * Handles canvas and also Spectator. */ public class MansionCanvas extends Canvas { final Display display; final int width, height; boolean paused; final static int NUM_SOURCES = 4; private Source[] sources = new Source[NUM_SOURCES]; private House house; private Walker walker; int forcedReverb = -1; String msg = ""; private int msgColor = 0xcc11cc; public MansionCanvas(Display d) { display = d; paused = true; width = getWidth(); height = getHeight(); house = new House(); // init sources: sources[0] = new Source(6000, 6500, "/largedog16k.wav", house, this); sources[1] = new Source(10000, 3500, "/budgie_16k.wav", house, this); sources[2] = new Source(1100, 6000, "/owl_16k.wav", house, this); sources[3] = new Source(1150, 6000, "/cock_16k.wav", house, this); for (int i = 0; i < NUM_SOURCES; i++){ System.out.println("starting source "+ i); Thread t = new Thread(sources[i]); t.start(); } walker = new Walker(); msg = "Welcome to Mansion!"; }
Create a method for drawing the graphics used by the application.
/** * Draws everything. */ protected void paint(Graphics g) { int x_min = g.getClipX(); int y_min = g.getClipY(); int w = g.getClipWidth(); int h = g.getClipHeight(); // Empty the frame g.setColor(0xffffff); g.fillRect(x_min, y_min, w, h); g.translate(width/2, height/2); // move origin to the center // Draw sources for (int i = 0; i < NUM_SOURCES; i++) { sources[i].draw(g, walker.getX(), walker.getY(), walker.getRot()); } // Draw house (walls and doors) house.draw(g, walker.getX(), walker.getY(), walker.getRot()); // Draw player (walker) at origin: g.setColor(0xdd2222); g.fillRect(-4, -1, 9, 2); // shoulders g.setColor(0x66660a); g.drawLine(0, -3, 0, -3); // nose g.setColor(0); g.fillArc(-2, -2, 5, 5, 0, 360); // head g.translate(-width/2, -height/2); // reset translation // Draw the frame g.setColor(0); g.drawRect(0, 0, width-1, height-1); // Draw message: if (msg != null) { g.setColor(0xffffff); g.setClip(0, height-14, width, height); g.fillRect(0, height-20, width-2, 18); g.setColor(msgColor); g.drawString(msg, 5, height-14, 0); g.setColor(0); g.drawRect(0, 0, width-1, height-1); } occludeSources(); }//paint()
Create a method for activating the sound sources that are located in the same room as the Walker object, and muting the rest.
/** * Starts sources that are in the same room (or space) and stops the rest */ private void occludeSources() { int listeningRoom = house.inWhichRoom(walker.getX()); for (int i = 0; i < NUM_SOURCES; i++) { if(listeningRoom == house.inWhichRoom(sources[i].getX())) { sources[i].start(); } else { sources[i].stop(); } } }
Create methods for detecting key presses and repeated key presses.
public void keyPressed(int keyCode) { keyAction(keyCode); } public void keyRepeated(int keyCode) { keyAction(keyCode); }
Create a method for giving functionality to the various key presses.
private void keyAction(int keyCode) { int action = getGameAction(keyCode); switch (action) { case LEFT: walker.rotateLeft(); break; case RIGHT: walker.rotateRight(); break; case UP: walker.moveForward(house); break; case DOWN: walker.moveBackward(house); break; case FIRE: forcedReverb += 1; forcedReverb = forcedReverb % House.NUM_REV_PRESETS; walker.forceReverb(forcedReverb); break; } msg = "" + walker.getRevName(); /*msg = "X:" + walker.getX() + "Y:" + walker.getY() + "r:" + walker.getRot()*10 + " " + walker.getRevName();*/ repaint(); }//keyAction()
Create a method for closing the sound sources.
/** * Closes the sound sources. */ void destroy() { for(int i=0; i < NUM_SOURCES; i++) { sources[i].destroy(); } }
Create methods for pausing and starting the running of the repainting.
boolean isPaused() { return paused; } void pause() { if (!paused) { paused = true; } repaint(); } void start() { if (paused) { paused = false; display.setCurrent(this); } repaint(); } }
The class that creates the actual mansion the game takes place in.
Create the House
class
file.
Import the required classes.
package com.nokia.mid.mansion; import javax.microedition.lcdui.Graphics;
Create the constructor and a method to run it..
/** * Contains the walls and the reverb settings. * */ public class House { public static final int NUM_REV_PRESETS = 10; private static final int ALLEY=0,ARENA=1, AUDITORIUM=2,BATHROOM=3,CAVE=4, HALLWAY=5,HANGAR=6,LIVINGROOM=7,MOUNTAINS=8,ROOM=9; static final String REV_PRESETS[] = { "alley", "arena", "auditorium", "bathroom", "cave", "hallway", "hangar", "livingroom", "mountains", "room" }; // coordinates and reverb settings of the rooms: private static final int[][] ROOMS = {//{Y_MIN,Y_MAX,X_MAX,REVERB_PRESET} {6000,6000,0,MOUNTAINS}, // dummy (sentinel) {3000,10000,4000,MOUNTAINS}, //yard {6000,7000,8000,HALLWAY}, {2000,10000,19000,AUDITORIUM}, {3500,3500,19000,ALLEY} // dummy (sentinel) }; public House (){ }
Create a method for detecting, whether a given coordinate is inside the bounds of the accessible "house" area.
/** * @return true, if given coordinates are inside of the house. */ public boolean isInside(int x, int y) { boolean inside = false; final int room = inWhichRoom(x); if (y+100 < ROOMS[room][1] && y-100 > ROOMS[room][0]) inside = true; return inside; }
Create a method for detecting the room of the "house" the given x-coordinate is in. Since none of the rooms are located on the same y-coordinates, a method for detecting them on that basis is not needed.
/** * Tells in which room is the given x-coordinate in. * * @return room index */ public int inWhichRoom(int x) { int room = ROOMS.length-1; for (int i = 0; i < ROOMS.length-1; i++) { if (x > ROOMS[i][2]) { room = i+1; } else { break; } } if (room >= ROOMS.length) System.out.println("bug in House.inWhichRoom()! room=" + room); return room; }
Create the methods to fetch the reverb preset names, by given room or by index.
/** * Gets the reverb preset name for the given room */ public static String presetName(int room) { if(room < ROOMS.length && room >= 0) { return REV_PRESETS[ROOMS[room][3]]; } else { return ""; } } /** * Gets reverb preset name by index */ public static String presetNameByIndex(int index) { if(index < NUM_REV_PRESETS && index >= 0) { return REV_PRESETS[index]; } else { return ""; } }
Create the
method for drawing the actual house to a Graphics
object.
/** * Draws the house to given Graphics. * @param dx x translation in millipixels * @param dy y translation in millipixels * @param rot rotation in deci-angles */ public void draw(Graphics g, int dx, int dy, int rot) { for (int i=1; i < ROOMS.length; i++) { // door: g.setColor(0xee1111); //brick /* following min/max coding is necessary, because if the door ovelaps east wall, there will be artifacts visible, because overlapping doesn't seem to be perfect: */ g.drawLine (Trig.transXS(ROOMS[i-1][2]-dx, Math.min(ROOMS[i][1],ROOMS[i-1][1])-dy, rot), Trig.transYS(ROOMS[i-1][2]-dx, Math.min(ROOMS[i][1],ROOMS[i-1][1])-dy, rot), Trig.transXS(ROOMS[i-1][2]-dx, Math.max(ROOMS[i][0],ROOMS[i-1][0])-dy, rot), Trig.transYS(ROOMS[i-1][2]-dx, Math.max(ROOMS[i][0],ROOMS[i-1][0])-dy, rot)); g.setColor(0x000000); // black //east (northern from door) wall: g.drawLine (Trig.transXS(ROOMS[i-1][2]-dx,ROOMS[i][1]-dy,rot), Trig.transYS(ROOMS[i-1][2]-dx,ROOMS[i][1]-dy,rot), Trig.transXS(ROOMS[i-1][2]-dx,ROOMS[i-1][1]-dy,rot), Trig.transYS(ROOMS[i-1][2]-dx,ROOMS[i-1][1]-dy,rot)); // east (southern from door) wall: g.drawLine (Trig.transXS(ROOMS[i-1][2]-dx,ROOMS[i][0]-dy,rot), Trig.transYS(ROOMS[i-1][2]-dx,ROOMS[i][0]-dy,rot), Trig.transXS(ROOMS[i-1][2]-dx,ROOMS[i-1][0]-dy,rot), Trig.transYS(ROOMS[i-1][2]-dx,ROOMS[i-1][0]-dy,rot)); //north wall: g.drawLine (Trig.transXS(ROOMS[i-1][2]-dx,ROOMS[i][0]-dy,rot), Trig.transYS(ROOMS[i-1][2]-dx,ROOMS[i][0]-dy,rot), Trig.transXS(ROOMS[i][2]-dx,ROOMS[i][0]-dy,rot), Trig.transYS(ROOMS[i][2]-dx,ROOMS[i][0]-dy,rot)); //south wall: g.drawLine (Trig.transXS(ROOMS[i-1][2]-dx,ROOMS[i][1]-dy,rot), Trig.transYS(ROOMS[i-1][2]-dx,ROOMS[i][1]-dy,rot), Trig.transXS(ROOMS[i][2]-dx,ROOMS[i][1]-dy,rot), Trig.transYS(ROOMS[i][2]-dx,ROOMS[i][1]-dy,rot)); } }//draw() }// House