/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* AndroidWorld Library, Copyright 2011 Bryan Chadwick *
* *
* FILE: ./android/world/World.java *
* *
* This file is part of AndroidWorld. *
* *
* AndroidWorld is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation, either version *
* 3 of the License, or (at your option) any later version. *
* *
* AndroidWorld is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with AndroidWorld. If not, see
* See the individual methods for detailed documentation. *
* **
* ** */ public abstract class World{ /** The BigBang/Handler */ private BigBang bigbang; /** Default Tick rate for the world: ~33 frames per second */ public static double DEFAULT_TICK_RATE = 0.03; /** Mouse down (button-down) event String */ public static String MOUSE_DOWN = BigBang.MOUSE_DOWN; /** Mouse up (button-up) event String */ public static String MOUSE_UP = BigBang.MOUSE_UP; /** Mouse motion (move) event String */ public static String MOUSE_MOVE = BigBang.MOUSE_MOVE; /** Mouse down & move (drag) event String */ public static String MOUSE_DRAG = BigBang.MOUSE_DRAG; /** Key arrow-up event String */ public static String KEY_ARROW_UP = BigBang.KEY_ARROW_UP; /** Key arrow-down event String */ public static String KEY_ARROW_DOWN = BigBang.KEY_ARROW_RIGHT; /** Key arrow-left event String */ public static String KEY_ARROW_LEFT = BigBang.KEY_ARROW_LEFT; /** Key arrow-right event String */ public static String KEY_ARROW_RIGHT = BigBang.KEY_ARROW_RIGHT; /** Menu Key event String. The menu key will usually be intercepted to open a save dialog * to enable the capture of application/game screen-shots. */ public static String KEY_MENU = BigBang.KEY_MENU; /** Search Key event String */ public static String KEY_SEARCH = BigBang.KEY_SEARCH; /** Return a visualization of this World as a {@link android.image.Scene Scene}. * See {@link android.image.EmptyScene}, {@link android.image.Scene#placeImage(Image, int, int)}, and * {@link android.image.Scene#addLine(int, int, int, int, String)} for documentation on * constructing Scenes */ public abstract Scene onDraw(); /** Return the tick rate for this World in seconds. For example, * 0.5 means two tick. The rate is only accessed when * bigBang() is initially called and the window is created. */ public double tickRate(){ return DEFAULT_TICK_RATE; } /** Produce a (possibly) new World based on the Tick of the clock. This * method is called to get the next world on each clock tick.*/ public World onTick(){ return this; } /** Produce a (possibly) new World when a touch event is triggered. * x and y are the location of the event on the device screen, * and event is a String that describes what kind of event * occurred. * ** Developing an Android application is a bit more work, since it requires the * Android development kit for Eclipse. After that, you can create an * Android Project and fill in all the parameters. The World/VoidWorld classes * only require a simple hook to be added to the application's Activity. *
* * Below is a simple example of aWorld
that adds a new point at each mouse click. The world * contains a {@link android.image.Scene Scene} and a new {@link android.image.Circle Circle} is placed for each *"button-down"
event received. The World is created in the * class that extends Activity. * ** import android.app.Activity; * import android.os.Bundle; * import android.view.Display; * * import android.image.*; * import android.world.World; * * public class MousePoints extends Activity{ * // Called when the activity is first created. * public void onCreate(Bundle savedState) { * super.onCreate(savedState); * * Display dis = getWindowManager().getDefaultDisplay(); * * // Create and start the World * new MousePointsWorld(new EmptyScene(dis.getWidth(), dis.getHeight()-50)) * .bigBang(this); * } * } * * class MousePointsWorld extends World{ * Scene scene; * * MousePointsWorld(Scene scene){ * this.scene = scene; * } * * public Scene onDraw(){ return this.scene; } * * public World onMouse(int x, int y, String me){ * if(!me.equals("button-down")){ * return this; * }else{ * return new MousePointsWorld( * this.scene.placeImage(new Circle(20, "solid", "red") * .overlay(new Circle(20, "outline", "black")), x, y)); * } * } * } ** * After a few finger-taps, the device will look something like this:
* **
* In addition to the normal World events (button-down/up) Android devices * include a "long-button-down" event, for when the * the user does a long press (touch and hold). *
** Possible Mouse Events *
"button-down" : | *The user presses the touch screen of the device |
"long-button-down" : | *The user presses and holds on the touch screen of the device |
"button-up" : | *The user releases the touch screen of the device |
"move" : | *The user moves the mouse in the World window |
"drag" : | *The user touches and moves on the touch screen of the device |
* Special Keys *
"up" : | *The user presses the up-arrow key |
"down" : | *The user presses the down-arrow key |
"left" : | *The user presses the left-arrow key |
"right" : | *The user presses the right-arrow key |
* Special Keys *
"up" : | *The user presses the up-arrow key |
"down" : | *The user presses the down-arrow key |
"left" : | *The user presses the left-arrow key |
"right" : | *The user presses the right-arrow key |
* If you are only concerned with the "down" angle (direction of down * with respect to the screen) you can calculate it with a method as follows: *
* double down(double x, double y, double z){ * double ang = Math.acos(x/Math.sqrt(x*x + y*y))+Math.PI; * if(y < 0)return 2*Math.PI-ang; * return ang; * } ** */ public World onOrientation(double x, double y, double z){ return this; } /** Kick off the interaction/animation. This method returns the final * state of the world after the user closes the World window. */ public World bigBang(Activity act){ return (World)this.makeBigBang().bigBang(act); } /** Kick off the interaction/animation in LANDSCAPE mode. */ public World bigBangLandscape(Activity act){ return (World)this.makeBigBang().bigBangLandscape(act); } /** Kick off the interaction/animation FULLSCREEN mode. This method returns the final * state of the world after the user closes the World window. */ public World bigBangFullscreen(Activity act){ return (World)this.makeBigBang().bigBangFullscreen(act); } /** Kick off the interaction/animation in FULLSCREEN/LANDSCAPE mode. */ public World bigBangLandscapeFullscreen(Activity act){ return (World)this.makeBigBang().bigBangLandscapeFullscreen(act); } /** Get a bigbang instance for this World */ private BigBang makeBigBang(){ this.bigbang = new BigBang(this) .onDraw(new WorldDraw()) .onTick(new WorldTick(), tickRate()) .onMouse(new WorldMouse()) .onKey(new WorldKey()) .onRelease(new WorldRelease()) .stopWhen(new WorldStop()) .lastScene(new WorldLast()) .orientation(new WorldOrient()); return this.bigbang; } /** Use to Disable Screen Shots */ public static void noScreenShots(){ BigBang.Handler.screenShots = false; } /** Use to temperarily disable onTick/interactions */ public void pause(){ this.bigbang.pause(); } /** Use to renable onTick/interactions */ public void unpause(){ this.bigbang.unpause(); } /** Wrapper for OnDraw callback */ private static class WorldDraw{ @SuppressWarnings("unused") Scene apply(World w){ return w.onDraw(); } } /** Wrapper for OnTick callback */ private static class WorldTick{ @SuppressWarnings("unused") World apply(World w){ return w.onTick(); } } /** Wrapper for OnMouse callback */ private static class WorldMouse{ @SuppressWarnings("unused") World apply(World w, int x, int y, String me) { return w.onMouse(x,y,me); } } /** Wrapper for OnKey callback */ private static class WorldKey{ @SuppressWarnings("unused") World apply(World w, String ke){ return w.onKey(ke); } } /** Wrapper for OnRelease callback */ private static class WorldRelease{ @SuppressWarnings("unused") World apply(World w, String ke){ return w.onRelease(ke); } } /** Wrapper for StopWhen callback */ private static class WorldStop{ @SuppressWarnings("unused") boolean apply(World w){ return w.stopWhen(); } } /** Wrapper for LastScene callback */ private static class WorldLast{ @SuppressWarnings("unused") Scene apply(World w){ return w.lastScene(); } } /** Wrapper for LastScene callback */ private static class WorldOrient{ @SuppressWarnings("unused") World apply(World w, float x, float y, float z){ return w.onOrientation(x,y,z); } } }