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