summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsm0a9f4 <sm0a9f4@1dde52a2-2b62-11df-8484-2f92f965d510>2010-05-03 04:02:32 +0000
committersm0a9f4 <sm0a9f4@1dde52a2-2b62-11df-8484-2f92f965d510>2010-05-03 04:02:32 +0000
commit9d4cc2572d37983607df38b0f4216ed76ac51814 (patch)
treeb0fba19324ec0b0274f4cbed4d30c55c1f13aa2e
parente1fe50fadc9160b2c4ee09350b781c9b80d54e1f (diff)
downloadreplicaisland-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
-rw-r--r--AndroidManifest.xml3
-rw-r--r--res/drawable/framerate_warning.pngbin0 -> 119 bytes
-rw-r--r--res/layout/slider_preference.xml4
-rw-r--r--res/raw/performancetest4.binbin0 -> 3063 bytes
-rw-r--r--res/values/strings.xml19
-rw-r--r--res/xml/level_tree.xml7
-rw-r--r--res/xml/preferences.xml19
-rw-r--r--src/com/replica/replicaisland/AndouKun.java52
-rw-r--r--src/com/replica/replicaisland/AnimationComponent.java18
-rw-r--r--src/com/replica/replicaisland/CollisionSystem.java4
-rw-r--r--src/com/replica/replicaisland/DrawableFactory.java2
-rw-r--r--src/com/replica/replicaisland/FrameRateWatcherComponent.java51
-rw-r--r--src/com/replica/replicaisland/GLSurfaceView.java37
-rw-r--r--src/com/replica/replicaisland/Game.java52
-rw-r--r--src/com/replica/replicaisland/GameObjectCollisionSystem.java4
-rw-r--r--src/com/replica/replicaisland/GameObjectFactory.java791
-rw-r--r--src/com/replica/replicaisland/GameObjectManager.java2
-rw-r--r--src/com/replica/replicaisland/GameRenderer.java2
-rw-r--r--src/com/replica/replicaisland/GameThread.java201
-rw-r--r--src/com/replica/replicaisland/GhostComponent.java43
-rw-r--r--src/com/replica/replicaisland/HudSystem.java46
-rw-r--r--src/com/replica/replicaisland/InputButton.java73
-rw-r--r--src/com/replica/replicaisland/InputGameInterface.java280
-rw-r--r--src/com/replica/replicaisland/InputKeyboard.java65
-rw-r--r--src/com/replica/replicaisland/InputSystem.java393
-rw-r--r--src/com/replica/replicaisland/InputXY.java96
-rw-r--r--src/com/replica/replicaisland/LaunchProjectileComponent.java70
-rw-r--r--src/com/replica/replicaisland/LauncherComponent.java5
-rw-r--r--src/com/replica/replicaisland/MainMenuActivity.java23
-rw-r--r--src/com/replica/replicaisland/ObjectRegistry.java1
-rw-r--r--src/com/replica/replicaisland/PhasedObjectManager.java8
-rw-r--r--src/com/replica/replicaisland/PlayerComponent.java75
-rw-r--r--src/com/replica/replicaisland/RenderSystem.java4
-rw-r--r--src/com/replica/replicaisland/SliderPreference.java40
-rw-r--r--src/com/replica/replicaisland/TiledVertexGrid.java10
-rw-r--r--src/com/replica/replicaisland/Utils.java1
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
new file mode 100644
index 0000000..b3ca873
--- /dev/null
+++ b/res/drawable/framerate_warning.png
Binary files differ
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
new file mode 100644
index 0000000..fc3adaa
--- /dev/null
+++ b/res/raw/performancetest4.bin
Binary files differ
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) {