diff options
author | sm0a9f4 <sm0a9f4@1dde52a2-2b62-11df-8484-2f92f965d510> | 2010-05-03 04:02:32 +0000 |
---|---|---|
committer | sm0a9f4 <sm0a9f4@1dde52a2-2b62-11df-8484-2f92f965d510> | 2010-05-03 04:02:32 +0000 |
commit | 9d4cc2572d37983607df38b0f4216ed76ac51814 (patch) | |
tree | b0fba19324ec0b0274f4cbed4d30c55c1f13aa2e | |
parent | e1fe50fadc9160b2c4ee09350b781c9b80d54e1f (diff) | |
download | replicaisland-9d4cc2572d37983607df38b0f4216ed76ac51814.tar.gz |
Public release v1.3.
+ Rewrote input system to better abstract different hardware from game. Major rework to this section.
+ Added nefarious hacks via "Safe Mode" to work around failures in broken GL drivers used by some handsets (Cliq et al).
+ Various bug fixes and performance improvements.
+ Cranked up pool sizes to allow for more simultaneous game objects. (Runtime heap high watermark is now ~6mb)
+ Fixed bugs in SliderPreference to allow it to be properly instanced.
+ Added some debug frame rate display tools.
git-svn-id: http://replicaisland.googlecode.com/svn/trunk@6 1dde52a2-2b62-11df-8484-2f92f965d510
36 files changed, 1377 insertions, 1124 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index f383a16..80119ef 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.replica.replicaisland" android:versionName="1.21" android:versionCode="12"> + package="com.replica.replicaisland" android:versionName="1.3" android:versionCode="13"> <application android:icon="@drawable/icon" android:label="@string/app_name" + android:debuggable="false" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" > <activity android:name=".MainMenuActivity" android:label="@string/app_name" diff --git a/res/drawable/framerate_warning.png b/res/drawable/framerate_warning.png Binary files differnew file mode 100644 index 0000000..b3ca873 --- /dev/null +++ b/res/drawable/framerate_warning.png diff --git a/res/layout/slider_preference.xml b/res/layout/slider_preference.xml index 0206eee..f35c896 100644 --- a/res/layout/slider_preference.xml +++ b/res/layout/slider_preference.xml @@ -13,7 +13,9 @@ <SeekBar xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/slider" android:layout_height="wrap_content" - android:layout_gravity="center_vertical" android:layout_width="250dp" android:layout_margin="10dp"/> + android:layout_gravity="center_vertical" + android:layout_width="100dp" + android:layout_margin="10dp"/> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/max" android:text="Max" diff --git a/res/raw/performancetest4.bin b/res/raw/performancetest4.bin Binary files differnew file mode 100644 index 0000000..fc3adaa --- /dev/null +++ b/res/raw/performancetest4.bin diff --git a/res/values/strings.xml b/res/values/strings.xml index 835e658..be55c34 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -26,12 +26,20 @@ <string name="preference_enable_sound">Enable Sound</string> <string name="preference_enable_sound_summary">Disabling sound may improve performance on some devices.</string> +<string name="preference_safe_mode">Safe Mode</string> +<string name="preference_safe_mode_summary">Enables safety hacks for broken devices (Cliq, etc), but causes some visual artifacts. Try this if you have problems.</string> + <string name="preference_configure_controls">Configure Controls</string> <string name="preference_enable_click_attack">Click Attack</string> <string name="preference_enable_click_attack_summary">Use the trackball click or directional pad center button to attack.</string> <string name="preference_enable_tilt_controls">Tilt Controls</string> <string name="preference_enable_tilt_controls_summary">EXPERIMENTAL! Tilt the phone left and right to drive the Android around. Good for devices with no trackball or d-pad.</string> +<string name="preference_movement_sensitivity">Motion Sensitivity</string> +<string name="preference_movement_sensitivity_summary">Adjusts the sensitivity of the trackball, d-pad, or optical sensor.</string> +<string name="preference_movement_min">Slow</string> +<string name="preference_movement_max">Fast</string> + <string name="preference_tilt_sensitivity">Tilt Sensitivity</string> <string name="preference_tilt_sensitivity_summary">Adjusts the sensitivity of the tilt controls.</string> <string name="preference_tilt_min">Slow</string> @@ -78,6 +86,15 @@ <string name="whats_new_dialog_ok">Rock on!</string> <string name="whats_new_dialog_message">Thanks for downloading Replica Island.\n\n <b>New in this version:</b>\n +\t• Fixed blackouts and crashes on Cliq, Backflip, etc. If you have problems try <b>Safe Mode</b> in the options screen.\n +\t• Improved controls, especially for Droid and other d-pad devices.\n +\t• Added <b>Motion Sensitivity</b> option to control options. Optical pad users (HTC Desire, Samsung Moment, etc) may want to turn sensitivity down a bit.\n +\t• Various performance and stability improvements.\n +\n +As of version 1.3, more than 500,000 users have downloaded Replica Island. Thank you for your support! +\n +\n +<b>New in version 1.21:</b>\n \t• Fixed crash when adjusting tilt sensitivity on Samsung Moment.\n \t• Added debug log option. \n \n @@ -95,7 +112,7 @@ own games, check out the source at our web site, replicaisland.net. Also note that this game sends anonymous play statistics back to a server. If you’d rather not allow that, you can turn it off in the options screen.</string> -<string name="whats_new_ticker">New in this version: Fix to tilt sensitivity crash on Samsung Moment, debug log options. New in 1.2: Crash fixes, fixes to the confusing Memory #034 puzzle, configurable controls, configurable tilt sensitivity.</string> +<string name="whats_new_ticker">New in this version: Fix blackouts on broken phones (Cliq, Backflip, etc), improved controls, adjustable control sensitivity, various performance and stability improvements.</string> <!-- Toast Messages --> <string name="memory_playback_start">MEMORY PLAYBACK START</string> diff --git a/res/xml/level_tree.xml b/res/xml/level_tree.xml index 1a5e589..2b83f09 100644 --- a/res/xml/level_tree.xml +++ b/res/xml/level_tree.xml @@ -310,8 +310,13 @@ </level> </group> - + <!-- + <group> + <level resource="@raw/performancetest4" title = "@string/level_performance_test2" time = "@string/level_test_time"/> +</group> + + <group> <level resource="@raw/puzzles_test" title = "@string/level_puzzle_test" time = "@string/level_test_time"/> <level resource="@raw/objecttestmap" title = "@string/level_object_test" time = "@string/level_test_time"/> diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 9136c5e..a263025 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -55,6 +55,16 @@ replica:attackKey="keyAttack" /> + <com.replica.replicaisland.SliderPreference + android:key="movementSensitivity" + android:defaultValue="100" + android:title="@string/preference_movement_sensitivity" + android:summary="@string/preference_movement_sensitivity_summary" + replica:maxText="@string/preference_movement_max" + replica:minText="@string/preference_movement_min" + android:persistent="true"/> + + <CheckBoxPreference android:key="enableTiltControls" android:title="@string/preference_enable_tilt_controls" @@ -76,6 +86,15 @@ </PreferenceScreen> + <CheckBoxPreference + android:key="safeMode" + android:title="@string/preference_safe_mode" + android:summaryOn="@string/preference_safe_mode_summary" + android:summaryOff="@string/preference_safe_mode_summary" + android:defaultValue="false" + android:persistent="true" + /> + </PreferenceCategory> <PreferenceCategory diff --git a/src/com/replica/replicaisland/AndouKun.java b/src/com/replica/replicaisland/AndouKun.java index dc29132..ed91b0d 100644 --- a/src/com/replica/replicaisland/AndouKun.java +++ b/src/com/replica/replicaisland/AndouKun.java @@ -60,12 +60,14 @@ public class AndouKun extends Activity implements SensorEventListener { public static final String PREFERENCE_LEVEL_INDEX = "levelIndex"; public static final String PREFERENCE_LEVEL_COMPLETED = "levelsCompleted"; public static final String PREFERENCE_SOUND_ENABLED = "enableSound"; + public static final String PREFERENCE_SAFE_MODE = "safeMode"; public static final String PREFERENCE_SESSION_ID = "session"; public static final String PREFERENCE_LAST_VERSION = "lastVersion"; public static final String PREFERENCE_STATS_ENABLED = "enableStats"; public static final String PREFERENCE_CLICK_ATTACK = "enableClickAttack"; public static final String PREFERENCE_TILT_CONTROLS = "enableTiltControls"; public static final String PREFERENCE_TILT_SENSITIVITY = "tiltSensitivity"; + public static final String PREFERENCE_MOVEMENT_SENSITIVITY = "movementSensitivity"; public static final String PREFERENCE_ENABLE_DEBUG = "enableDebug"; public static final String PREFERENCE_LEFT_KEY = "keyLeft"; @@ -79,7 +81,7 @@ public class AndouKun extends Activity implements SensorEventListener { // If the version is a negative number, debug features (logging and a debug menu) // are enabled. - public static final int VERSION = 12; + public static final int VERSION = 13; private GLSurfaceView mGLSurfaceView; private Game mGame; @@ -125,6 +127,7 @@ public class AndouKun extends Activity implements SensorEventListener { //mGLSurfaceView.setGLWrapper(new GLErrorLogger()); mGLSurfaceView.setEGLConfigChooser(false); // 16 bit, no z-buffer + //mGLSurfaceView.setDebugFlags(GLSurfaceView.DEBUG_CHECK_GL_ERROR | GLSurfaceView.DEBUG_LOG_GL_CALLS); mGame = new Game(); mGame.setSurfaceView(mGLSurfaceView); DisplayMetrics dm = new DisplayMetrics(); @@ -267,9 +270,11 @@ public class AndouKun extends Activity implements SensorEventListener { final boolean soundEnabled = prefs.getBoolean(PREFERENCE_SOUND_ENABLED, true); + final boolean safeMode = prefs.getBoolean(PREFERENCE_SAFE_MODE, false); final boolean clickAttack = prefs.getBoolean(PREFERENCE_CLICK_ATTACK, true); final boolean tiltControls = prefs.getBoolean(PREFERENCE_TILT_CONTROLS, false); final int tiltSensitivity = prefs.getInt(PREFERENCE_TILT_SENSITIVITY, 50); + final int movementSensitivity = prefs.getInt(PREFERENCE_MOVEMENT_SENSITIVITY, 100); final int leftKey = prefs.getInt(PREFERENCE_LEFT_KEY, KeyEvent.KEYCODE_DPAD_LEFT); final int rightKey = prefs.getInt(PREFERENCE_RIGHT_KEY, KeyEvent.KEYCODE_DPAD_RIGHT); @@ -277,8 +282,9 @@ public class AndouKun extends Activity implements SensorEventListener { final int attackKey = prefs.getInt(PREFERENCE_ATTACK_KEY, KeyEvent.KEYCODE_SHIFT_LEFT); mGame.setSoundEnabled(soundEnabled); - mGame.setControlOptions(clickAttack, tiltControls, tiltSensitivity); + mGame.setControlOptions(clickAttack, tiltControls, tiltSensitivity, movementSensitivity); mGame.setKeyConfig(leftKey, rightKey, jumpKey, attackKey); + mGame.setSafeMode(safeMode); if (mSensorManager != null) { Sensor orientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); @@ -293,35 +299,31 @@ public class AndouKun extends Activity implements SensorEventListener { @Override public boolean onTrackballEvent(MotionEvent event) { - mGame.onTrackballEvent(event); - final long time = System.currentTimeMillis(); - if (time - mLastRollTime < 4) { - // Sleep so that the main thread doesn't get flooded with UI events. - try { - Thread.sleep(4); - } catch (InterruptedException e) { - // No big deal if this sleep is interrupted. - } - } - mLastRollTime = time; + if (!mGame.isPaused()) { + mGame.onTrackballEvent(event); + final long time = System.currentTimeMillis(); + mLastRollTime = time; + } return true; } @Override public boolean onTouchEvent(MotionEvent event) { - mGame.onTouchEvent(event); - - final long time = System.currentTimeMillis(); - if (event.getAction() == MotionEvent.ACTION_MOVE && time - mLastTouchTime < 32) { - // Sleep so that the main thread doesn't get flooded with UI events. - try { - Thread.sleep(32); - } catch (InterruptedException e) { - // No big deal if this sleep is interrupted. + if (!mGame.isPaused()) { + mGame.onTouchEvent(event); + + final long time = System.currentTimeMillis(); + if (event.getAction() == MotionEvent.ACTION_MOVE && time - mLastTouchTime < 32) { + // Sleep so that the main thread doesn't get flooded with UI events. + try { + Thread.sleep(32); + } catch (InterruptedException e) { + // No big deal if this sleep is interrupted. + } + mGame.getRenderer().waitDrawingComplete(); } - mGame.getRenderer().waitDrawingComplete(); - } - mLastTouchTime = time; + mLastTouchTime = time; + } return true; } diff --git a/src/com/replica/replicaisland/AnimationComponent.java b/src/com/replica/replicaisland/AnimationComponent.java index 70ecf04..4f037a7 100644 --- a/src/com/replica/replicaisland/AnimationComponent.java +++ b/src/com/replica/replicaisland/AnimationComponent.java @@ -203,10 +203,11 @@ public class AnimationComponent extends GameComponent { float opacity = 1.0f; if (currentAction == ActionType.MOVE) { - InputSystem input = sSystemRegistry.inputSystem; - if (input.getRollDirection().x < 0.0f) { + InputGameInterface input = sSystemRegistry.inputGameInterface; + final InputXY dpad = input.getDirectionalPad(); + if (dpad.getX() < 0.0f) { parentObject.facingDirection.x = -1.0f; - } else if (input.getRollDirection().x > 0.0f) { + } else if (dpad.getX() > 0.0f) { parentObject.facingDirection.x = 1.0f; } @@ -221,14 +222,11 @@ public class AnimationComponent extends GameComponent { mSprite.playAnimation(PlayerAnimations.MOVE.ordinal()); } - if (input.getClickPressed() || - (input.getTouchPressed() && input.getTouchedWithinRegion( - ButtonConstants.STOMP_BUTTON_REGION_X, - ButtonConstants.STOMP_BUTTON_REGION_Y, - ButtonConstants.STOMP_BUTTON_REGION_WIDTH, - ButtonConstants.STOMP_BUTTON_REGION_HEIGHT))) { + final InputButton attackButton = input.getAttackButton(); + + if (attackButton.getPressed()) { // charge - final float pressedTime = gameTime - input.getLastClickTime(); + final float pressedTime = gameTime - attackButton.getLastPressedTime(); final float wave = (float)Math.cos(pressedTime * (float)Math.PI * 2.0f); opacity = (wave * 0.25f) + 0.75f; } diff --git a/src/com/replica/replicaisland/CollisionSystem.java b/src/com/replica/replicaisland/CollisionSystem.java index 0f6772e..be8221d 100644 --- a/src/com/replica/replicaisland/CollisionSystem.java +++ b/src/com/replica/replicaisland/CollisionSystem.java @@ -357,8 +357,8 @@ public class CollisionSystem extends BaseObject { // Note: I'm deviating from the Bresenham algorithm here by adding one to force the end // tile to be visited. - final int lateralDelta = Math.abs(deltaX) + 1; - final int verticalDelta = Math.abs(deltaY) + 1; + final int lateralDelta = (endTileX > 0 && endTileX < worldWidth - 1) ? Math.abs(deltaX) + 1 : Math.abs(deltaX); + final int verticalDelta = (endTileY > 0 && endTileY < worldHeight - 1) ? Math.abs(deltaY) + 1 : Math.abs(deltaY); final int deltaX2 = lateralDelta * 2; final int deltaY2 = verticalDelta * 2; diff --git a/src/com/replica/replicaisland/DrawableFactory.java b/src/com/replica/replicaisland/DrawableFactory.java index 7c2f14c..10e8db3 100644 --- a/src/com/replica/replicaisland/DrawableFactory.java +++ b/src/com/replica/replicaisland/DrawableFactory.java @@ -23,7 +23,7 @@ package com.replica.replicaisland; * pools of objects so no actual allocations occur after bootstrap. */ public class DrawableFactory extends BaseObject { - private final static int BITMAP_POOL_SIZE = 128; + private final static int BITMAP_POOL_SIZE = 512; private DrawableBitmapPool mBitmapPool; private ScrollableBitmapPool mScrollableBitmapPool; diff --git a/src/com/replica/replicaisland/FrameRateWatcherComponent.java b/src/com/replica/replicaisland/FrameRateWatcherComponent.java new file mode 100644 index 0000000..82077c9 --- /dev/null +++ b/src/com/replica/replicaisland/FrameRateWatcherComponent.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.replica.replicaisland; + +public class FrameRateWatcherComponent extends GameComponent { + private RenderComponent mRenderComponent; + private DrawableObject mDrawable; + private float mMaxFrameTime = 1.0f / 30.0f; + + public FrameRateWatcherComponent() { + super(); + setPhase(GameComponent.ComponentPhases.THINK.ordinal()); + } + + @Override + public void reset() { + mRenderComponent = null; + mDrawable = null; + } + + @Override + public void update(float timeDelta, BaseObject parent) { + if (mRenderComponent != null && mDrawable != null) { + if (timeDelta > mMaxFrameTime) { + mRenderComponent.setDrawable(mDrawable); + } else { + mRenderComponent.setDrawable(null); + } + } + } + + public void setup(RenderComponent render, DrawableObject drawable) { + mRenderComponent = render; + mDrawable = drawable; + } +} diff --git a/src/com/replica/replicaisland/GLSurfaceView.java b/src/com/replica/replicaisland/GLSurfaceView.java index e56f62a..d187e40 100644 --- a/src/com/replica/replicaisland/GLSurfaceView.java +++ b/src/com/replica/replicaisland/GLSurfaceView.java @@ -508,6 +508,10 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback public void loadBuffers(BufferLibrary library) { mGLThread.loadBuffers(library); } + + public void setSafeMode(boolean safeMode) { + mGLThread.setSafeMode(safeMode); + } /** * Queue a runnable to be run on the GL rendering thread. This can be used @@ -1121,7 +1125,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback int w = 0; int h = 0; Runnable event = null; - + int framesSinceResetHack = 0; while (true) { synchronized (sGLThreadManager) { while (true) { @@ -1244,6 +1248,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback mGL = gl; mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig); createEglSurface = false; + framesSinceResetHack = 0; } @@ -1260,11 +1265,34 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback if (LOG_RENDERER) { DebugLog.w("GLThread", "onDrawFrame"); } - mRenderer.onDrawFrame(gl); + + // Some phones (Motorola Cliq, Backflip; also the + // Huawei Pulse, and maybe the Samsung Behold II), use a + // broken graphics driver from Qualcomm. It fails in a + // very specific case: when the EGL context is lost due to + // resource constraints, and then recreated, if GL commands + // are sent within two frames of the surface being created + // then eglSwapBuffers() will hang. Normally, applications using + // the stock GLSurfaceView never run into this problem because it + // discards the EGL context explicitly on every pause. But + // I've modified this class to not do that--I only want to reload + // textures when the context is actually lost--so this bug + // revealed itself as black screens on devices like the Cliq. + // Thus, in "safe mode," I force two swaps to occur before + // issuing any GL commands. Don't ask me how long it took + // to figure this out. + if (framesSinceResetHack > 1 || !mSafeMode) { + mRenderer.onDrawFrame(gl); + } + + framesSinceResetHack++; + if(!mEglHelper.swap()) { if (LOG_SURFACE) { DebugLog.i("GLThread", "egl surface lost tid=" + getId()); } + + stopEglLocked(); } } @@ -1475,6 +1503,10 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback sGLThreadManager.notifyAll(); } } + + public void setSafeMode(boolean on) { + mSafeMode = on; + } // Once the thread is started, all accesses to the following member // variables are protected by the sGLThreadManager monitor @@ -1493,6 +1525,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback private ArrayList<Runnable> mEventQueue = new ArrayList<Runnable>(); private GL10 mGL; private boolean mHasFocus; + private boolean mSafeMode = false; // End of member variables protected by the sGLThreadManager monitor. diff --git a/src/com/replica/replicaisland/Game.java b/src/com/replica/replicaisland/Game.java index 228b5fa..95b3517 100644 --- a/src/com/replica/replicaisland/Game.java +++ b/src/com/replica/replicaisland/Game.java @@ -17,6 +17,7 @@ package com.replica.replicaisland; import android.content.Context; +import android.view.KeyEvent; import android.view.MotionEvent; import android.widget.Toast; @@ -93,9 +94,12 @@ public class Game extends AllocationGuard { MainLoop gameRoot = new MainLoop(); InputSystem input = new InputSystem(); - gameRoot.add(input); BaseObject.sSystemRegistry.inputSystem = input; + BaseObject.sSystemRegistry.registerForReset(input); + InputGameInterface inputInterface = new InputGameInterface(); + gameRoot.add(inputInterface); + BaseObject.sSystemRegistry.inputGameInterface = inputInterface; LevelSystem level = new LevelSystem(); BaseObject.sSystemRegistry.levelSystem = level; @@ -198,6 +202,9 @@ public class Game extends AllocationGuard { longTermTextureLibrary.allocateTexture(R.drawable.ui_gem), 0, 0)); BaseObject.sSystemRegistry.hudSystem = hud; + if (AndouKun.VERSION < 0) { + hud.setShowFPS(true); + } gameRoot.add(hud); BaseObject.sSystemRegistry.vibrationSystem = new VibrationSystem(); @@ -366,19 +373,20 @@ public class Game extends AllocationGuard { public boolean onTrackballEvent(MotionEvent event) { if (mRunning) { - mGameThread.rollEvent(event.getRawX(), event.getRawY()); - boolean clickDown = event.getAction() == MotionEvent.ACTION_DOWN; - if ((clickDown && event.getPressure() > 0) - || event.getAction() == MotionEvent.ACTION_UP){ - mGameThread.clickEvent(clickDown); - } + if (event.getAction() == MotionEvent.ACTION_MOVE) { + BaseObject.sSystemRegistry.inputSystem.roll(event.getRawX(), event.getRawY()); + } else if (event.getAction() == MotionEvent.ACTION_DOWN) { + onKeyDownEvent(KeyEvent.KEYCODE_DPAD_CENTER); + } else if (event.getAction() == MotionEvent.ACTION_UP) { + onKeyUpEvent(KeyEvent.KEYCODE_DPAD_CENTER); + } } return true; } public boolean onOrientationEvent(float x, float y, float z) { if (mRunning) { - mGameThread.orientationEvent(x, y, z); + BaseObject.sSystemRegistry.inputSystem.setOrientation(x, y, z); } return true; } @@ -386,10 +394,10 @@ public class Game extends AllocationGuard { public boolean onTouchEvent(MotionEvent event) { if (mRunning) { if (event.getAction() == MotionEvent.ACTION_UP) { - mGameThread.touchUpEvent(event.getRawX() * (1.0f / mContextParameters.viewScaleX), + BaseObject.sSystemRegistry.inputSystem.touchUp(event.getRawX() * (1.0f / mContextParameters.viewScaleX), event.getRawY() * (1.0f / mContextParameters.viewScaleY)); } else { - mGameThread.touchDownEvent(event.getRawX() * (1.0f / mContextParameters.viewScaleX), + BaseObject.sSystemRegistry.inputSystem.touchDown(event.getRawX() * (1.0f / mContextParameters.viewScaleX), event.getRawY() * (1.0f / mContextParameters.viewScaleY)); } @@ -400,7 +408,7 @@ public class Game extends AllocationGuard { public boolean onKeyDownEvent(int keyCode) { boolean result = false; if (mRunning) { - result = mGameThread.keydownEvent(keyCode); + BaseObject.sSystemRegistry.inputSystem.keyDown(keyCode); } return result; } @@ -408,7 +416,7 @@ public class Game extends AllocationGuard { public boolean onKeyUpEvent(int keyCode) { boolean result = false; if (mRunning) { - result = mGameThread.keyupEvent(keyCode); + BaseObject.sSystemRegistry.inputSystem.keyUp(keyCode); } return result; } @@ -485,12 +493,15 @@ public class Game extends AllocationGuard { BaseObject.sSystemRegistry.soundSystem.setSoundEnabled(soundEnabled); } - public void setControlOptions(boolean clickAttack, boolean tiltControls, int tiltSensitivity) { - if (mGameThread != null) { - mGameThread.setClickActive(clickAttack); - } - BaseObject.sSystemRegistry.inputSystem.setUseOrientationForRoll(tiltControls); - BaseObject.sSystemRegistry.inputSystem.setOrientationSensitivityModifier((tiltSensitivity / 100.0f)); + public void setControlOptions(boolean clickAttack, boolean tiltControls, int tiltSensitivity, int movementSensitivity) { + BaseObject.sSystemRegistry.inputGameInterface.setUseClickForAttack(clickAttack); + BaseObject.sSystemRegistry.inputGameInterface.setUseOrientationForMovement(tiltControls); + BaseObject.sSystemRegistry.inputGameInterface.setOrientationMovementSensitivity((tiltSensitivity / 100.0f)); + BaseObject.sSystemRegistry.inputGameInterface.setMovementSensitivity((movementSensitivity / 100.0f)); + } + + public void setSafeMode(boolean safe) { + mSurfaceView.setSafeMode(safe); } public float getGameTime() { @@ -507,10 +518,7 @@ public class Game extends AllocationGuard { public void setKeyConfig(int leftKey, int rightKey, int jumpKey, int attackKey) { - if (mGameThread != null) { - mGameThread.setKeyConfig(leftKey, rightKey, jumpKey, attackKey); - } - + BaseObject.sSystemRegistry.inputGameInterface.setKeys(leftKey, rightKey, jumpKey, attackKey); } } diff --git a/src/com/replica/replicaisland/GameObjectCollisionSystem.java b/src/com/replica/replicaisland/GameObjectCollisionSystem.java index eb89090..a252387 100644 --- a/src/com/replica/replicaisland/GameObjectCollisionSystem.java +++ b/src/com/replica/replicaisland/GameObjectCollisionSystem.java @@ -32,8 +32,8 @@ import com.replica.replicaisland.CollisionParameters.HitType; * HitReactionComponent, if one has been specified. */ public class GameObjectCollisionSystem extends BaseObject { - private static final int MAX_COLLIDING_OBJECTS = 64; - private static final int COLLISION_RECORD_POOL_SIZE = 64; + private static final int MAX_COLLIDING_OBJECTS = 256; + private static final int COLLISION_RECORD_POOL_SIZE = 256; private static final CollisionVolumeComparator sCollisionVolumeComparator = new CollisionVolumeComparator(); private static CollisionVolume.FlipInfo sFlip = new CollisionVolume.FlipInfo(); diff --git a/src/com/replica/replicaisland/GameObjectFactory.java b/src/com/replica/replicaisland/GameObjectFactory.java index da9ca3d..3dc752b 100644 --- a/src/com/replica/replicaisland/GameObjectFactory.java +++ b/src/com/replica/replicaisland/GameObjectFactory.java @@ -31,7 +31,7 @@ import com.replica.replicaisland.GameObject.Team; * a) generated from data at compile time, or b) described by data at runtime. */ public class GameObjectFactory extends BaseObject { - private final static int MAX_GAME_OBJECTS = 256; + private final static int MAX_GAME_OBJECTS = 384; private final static ComponentPoolComparator sComponentPoolComparator = new ComponentPoolComparator(); private FixedSizeArray<FixedSizeArray<BaseObject>> mStaticData; private FixedSizeArray<GameComponentPool> mComponentPools; @@ -116,11 +116,16 @@ public class GameObjectFactory extends BaseObject { CAMERA_BIAS(56), - SMOKE_BIG(57), - SMOKE_SMALL(58), + FRAMERATE_WATCHER(57), + INFINITE_SPAWNER(58), + + SMOKE_BIG(59), + SMOKE_SMALL(60), + + CRUSH_FLASH(61), + FLASH(62), + - CRUSH_FLASH(59), - FLASH(60), // Projectiles ENERGY_BALL(68), @@ -206,42 +211,43 @@ public class GameObjectFactory extends BaseObject { ComponentClass[] componentTypes = { new ComponentClass(AnimationComponent.class, 1), new ComponentClass(AttackAtDistanceComponent.class, 16), - new ComponentClass(BackgroundCollisionComponent.class, 128), + new ComponentClass(BackgroundCollisionComponent.class, 192), new ComponentClass(ButtonAnimationComponent.class, 32), new ComponentClass(CameraBiasComponent.class, 8), - new ComponentClass(ChangeComponentsComponent.class, 128), + new ComponentClass(ChangeComponentsComponent.class, 256), new ComponentClass(DoorAnimationComponent.class, 256), //! new ComponentClass(DynamicCollisionComponent.class, 256), - new ComponentClass(EnemyAnimationComponent.class, 128), + new ComponentClass(EnemyAnimationComponent.class, 256), new ComponentClass(FadeDrawableComponent.class, 32), new ComponentClass(FixedAnimationComponent.class, 8), + new ComponentClass(FrameRateWatcherComponent.class, 1), new ComponentClass(GenericAnimationComponent.class, 32), - new ComponentClass(GhostComponent.class, 64), + new ComponentClass(GhostComponent.class, 256), new ComponentClass(GravityComponent.class, 128), new ComponentClass(HitPlayerComponent.class, 256), new ComponentClass(HitReactionComponent.class, 256), new ComponentClass(InventoryComponent.class, 128), new ComponentClass(LauncherComponent.class, 16), new ComponentClass(LaunchProjectileComponent.class, 128), - new ComponentClass(LifetimeComponent.class, 256), + new ComponentClass(LifetimeComponent.class, 384), new ComponentClass(MotionBlurComponent.class, 1), new ComponentClass(MovementComponent.class, 128), new ComponentClass(NPCAnimationComponent.class, 8), new ComponentClass(NPCComponent.class, 8), new ComponentClass(OrbitalMagnetComponent.class, 1), - new ComponentClass(PatrolComponent.class, 128), + new ComponentClass(PatrolComponent.class, 256), new ComponentClass(PhysicsComponent.class, 8), new ComponentClass(PlayerComponent.class, 1), new ComponentClass(PlaySingleSoundComponent.class, 32), new ComponentClass(PopOutComponent.class, 32), - new ComponentClass(RenderComponent.class, 256), + new ComponentClass(RenderComponent.class, 384), new ComponentClass(ScrollerComponent.class, 8), new ComponentClass(SelectDialogComponent.class, 8), new ComponentClass(SimpleCollisionComponent.class, 32), - new ComponentClass(SimplePhysicsComponent.class, 128), + new ComponentClass(SimplePhysicsComponent.class, 256), new ComponentClass(SleeperComponent.class, 32), new ComponentClass(SolidSurfaceComponent.class, 16), - new ComponentClass(SpriteComponent.class, 256), + new ComponentClass(SpriteComponent.class, 384), new ComponentClass(TheSourceComponent.class, 1), @@ -293,6 +299,16 @@ public class GameObjectFactory extends BaseObject { } } + protected boolean componentAvailable(Class<?> componentType, int count) { + boolean canAllocate = false; + GameComponentPool pool = getComponentPool(componentType); + assert pool != null; + if (pool != null) { + canAllocate = pool.getAllocatedCount() + count < pool.getSize(); + } + return canAllocate; + } + public void preloadEffects() { // These textures appear in every level, so they are long-term. TextureLibrary textureLibrary = sSystemRegistry.longTermTextureLibrary; @@ -491,6 +507,12 @@ public class GameObjectFactory extends BaseObject { case CAMERA_BIAS: newObject = spawnCameraBias(x, y); break; + case FRAMERATE_WATCHER: + newObject = spawnFrameRateWatcher(x, y); + break; + case INFINITE_SPAWNER: + newObject = spawnObjectInfiniteSpawner(x, y); + break; case SMOKE_BIG: newObject = spawnEffectSmokeBig(x, y); break; @@ -503,6 +525,7 @@ public class GameObjectFactory extends BaseObject { case FLASH: newObject = spawnEffectFlash(x, y); break; + case ENERGY_BALL: newObject = spawnEnergyBall(x, y, horzFlip); break; @@ -3813,7 +3836,7 @@ public class GameObjectFactory extends BaseObject { GhostComponent ghost = (GhostComponent)allocateComponent(GhostComponent.class); ghost.setMovementSpeed(2000.0f); - ghost.setAcceleration(300.0f); + ghost.setAcceleration(700.0f); //300 ghost.setUseOrientationSensor(true); ghost.setKillOnRelease(true); @@ -5095,7 +5118,19 @@ public class GameObjectFactory extends BaseObject { return object; } -public GameObject spawnObjectBreakableBlock(float positionX, float positionY) { + public GameObject spawnObjectInfiniteSpawner(float positionX, float positionY) { + GameObject object = spawnObjectBrobotSpawner(positionX, positionY, false); + object.facingDirection.y = -1; //vertical flip + LaunchProjectileComponent gun = object.findByClass(LaunchProjectileComponent.class); + if (gun != null) { + gun.enableProjectileTracking(68); + gun.setDelayBetweenShots(0.5f); + } + + return object; + } + + public GameObject spawnObjectBreakableBlock(float positionX, float positionY) { TextureLibrary textureLibrary = sSystemRegistry.shortTermTextureLibrary; @@ -5913,182 +5948,190 @@ public GameObject spawnObjectBreakableBlock(float positionX, float positionY) { public GameObject spawnEffectSmokeBig(float positionX, float positionY) { TextureLibrary textureLibrary = sSystemRegistry.longTermTextureLibrary; - GameObject object = mGameObjectPool.allocate(); - object.getPosition().set(positionX, positionY); - object.activationRadius = mTightActivationRadius; - object.width = 32; - object.height = 32; - - FixedSizeArray<BaseObject> staticData = getStaticData(GameObjectType.SMOKE_BIG); - if (staticData == null) { - final int staticObjectCount = 6; - staticData = new FixedSizeArray<BaseObject>(staticObjectCount); - - GameComponent movement = allocateComponent(MovementComponent.class); - - - AnimationFrame frame2 = new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_smoke_big02), - Utils.framesToTime(24, 1), null, null); - - AnimationFrame frame3 = new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_smoke_big03), - Utils.framesToTime(24, 1), null, null); - - AnimationFrame frame4 = new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_smoke_big04), - Utils.framesToTime(24, 1), null, null); - - AnimationFrame frame5 = new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_smoke_big05), - Utils.framesToTime(24, 1), null, null); - - SpriteAnimation idle = new SpriteAnimation(0, 5); - idle.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_smoke_big01), - Utils.framesToTime(24, 10), null, null)); - idle.addFrame(frame2); - idle.addFrame(frame3); - idle.addFrame(frame4); - idle.addFrame(frame5); - - SpriteAnimation idle2 = new SpriteAnimation(1, 5); - idle2.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_smoke_big01), - Utils.framesToTime(24, 13), null, null)); - idle2.addFrame(frame2); - idle2.addFrame(frame3); - idle2.addFrame(frame4); - idle2.addFrame(frame5); - - SpriteAnimation idle3 = new SpriteAnimation(2, 5); - idle3.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_smoke_big01), - Utils.framesToTime(24, 8), null, null)); - idle3.addFrame(frame2); - idle3.addFrame(frame3); - idle3.addFrame(frame4); - idle3.addFrame(frame5); - - SpriteAnimation idle4 = new SpriteAnimation(3, 5); - idle4.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_smoke_big01), - Utils.framesToTime(24, 5), null, null)); - idle4.addFrame(frame2); - idle4.addFrame(frame3); - idle4.addFrame(frame4); - idle4.addFrame(frame5); - - SpriteAnimation idle5 = new SpriteAnimation(4, 5); - idle5.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_smoke_big01), - Utils.framesToTime(24, 15), null, null)); - idle5.addFrame(frame2); - idle5.addFrame(frame3); - idle5.addFrame(frame4); - idle5.addFrame(frame5); - - staticData.add(idle); - staticData.add(idle2); - staticData.add(idle3); - staticData.add(idle4); - staticData.add(idle5); - staticData.add(movement); - setStaticData(GameObjectType.SMOKE_BIG, staticData); - } - - RenderComponent render = (RenderComponent)allocateComponent(RenderComponent.class); - render.setPriority(SortConstants.EFFECT); - - SpriteComponent sprite = (SpriteComponent)allocateComponent(SpriteComponent.class); - sprite.setSize((int)object.width, (int)object.height); - sprite.setRenderComponent(render); - - LifetimeComponent lifetime = (LifetimeComponent)allocateComponent(LifetimeComponent.class); - lifetime.setDieWhenInvisible(true); - - object.destroyOnDeactivation = true; - - object.add(lifetime); - object.add(render); - object.add(sprite); - - addStaticData(GameObjectType.SMOKE_BIG, object, sprite); + GameObject object = null; + // This is just an effect, so we can live without it if our pools are exhausted. + if (componentAvailable(RenderComponent.class, 1)) { + object = mGameObjectPool.allocate(); + + object.getPosition().set(positionX, positionY); + object.activationRadius = mTightActivationRadius; + object.width = 32; + object.height = 32; + + FixedSizeArray<BaseObject> staticData = getStaticData(GameObjectType.SMOKE_BIG); + if (staticData == null) { + final int staticObjectCount = 6; + staticData = new FixedSizeArray<BaseObject>(staticObjectCount); + + GameComponent movement = allocateComponent(MovementComponent.class); + + + AnimationFrame frame2 = new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_smoke_big02), + Utils.framesToTime(24, 1), null, null); + + AnimationFrame frame3 = new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_smoke_big03), + Utils.framesToTime(24, 1), null, null); + + AnimationFrame frame4 = new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_smoke_big04), + Utils.framesToTime(24, 1), null, null); + + AnimationFrame frame5 = new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_smoke_big05), + Utils.framesToTime(24, 1), null, null); + + SpriteAnimation idle = new SpriteAnimation(0, 5); + idle.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_smoke_big01), + Utils.framesToTime(24, 10), null, null)); + idle.addFrame(frame2); + idle.addFrame(frame3); + idle.addFrame(frame4); + idle.addFrame(frame5); + + SpriteAnimation idle2 = new SpriteAnimation(1, 5); + idle2.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_smoke_big01), + Utils.framesToTime(24, 13), null, null)); + idle2.addFrame(frame2); + idle2.addFrame(frame3); + idle2.addFrame(frame4); + idle2.addFrame(frame5); + + SpriteAnimation idle3 = new SpriteAnimation(2, 5); + idle3.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_smoke_big01), + Utils.framesToTime(24, 8), null, null)); + idle3.addFrame(frame2); + idle3.addFrame(frame3); + idle3.addFrame(frame4); + idle3.addFrame(frame5); + + SpriteAnimation idle4 = new SpriteAnimation(3, 5); + idle4.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_smoke_big01), + Utils.framesToTime(24, 5), null, null)); + idle4.addFrame(frame2); + idle4.addFrame(frame3); + idle4.addFrame(frame4); + idle4.addFrame(frame5); + + SpriteAnimation idle5 = new SpriteAnimation(4, 5); + idle5.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_smoke_big01), + Utils.framesToTime(24, 15), null, null)); + idle5.addFrame(frame2); + idle5.addFrame(frame3); + idle5.addFrame(frame4); + idle5.addFrame(frame5); + + staticData.add(idle); + staticData.add(idle2); + staticData.add(idle3); + staticData.add(idle4); + staticData.add(idle5); + staticData.add(movement); + setStaticData(GameObjectType.SMOKE_BIG, staticData); + } + + RenderComponent render = (RenderComponent)allocateComponent(RenderComponent.class); + render.setPriority(SortConstants.EFFECT); + + SpriteComponent sprite = (SpriteComponent)allocateComponent(SpriteComponent.class); + sprite.setSize((int)object.width, (int)object.height); + sprite.setRenderComponent(render); + + LifetimeComponent lifetime = (LifetimeComponent)allocateComponent(LifetimeComponent.class); + lifetime.setDieWhenInvisible(true); + + object.destroyOnDeactivation = true; + + object.add(lifetime); + object.add(render); + object.add(sprite); + + addStaticData(GameObjectType.SMOKE_BIG, object, sprite); + + final int animIndex = (int)(Math.random() * sprite.getAnimationCount()); + final SpriteAnimation idle = sprite.findAnimation(animIndex); + if (idle != null) { + lifetime.setTimeUntilDeath(idle.getLength()); + sprite.playAnimation(animIndex); + } + - final int animIndex = (int)(Math.random() * sprite.getAnimationCount()); - final SpriteAnimation idle = sprite.findAnimation(animIndex); - if (idle != null) { - lifetime.setTimeUntilDeath(idle.getLength()); - sprite.playAnimation(animIndex); } - - - return object; } public GameObject spawnEffectSmokeSmall(float positionX, float positionY) { TextureLibrary textureLibrary = sSystemRegistry.longTermTextureLibrary; - GameObject object = mGameObjectPool.allocate(); - object.getPosition().set(positionX, positionY); - object.activationRadius = mAlwaysActive; - object.width = 16; - object.height = 16; - - FixedSizeArray<BaseObject> staticData = getStaticData(GameObjectType.SMOKE_SMALL); - if (staticData == null) { - final int staticObjectCount = 2; - staticData = new FixedSizeArray<BaseObject>(staticObjectCount); - - GameComponent movement = allocateComponent(MovementComponent.class); - - SpriteAnimation idle = new SpriteAnimation(0, 5); - idle.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_smoke_small01), - Utils.framesToTime(24, 10), null, null)); - idle.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_smoke_small02), - Utils.framesToTime(24, 1), null, null)); - idle.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_smoke_small03), - Utils.framesToTime(24, 1), null, null)); - idle.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_smoke_small04), - Utils.framesToTime(24, 1), null, null)); - idle.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_smoke_small05), - Utils.framesToTime(24, 1), null, null)); - - staticData.add(idle); - staticData.add(movement); - setStaticData(GameObjectType.SMOKE_SMALL, staticData); - } - - RenderComponent render = (RenderComponent)allocateComponent(RenderComponent.class); - render.setPriority(SortConstants.EFFECT); - - SpriteComponent sprite = (SpriteComponent)allocateComponent(SpriteComponent.class); - sprite.setSize((int)object.width, (int)object.height); - sprite.setRenderComponent(render); - - LifetimeComponent lifetime = (LifetimeComponent)allocateComponent(LifetimeComponent.class); - lifetime.setDieWhenInvisible(true); - - object.destroyOnDeactivation = true; - - object.add(lifetime); - object.add(render); - object.add(sprite); - - addStaticData(GameObjectType.SMOKE_SMALL, object, sprite); - - final SpriteAnimation idle = sprite.findAnimation(0); - if (idle != null) { - lifetime.setTimeUntilDeath(idle.getLength()); + GameObject object = null; + // This is just an effect, so we can live without it if our pools are exhausted. + if (componentAvailable(RenderComponent.class, 1)) { + object = mGameObjectPool.allocate(); + object.getPosition().set(positionX, positionY); + object.activationRadius = mAlwaysActive; + object.width = 16; + object.height = 16; + + FixedSizeArray<BaseObject> staticData = getStaticData(GameObjectType.SMOKE_SMALL); + if (staticData == null) { + final int staticObjectCount = 2; + staticData = new FixedSizeArray<BaseObject>(staticObjectCount); + + GameComponent movement = allocateComponent(MovementComponent.class); + + SpriteAnimation idle = new SpriteAnimation(0, 5); + idle.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_smoke_small01), + Utils.framesToTime(24, 10), null, null)); + idle.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_smoke_small02), + Utils.framesToTime(24, 1), null, null)); + idle.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_smoke_small03), + Utils.framesToTime(24, 1), null, null)); + idle.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_smoke_small04), + Utils.framesToTime(24, 1), null, null)); + idle.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_smoke_small05), + Utils.framesToTime(24, 1), null, null)); + + staticData.add(idle); + staticData.add(movement); + setStaticData(GameObjectType.SMOKE_SMALL, staticData); + } + + RenderComponent render = (RenderComponent)allocateComponent(RenderComponent.class); + render.setPriority(SortConstants.EFFECT); + + SpriteComponent sprite = (SpriteComponent)allocateComponent(SpriteComponent.class); + sprite.setSize((int)object.width, (int)object.height); + sprite.setRenderComponent(render); + + LifetimeComponent lifetime = (LifetimeComponent)allocateComponent(LifetimeComponent.class); + lifetime.setDieWhenInvisible(true); + + object.destroyOnDeactivation = true; + + object.add(lifetime); + object.add(render); + object.add(sprite); + + addStaticData(GameObjectType.SMOKE_SMALL, object, sprite); + + final SpriteAnimation idle = sprite.findAnimation(0); + if (idle != null) { + lifetime.setTimeUntilDeath(idle.getLength()); + } + + sprite.playAnimation(0); } - - sprite.playAnimation(0); return object; } @@ -6096,153 +6139,192 @@ public GameObject spawnObjectBreakableBlock(float positionX, float positionY) { public GameObject spawnEffectCrushFlash(float positionX, float positionY) { TextureLibrary textureLibrary = sSystemRegistry.longTermTextureLibrary; - GameObject object = mGameObjectPool.allocate(); - object.getPosition().set(positionX, positionY); - object.activationRadius = mAlwaysActive; - object.width = 64; - object.height = 64; - - FixedSizeArray<BaseObject> staticData = getStaticData(GameObjectType.CRUSH_FLASH); - if (staticData == null) { - final int staticObjectCount = 2; - staticData = new FixedSizeArray<BaseObject>(staticObjectCount); - - SpriteAnimation back = new SpriteAnimation(0, 3); - back.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_crush_back01), - Utils.framesToTime(24, 1), null, null)); - back.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_crush_back02), - Utils.framesToTime(24, 1), null, null)); - back.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_crush_back03), - Utils.framesToTime(24, 1), null, null)); - - SpriteAnimation front = new SpriteAnimation(1, 7); - front.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_crush_front01), - Utils.framesToTime(24, 1), null, null)); - front.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_crush_front02), - Utils.framesToTime(24, 1), null, null)); - front.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_crush_front03), - Utils.framesToTime(24, 1), null, null)); - front.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_crush_front04), - Utils.framesToTime(24, 1), null, null)); - front.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_crush_front05), - Utils.framesToTime(24, 1), null, null)); - front.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_crush_front06), - Utils.framesToTime(24, 1), null, null)); - front.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_crush_front07), - Utils.framesToTime(24, 1), null, null)); - - - staticData.add(back); - staticData.add(front); - setStaticData(GameObjectType.CRUSH_FLASH, staticData); + GameObject object = null; + // This is just an effect, so we can live without it if our pools are exhausted. + if (componentAvailable(RenderComponent.class, 1)) { + object = mGameObjectPool.allocate(); + object.getPosition().set(positionX, positionY); + object.activationRadius = mAlwaysActive; + object.width = 64; + object.height = 64; + + FixedSizeArray<BaseObject> staticData = getStaticData(GameObjectType.CRUSH_FLASH); + if (staticData == null) { + final int staticObjectCount = 2; + staticData = new FixedSizeArray<BaseObject>(staticObjectCount); + + SpriteAnimation back = new SpriteAnimation(0, 3); + back.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_crush_back01), + Utils.framesToTime(24, 1), null, null)); + back.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_crush_back02), + Utils.framesToTime(24, 1), null, null)); + back.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_crush_back03), + Utils.framesToTime(24, 1), null, null)); + + SpriteAnimation front = new SpriteAnimation(1, 7); + front.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_crush_front01), + Utils.framesToTime(24, 1), null, null)); + front.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_crush_front02), + Utils.framesToTime(24, 1), null, null)); + front.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_crush_front03), + Utils.framesToTime(24, 1), null, null)); + front.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_crush_front04), + Utils.framesToTime(24, 1), null, null)); + front.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_crush_front05), + Utils.framesToTime(24, 1), null, null)); + front.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_crush_front06), + Utils.framesToTime(24, 1), null, null)); + front.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_crush_front07), + Utils.framesToTime(24, 1), null, null)); + + + staticData.add(back); + staticData.add(front); + setStaticData(GameObjectType.CRUSH_FLASH, staticData); + } + + + RenderComponent backRender = (RenderComponent)allocateComponent(RenderComponent.class); + backRender.setPriority(SortConstants.EFFECT); + + SpriteComponent backSprite = (SpriteComponent)allocateComponent(SpriteComponent.class); + backSprite.setSize((int)object.width, (int)object.height); + backSprite.setRenderComponent(backRender); + + RenderComponent foreRender = (RenderComponent)allocateComponent(RenderComponent.class); + foreRender.setPriority(SortConstants.FOREGROUND_EFFECT); + + SpriteComponent foreSprite = (SpriteComponent)allocateComponent(SpriteComponent.class); + foreSprite.setSize((int)object.width, (int)object.height); + foreSprite.setRenderComponent(foreRender); + + LifetimeComponent lifetime = (LifetimeComponent)allocateComponent(LifetimeComponent.class); + + + object.add(lifetime); + object.add(backRender); + object.add(foreRender); + object.add(foreSprite); + object.add(backSprite); + + addStaticData(GameObjectType.CRUSH_FLASH, object, backSprite); + addStaticData(GameObjectType.CRUSH_FLASH, null, foreSprite); + + + final SpriteAnimation idle = foreSprite.findAnimation(1); + if (idle != null) { + lifetime.setTimeUntilDeath(idle.getLength()); + } + + backSprite.playAnimation(0); + foreSprite.playAnimation(1); } - - RenderComponent backRender = (RenderComponent)allocateComponent(RenderComponent.class); - backRender.setPriority(SortConstants.EFFECT); - - SpriteComponent backSprite = (SpriteComponent)allocateComponent(SpriteComponent.class); - backSprite.setSize((int)object.width, (int)object.height); - backSprite.setRenderComponent(backRender); - - RenderComponent foreRender = (RenderComponent)allocateComponent(RenderComponent.class); - foreRender.setPriority(SortConstants.FOREGROUND_EFFECT); - - SpriteComponent foreSprite = (SpriteComponent)allocateComponent(SpriteComponent.class); - foreSprite.setSize((int)object.width, (int)object.height); - foreSprite.setRenderComponent(foreRender); - - LifetimeComponent lifetime = (LifetimeComponent)allocateComponent(LifetimeComponent.class); - + return object; + } - object.add(lifetime); - object.add(backRender); - object.add(foreRender); - object.add(foreSprite); - object.add(backSprite); - - addStaticData(GameObjectType.CRUSH_FLASH, object, backSprite); - addStaticData(GameObjectType.CRUSH_FLASH, null, foreSprite); - - - final SpriteAnimation idle = foreSprite.findAnimation(1); - if (idle != null) { - lifetime.setTimeUntilDeath(idle.getLength()); + public GameObject spawnEffectFlash(float positionX, float positionY) { + TextureLibrary textureLibrary = sSystemRegistry.longTermTextureLibrary; + GameObject object = null; + // This is just an effect, so we can live without it if our pools are exhausted. + if (componentAvailable(RenderComponent.class, 1)) { + object = mGameObjectPool.allocate(); + object.getPosition().set(positionX, positionY); + object.activationRadius = mAlwaysActive; + object.width = 64; + object.height = 64; + + FixedSizeArray<BaseObject> staticData = getStaticData(GameObjectType.FLASH); + if (staticData == null) { + final int staticObjectCount = 1; + staticData = new FixedSizeArray<BaseObject>(staticObjectCount); + + SpriteAnimation back = new SpriteAnimation(0, 3); + back.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_crush_back01), + Utils.framesToTime(24, 1), null, null)); + back.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_crush_back02), + Utils.framesToTime(24, 1), null, null)); + back.addFrame(new AnimationFrame( + textureLibrary.getTextureByResource(R.drawable.effect_crush_back03), + Utils.framesToTime(24, 1), null, null)); + + + staticData.add(back); + setStaticData(GameObjectType.FLASH, staticData); + } + + + RenderComponent backRender = (RenderComponent)allocateComponent(RenderComponent.class); + backRender.setPriority(SortConstants.EFFECT); + + SpriteComponent backSprite = (SpriteComponent)allocateComponent(SpriteComponent.class); + backSprite.setSize((int)object.width, (int)object.height); + backSprite.setRenderComponent(backRender); + + + + LifetimeComponent lifetime = (LifetimeComponent)allocateComponent(LifetimeComponent.class); + + + object.add(lifetime); + object.add(backRender); + object.add(backSprite); + + addStaticData(GameObjectType.FLASH, object, backSprite); + + + final SpriteAnimation idle = backSprite.findAnimation(0); + if (idle != null) { + lifetime.setTimeUntilDeath(idle.getLength()); + } + + backSprite.playAnimation(0); } - backSprite.playAnimation(0); - foreSprite.playAnimation(1); - return object; } - public GameObject spawnEffectFlash(float positionX, float positionY) { - TextureLibrary textureLibrary = sSystemRegistry.longTermTextureLibrary; + public GameObject spawnFrameRateWatcher(float positionX, float positionY) { + TextureLibrary textureLibrary = sSystemRegistry.shortTermTextureLibrary; + ContextParameters params = sSystemRegistry.contextParameters; + GameObject object = mGameObjectPool.allocate(); - object.getPosition().set(positionX, positionY); + object.getPosition().set(250, 0); // HACK! object.activationRadius = mAlwaysActive; - object.width = 64; - object.height = 64; - - FixedSizeArray<BaseObject> staticData = getStaticData(GameObjectType.FLASH); - if (staticData == null) { - final int staticObjectCount = 1; - staticData = new FixedSizeArray<BaseObject>(staticObjectCount); - - SpriteAnimation back = new SpriteAnimation(0, 3); - back.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_crush_back01), - Utils.framesToTime(24, 1), null, null)); - back.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_crush_back02), - Utils.framesToTime(24, 1), null, null)); - back.addFrame(new AnimationFrame( - textureLibrary.getTextureByResource(R.drawable.effect_crush_back03), - Utils.framesToTime(24, 1), null, null)); - - - staticData.add(back); - setStaticData(GameObjectType.FLASH, staticData); - } + object.width = params.gameWidth; + object.height = params.gameHeight; + DrawableBitmap indicator = new DrawableBitmap( + textureLibrary.allocateTexture(R.drawable.framerate_warning), + (int)object.width, + (int)object.height); - RenderComponent backRender = (RenderComponent)allocateComponent(RenderComponent.class); - backRender.setPriority(SortConstants.EFFECT); + indicator.setCrop(0, 8, 8, 8); // hack! this shouldn't be hard-coded. - SpriteComponent backSprite = (SpriteComponent)allocateComponent(SpriteComponent.class); - backSprite.setSize((int)object.width, (int)object.height); - backSprite.setRenderComponent(backRender); + RenderComponent render = (RenderComponent)allocateComponent(RenderComponent.class); + render.setPriority(SortConstants.OVERLAY); + render.setCameraRelative(false); - - - LifetimeComponent lifetime = (LifetimeComponent)allocateComponent(LifetimeComponent.class); - - - object.add(lifetime); - object.add(backRender); - object.add(backSprite); - - addStaticData(GameObjectType.FLASH, object, backSprite); - + FrameRateWatcherComponent watcher = (FrameRateWatcherComponent)allocateComponent(FrameRateWatcherComponent.class); + watcher.setup(render, indicator); - final SpriteAnimation idle = backSprite.findAnimation(0); - if (idle != null) { - lifetime.setTimeUntilDeath(idle.getLength()); - } + object.add(render); + object.add(watcher); - backSprite.playAnimation(0); - + return object; } @@ -6336,46 +6418,49 @@ public GameObject spawnObjectBreakableBlock(float positionX, float positionY) { public GameObject spawnSmokePoof(float positionX, float positionY) { - GameObject object = mGameObjectPool.allocate(); - object.getPosition().set(positionX, positionY); - object.activationRadius = mTightActivationRadius; - object.width = 1; - object.height = 1; - - LifetimeComponent lifetime = (LifetimeComponent)allocateComponent(LifetimeComponent.class); - lifetime.setTimeUntilDeath(0.5f); - - LaunchProjectileComponent smokeGun - = (LaunchProjectileComponent)allocateComponent(LaunchProjectileComponent.class); - smokeGun.setSetsPerActivation(1); - smokeGun.setShotsPerSet(3); - smokeGun.setDelayBetweenShots(0.0f); - smokeGun.setObjectTypeToSpawn(GameObjectType.SMOKE_BIG); - smokeGun.setVelocityX(200.0f); - smokeGun.setVelocityY(200.0f); - smokeGun.setOffsetX(16); - smokeGun.setOffsetY(16); - smokeGun.setThetaError(1.0f); - - LaunchProjectileComponent smokeGun2 - = (LaunchProjectileComponent)allocateComponent(LaunchProjectileComponent.class); - smokeGun2.setSetsPerActivation(1); - smokeGun2.setShotsPerSet(3); - smokeGun2.setDelayBetweenShots(0.0f); - smokeGun2.setObjectTypeToSpawn(GameObjectType.SMOKE_SMALL); - smokeGun2.setVelocityX(200.0f); - smokeGun2.setVelocityY(200.0f); - smokeGun2.setThetaError(1.0f); - smokeGun2.setOffsetX(16); - smokeGun2.setOffsetY(16); - - object.life = 1; - object.destroyOnDeactivation = true; - - object.add(lifetime); - object.add(smokeGun); - object.add(smokeGun2); - + GameObject object = null; + // This is just an effect, so we can live without it if our pools are exhausted. + if (componentAvailable(LaunchProjectileComponent.class, 2)) { + object = mGameObjectPool.allocate(); + object.getPosition().set(positionX, positionY); + object.activationRadius = mTightActivationRadius; + object.width = 1; + object.height = 1; + + LifetimeComponent lifetime = (LifetimeComponent)allocateComponent(LifetimeComponent.class); + lifetime.setTimeUntilDeath(0.5f); + + LaunchProjectileComponent smokeGun + = (LaunchProjectileComponent)allocateComponent(LaunchProjectileComponent.class); + smokeGun.setSetsPerActivation(1); + smokeGun.setShotsPerSet(3); + smokeGun.setDelayBetweenShots(0.0f); + smokeGun.setObjectTypeToSpawn(GameObjectType.SMOKE_BIG); + smokeGun.setVelocityX(200.0f); + smokeGun.setVelocityY(200.0f); + smokeGun.setOffsetX(16); + smokeGun.setOffsetY(16); + smokeGun.setThetaError(1.0f); + + LaunchProjectileComponent smokeGun2 + = (LaunchProjectileComponent)allocateComponent(LaunchProjectileComponent.class); + smokeGun2.setSetsPerActivation(1); + smokeGun2.setShotsPerSet(3); + smokeGun2.setDelayBetweenShots(0.0f); + smokeGun2.setObjectTypeToSpawn(GameObjectType.SMOKE_SMALL); + smokeGun2.setVelocityX(200.0f); + smokeGun2.setVelocityY(200.0f); + smokeGun2.setThetaError(1.0f); + smokeGun2.setOffsetX(16); + smokeGun2.setOffsetY(16); + + object.life = 1; + object.destroyOnDeactivation = true; + + object.add(lifetime); + object.add(smokeGun); + object.add(smokeGun2); + } return object; } diff --git a/src/com/replica/replicaisland/GameObjectManager.java b/src/com/replica/replicaisland/GameObjectManager.java index 409c60e..c2362fc 100644 --- a/src/com/replica/replicaisland/GameObjectManager.java +++ b/src/com/replica/replicaisland/GameObjectManager.java @@ -31,7 +31,7 @@ import java.util.Comparator; * deactivated. */ public class GameObjectManager extends ObjectManager { - private static final int MAX_GAME_OBJECTS = 256; + private static final int MAX_GAME_OBJECTS = 384; private float mMaxActivationRadius; private final static HorizontalPositionComparator sGameObjectComparator = new HorizontalPositionComparator(); diff --git a/src/com/replica/replicaisland/GameRenderer.java b/src/com/replica/replicaisland/GameRenderer.java index 215492f..3fa1185 100644 --- a/src/com/replica/replicaisland/GameRenderer.java +++ b/src/com/replica/replicaisland/GameRenderer.java @@ -177,7 +177,7 @@ public class GameRenderer implements GLSurfaceView.Renderer { /** Draws the scene. Note that the draw queue is locked for the duration of this function. */ public void onDrawFrame(GL10 gl) { - + long time = SystemClock.uptimeMillis(); long time_delta = (time - mLastTime); diff --git a/src/com/replica/replicaisland/GameThread.java b/src/com/replica/replicaisland/GameThread.java index 3b3534d..ad5c08e 100644 --- a/src/com/replica/replicaisland/GameThread.java +++ b/src/com/replica/replicaisland/GameThread.java @@ -27,42 +27,9 @@ import android.view.KeyEvent; */ public class GameThread implements Runnable { private long mLastTime; - private float mLastMotionX; - private float mLastMotionY; - private int mLastTouchX; - private int mLastTouchY; - private boolean mTouchReleased; - private boolean mClickUp; - private boolean mClickDown; - private float mOrientationX; - private float mOrientationY; - private float mOrientationZ; - private boolean mOrientationChanged; - private boolean mKeyLeft; - private boolean mKeyRight; - private boolean mKeyDown; - private boolean mKeyUp; - private boolean mKeyTouch; - private boolean mKeyClick; - private boolean mKeyInputReceived; - private boolean mKeyLeftUp; - private boolean mKeyRightUp; - private boolean mKeyDownUp; - private boolean mKeyUpUp; - private boolean mKeyTouchUp; - private boolean mKeyClickUp; - private boolean mClickActive; - - // Configurable key codes - private int mLeftKey = KeyEvent.KEYCODE_DPAD_LEFT; - private int mRightKey = KeyEvent.KEYCODE_DPAD_RIGHT; - private int mJumpKey = KeyEvent.KEYCODE_SPACE; - private int mAttackKey = KeyEvent.KEYCODE_SHIFT_LEFT; - private ObjectManager mGameRoot; private GameRenderer mRenderer; - private Object mInputLock; private Object mPauseLock; private boolean mFinished; private boolean mPaused = false; @@ -74,7 +41,6 @@ public class GameThread implements Runnable { public GameThread(GameRenderer renderer) { mLastTime = SystemClock.uptimeMillis(); mRenderer = renderer; - mInputLock = new Object(); mPauseLock = new Object(); mFinished = false; mPaused = false; @@ -97,73 +63,6 @@ public class GameThread implements Runnable { } mLastTime = time; - synchronized (mInputLock) { - - - if (mKeyInputReceived) { - BaseObject.sSystemRegistry.inputSystem.keyUp( - mKeyLeftUp, - mKeyRightUp, - mKeyUpUp, - mKeyDownUp, - mKeyTouchUp, - mKeyClickUp); - BaseObject.sSystemRegistry.inputSystem.keyDown( - mKeyLeft, - mKeyRight, - mKeyUp, - mKeyDown, - mKeyTouch, - mKeyClick); - mKeyInputReceived = false; - mKeyLeft = false; - mKeyRight = false; - mKeyUp = false; - mKeyDown = false; - mKeyTouch = false; - mKeyClick = false; - mKeyLeftUp = false; - mKeyRightUp = false; - mKeyUpUp = false; - mKeyDownUp = false; - mKeyTouchUp = false; - mKeyClickUp = false; - } - - if (mLastMotionX != 0 || mLastMotionY != 0) { - BaseObject.sSystemRegistry.inputSystem - .roll(mLastMotionX, mLastMotionY); - mLastMotionX = 0; - mLastMotionY = 0; - } - if (mLastTouchX != 0 || mLastTouchY != 0) { - BaseObject.sSystemRegistry.inputSystem - .touch(mLastTouchX, mLastTouchY, mTouchReleased); - mLastTouchX = 0; - mLastTouchY = 0; - mTouchReleased = false; - } - - if (mClickDown) { - BaseObject.sSystemRegistry.inputSystem.clickDown(); - mClickDown = false; - } - if (mClickUp) { - BaseObject.sSystemRegistry.inputSystem.clickUp(); - mClickUp = false; - } - - if (mOrientationChanged) { - BaseObject.sSystemRegistry.inputSystem.setOrientation( - mOrientationX, - mOrientationY, - mOrientationZ); - mOrientationChanged = false; - } - - - } - mGameRoot.update(secondsDelta, null); CameraSystem camera = mGameRoot.sSystemRegistry.cameraSystem; @@ -186,6 +85,7 @@ public class GameThread implements Runnable { DebugLog.d("Game Profile", "Average: " + averageFrameTime); mProfileTime = 0; mProfileFrames = 0; + mGameRoot.sSystemRegistry.hudSystem.setFPS(1000 / (int)averageFrameTime); } } // If the game logic completed in less than 16ms, that means it's running @@ -250,104 +150,5 @@ public class GameThread implements Runnable { public void setGameRoot(ObjectManager gameRoot) { mGameRoot = gameRoot; } - - public void rollEvent(float f, float g) { - synchronized (mInputLock) { - mLastMotionX += f; - mLastMotionY += g; - } - } - - public void clickEvent(boolean down) { - synchronized (mInputLock) { - if (down) { - mClickDown = true; - } else { - mClickUp = true; - } - } - } - - public void orientationEvent(float x, float y, float z) { - synchronized (mInputLock) { - mOrientationX = x; - mOrientationY = y; - mOrientationZ = z; - mOrientationChanged = true; - } - } - - public void touchDownEvent(float x, float y) { - synchronized (mInputLock) { - mTouchReleased = false; - mLastTouchX = (int)x; - mLastTouchY = (int)y; - } - } - - public void touchUpEvent(float x, float y) { - synchronized (mInputLock) { - mTouchReleased = true; - mLastTouchX = (int)x; - mLastTouchY = (int)y; - } - } - - public boolean keydownEvent(int keycode) { - boolean ateKey = true; - synchronized (mInputLock) { - if (keycode == mLeftKey) { - mKeyLeft = true; - } else if (keycode == mRightKey) { - mKeyRight = true; - } else if (keycode == mJumpKey) { - mKeyTouch = true; - } else if (keycode == mAttackKey) { - mKeyClick = true; - } else if (mClickActive && keycode == KeyEvent.KEYCODE_DPAD_CENTER) { - mKeyClick = true; - } else { - ateKey = false; - } - - mKeyInputReceived = ateKey; - } - return ateKey; - } - - public boolean keyupEvent(int keycode) { - boolean ateKey = true; - synchronized (mInputLock) { - if (keycode == mLeftKey) { - mKeyLeftUp = true; - } else if (keycode == mRightKey) { - mKeyRightUp = true; - } else if (keycode == mJumpKey) { - mKeyTouchUp = true; - } else if (keycode == mAttackKey) { - mKeyClickUp = true; - } else if (mClickActive && keycode == KeyEvent.KEYCODE_DPAD_CENTER) { - mKeyClickUp = true; - } else { - ateKey = false; - } - mKeyInputReceived = ateKey; - } - return ateKey; - } - - public void setKeyConfig(int leftKey, int rightKey, int jumpKey, - int attackKey) { - synchronized (mInputLock) { - mLeftKey = leftKey; - mRightKey = rightKey; - mJumpKey = jumpKey; - mAttackKey = attackKey; - } - } - - public void setClickActive(boolean clickAttack) { - mClickActive = clickAttack; - } } diff --git a/src/com/replica/replicaisland/GhostComponent.java b/src/com/replica/replicaisland/GhostComponent.java index 9d02edb..f6a27b7 100644 --- a/src/com/replica/replicaisland/GhostComponent.java +++ b/src/com/replica/replicaisland/GhostComponent.java @@ -58,7 +58,7 @@ public class GhostComponent extends GameComponent { public void update(float timeDelta, BaseObject parent) { GameObject parentObject = (GameObject) parent; boolean timeToRelease = false; - final InputSystem input = sSystemRegistry.inputSystem; + final InputGameInterface input = sSystemRegistry.inputGameInterface; final CameraSystem camera = sSystemRegistry.cameraSystem; if (parentObject.life > 0) { @@ -90,44 +90,39 @@ public class GhostComponent extends GameComponent { if (input != null) { if (mUseOrientationSensor) { + final InputXY tilt = input.getTilt(); parentObject.getTargetVelocity().x = - input.getPitch() * mMovementSpeed; + tilt.getX() * mMovementSpeed; parentObject.getTargetVelocity().y = - input.getRoll() * mMovementSpeed; + tilt.getY() * mMovementSpeed; parentObject.getAcceleration().x = mAcceleration; parentObject.getAcceleration().y = mAcceleration; } else { - final Vector2 rollDirection = input.getRollDirection(); + final InputXY dpad = input.getDirectionalPad(); parentObject.getTargetVelocity().x = - rollDirection.x * mMovementSpeed; + dpad.getX() * mMovementSpeed; parentObject.getAcceleration().x = mAcceleration; } - final boolean buttonPressed = input.getTouchPressed() - && input.getTouchedWithinRegion( - ButtonConstants.FLY_BUTTON_REGION_X, - ButtonConstants.FLY_BUTTON_REGION_Y, - ButtonConstants.FLY_BUTTON_REGION_WIDTH, - ButtonConstants.FLY_BUTTON_REGION_HEIGHT); + final InputButton jumpButton = input.getJumpButton(); + final TimeSystem time = sSystemRegistry.timeSystem; + final float gameTime = time.getGameTime(); - if (buttonPressed - && input.getTouchTriggered() - && parentObject.touchingGround() + if (jumpButton.getTriggered(gameTime) + && parentObject.touchingGround() + && parentObject.getVelocity().y <= 0.0f && !mChangeActionOnButton) { - parentObject.getImpulse().y += mJumpImpulse;// * timeDelta; - } else if (mChangeActionOnButton && buttonPressed) { + parentObject.getImpulse().y += mJumpImpulse; + } else if (mChangeActionOnButton && jumpButton.getPressed()) { parentObject.setCurrentAction(mButtonPressedAction); } - if (input.getClickTriggered() || - (input.getTouchTriggered() && input.getTouchedWithinRegion( - ButtonConstants.STOMP_BUTTON_REGION_X, - ButtonConstants.STOMP_BUTTON_REGION_Y, - ButtonConstants.STOMP_BUTTON_REGION_WIDTH, - ButtonConstants.STOMP_BUTTON_REGION_HEIGHT))) { + final InputButton attackButton = input.getAttackButton(); + + if (attackButton.getTriggered(gameTime)) { timeToRelease = true; } } @@ -186,10 +181,10 @@ public class GhostComponent extends GameComponent { } else { control.deactivateGhost(mDelayOnRelease); } - final InputSystem input = sSystemRegistry.inputSystem; + /* final InputSystem input = sSystemRegistry.inputSystem; if (input != null) { input.clearClickTriggered(); - } + }*/ } if (mAmbientSoundStream > -1) { diff --git a/src/com/replica/replicaisland/HudSystem.java b/src/com/replica/replicaisland/HudSystem.java index 44af450..b5ba663 100644 --- a/src/com/replica/replicaisland/HudSystem.java +++ b/src/com/replica/replicaisland/HudSystem.java @@ -72,6 +72,12 @@ public class HudSystem extends BaseObject { private boolean mCoinDigitsChanged; private boolean mRubyDigitsChanged; + private int mFPS; + private Vector2 mFPSLocation; + private int[] mFPSDigits; + private boolean mFPSDigitsChanged; + private boolean mShowFPS; + private DrawableBitmap[] mDigitDrawables; private DrawableBitmap mXDrawable; @@ -82,9 +88,11 @@ public class HudSystem extends BaseObject { mStompButtonLocation = new Vector2(); mCoinLocation = new Vector2(); mRubyLocation = new Vector2(); + mFPSLocation = new Vector2(); mDigitDrawables = new DrawableBitmap[10]; mCoinDigits = new int[MAX_DIGITS]; mRubyDigits = new int[MAX_DIGITS]; + mFPSDigits = new int[MAX_DIGITS]; reset(); } @@ -114,6 +122,11 @@ public class HudSystem extends BaseObject { mRubyDigits[1] = -1; mCoinDigitsChanged = true; mRubyDigitsChanged = true; + mFPS = 0; + mFPSDigits[0] = 0; + mFPSDigits[1] = -1; + mFPSDigitsChanged = true; + mShowFPS = false; for (int x = 0; x < mDigitDrawables.length; x++) { mDigitDrawables[x] = null; } @@ -183,6 +196,15 @@ public class HudSystem extends BaseObject { mCoinCount = newInventory.coinCount; mRubyCount = newInventory.rubyCount; } + + public void setFPS(int fps) { + mFPSDigitsChanged = (fps != mFPS); + mFPS = fps; + } + + public void setShowFPS(boolean show) { + mShowFPS = show; + } @Override public void update(float timeDelta, BaseObject parent) { @@ -292,7 +314,7 @@ public class HudSystem extends BaseObject { } final float offset = mCoinDrawable.getWidth() * 0.75f; mCoinLocation.x += offset; - drawNumber(mCoinLocation, mCoinDigits); + drawNumber(mCoinLocation, mCoinDigits, true); mCoinLocation.x -= offset; } @@ -311,11 +333,21 @@ public class HudSystem extends BaseObject { } final float offset = mRubyDrawable.getWidth() * 0.75f; mRubyLocation.x += offset; - drawNumber(mRubyLocation, mRubyDigits); + drawNumber(mRubyLocation, mRubyDigits, true); mRubyLocation.x -= offset; } } + if (mShowFPS) { + if (mFPSDigitsChanged) { + int count = intToDigitArray(mFPS, mFPSDigits); + mFPSDigitsChanged = false; + mFPSLocation.set(params.gameWidth - ((count + 1) * mDigitDrawables[0].getWidth()), 20.0f); + + } + drawNumber(mFPSLocation, mFPSDigits, false); + } + if (mFading && factory != null) { final float time = sSystemRegistry.timeSystem.getRealTime(); @@ -357,7 +389,7 @@ public class HudSystem extends BaseObject { } } - private void drawNumber(Vector2 location, int[] digits) { + private void drawNumber(Vector2 location, int[] digits, boolean drawX) { final RenderSystem render = sSystemRegistry.renderSystem; if (mDigitDrawables[0].getWidth() == 0) { @@ -377,17 +409,19 @@ public class HudSystem extends BaseObject { final float characterWidth = mDigitDrawables[0].getWidth() / 2.0f; float offset = 0.0f; - if (mXDrawable != null) { + if (mXDrawable != null && drawX) { render.scheduleForDraw(mXDrawable, location, SortConstants.HUD, false); + location.x += characterWidth; + offset += characterWidth; } for (int x = 0; x < digits.length && digits[x] != -1; x++) { int index = digits[x]; DrawableBitmap digit = mDigitDrawables[index]; if (digit != null) { - location.x += characterWidth; - offset += characterWidth; render.scheduleForDraw(digit, location, SortConstants.HUD, false); + location.x += characterWidth; + offset += characterWidth; } } diff --git a/src/com/replica/replicaisland/InputButton.java b/src/com/replica/replicaisland/InputButton.java new file mode 100644 index 0000000..4693241 --- /dev/null +++ b/src/com/replica/replicaisland/InputButton.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.replica.replicaisland; + +public class InputButton { + private boolean mDown; + private float mLastPressedTime; + private float mDownTime; + private float mMagnitude; + + public void press(float currentTime, float magnitude) { + if (!mDown) { + mDown = true; + mDownTime = currentTime; + } + mMagnitude = magnitude; + mLastPressedTime = currentTime; + } + + public void release() { + mDown = false; + } + + public final boolean getPressed() { + return mDown; + } + + public final boolean getTriggered(float currentTime) { + return mDown && currentTime - mDownTime <= BaseObject.sSystemRegistry.timeSystem.getFrameDelta() * 2.0f; + } + + public final float getPressedDuration(float currentTime) { + return currentTime - mDownTime; + } + + public final float getLastPressedTime() { + return mLastPressedTime; + } + + public final float getMagnitude() { + float magnitude = 0.0f; + if (mDown) { + magnitude = mMagnitude; + } + return magnitude; + } + + public final void setMagnitude(float magnitude) { + mMagnitude = magnitude; + } + + public final void reset() { + mDown = false; + mMagnitude = 0.0f; + mLastPressedTime = 0.0f; + mDownTime = 0.0f; + } +} diff --git a/src/com/replica/replicaisland/InputGameInterface.java b/src/com/replica/replicaisland/InputGameInterface.java new file mode 100644 index 0000000..3625a49 --- /dev/null +++ b/src/com/replica/replicaisland/InputGameInterface.java @@ -0,0 +1,280 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.replica.replicaisland; + +import android.view.KeyEvent; + +public class InputGameInterface extends BaseObject { + private static final float ORIENTATION_DEAD_ZONE_MIN = 0.03f; + private static final float ORIENTATION_DEAD_ZONE_MAX = 0.1f; + private static final float ORIENTATION_DEAD_ZONE_SCALE = 0.75f; + + private final static float ROLL_TIMEOUT = 0.1f; + private final static float ROLL_RESET_DELAY = 0.075f; + + // Raw trackball input is filtered by this value. Increasing it will + // make the control more twitchy, while decreasing it will make the control more precise. + private final static float ROLL_FILTER = 0.4f; + private final static float ROLL_DECAY = 8.0f; + + private final static float KEY_FILTER = 0.25f; + + private InputButton mJumpButton = new InputButton(); + private InputButton mAttackButton = new InputButton(); + private InputXY mDirectionalPad = new InputXY(); + private InputXY mTilt = new InputXY(); + + private int mLeftKeyCode = KeyEvent.KEYCODE_DPAD_LEFT; + private int mRightKeyCode = KeyEvent.KEYCODE_DPAD_RIGHT; + private int mJumpKeyCode = KeyEvent.KEYCODE_SPACE; + private int mAttackKeyCode = KeyEvent.KEYCODE_SHIFT_LEFT; + + private float mOrientationDeadZoneMin = ORIENTATION_DEAD_ZONE_MIN; + private float mOrientationDeadZoneMax = ORIENTATION_DEAD_ZONE_MAX; + private float mOrientationDeadZoneScale = ORIENTATION_DEAD_ZONE_SCALE; + private float mOrientationSensitivity = 1.0f; + private float mOrientationSensitivityFactor = 1.0f; + private float mMovementSensitivity = 1.0f; + + + private boolean mUseClickButtonForAttack = true; + private boolean mUseOrientationForMovement = false; + + private float mLastRollTime; + + public InputGameInterface() { + super(); + reset(); + } + + @Override + public void reset() { + mJumpButton.release(); + mAttackButton.release(); + mDirectionalPad.release(); + mTilt.release(); + } + + + + @Override + public void update(float timeDelta, BaseObject parent) { + InputSystem input = sSystemRegistry.inputSystem; + final InputButton[] keys = input.getKeyboard().getKeys(); + final InputXY orientation = input.getOrientationSensor(); + + // tilt is easy + mTilt.clone(orientation); + + // update movement inputs + if (mUseOrientationForMovement) { + mDirectionalPad.clone(orientation); + mDirectionalPad.setMagnitude( + filterOrientationForMovement(orientation.getX()), + filterOrientationForMovement(orientation.getY())); + } else { + // keys or trackball + final InputXY trackball = input.getTrackball(); + final InputButton left = keys[mLeftKeyCode]; + final InputButton right = keys[mRightKeyCode]; + final float leftPressedTime = left.getLastPressedTime(); + final float rightPressedTime = right.getLastPressedTime(); + + final float gameTime = sSystemRegistry.timeSystem.getGameTime(); + + if (trackball.getLastPressedTime() > Math.max(leftPressedTime, rightPressedTime)) { + // The trackball never goes "up", so force it to turn off if it wasn't triggered in the last frame. + // What follows is a bunch of code to filter trackball events into something like a dpad event. + // The goals here are: + // - For roll events that occur in quick succession to accumulate. + // - For roll events that occur with more time between them, lessen the impact of older events + // - In the absence of roll events, fade the roll out over time. + if (gameTime - trackball.getLastPressedTime() < ROLL_TIMEOUT) { + float newX; + float newY; + final float delay = Math.max(ROLL_RESET_DELAY, timeDelta); + if (gameTime - mLastRollTime <= delay) { + newX = mDirectionalPad.getX() + (trackball.getX() * ROLL_FILTER * mMovementSensitivity); + newY = mDirectionalPad.getY() + (trackball.getY() * ROLL_FILTER * mMovementSensitivity); + } else { + float oldX = mDirectionalPad.getX() != 0.0f ? mDirectionalPad.getX() / 2.0f : 0.0f; + float oldY = mDirectionalPad.getX() != 0.0f ? mDirectionalPad.getX() / 2.0f : 0.0f; + newX = oldX + (trackball.getX() * ROLL_FILTER * mMovementSensitivity); + newY = oldY + (trackball.getX() * ROLL_FILTER * mMovementSensitivity); + } + + mDirectionalPad.press(gameTime, newX, newY); + mLastRollTime = gameTime; + trackball.release(); + } else { + float x = mDirectionalPad.getX(); + float y = mDirectionalPad.getY(); + if (x != 0.0f) { + int sign = Utils.sign(x); + x = x - (sign * ROLL_DECAY * timeDelta); + if (Utils.sign(x) != sign) { + x = 0.0f; + } + } + + if (y != 0.0f) { + int sign = Utils.sign(y); + y = y - (sign * ROLL_DECAY * timeDelta); + if (Utils.sign(x) != sign) { + y = 0.0f; + } + } + + + if (x == 0 && y == 0) { + mDirectionalPad.release(); + } else { + mDirectionalPad.setMagnitude(x, y); + } + } + + } else { + float xMagnitude = 0.0f; + float yMagnitude = 0.0f; + float pressTime = 0.0f; + // left and right are mutually exclusive + if (leftPressedTime > rightPressedTime) { + xMagnitude = -left.getMagnitude() * KEY_FILTER * mMovementSensitivity; + pressTime = leftPressedTime; + } else { + xMagnitude = right.getMagnitude() * KEY_FILTER * mMovementSensitivity; + pressTime = rightPressedTime; + } + + if (xMagnitude != 0.0f) { + mDirectionalPad.press(pressTime, xMagnitude, yMagnitude); + } else { + mDirectionalPad.release(); + } + } + } + + // update other buttons + final InputButton jumpKey = keys[mJumpKeyCode]; + final InputXY touch = input.getTouchScreen(); + + if (jumpKey.getPressed()) { + mJumpButton.press(jumpKey.getLastPressedTime(), jumpKey.getMagnitude()); + } else if (touch.getPressed() && getTouchedWithinRegion( + touch.getX(), + touch.getY(), + ButtonConstants.FLY_BUTTON_REGION_X, + ButtonConstants.FLY_BUTTON_REGION_Y, + ButtonConstants.FLY_BUTTON_REGION_WIDTH, + ButtonConstants.FLY_BUTTON_REGION_HEIGHT)) { + if (!mJumpButton.getPressed()) { + mJumpButton.press(touch.getLastPressedTime(), 1.0f); + } + } else { + mJumpButton.release(); + } + + final InputButton attackKey = keys[mAttackKeyCode]; + final InputButton clickButton = keys[KeyEvent.KEYCODE_DPAD_CENTER]; // special case + + if (mUseClickButtonForAttack && clickButton.getPressed()) { + mAttackButton.press(clickButton.getLastPressedTime(), clickButton.getMagnitude()); + } else if (attackKey.getPressed()) { + mAttackButton.press(attackKey.getLastPressedTime(), attackKey.getMagnitude()); + } else if (touch.getPressed() && getTouchedWithinRegion( + touch.getX(), + touch.getY(), + ButtonConstants.STOMP_BUTTON_REGION_X, + ButtonConstants.STOMP_BUTTON_REGION_Y, + ButtonConstants.STOMP_BUTTON_REGION_WIDTH, + ButtonConstants.STOMP_BUTTON_REGION_HEIGHT)) { + // Since touch events come in constantly, we only want to press the attack button + // here if it's not already down. That makes it act like the other buttons (down once then up). + if (!mAttackButton.getPressed()) { + mAttackButton.press(touch.getLastPressedTime(), 1.0f); + } + } else { + mAttackButton.release(); + } + } + + + private float filterOrientationForMovement(float magnitude) { + float scaledMagnitude = magnitude * mOrientationSensitivityFactor; + + return deadZoneFilter(scaledMagnitude, mOrientationDeadZoneMin, mOrientationDeadZoneMax, mOrientationDeadZoneScale); + } + + private float deadZoneFilter(float magnitude, float min, float max, float scale) { + float smoothedMagnatude = magnitude; + if (Math.abs(magnitude) < min) { + smoothedMagnatude = 0.0f; // dead zone + } else if (Math.abs(magnitude) < max) { + smoothedMagnatude *= scale; + } + + return smoothedMagnatude; + } + + private final boolean getTouchedWithinRegion(float x, float y, float regionX, float regionY, float regionWidth, float regionHeight) { + return (x >= regionX && + y >= regionY && + x <= regionX + regionWidth && + y <= regionY + regionHeight); + } + + public final InputXY getDirectionalPad() { + return mDirectionalPad; + } + + public final InputXY getTilt() { + return mTilt; + } + + public final InputButton getJumpButton() { + return mJumpButton; + } + + public final InputButton getAttackButton() { + return mAttackButton; + } + + public void setKeys(int left, int right, int jump, int attack) { + mLeftKeyCode = left; + mRightKeyCode = right; + mJumpKeyCode = jump; + mAttackKeyCode = attack; + } + + public void setUseClickForAttack(boolean click) { + mUseClickButtonForAttack = click; + } + + public void setUseOrientationForMovement(boolean orientation) { + mUseOrientationForMovement = orientation; + } + + public void setOrientationMovementSensitivity(float sensitivity) { + mOrientationSensitivity = sensitivity; + mOrientationSensitivityFactor = 2.9f * sensitivity + 0.1f; + } + + public void setMovementSensitivity(float sensitivity) { + mMovementSensitivity = sensitivity; + } + +} diff --git a/src/com/replica/replicaisland/InputKeyboard.java b/src/com/replica/replicaisland/InputKeyboard.java new file mode 100644 index 0000000..655e5ff --- /dev/null +++ b/src/com/replica/replicaisland/InputKeyboard.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.replica.replicaisland; + + +import android.view.KeyEvent; + +public class InputKeyboard { + private InputButton[] mKeys; + + public InputKeyboard() { + final int count = KeyEvent.getMaxKeyCode(); + mKeys = new InputButton[count]; + for (int x = 0; x < count; x++) { + mKeys[x] = new InputButton(); + } + } + + public void press(float currentTime, int keycode) { + assert keycode >= 0 && keycode < mKeys.length; + if (keycode >= 0 && keycode < mKeys.length){ + mKeys[keycode].press(currentTime, 1.0f); + } + } + + public void release(int keycode) { + assert keycode >= 0 && keycode < mKeys.length; + if (keycode >= 0 && keycode < mKeys.length){ + mKeys[keycode].release(); + } + } + + public void releaseAll() { + final int count = mKeys.length; + for (int x = 0; x < count; x++) { + mKeys[x].release(); + } + } + + public InputButton[] getKeys() { + return mKeys; + } + + public void resetAll() { + final int count = mKeys.length; + for (int x = 0; x < count; x++) { + mKeys[x].reset(); + } + } +} diff --git a/src/com/replica/replicaisland/InputSystem.java b/src/com/replica/replicaisland/InputSystem.java index c0e2272..6bc4ed8 100644 --- a/src/com/replica/replicaisland/InputSystem.java +++ b/src/com/replica/replicaisland/InputSystem.java @@ -22,232 +22,41 @@ package com.replica.replicaisland; */ public class InputSystem extends BaseObject { - private class InputButton { - private static final float BUTTON_LIFETIME = -1.0f; //60.0f * 10.0f; - - private float mTimeout = BUTTON_LIFETIME; - private boolean mDown; - private boolean mReleased; - private int mDownFrames; - private float mLastPressedTime; - private float mDownTime; - private float mMagnitude; - private boolean mActive = true; // if false, does all necessary tracking but returns false to queries. - - public void press(float currentTime, float magnitude) { - if (!mDown) { - mDown = true; - mDownFrames = 0; - mDownTime = currentTime; - } - mMagnitude = magnitude; - mLastPressedTime = currentTime; - mReleased = false; - } - - public void release() { - mReleased = true; - } - - public void update(float currentTime) { - if (mDown) { - mDownFrames++; - if (mDownFrames > 1) { - if (mReleased || (mTimeout > 0.0f && (currentTime - mLastPressedTime) > mTimeout)) { - mDown = false; - } - } - } - } - - public final boolean getPressed() { - return mActive ? mDown : false; - } - - public final boolean getTriggered() { - return mActive ? (mDown && mDownFrames <= 1) : false; - } - - public final float getPressedDuration(float currentTime) { - return mActive ? (currentTime - mDownTime) : 0.0f; - } - - public final float getLastPressedTime() { - return mLastPressedTime; - } - - public final float getMagnitude() { - float magnitude = 0.0f; - if (mActive && mDown) { - magnitude = mMagnitude; - } - return magnitude; - } - - public final void setTimeout(float timeout) { - mTimeout = timeout; - } - - public void setActive(boolean active) { - mActive = active; - } - } - - private class InputXY { - private InputButton mXAxis = new InputButton(); - private InputButton mYAxis = new InputButton(); - - public final void press(float currentTime, float x, float y) { - mXAxis.press(currentTime, x); - mYAxis.press(currentTime, y); - } - - public final void release() { - mXAxis.release(); - mYAxis.release(); - } - - public final void update(float currentTime) { - mXAxis.update(currentTime); - mYAxis.update(currentTime); - } - - public final boolean getTriggered() { - return mXAxis.getTriggered() || mYAxis.getTriggered(); - } - - public final boolean getPressed() { - return mXAxis.getPressed() || mYAxis.getPressed(); - } - - public final void setVector(Vector2 vector) { - vector.x = mXAxis.getMagnitude(); - vector.y = mYAxis.getMagnitude(); - } - - public final float getX() { - return mXAxis.getMagnitude(); - } - - public final float getY() { - return mYAxis.getMagnitude(); - } - - public final float getLastPressedTime() { - return Math.max(mXAxis.getLastPressedTime(), mYAxis.getLastPressedTime()); - } - - public final void releaseX() { - mXAxis.release(); - } - - public final void releaseY() { - mYAxis.release(); - } - - public final void setTimeout(float timeout) { - mXAxis.setTimeout(timeout); - mYAxis.setTimeout(timeout); - } - } - - private final static float KEY_ROLL_SPEED = 0.25f; - private final static float TILT_ROLL_SPEED = 1.0f; - private final static float TILT_ROLL_MODIFIER = 8.0f; - private final static float DPAD_TIMEOUT = -1.0f; //2.0f; - private final static float ROLL_TIMEOUT = 0.1f; - private final static int ROLL_HISTORY_SIZE = 10; - // Raw trackball input is filtered by this value. Increasing it will - // make the control more twitchy, while decreasing it will make the control more precise. - private final static float ROLL_FILTER = 0.4f; - - private InputXY mTouchScreen = new InputXY(); + private InputXY mTouchScreen = new InputXY(); // I guess for multitouch this could be an array. private InputXY mOrientationSensor = new InputXY(); - private InputXY mDirectionalPad = new InputXY(); - private InputButton mClick = new InputButton(); - - private Vector2 mTempDirection = new Vector2(); - - // Roll averaging - private FixedSizeArray<Vector2> mRecentRollInput = new FixedSizeArray<Vector2>(ROLL_HISTORY_SIZE); - private int mCurrentInputSlot; - private Vector2 mCurrentRollDirection = new Vector2(); - - private boolean mUseOrientationForRoll = false; // If true, pipes tilt into the directional pad. - private float mOrientationSensitivityModifier = 0.5f; - + private InputXY mTrackball = new InputXY(); + private InputKeyboard mKeyboard = new InputKeyboard(); + public InputSystem() { super(); - for (int x = 0; x < ROLL_HISTORY_SIZE; x++) { - mRecentRollInput.add(new Vector2()); - } reset(); } @Override public void reset() { - mCurrentInputSlot = 0; - mCurrentRollDirection.zero(); + mTrackball.reset(); + mTouchScreen.reset(); + mKeyboard.resetAll(); + mOrientationSensor.reset(); } public void roll(float x, float y) { - if (!mDirectionalPad.getPressed()) { - for (int index = 0; index < ROLL_HISTORY_SIZE; index++) { - mRecentRollInput.get(index).zero(); - } - mCurrentRollDirection.set(x * ROLL_FILTER, y * ROLL_FILTER); - mRecentRollInput.get(0).set(x * ROLL_FILTER, y * ROLL_FILTER); - mCurrentInputSlot = 1; - } else { - // recalculate accumulated direction - mCurrentRollDirection.subtract(mRecentRollInput.get(mCurrentInputSlot)); - mRecentRollInput.get(mCurrentInputSlot).set(x * ROLL_FILTER, y * ROLL_FILTER); - mCurrentRollDirection.add(mRecentRollInput.get(mCurrentInputSlot)); - - mCurrentInputSlot = (mCurrentInputSlot + 1) % ROLL_HISTORY_SIZE; - - // Clamp to 1.0 - if (Math.abs(mCurrentRollDirection.x) > 1.0f) { - if (mCurrentRollDirection.x < 0.0f) { - mCurrentRollDirection.x = (-1.0f); - } else { - mCurrentRollDirection.x = (1.0f); - } - } - - if (Math.abs(mCurrentRollDirection.y) > 1.0f) { - if (mCurrentRollDirection.y < 0.0f) { - mCurrentRollDirection.y = (-1.0f); - } else { - mCurrentRollDirection.y = (1.0f); - } - } - } TimeSystem time = sSystemRegistry.timeSystem; - mDirectionalPad.setTimeout(ROLL_TIMEOUT); - mDirectionalPad.press(time.getGameTime(), mCurrentRollDirection.x, mCurrentRollDirection.y); + mTrackball.press(time.getGameTime(), mTrackball.getX() + x, mTrackball.getY() + y); } - public void touch(int x, int y, boolean released) { - if (released) { - mTouchScreen.release(); - } else { - ContextParameters params = sSystemRegistry.contextParameters; - TimeSystem time = sSystemRegistry.timeSystem; - // Change the origin of the touch location from the top-left to the bottom-left to match - // OpenGL space. - // TODO: UNIFY THIS SHIT - mTouchScreen.press(time.getGameTime(), x, params.gameHeight - y); - } + public void touchDown(float x, float y) { + ContextParameters params = sSystemRegistry.contextParameters; + TimeSystem time = sSystemRegistry.timeSystem; + // Change the origin of the touch location from the top-left to the bottom-left to match + // OpenGL space. + // TODO: UNIFY THIS SHIT + mTouchScreen.press(time.getGameTime(), x, params.gameHeight - y); } - public void clickDown() { - TimeSystem time = sSystemRegistry.timeSystem; - mClick.press(time.getGameTime(), 1.0f); - } - - public void clickUp() { - mClick.release(); + public void touchUp(float x, float y) { + // TODO: record up location? + mTouchScreen.release(); } public void setOrientation(float azimuth, float pitch, float roll) { @@ -258,163 +67,43 @@ public class InputSystem extends BaseObject { TimeSystem time = sSystemRegistry.timeSystem; mOrientationSensor.press(time.getGameTime(), correctedPitch, correctedRoll); - if (mUseOrientationForRoll) { - float smoothedPitch = correctedPitch; - float smoothedRoll = correctedRoll; - if (Math.abs(correctedPitch) < 0.03f) { - smoothedPitch = 0.0f; // dead zone - } else if (Math.abs(correctedPitch) < 0.1f) { - smoothedPitch *= 0.75f; - } - if (Math.abs(smoothedRoll) < 0.03f) { - smoothedRoll = 0.0f; // dead zone - } else if (Math.abs(smoothedRoll) < 0.1f) { - smoothedRoll *= 0.75f; - } - - //roll(smoothedPitch * TILT_ROLL_SPEED, smoothedRoll * TILT_ROLL_SPEED); - mDirectionalPad.press(time.getGameTime(), - smoothedPitch * (TILT_ROLL_SPEED + (TILT_ROLL_MODIFIER * mOrientationSensitivityModifier)), - smoothedRoll * (TILT_ROLL_SPEED + (TILT_ROLL_MODIFIER * mOrientationSensitivityModifier))); - } + } - public void keyDown(boolean left, boolean right, boolean up, boolean down, - boolean touch, boolean click) { - float x = 0.0f; - float y = 0.0f; - TimeSystem time = sSystemRegistry.timeSystem; + public void keyDown(int keycode) { + TimeSystem time = sSystemRegistry.timeSystem; final float gameTime = time.getGameTime(); - if (left) { - x = -KEY_ROLL_SPEED; - } else if (right) { - x = KEY_ROLL_SPEED; - } - if (up) { - y = KEY_ROLL_SPEED; - } else if (down) { - y = -KEY_ROLL_SPEED; - } - if (x != 0.0f || y != 0.0f) { - mDirectionalPad.setTimeout(DPAD_TIMEOUT); - mDirectionalPad.press(gameTime, x, y); - } - - if (touch) { - mTouchScreen.press(gameTime, 0, 0); - } - - if (click) { - mClick.press(gameTime, 1.0f); - } + mKeyboard.press(gameTime, keycode); } - public void keyUp(boolean left, boolean right, boolean up, boolean down, - boolean touch, boolean click) { - if (left || right) { - mDirectionalPad.releaseX(); - } - - if (up || down) { - mDirectionalPad.releaseY(); - } - - if (touch) { - mTouchScreen.release(); - } - - if (click) { - mClick.release(); - } + public void keyUp(int keycode) { + mKeyboard.release(keycode); } public void releaseAllKeys() { - mDirectionalPad.releaseX(); - mDirectionalPad.releaseY(); + mTrackball.releaseX(); + mTrackball.releaseY(); mTouchScreen.release(); - mClick.release(); + mKeyboard.releaseAll(); + mOrientationSensor.release(); } - @Override - public void update(float timeDelta, BaseObject parent) { - TimeSystem time = sSystemRegistry.timeSystem; - final float gameTime = time.getGameTime(); - - mTouchScreen.update(gameTime); - mDirectionalPad.update(gameTime); - mOrientationSensor.update(gameTime); - mClick.update(gameTime); - } - - public final boolean getRollTriggered() { - return mDirectionalPad.getPressed(); - } + public InputXY getTouchScreen() { + return mTouchScreen; + } - public final Vector2 getRollDirection() { - mDirectionalPad.setVector(mTempDirection); - return mTempDirection; - } - - public final boolean getTouchTriggered() { - return mTouchScreen.getTriggered(); - } - - public final boolean getTouchPressed() { - return mTouchScreen.getPressed(); - } + public InputXY getOrientationSensor() { + return mOrientationSensor; + } - public final Vector2 getTouchPosition() { - mTouchScreen.setVector(mTempDirection); - return mTempDirection; - } - - public final boolean getTouchedWithinRegion(int x, int y, int width, int height) { - mTouchScreen.setVector(mTempDirection); + public InputXY getTrackball() { + return mTrackball; + } - return (mTempDirection.x >= x && - mTempDirection.y >= y && - mTempDirection.x <= x + width && - mTempDirection.y <= y + height); - } - - public final boolean getClickTriggered() { - return mClick.getTriggered(); - } - - public final void clearClickTriggered() { - mClick.release(); - } - - public final boolean getClickPressed() { - return mClick.getPressed(); - } - - public final float getLastRollTime() { - return mDirectionalPad.getLastPressedTime(); - } - - public final float getLastTouchTime() { - return mTouchScreen.getLastPressedTime(); - } - - public final float getLastClickTime() { - return mClick.getLastPressedTime(); - } + public InputKeyboard getKeyboard() { + return mKeyboard; + } - public final float getPitch() { - return mOrientationSensor.getX(); - } - public final float getRoll() { - return mOrientationSensor.getY(); - } - public void setUseOrientationForRoll(boolean rollWithOrientation) { - mUseOrientationForRoll = rollWithOrientation; - } - - public void setOrientationSensitivityModifier(float modifier) { - mOrientationSensitivityModifier = modifier; - } - } diff --git a/src/com/replica/replicaisland/InputXY.java b/src/com/replica/replicaisland/InputXY.java new file mode 100644 index 0000000..c74b815 --- /dev/null +++ b/src/com/replica/replicaisland/InputXY.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.replica.replicaisland; + + +public class InputXY { + private InputButton mXAxis; + private InputButton mYAxis; + + public InputXY() { + mXAxis = new InputButton(); + mYAxis = new InputButton(); + } + + public InputXY(InputButton xAxis, InputButton yAxis) { + mXAxis = xAxis; + mYAxis = yAxis; + } + + public final void press(float currentTime, float x, float y) { + mXAxis.press(currentTime, x); + mYAxis.press(currentTime, y); + } + + public final void release() { + mXAxis.release(); + mYAxis.release(); + } + + public boolean getTriggered(float time) { + return mXAxis.getTriggered(time) || mYAxis.getTriggered(time); + } + + public boolean getPressed() { + return mXAxis.getPressed() || mYAxis.getPressed(); + } + + public final void setVector(Vector2 vector) { + vector.x = mXAxis.getMagnitude(); + vector.y = mYAxis.getMagnitude(); + } + + public final float getX() { + return mXAxis.getMagnitude(); + } + + public final float getY() { + return mYAxis.getMagnitude(); + } + + public final float getLastPressedTime() { + return Math.max(mXAxis.getLastPressedTime(), mYAxis.getLastPressedTime()); + } + + public final void releaseX() { + mXAxis.release(); + } + + public final void releaseY() { + mYAxis.release(); + } + + + public void setMagnitude(float x, float y) { + mXAxis.setMagnitude(x); + mYAxis.setMagnitude(y); + } + + public void reset() { + mXAxis.reset(); + mYAxis.reset(); + } + + public void clone(InputXY other) { + if (other.getPressed()) { + press(other.getLastPressedTime(), other.getX(), other.getY()); + } else { + release(); + } + } +} diff --git a/src/com/replica/replicaisland/LaunchProjectileComponent.java b/src/com/replica/replicaisland/LaunchProjectileComponent.java index 5ea17aa..aa03bd8 100644 --- a/src/com/replica/replicaisland/LaunchProjectileComponent.java +++ b/src/com/replica/replicaisland/LaunchProjectileComponent.java @@ -146,40 +146,42 @@ public class LaunchProjectileComponent extends GameComponent { final float x = parentObject.getPosition().x + offsetX; final float y = parentObject.getPosition().y + offsetY; GameObject object = factory.spawn(mObjectTypeToSpawn, x, y, flip); - mWorkingVector.set(1.0f, 1.0f); - if (mThetaError > 0.0f) { - final float angle = (float)(Math.random() * mThetaError * Math.PI * 2.0f); - mWorkingVector.x = (float)Math.sin(angle); - mWorkingVector.y = (float)Math.cos(angle); - if (Utils.close(mWorkingVector.length2(), 0.0f)) { - mWorkingVector.set(1.0f, 1.0f); - } - } - mWorkingVector.x *= flip ? -mVelocityX : mVelocityX; - mWorkingVector.y *= mVelocityY; - - object.getVelocity().set(mWorkingVector); - object.getTargetVelocity().set(mWorkingVector); - // Center the projectile on the spawn point. - object.getPosition().x -= object.width / 2.0f; - object.getPosition().y -= object.height / 2.0f; - - - if (mTrackProjectiles) { - object.commitUpdates(); - LifetimeComponent projectileLife = object.findByClass(LifetimeComponent.class); - if (projectileLife != null) { - projectileLife.setTrackingSpawner(this); - mTrackedProjectileCount++; - } - } - manager.add(object); - - if (mShootSound != null) { - SoundSystem sound = sSystemRegistry.soundSystem; - if (sound != null) { - sound.play(mShootSound, false, SoundSystem.PRIORITY_NORMAL); - } + if (object != null) { + mWorkingVector.set(1.0f, 1.0f); + if (mThetaError > 0.0f) { + final float angle = (float)(Math.random() * mThetaError * Math.PI * 2.0f); + mWorkingVector.x = (float)Math.sin(angle); + mWorkingVector.y = (float)Math.cos(angle); + if (Utils.close(mWorkingVector.length2(), 0.0f)) { + mWorkingVector.set(1.0f, 1.0f); + } + } + mWorkingVector.x *= flip ? -mVelocityX : mVelocityX; + mWorkingVector.y *= mVelocityY; + + object.getVelocity().set(mWorkingVector); + object.getTargetVelocity().set(mWorkingVector); + // Center the projectile on the spawn point. + object.getPosition().x -= object.width / 2.0f; + object.getPosition().y -= object.height / 2.0f; + + + if (mTrackProjectiles) { + object.commitUpdates(); + LifetimeComponent projectileLife = object.findByClass(LifetimeComponent.class); + if (projectileLife != null) { + projectileLife.setTrackingSpawner(this); + mTrackedProjectileCount++; + } + } + manager.add(object); + + if (mShootSound != null) { + SoundSystem sound = sSystemRegistry.soundSystem; + if (sound != null) { + sound.play(mShootSound, false, SoundSystem.PRIORITY_NORMAL); + } + } } } diff --git a/src/com/replica/replicaisland/LauncherComponent.java b/src/com/replica/replicaisland/LauncherComponent.java index 640d4e7..47bf3b1 100644 --- a/src/com/replica/replicaisland/LauncherComponent.java +++ b/src/com/replica/replicaisland/LauncherComponent.java @@ -127,8 +127,9 @@ public class LauncherComponent extends GameComponent { position.x + (mLaunchEffectOffsetX * parentObject.facingDirection.x), position.y + (mLaunchEffectOffsetY * parentObject.facingDirection.y), false); - - manager.add(effect); + if (effect != null) { + manager.add(effect); + } } } } diff --git a/src/com/replica/replicaisland/MainMenuActivity.java b/src/com/replica/replicaisland/MainMenuActivity.java index d7ed560..87c8bed 100644 --- a/src/com/replica/replicaisland/MainMenuActivity.java +++ b/src/com/replica/replicaisland/MainMenuActivity.java @@ -23,6 +23,7 @@ import android.app.Dialog; import android.content.Intent; import android.content.SharedPreferences; import android.media.AudioManager; +import android.os.Build; import android.os.Bundle; import android.view.View; import android.view.animation.Animation; @@ -166,8 +167,30 @@ public class MainMenuActivity extends Activity { editor.commit(); } } + } + + + if (Math.abs(lastVersion) < Math.abs(AndouKun.VERSION)) { + // This is a new install or an upgrade. + + // Check the safe mode option. + // Useful reference: http://en.wikipedia.org/wiki/List_of_Android_devices + if (Build.PRODUCT.contains("morrison") || // Motorola Cliq/Dext + Build.MODEL.contains("Pulse") || // Huawei Pulse + Build.MODEL.contains("U8220") || // Huawei Pulse + Build.MODEL.contains("U8230") || // Huawei U8230 + Build.MODEL.contains("MB300") || // Motorola Backflip + Build.MODEL.contains("Behold+II")) { // Samsung Behold II + // These are all models that users have complained about. They likely use + // the same buggy QTC graphics driver. Turn on Safe Mode by default + // for these devices. + SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean(AndouKun.PREFERENCE_SAFE_MODE, true); + editor.commit(); + } + // show what's new message SharedPreferences.Editor editor = prefs.edit(); editor.putInt(AndouKun.PREFERENCE_LAST_VERSION, AndouKun.VERSION); diff --git a/src/com/replica/replicaisland/ObjectRegistry.java b/src/com/replica/replicaisland/ObjectRegistry.java index cc14803..8d83cb9 100644 --- a/src/com/replica/replicaisland/ObjectRegistry.java +++ b/src/com/replica/replicaisland/ObjectRegistry.java @@ -45,6 +45,7 @@ public class ObjectRegistry extends BaseObject { public HitPointPool hitPointPool; public HotSpotSystem hotSpotSystem; public HudSystem hudSystem; + public InputGameInterface inputGameInterface; public InputSystem inputSystem; public LevelBuilder levelBuilder; public LevelSystem levelSystem; diff --git a/src/com/replica/replicaisland/PhasedObjectManager.java b/src/com/replica/replicaisland/PhasedObjectManager.java index a20ed34..7a68f10 100644 --- a/src/com/replica/replicaisland/PhasedObjectManager.java +++ b/src/com/replica/replicaisland/PhasedObjectManager.java @@ -36,6 +36,14 @@ public class PhasedObjectManager extends ObjectManager { getPendingObjects().setComparator(sPhasedObjectComparator); mSearchDummy = new PhasedObject(); } + + public PhasedObjectManager(int arraySize) { + super(arraySize); + mDirty = false; + getObjects().setComparator(sPhasedObjectComparator); + getPendingObjects().setComparator(sPhasedObjectComparator); + mSearchDummy = new PhasedObject(); + } @Override public void commitUpdates() { diff --git a/src/com/replica/replicaisland/PlayerComponent.java b/src/com/replica/replicaisland/PlayerComponent.java index e43b13d..de36bb8 100644 --- a/src/com/replica/replicaisland/PlayerComponent.java +++ b/src/com/replica/replicaisland/PlayerComponent.java @@ -82,9 +82,6 @@ public class PlayerComponent extends GameComponent { private boolean mGhostActive; private float mGhostDeactivatedTime; private float mGhostChargeTime; - private boolean mJumpButtonPressed; - private boolean mAttackButtonPressed; - private boolean mAttackButtonTriggered; private InventoryComponent mInventory; private Vector2 mHotSpotTestPoint; private ChangeComponentsComponent mInvincibleSwap; @@ -112,7 +109,6 @@ public class PlayerComponent extends GameComponent { mJumpTime = 0.0f; mGhostActive = false; mGhostDeactivatedTime = 0.0f; - mJumpButtonPressed = false; mInventory = null; mGhostChargeTime = 0.0f; mHotSpotTestPoint.zero(); @@ -120,13 +116,11 @@ public class PlayerComponent extends GameComponent { mInvincibleEndTime = 0.0f; mHitReaction = null; mFuelAirRefillSpeed = FUEL_AIR_REFILL_SPEED; - mAttackButtonPressed = false; - mAttackButtonTriggered = false; } protected void move(float time, float timeDelta, GameObject parentObject) { VectorPool pool = sSystemRegistry.vectorPool; - InputSystem input = sSystemRegistry.inputSystem; + InputGameInterface input = sSystemRegistry.inputGameInterface; if (pool != null && input != null) { @@ -142,16 +136,18 @@ public class PlayerComponent extends GameComponent { } } - if (input.getRollTriggered() || mJumpButtonPressed) { + final InputXY dpad = input.getDirectionalPad(); + final InputButton jumpButton = input.getJumpButton(); + + if (dpad.getPressed() || jumpButton.getPressed()) { Vector2 impulse = pool.allocate(); - if (input.getRollTriggered()) { - impulse.set(input.getRollDirection()); - impulse.y = 0.0f; + if (dpad.getPressed()) { + impulse.set(dpad.getX(), 0.0f); } - if (mJumpButtonPressed) { - if (input.getTouchTriggered() && mTouchingGround) { + if (jumpButton.getPressed()) { + if (jumpButton.getTriggered(time) && mTouchingGround) { // In this case, velocity is instant so we don't need to scale // it by time. impulse.y = AIR_VERTICAL_IMPULSE_SPEED_FROM_GROUND; @@ -226,9 +222,7 @@ public class PlayerComponent extends GameComponent { mTouchingGround = parentObject.touchingGround(); mRocketsOn = false; - mJumpButtonPressed = false; - mAttackButtonPressed = false; - mAttackButtonTriggered = false; + if (parentObject.getCurrentAction() == ActionType.INVALID) { gotoMove(parentObject); @@ -260,37 +254,7 @@ public class PlayerComponent extends GameComponent { mHitReaction.setForceInvincible(false); } } - - // TODO: the region we are testing here should probably be moved out into some constants - // file and then independently tested by the hud and by the player so we can remove - // this cross dependency. - InputSystem input = sSystemRegistry.inputSystem; - if (input != null) { - if (input.getTouchPressed()) { - if (input.getTouchedWithinRegion( - ButtonConstants.FLY_BUTTON_REGION_X, - ButtonConstants.FLY_BUTTON_REGION_Y, - ButtonConstants.FLY_BUTTON_REGION_WIDTH, - ButtonConstants.FLY_BUTTON_REGION_HEIGHT)) { - mJumpButtonPressed = true; - } else if (input.getTouchedWithinRegion( - ButtonConstants.STOMP_BUTTON_REGION_X, - ButtonConstants.STOMP_BUTTON_REGION_Y, - ButtonConstants.STOMP_BUTTON_REGION_WIDTH, - ButtonConstants.STOMP_BUTTON_REGION_HEIGHT)) { - mAttackButtonPressed = true; - if (input.getTouchTriggered()) { - mAttackButtonTriggered = true; - } - } - } - if (input.getClickPressed()) { - mAttackButtonPressed = true; - if (input.getClickTriggered()) { - mAttackButtonTriggered = true; - } - } - } + // Watch for hit reactions or death interrupting the state machine. if (mState != State.DEAD && mState != State.WIN ) { @@ -344,9 +308,10 @@ public class PlayerComponent extends GameComponent { } final HudSystem hud = sSystemRegistry.hudSystem; + final InputGameInterface input = sSystemRegistry.inputGameInterface; if (hud != null) { hud.setFuelPercent(mFuel / FUEL_AMOUNT); - hud.setButtonState(mJumpButtonPressed, mAttackButtonPressed); + hud.setButtonState(input.getJumpButton().getPressed(), input.getAttackButton().getPressed()); } } @@ -360,10 +325,12 @@ public class PlayerComponent extends GameComponent { if (!mGhostActive) { move(time, timeDelta, parentObject); - InputSystem input = sSystemRegistry.inputSystem; - if (mAttackButtonTriggered && !mTouchingGround) { + final InputGameInterface input = sSystemRegistry.inputGameInterface; + final InputButton attackButton = input.getAttackButton(); + + if (attackButton.getTriggered(time) && !mTouchingGround) { gotoStomp(parentObject); - } else if (mAttackButtonPressed && mTouchingGround + } else if (attackButton.getPressed() && mTouchingGround && mGhostDeactivatedTime + GHOST_REACTIVATION_DELAY < time) { mGhostChargeTime += timeDelta; if (mGhostChargeTime > GHOST_CHARGE_TIME) { @@ -389,11 +356,9 @@ public class PlayerComponent extends GameComponent { if (camera != null) { camera.setTarget(ghost); } - - input.clearClickTriggered(); - } + } } - } else if (!input.getClickPressed()) { + } else if (!attackButton.getPressed()) { mGhostChargeTime = 0.0f; } } diff --git a/src/com/replica/replicaisland/RenderSystem.java b/src/com/replica/replicaisland/RenderSystem.java index 349d53d..ffe3794 100644 --- a/src/com/replica/replicaisland/RenderSystem.java +++ b/src/com/replica/replicaisland/RenderSystem.java @@ -32,7 +32,7 @@ public class RenderSystem extends BaseObject { private int mQueueIndex; private final static int DRAW_QUEUE_COUNT = 2; - private final static int MAX_RENDER_OBJECTS_PER_FRAME = 128; + private final static int MAX_RENDER_OBJECTS_PER_FRAME = 256; private final static int MAX_RENDER_OBJECTS = MAX_RENDER_OBJECTS_PER_FRAME * DRAW_QUEUE_COUNT; public RenderSystem() { @@ -40,7 +40,7 @@ public class RenderSystem extends BaseObject { mElementPool = new RenderElementPool(MAX_RENDER_OBJECTS); mRenderQueues = new ObjectManager[DRAW_QUEUE_COUNT]; for (int x = 0; x < DRAW_QUEUE_COUNT; x++) { - mRenderQueues[x] = new PhasedObjectManager(); + mRenderQueues[x] = new PhasedObjectManager(MAX_RENDER_OBJECTS_PER_FRAME); } mQueueIndex = 0; } diff --git a/src/com/replica/replicaisland/SliderPreference.java b/src/com/replica/replicaisland/SliderPreference.java index 4e91887..8a90984 100644 --- a/src/com/replica/replicaisland/SliderPreference.java +++ b/src/com/replica/replicaisland/SliderPreference.java @@ -17,9 +17,7 @@ package com.replica.replicaisland; import android.util.AttributeSet; -import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; import android.widget.SeekBar; import android.widget.TextView; import android.widget.SeekBar.OnSeekBarChangeListener; @@ -38,10 +36,14 @@ public class SliderPreference extends Preference implements OnSeekBarChangeListe public SliderPreference(Context context) { super(context); + + setWidgetLayoutResource(R.layout.slider_preference); } public SliderPreference(Context context, AttributeSet attrs) { this(context, attrs, android.R.attr.preferenceStyle); + + setWidgetLayoutResource(R.layout.slider_preference); } public SliderPreference(Context context, AttributeSet attrs, int defStyle) { @@ -53,41 +55,35 @@ public class SliderPreference extends Preference implements OnSeekBarChangeListe mMaxText = a.getString(R.styleable.SliderPreference_maxText); a.recycle(); + + setWidgetLayoutResource(R.layout.slider_preference); } @Override - protected View onCreateView(ViewGroup parent){ - View shell = super.onCreateView(parent); - - ViewGroup widget = (ViewGroup)shell.findViewById(android.R.id.widget_frame); - - View root = LayoutInflater.from(getContext()).inflate( - R.layout.slider_preference, widget, true); - + protected void onBindView(View view) { + super.onBindView(view); + if (mMinText != null) { - TextView minText = (TextView)root.findViewById(R.id.min); + TextView minText = (TextView)view.findViewById(R.id.min); minText.setText(mMinText); } if (mMaxText != null) { - TextView minText = (TextView)root.findViewById(R.id.max); - minText.setText(mMaxText); + TextView maxText = (TextView)view.findViewById(R.id.max); + maxText.setText(mMaxText); } - SeekBar bar = (SeekBar)root.findViewById(R.id.slider); + SeekBar bar = (SeekBar)view.findViewById(R.id.slider); bar.setMax(MAX_SLIDER_VALUE); bar.setProgress(mValue); bar.setOnSeekBarChangeListener(this); - - return shell; } public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - - mValue = progress; - persistInt(mValue); - - notifyChanged(); + if (fromUser) { + mValue = progress; + persistInt(mValue); + } } public void onStartTrackingTouch(SeekBar seekBar) { @@ -98,7 +94,7 @@ public class SliderPreference extends Preference implements OnSeekBarChangeListe @Override - protected Object onGetDefaultValue(TypedArray ta,int index){ + protected Object onGetDefaultValue(TypedArray ta,int index) { int dValue = (int)ta.getInt(index, INITIAL_VALUE); return (int)Utils.clamp(dValue, 0, MAX_SLIDER_VALUE); diff --git a/src/com/replica/replicaisland/TiledVertexGrid.java b/src/com/replica/replicaisland/TiledVertexGrid.java index 5d6af48..8de6d90 100644 --- a/src/com/replica/replicaisland/TiledVertexGrid.java +++ b/src/com/replica/replicaisland/TiledVertexGrid.java @@ -35,6 +35,8 @@ public class TiledVertexGrid extends BaseObject { private int mTilesPerRow; private int mTilesPerColumn; + private Boolean mGenerated; + public TiledVertexGrid(Texture texture, int width, int height, int tileWidth, int tileHeight) { super(); mTileWidth = tileWidth; @@ -42,12 +44,11 @@ public class TiledVertexGrid extends BaseObject { mWidth = width; mHeight = height; mTexture = texture; + mGenerated = false; } @Override public void reset() { - // TODO Auto-generated method stub - } public void setWorld(TiledWorld world) { @@ -129,7 +130,7 @@ public class TiledVertexGrid extends BaseObject { public void draw(float x, float y, float scrollOriginX, float scrollOriginY) { TiledWorld world = mWorld; GL10 gl = OpenGLSystem.getGL(); - if (mTileMap == null && world != null && gl != null && mTexture != null) { + if (!mGenerated && world != null && gl != null && mTexture != null) { final int tilesAcross = mWorld.getWidth(); final int tilesDown = mWorld.getHeight(); @@ -143,13 +144,14 @@ public class TiledVertexGrid extends BaseObject { Grid grid = generateGrid((int)mWorldPixelWidth, (int)mWorldPixelHeight, 0, 0); mTileMap = grid; + mGenerated = true; if (grid != null) { bufferLibrary.add(grid); if (sSystemRegistry.contextParameters.supportsVBOs) { grid.generateHardwareBuffers(gl); } } - + } final Grid tileMap = mTileMap; diff --git a/src/com/replica/replicaisland/Utils.java b/src/com/replica/replicaisland/Utils.java index 97b62d1..52068ab 100644 --- a/src/com/replica/replicaisland/Utils.java +++ b/src/com/replica/replicaisland/Utils.java @@ -54,6 +54,7 @@ public class Utils { return result; } + public final static int byteArrayToInt(byte[] b) { if (b.length != 4) { |