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