More work, including more input methods
[rokon:rokon.git] / src / com / stickycoding / rokon / Scene.java
1 package com.stickycoding.rokon;\r
2 \r
3 import java.lang.reflect.InvocationTargetException;\r
4 import java.lang.reflect.Method;\r
5 import java.util.Arrays;\r
6 \r
7 import javax.microedition.khronos.opengles.GL10;\r
8 \r
9 import android.view.KeyEvent;\r
10 import android.view.MotionEvent;\r
11 \r
12 import com.badlogic.gdx.physics.box2d.Contact;\r
13 import com.badlogic.gdx.physics.box2d.ContactListener;\r
14 import com.badlogic.gdx.physics.box2d.World;\r
15 import com.stickycoding.rokon.background.Background;\r
16 import com.stickycoding.rokon.device.Graphics;\r
17 \r
18 /**\r
19  * Scene.java\r
20  * A Scene holds and prepares drawable objects or object groups\r
21  * \r
22  * @author Richard\r
23  */\r
24 public class Scene {\r
25         \r
26         public static final int SCENE_TEXTURE_COUNT = 32;\r
27         public static final int DEFAULT_LAYER_COUNT = 1;\r
28         public static final int DEFAULT_LAYER_OBJECT_COUNT = 32;\r
29 \r
30         protected Layer[] layer;\r
31         protected boolean loadedTextures;\r
32         protected int layerCount;\r
33         protected Window window = null;\r
34         protected Texture[] texturesToLoad;\r
35         protected Texture[] texturesOnHardware;\r
36         protected boolean useInvoke;\r
37         protected World world;\r
38         protected boolean usePhysics = false;\r
39         protected ContactListener contactListener;\r
40         protected boolean useContactListener;\r
41         protected Background background;\r
42         \r
43         protected float defaultLineWidth = 1;\r
44 \r
45         public void onPreDraw(GL10 gl) { }\r
46         public void onPostDraw(GL10 gl) { }\r
47         \r
48         public void onPause() { }\r
49         public void onResume() { }\r
50         \r
51         public void onTouchDown(GameObject object, float x, float y, MotionEvent event) { }\r
52         public void onTouchUp(GameObject object, float x, float y, MotionEvent event) { }\r
53         public void onTouchMove(GameObject object, float x, float y, MotionEvent event) { }\r
54         public void onTouch(GameObject object, float x, float y, MotionEvent event) { }\r
55         public void onTouchDown(float x, float y, MotionEvent event) { }\r
56         public void onTouchMove(float x, float y, MotionEvent event) { }\r
57         public void onTouch(float x, float y, MotionEvent event) { }\r
58         public void onTouchUp(float x, float y, MotionEvent event) { }\r
59         \r
60         public void onTouchDownReal(float x, float y, MotionEvent event) { }\r
61         public void onTouchMoveReal(float x, float y, MotionEvent event) { }\r
62         public void onTouchUpReal(float x, float y, MotionEvent event) { }\r
63         public void onTouchReal(float x, float y, MotionEvent event) { }\r
64 \r
65         public void onKeyDown(int keyCode, KeyEvent event) { }\r
66         public void onKeyUp(int keyCode, KeyEvent event) { }\r
67         public void onTrackballEvent(MotionEvent event) { }\r
68         \r
69         /**\r
70          * Sets a World for the physics in this Scene\r
71          * Automatically flags usePhysics\r
72          * \r
73          * @param world valid World object\r
74          */\r
75         public void setWorld(World world) {\r
76                 this.world = world;\r
77                 Physics.world = world;\r
78                 usePhysics = true;\r
79         }\r
80         \r
81         /**\r
82          * Returns the World associated with this Scene\r
83          * \r
84          * @return NULL if no World set\r
85          */\r
86         public World getWorld() {\r
87                 return world;\r
88         }\r
89         \r
90         /**\r
91          * Flags to use physics in this Scene\r
92          */\r
93         public void usePhysics() {\r
94                 usePhysics = true;\r
95         }\r
96         \r
97         /**\r
98          * Flags to not use physics\r
99          */\r
100         public void noPhysics() {\r
101                 usePhysics = false;\r
102         }\r
103         \r
104         /**\r
105          * Removes the World from this Scene\r
106          */\r
107         public void removeWorld() {\r
108                 this.world = null;\r
109                 Physics.world = null;\r
110                 usePhysics = false;\r
111         }\r
112         \r
113         /**\r
114          * Triggers the Scene to begin invoking methods on certain events, this is not set by default.\r
115          * If the methods that are to be invoked don't exist, no exceptions will be raised.\r
116          */\r
117         public void useInvoke() {\r
118                 useInvoke = true;\r
119         }\r
120         \r
121         /**\r
122          * Stops the Scene from invoking methods on events, this is the default state\r
123          */\r
124         public void stopInvoke() {\r
125                 useInvoke = false;\r
126         }\r
127         \r
128         /**\r
129          * Invokes a method inside the Scene class, defined by given parameters.\r
130          * If no parameters exist, use the alternative invoke method\r
131          * \r
132          * @param methodName String\r
133          * @param params Class[]\r
134          * @param paramValues Object[]\r
135          * \r
136          * @return TRUE if successful, FALSE otherwise\r
137          */\r
138         public boolean invoke(String methodName, Class<?>[] params, Object[] paramValues) {\r
139                 for(Method m : this.getClass().getDeclaredMethods()) {\r
140                         if(m.getName().equals(methodName)) {\r
141                                 if(Arrays.equals(params, m.getParameterTypes())) {\r
142                                         try {\r
143                                                 m.invoke(this, paramValues);\r
144                                                 return true;\r
145                                         } catch (IllegalArgumentException e) {\r
146                                                 Debug.error("Invoking, IllegalArgument");\r
147                                                 e.printStackTrace();\r
148                                                 return false;\r
149                                         } catch (IllegalAccessException e) {\r
150                                                 Debug.error("Invoking, IllegalAccess");\r
151                                                 e.printStackTrace();\r
152                                                 return false;\r
153                                         } catch (InvocationTargetException e) {\r
154                                                 Debug.error("Invoking, IllegalTarget");\r
155                                                 e.printStackTrace();\r
156                                                 return false;\r
157                                         }\r
158                                 }\r
159                         }\r
160                 }\r
161                 return false;\r
162         }\r
163         \r
164         /**\r
165          * Invokes a method by parameters inside a Callback object\r
166          * \r
167          * @param callback valid Callback object\r
168          * @return TRUE if successful, FALSE otherwise\r
169          */\r
170         public boolean invoke(Callback callback) {\r
171                 if(callback.parameters == null) {\r
172                         return invoke(callback.methodName);\r
173                 } \r
174                 if(callback.parameterTypes == null) {\r
175                         return invoke(callback.methodName, callback.parameters);\r
176                 }\r
177                 return invoke(callback.methodName, callback.parameterTypes, callback.parameters);\r
178         }\r
179         \r
180         /**\r
181          * USE AT YOUR OWN RISK\r
182          * Invokes a method inside the Scene class, it selects the first matching method name and tries to pass on given parameters\r
183          * An error will be raised if this isn't the correct method. This routine is simply for those too lazy (or wanting to save\r
184          * on a little processing time) and are 100% sure there are no name conflicts.\r
185          * \r
186          * IllegalArgumentException may be passed to the Debug class, logcat will be notified - but there is no way to test at your end.\r
187          * \r
188          * @param methodName String\r
189          * @param paramValues Object[]\r
190          * \r
191          * @return TRUE if successful, FALSE otherwise\r
192          */\r
193         public boolean invoke(String methodName, Object[] paramValues) {\r
194                 for(Method m : this.getClass().getDeclaredMethods()) {\r
195                         if(m.getName().equals(methodName)) {\r
196                                 try {\r
197                                         m.invoke(this, paramValues);\r
198                                         return true;\r
199                                 } catch (IllegalArgumentException e) {\r
200                                         Debug.error("Invoking, IllegalArgument");\r
201                                         e.printStackTrace();\r
202                                         return false;\r
203                                 } catch (IllegalAccessException e) {\r
204                                         Debug.error("Invoking, IllegalAccess");\r
205                                         e.printStackTrace();\r
206                                         return false;\r
207                                 } catch (InvocationTargetException e) {\r
208                                         Debug.error("Invoking, IllegalTarget");\r
209                                         e.printStackTrace();\r
210                                         return false;\r
211                                 }\r
212                         }\r
213                 }\r
214                 return false;\r
215         }\r
216         \r
217         /**\r
218          * Invokes a method inside the Scene class, assuming there are no parameters to pass\r
219          * \r
220          * @param methodName String\r
221          * \r
222          * @return TRUE if successful, FALSE otherwise\r
223          */\r
224         public boolean invoke(String methodName) {\r
225                 for(Method m : this.getClass().getDeclaredMethods()) {\r
226                         if(m.getName().equals(methodName)) {\r
227                                 if(m.getParameterTypes().length == 0) {\r
228                                         try {\r
229                                                 m.invoke(this);\r
230                                                 return true;\r
231                                         } catch (IllegalArgumentException e) {\r
232                                                 Debug.error("Invoking, IllegalArgument");\r
233                                                 e.printStackTrace();\r
234                                                 return false;\r
235                                         } catch (IllegalAccessException e) {\r
236                                                 Debug.error("Invoking, IllegalAccess");\r
237                                                 e.printStackTrace();\r
238                                                 return false;\r
239                                         } catch (InvocationTargetException e) {\r
240                                                 Debug.error("Invoking, IllegalTarget");\r
241                                                 e.printStackTrace();\r
242                                                 return false;\r
243                                         }\r
244                                 }\r
245                         }\r
246                 }\r
247                 return false;\r
248         }\r
249         \r
250         protected void handleTouch(MotionEvent event) {\r
251                 float realX = event.getX() * (Graphics.getWidthPixels() / RokonActivity.gameWidth);\r
252                 float realY = event.getY() * (Graphics.getHeightPixels() / RokonActivity.gameHeight);\r
253                 if(window != null) {\r
254                         float xFraction = event.getX() / Graphics.getWidthPixels();\r
255                         float yFraction = event.getY() / Graphics.getHeightPixels();\r
256                         float gameX = window.x + (window.width * xFraction);\r
257                         float gameY = window.y + (window.height * yFraction);\r
258                         event.setLocation(gameX, gameY);\r
259                 } else {\r
260                         event.setLocation(event.getX() * (Graphics.getWidthPixels() / RokonActivity.gameWidth), event.getY() * (Graphics.getHeightPixels()  / RokonActivity.gameHeight));                       \r
261                 }\r
262                 onTouch(event.getX(), event.getY(), event);\r
263                 onTouchReal(realX, realY, event);\r
264                 switch(event.getAction()) {\r
265                         case MotionEvent.ACTION_DOWN:\r
266                                 onTouchDown(event.getX(), event.getY(), event);\r
267                                 onTouchDownReal(realX, realY, event);\r
268                                 break;\r
269                         case MotionEvent.ACTION_UP:\r
270                                 onTouchUp(event.getX(), event.getY(), event);\r
271                                 onTouchUpReal(realX, realY, event);\r
272                                 break;\r
273                         case MotionEvent.ACTION_MOVE:\r
274                                 onTouch(event.getX(), event.getY(), event);\r
275                                 onTouchUp(realX, realY, event);\r
276                                 break;\r
277                 }\r
278                 for(int i = 0; i < layerCount; i++) {\r
279                         for(int j = 0; j < layer[i].maximumDrawableObjects; j++) {\r
280                                 float checkX, checkY;\r
281                                 checkX = event.getX();\r
282                                 checkY = event.getY();\r
283                                 if(layer[i].ignoreWindow) {\r
284                                         checkX = realX;\r
285                                         checkY = realY;\r
286                                 }\r
287                                 GameObject object = layer[i].gameObjects.get(j);\r
288                                 if(object != null && object.isTouchable) {\r
289                                         if(MathHelper.pointInRect(checkX, checkY, object.x, object.y, object.width, object.height)) {\r
290                                                 onTouch(object, checkX, checkY, event);\r
291                                                 if(object.getName() != null) {\r
292                                                         invoke(object.getName() + "_onTouch", new Class[] { float.class, float.class, MotionEvent.class }, new Object[] { event.getX(), event.getY(), event });\r
293                                                 }\r
294                                                 switch(event.getAction()) {\r
295                                                         case MotionEvent.ACTION_DOWN:\r
296                                                                 onTouchDown(object, checkX, checkY, event);\r
297                                                                 if(object.getName() != null) {\r
298                                                                         invoke(object.getName() + "_onTouchDown", new Class[] { float.class, float.class, MotionEvent.class }, new Object[] { event.getX(), event.getY(), event });\r
299                                                                 }\r
300                                                                 break;\r
301                                                         case MotionEvent.ACTION_UP:\r
302                                                                 onTouchUp(object, checkX, checkY, event);\r
303                                                                 if(object.getName() != null) {\r
304                                                                         invoke(object.getName() + "_onTouchUp", new Class[] { float.class, float.class, MotionEvent.class }, new Object[] { event.getX(), event.getY(), event });\r
305                                                                 }\r
306                                                                 break;\r
307                                                         case MotionEvent.ACTION_MOVE:\r
308                                                                 onTouch(object, checkX, checkY, event);\r
309                                                                 if(object.getName() != null) {\r
310                                                                         invoke(object.getName() + "_onTouchMove", new Class[] { float.class, float.class, MotionEvent.class }, new Object[] { event.getX(), event.getY(), event });\r
311                                                                 }\r
312                                                                 break;\r
313                                                 }\r
314                                         }\r
315                                 }\r
316                         }\r
317                 }\r
318         }\r
319         \r
320         /**\r
321          * Creates a new Scene with given layer count, and a corresponding maximum DrawableObject count \r
322          * \r
323          * @param layerCount maximum number of layers\r
324          * @param layerObjectCount maximum number of DrawableObjects per layer, the array length must match layerCount\r
325          */\r
326         public Scene(int layerCount, int[] layerObjectCount) {\r
327                 this.layerCount = layerCount;\r
328                 layer = new Layer[layerCount];\r
329                 for(int i = 0; i < layerCount; i++) {\r
330                         layer[i] = new Layer(this, layerObjectCount[i]);\r
331                 }\r
332                 prepareNewScene();\r
333         }\r
334         \r
335         /**\r
336          * Creates a new Scene with given layer count, all layers will have the same maximum number of DrawableObjects\r
337          * \r
338          * @param layerCount maximum number of layers\r
339          * @param layerObjectCount maximum number of DrawableObjects per layer\r
340          */\r
341         public Scene(int layerCount, int layerObjectCount) {\r
342                 this.layerCount = layerCount;\r
343                 layer = new Layer[layerCount];\r
344                 for(int i = 0; i < layerCount; i++) {\r
345                         layer[i] = new Layer(this, layerObjectCount);\r
346                 }\r
347                 prepareNewScene();\r
348         }\r
349         \r
350         /**\r
351          * Creates a new Scene with given layer count, and a default maximum DrawableObject count of DEFAULT_LAYER_OBJECT_COUNT\r
352          * \r
353          * @param layerCount maximum number of layers\r
354          */\r
355         public Scene(int layerCount) {\r
356                 this(layerCount, DEFAULT_LAYER_OBJECT_COUNT);\r
357         }\r
358         \r
359         /**\r
360          * Creates a new Scene with defaults, DEFAULT_LAYER_COUNT and DEFAULT_LAYER_OBJECT_COUNT\r
361          */\r
362         public Scene() {\r
363                 this(DEFAULT_LAYER_COUNT, DEFAULT_LAYER_OBJECT_COUNT);\r
364                 \r
365         }\r
366         \r
367         private void prepareNewScene() {\r
368                 texturesToLoad = new Texture[SCENE_TEXTURE_COUNT];\r
369                 texturesOnHardware = new Texture[SCENE_TEXTURE_COUNT];\r
370         }\r
371         \r
372         /**\r
373          * Flags a Texture to be loaded into this Scene\r
374          * This must be called before RokonActivity.setScene\r
375          * \r
376          * @param texture valid Texture object\r
377          */\r
378         public void useTexture(Texture texture) {\r
379                 for(int i = 0; i < texturesToLoad.length; i++) {\r
380                         if(texturesToLoad[i] == texture) return;\r
381                         if(texturesToLoad[i] == null) {\r
382                                 texturesToLoad[i] = texture;\r
383                                 return;\r
384                         }\r
385                 }\r
386                 Debug.warning("Scene.useTexture", "Tried loading too many Textures onto the Scene, max is " + texturesToLoad.length);\r
387         }\r
388         \r
389         /**\r
390          * Defines the active Window for this Scene\r
391          * If no Window is given, a default static view will be rendered \r
392          * \r
393          * @param window\r
394          */\r
395         public void setWindow(Window window) {\r
396                 if(window == null) {\r
397                         Debug.warning("Scene.setWindow", "Tried setting a NULL Window");\r
398                         return;\r
399                 }\r
400                 this.window = window;\r
401         }\r
402         \r
403         /**\r
404          * Removes the current active Window, returning it to NULL\r
405          */\r
406         public void removeWindow() {\r
407                 window = null;\r
408         }\r
409         \r
410         /**\r
411          * @return NULL if there is no Window associated with this Scene\r
412          */\r
413         public Window getWindow() {\r
414                 if(window == null)\r
415                         return null;\r
416                 return window;\r
417         }\r
418         \r
419         /**\r
420          * Fetches the Layer object associated with the given index\r
421          * \r
422          * @param index the index of the Layer\r
423          * @return NULL if invalid index is given\r
424          */\r
425         public Layer getLayer(int index) {\r
426                 if(index < 0 || index > layerCount) {\r
427                         Debug.warning("Scene.getLayer", "Tried fetching invalid layer (" + index + "), maximum is " + layerCount);\r
428                         return null;\r
429                 }\r
430                 return layer[index];\r
431         }\r
432         \r
433         /**\r
434          * Clears the DrawableObjects from all Layers\r
435          */\r
436         public void clear() {\r
437                 for(int i = 0; i < layerCount; i++) {\r
438                         layer[i].clear();\r
439                 }\r
440         }\r
441         \r
442         /**\r
443          * Clears all the DrawableObjects from a specified Layer\r
444          * \r
445          * @param index the index of the Layer\r
446          */\r
447         public void clearLayer(int index) {\r
448                 if(index <= 0 || index > layerCount) {\r
449                         Debug.warning("Scene.clearLayer", "Tried clearing invalid layer (" + index + "), maximum is " + layerCount);\r
450                         return;\r
451                 }\r
452                 layer[index].clear();\r
453         }\r
454         \r
455         /**\r
456          * Moves a Layer from one index to another, and shuffles the others up or down to accomodate\r
457          * \r
458          * @param startIndex the current index of the Layer\r
459          * @param endIndex the desired final index of the Layer\r
460          */\r
461         public void moveLayer(int startIndex, int endIndex) {\r
462                 if(startIndex == endIndex) {\r
463                         Debug.warning("Scene.moveLayer", "Tried moving a Layer to its own position, stupid");\r
464                         return;\r
465                 }\r
466                 if(startIndex <= 0 || startIndex > layerCount) {\r
467                         Debug.warning("Scene.moveLayer", "Tried moving an invalid Layer, startIndex=" + startIndex + ", maximum is " + layerCount);\r
468                         return;\r
469                 }\r
470                 if(endIndex <= 0 || endIndex > layerCount) {\r
471                         Debug.warning("Scene.moveLayer", "Tried moving an invalid Layer, endIndex=" + endIndex + ", maximum is " + layerCount);\r
472                         return;\r
473                 }\r
474                 Layer temporaryLayer = layer[startIndex];\r
475                 if(endIndex < startIndex) {\r
476                         for(int i = endIndex; i < startIndex; i++) {\r
477                                 layer[i + 1] = layer[i];\r
478                         }\r
479                         layer[endIndex] = temporaryLayer;\r
480                 }\r
481                 if(endIndex > startIndex) { \r
482                         for(int i = startIndex; i < endIndex; i++) {\r
483                                 layer[i] = layer[i + 1];\r
484                         }\r
485                         layer[endIndex] = temporaryLayer;\r
486                 }\r
487         }\r
488         \r
489         /**\r
490          * Switches the position of one Layer with another\r
491          * \r
492          * @param layer1 the index of the first Layer\r
493          * @param layer2 the index of the second Layer\r
494          */\r
495         public void switchLayers(int layer1, int layer2) {\r
496                 if(layer1 == layer2) {\r
497                         Debug.warning("Scene.switchLayers", "Tried switching the same Layer");\r
498                         return;\r
499                 }\r
500                 if(layer1 < 0 || layer1 > layerCount) {\r
501                         Debug.warning("Scene.switchLayers", "Tried switch an invalid Layer, layer1=" + layer1 + ", maximum is " + layerCount);\r
502                         return;\r
503                 }\r
504                 if(layer2 < 0 || layer2 > layerCount) {\r
505                         Debug.warning("Scene.switchLayers", "Tried switch an invalid Layer, layer2=" + layer2 + ", maximum is " + layerCount);\r
506                         return;\r
507                 }\r
508                 Layer temporaryLayer = layer[layer1];\r
509                 layer[layer1] = layer[layer2];\r
510                 layer[layer2] = temporaryLayer;\r
511         }\r
512         \r
513         /**\r
514          * Replaces a Layer object in this Scene\r
515          * \r
516          * @param index a valid index for a Layer, less than getLayerCount\r
517          * @param layer a valid Layer object to replace the existing Layer\r
518          */\r
519         public void setLayer(int index, Layer layer) {\r
520                 if(layer == null) {\r
521                         Debug.warning("Scene.setLayer", "Tried setting to a null Layer");\r
522                         return;\r
523                 }\r
524                 if(index < 0 || index > layerCount) {\r
525                         Debug.warning("Scene.setLayer", "Tried setting an invalid Layer, index=" + index + ", maximum is " + layerCount);\r
526                         return;\r
527                 }\r
528                 this.layer[index] = layer;\r
529         }\r
530         \r
531         /**\r
532          * Adds a DrawableObject to the first (0th) Layer\r
533          * \r
534          * @param drawableObject a valid DrawableObject\r
535          */\r
536         public void add(GameObject drawableObject) {\r
537                 layer[0].add(drawableObject);\r
538         }\r
539         \r
540         /**\r
541          * Adds a DrawableObject to a given Layer\r
542          * \r
543          * @param layerIndex a valid index of a Layer\r
544          * @param drawableObject a valid DrawableObject\r
545          */\r
546         public void add(int layerIndex, GameObject drawableObject) {\r
547                 if(layerIndex < 0 || layerIndex > layerCount) {\r
548                         Debug.warning("Scene.add", "Tried adding to an invalid Layer, layerIndex=" + layerIndex + ", maximum is " + layerCount);\r
549                         return;\r
550                 }\r
551                 if(drawableObject == null) {\r
552                         Debug.warning("Scene.add", "Tried adding a NULL DrawableObject");\r
553                         return;\r
554                 }\r
555                 layer[layerIndex].add(drawableObject);\r
556         }\r
557         \r
558         /**\r
559          * Removes a DrawableObject from the Scene\r
560          * \r
561          * @param drawableObject a valid DrawableObject\r
562          */\r
563         public void remove(DrawableObject drawableObject) {\r
564                 drawableObject.remove();\r
565         }\r
566         \r
567         protected void onUpdate() {\r
568                 \r
569         }\r
570         \r
571         protected void onGameLoop() {\r
572                 \r
573         }\r
574         \r
575         protected void onSetScene() {\r
576                 loadedTextures = false;\r
577         }\r
578         \r
579         protected void onEndScene() {\r
580                 \r
581         }\r
582         \r
583         protected void onLoadTextures(GL10 gl) {\r
584                 Debug.print("Loading textures onto the Scene");\r
585                 for(int i = 0; i < texturesToLoad.length; i++) {\r
586                         if(texturesToLoad[i] != null) {\r
587                                 texturesToLoad[i].onLoadTexture(gl);\r
588                                 boolean foundSpace = false;\r
589                                 for(int j = 0; j < texturesOnHardware.length; j++) {\r
590                                         if(texturesOnHardware[j] == null) {\r
591                                                 Debug.print("found room...");\r
592                                                 texturesOnHardware[j] = texturesToLoad[i];\r
593                                                 foundSpace = true;\r
594                                                 break;\r
595                                         }\r
596                                 }\r
597                                 if(!foundSpace) {\r
598                                         Debug.warning("Loading more textures than we can remember - will not be there if we onPause, may not be destroyed on Scene death");\r
599                                 }\r
600                                 texturesToLoad[i] = null;\r
601                         }\r
602                 }\r
603                 loadedTextures = true;\r
604         }\r
605         \r
606         protected void onReloadTextures(GL10 gl) {\r
607                 texturesToLoad = texturesOnHardware;\r
608                 for(int i = 0; i < texturesOnHardware.length; i++) {\r
609                         texturesOnHardware[i] = null;\r
610                 }\r
611                 onLoadTextures(gl);\r
612         }\r
613         \r
614         protected void onDraw(GL10 gl) {\r
615                 onPreDraw(gl);\r
616                 gl.glClear(GL10.GL_COLOR_BUFFER_BIT);\r
617                 if(background != null) {\r
618                         background.onDraw(gl);\r
619                 }\r
620                 if(window != null) {\r
621                         window.onUpdate(gl);\r
622                 }\r
623                 if(usePhysics && !pausePhysics) {\r
624                         world.step(Time.getTicksFraction(), 10, 10);\r
625                 }\r
626                 gl.glMatrixMode(GL10.GL_MODELVIEW);\r
627         gl.glLoadIdentity();\r
628                 for(int i = 0; i < layerCount; i++) {\r
629                         layer[i].onDraw(gl);\r
630                 }\r
631                 onPostDraw(gl);\r
632         }\r
633         \r
634         protected boolean pausePhysics = false;\r
635         \r
636         public void pausePhysics() {\r
637                 pausePhysics = true;\r
638         }\r
639         \r
640         public void resumePhysics() {\r
641                 pausePhysics = false;\r
642         }\r
643         \r
644         public void setBackground(Background background) {\r
645                 this.background = background;\r
646                 background.parentScene = this;\r
647         }\r
648         \r
649         public Background getBackground() {\r
650                 return this.background;\r
651         }\r
652         \r
653         \r
654         \r
655         \r
656         \r
657         \r
658         \r
659         \r
660         protected class SceneContactListener implements ContactListener {\r
661 \r
662                 public void beginContact(Contact contact) {\r
663                         // TODO Auto-generated method stub\r
664                         \r
665                 }\r
666 \r
667                 public void endContact(Contact contact) {\r
668                         // TODO Auto-generated method stub\r
669                         \r
670                 }\r
671                 \r
672         }\r
673         \r
674         public void useContactListener() {\r
675                 if(contactListener == null) {\r
676                         contactListener = new SceneContactListener();\r
677                 }\r
678                 useContactListener = true;\r
679         }\r
680         \r
681         public void stopContactListener() {\r
682                 useContactListener = false;\r
683         }\r
684         \r
685         public void setContactListener(ContactListener contactListener) {\r
686                 this.contactListener = contactListener;\r
687         }\r
688         \r
689         public void setDefaultLineWidth(float lineWidth) {\r
690                 defaultLineWidth = lineWidth;\r
691         }\r
692         \r
693         public float getDefaultLineWidth() {\r
694                 return defaultLineWidth;\r
695         }\r
696         \r
697         \r
698         \r
699 }\r