Added:
trunk/content_package/Classic/tiles_1.txt
trunk/content_package/Classic/tiles_default.txt
trunk/content_package/Classic/tiles_forest.png
- copied unchanged from r73,
/trunk/content_package/Classic/tiles_1.png
trunk/content_package/Classic/tiles_industrial.png
- copied unchanged from r73,
/trunk/content_package/Classic/tiles_default.png
Removed:
trunk/content_package/Classic/tiles_1.png
trunk/content_package/Classic/tiles_default.png
trunk/src/android/com/abb/Blood.java
trunk/src/android/com/abb/Fire.java
trunk/src/android/com/abb/Projectile.java
Modified:
trunk/content_package/Classic/level_1.txt
trunk/content_package/misc.png
trunk/editor/editor.glade
trunk/editor/editor.py
trunk/src/android/com/abb/ArticulatedEntity.java
trunk/src/android/com/abb/Avatar.java
trunk/src/android/com/abb/Enemy.java
trunk/src/android/com/abb/Entity.java
trunk/src/android/com/abb/GameState.java
trunk/src/android/com/abb/GameView.java
trunk/src/android/com/abb/Graphics.java
trunk/src/android/com/abb/Map.java
trunk/src/android/com/abb/Weapon.java
Log:
Performance improvments all around. Modified level format slightly to save
disk space. Improved level editor interface. Various bug fixes.
Modified: trunk/content_package/Classic/level_1.txt
==============================================================================
--- trunk/content_package/Classic/level_1.txt (original)
+++ trunk/content_package/Classic/level_1.txt Tue Mar 10 21:26:27 2009
@@ -29,14 +29,11 @@
38,70,"enemy=hopper.enemy"
38,71,"enemy=hopper.enemy"
38,72,"enemy=hopper.enemy"
-38,82,"enemy=hopper.enemy"
39,70,"enemy=hopper.enemy"
39,71,"enemy=hopper.enemy"
39,72,"enemy=hopper.enemy"
-39,82,"enemy=hopper.enemy"
40,70,"enemy=hopper.enemy"
40,71,"enemy=hopper.enemy"
-40,82,"enemy=hopper.enemy"
41,70,"enemy=hopper.enemy"
41,71,"enemy=hopper.enemy"
41,72,"enemy=hopper.enemy"
Added: trunk/content_package/Classic/tiles_1.txt
==============================================================================
--- (empty file)
+++ trunk/content_package/Classic/tiles_1.txt Tue Mar 10 21:26:27 2009
@@ -0,0 +1 @@
+tiles_forest.png
Added: trunk/content_package/Classic/tiles_default.txt
==============================================================================
--- (empty file)
+++ trunk/content_package/Classic/tiles_default.txt Tue Mar 10 21:26:27 2009
@@ -0,0 +1 @@
+tiles_industrial.png
Modified: trunk/content_package/misc.png
==============================================================================
Binary files. No diff available.
Modified: trunk/editor/editor.glade
==============================================================================
--- trunk/editor/editor.glade (original)
+++ trunk/editor/editor.glade Tue Mar 10 21:26:27 2009
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--Generated with glade3 3.4.5 on Mon Dec 8 21:09:42 2008 -->
+<!--Generated with glade3 3.4.5 on Sat Mar 7 21:28:19 2009 -->
<glade-interface>
<widget class="GtkWindow" id="window">
<property name="visible">True</property>
@@ -25,11 +25,26 @@
<widget class="GtkMenu" id="menu1">
<property name="visible">True</property>
<child>
+ <widget class="GtkImageMenuItem" id="menuitem_new">
+ <property name="visible">True</property>
+ <property name="label"
translatable="yes">New</property>
+ <property name="use_underline">True</property>
+ <signal name="activate"
handler="on_menuitem_new_activate"/>
+ <accelerator key="n" modifiers="GDK_CONTROL_MASK"
signal="activate"/>
+ <child internal-child="image">
+ <widget class="GtkImage" id="menu-item-image5">
+ <property name="stock">gtk-new</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
<widget class="GtkImageMenuItem"
id="menuitem_loadlevel">
<property name="visible">True</property>
<property name="label" translatable="yes">Load
Level...</property>
<property name="use_underline">True</property>
<signal name="activate"
handler="on_menuitem_loadlevel_activate"/>
+ <accelerator key="o" modifiers="GDK_CONTROL_MASK"
signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image91">
<property name="stock">gtk-open</property>
@@ -46,6 +61,20 @@
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image92">
<property name="stock">gtk-open</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menuitem_save">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Save
Level</property>
+ <property name="use_underline">True</property>
+ <signal name="activate"
handler="on_menuitem_save_activate"/>
+ <accelerator key="s" modifiers="GDK_CONTROL_MASK"
signal="activate"/>
+ <child internal-child="image">
+ <widget class="GtkImage" id="menu-item-image7">
+ <property name="stock">gtk-save</property>
</widget>
</child>
</widget>
Modified: trunk/editor/editor.py
==============================================================================
--- trunk/editor/editor.py (original)
+++ trunk/editor/editor.py Tue Mar 10 21:26:27 2009
@@ -76,29 +76,23 @@
signals = { 'on_brushes_expose_event' : self.BrushesExposeEvent,
'on_tiles_expose_event' : self.TilesExposeEvent,
'on_quit_menuitem_activate' : gtk.main_quit,
+ 'on_menuitem_new_activate' : self.NewMenu,
'on_menuitem_loadlevel_activate' : self.LoadLevelMenu,
'on_menuitem_loadbrushes_activate' : self.LoadBrushesMenu,
- 'on_menuitem_savelevel_activate' : self.SaveLevelMenu,
+ 'on_menuitem_save_activate' : self.SaveLevelMenu,
+ 'on_menuitem_savelevel_activate' : self.SaveLevelAsMenu,
'on_brushes_button_press_event' : self.BrushesClickEvent,
'on_tiles_button_press_event' : self.TilesClickEvent,
'on_tiles_scroll_event' : self.TilesScrollEvent,
'on_window_key_press_event' : self.TilesKeyEvent }
self.tree.signal_autoconnect(signals)
- # Misc editor state initialization.
- self._tiles = []
- for n in xrange(0, LEVEL_WIDTH * LEVEL_HEIGHT):
- self._tiles.append(0)
- self._triggers = []
- for n in xrange(0, LEVEL_WIDTH * LEVEL_HEIGHT):
- self._triggers.append(None)
+ # Initialize misc editor state and clear the document.
self._brushes_surface = None
self._selected_brush = 0
- self._view_x = 0
- self._view_y = 0
- self._view_zoom = INITIAL_ZOOM
+ self.NewMenu(None)
- # Load last opened files
+ # Load last opened files if any such records exist.
if os.path.exists(LAST_BRUSH_PATH):
file_path = open(LAST_BRUSH_PATH).readlines()[0].strip()
if os.path.exists(file_path):
@@ -124,10 +118,23 @@
return -1
return LEVEL_HEIGHT * int(world_x / TILE_SIZE) + int(world_y /
TILE_SIZE)
+ def NewMenu(self, widget):
+ self._view_x = 0
+ self._view_y = 0
+ self._view_zoom = INITIAL_ZOOM
+ self._tiles = [0] * LEVEL_WIDTH * LEVEL_HEIGHT
+ self._triggers = [None] * LEVEL_WIDTH * LEVEL_HEIGHT
+ self._current_file = None
+ self.SetCleanWindowTitle()
+ self.window.queue_draw()
+
def LoadLevelFromFile(self, file_path):
+ assert file_path
assert 0 == os.system('mkdir -p %s' % SETTINGS_DIR)
open(LAST_LEVEL_PATH, 'w').write(file_path)
+ self._current_file = file_path
+ self.SetCleanWindowTitle()
level_lines = open(file_path).readlines()
raw_tiles = level_lines[0].strip()
for tile in xrange(LEVEL_WIDTH * LEVEL_HEIGHT):
@@ -155,7 +162,6 @@
def LoadBrushesFromFile(self, file_path):
assert 0 == os.system('mkdir -p %s' % SETTINGS_DIR)
open(LAST_BRUSH_PATH, 'w').write(file_path)
-
self._brushes_surface = cairo.ImageSurface.create_from_png(file_path)
self.window.queue_draw()
@@ -164,22 +170,46 @@
if file_path:
self.LoadBrushesFromFile(file_path)
- def SaveLevelMenu(self, widget):
- file_path = self.ChooseSaveFile()
+ def SetDirtyWindowTitle(self):
+ if self._current_file:
+ window_title = self.window.get_title()
+ if window_title[0] != '*':
+ self.window.set_title('*' + self._current_file)
+ else:
+ self.window.set_title('*(Unsaved Level)')
+
+ def SetCleanWindowTitle(self):
+ if self._current_file:
+ self.window.set_title(self._current_file)
+ else:
+ self.window.set_title('(Unsaved Level)')
+
+ def SaveLevelToFile(self, file_path):
+ assert file_path
+ self._current_file = file_path
+ self.SetCleanWindowTitle()
+ level_string = map(lambda tile : '%c' % (tile + ord('a')), self._tiles)
+ level_file = open(file_path, 'w')
+ level_file.write(''.join(level_string))
+ for x in xrange(0, LEVEL_WIDTH):
+ for y in xrange(0, LEVEL_HEIGHT):
+ index = LEVEL_HEIGHT * x + y
+ trigger_string = self._triggers[index];
+ if trigger_string:
+ level_file.write('\n%d,%d,"%s"' % (x, y, trigger_string))
- assert 0 == os.system('mkdir -p %s' % SETTINGS_DIR)
- open(LAST_LEVEL_PATH, 'w').write(file_path)
+ def SaveLevelMenu(self, widget):
+ if self._current_file:
+ self.SaveLevelToFile(self._current_file)
+ else:
+ self.SaveLevelAsMenu(widget)
+ def SaveLevelAsMenu(self, widget):
+ file_path = self.ChooseSaveFile()
if file_path:
- level_string = map(lambda tile : '%c' % (tile + ord('a')),
self._tiles)
- level_file = open(file_path, 'w')
- level_file.write(''.join(level_string))
- for x in xrange(0, LEVEL_WIDTH):
- for y in xrange(0, LEVEL_HEIGHT):
- index = LEVEL_HEIGHT * x + y
- trigger_string = self._triggers[index];
- if trigger_string:
- level_file.write('\n%d,%d,"%s"' % (x, y, trigger_string))
+ assert 0 == os.system('mkdir -p %s' % SETTINGS_DIR)
+ open(LAST_LEVEL_PATH, 'w').write(file_path)
+ self.SaveLevelToFile(file_path)
def BrushesClickEvent(self, widget, event):
self._selected_brush = int(event.y / BRUSHES_ZOOM / TILE_SIZE)
@@ -218,10 +248,12 @@
self._tiles[tile_index] = self._selected_brush
self._triggers[tile_index] = None
self.window.queue_draw()
+ self.SetDirtyWindowTitle()
elif event.button == 3: # Right click.
trigger_editor_window = (
TriggerEditorWindow(self.window, self._triggers, tile_index))
self.window.queue_draw()
+ self.SetDirtyWindowTitle()
def TilesKeyEvent(self, widget, event):
if event.keyval == LEFT_KEY:
Modified: trunk/src/android/com/abb/ArticulatedEntity.java
==============================================================================
--- trunk/src/android/com/abb/ArticulatedEntity.java (original)
+++ trunk/src/android/com/abb/ArticulatedEntity.java Tue Mar 10 21:26:27
2009
@@ -138,7 +138,7 @@
* the part. */
public Matrix getPartTransformation(String part_name) {
Part part = findPartByName(part_name);
- Assert.assertNotNull("Unknown part name: " + part_name, part);
+ Assert.assertNotNull(part);
return part.transformation;
}
@@ -210,7 +210,7 @@
}
private float[] mTransformationData = new float[9];
- }
+ } // class Part
/** The Animation class stores and provides access to a independent, time
* varying set of values called tracks. */
@@ -332,7 +332,7 @@
private float mTime;
private TreeMap<String, ArrayList<KeyFrame>> mKeyFrames =
new TreeMap<String, ArrayList<KeyFrame>>();
- }
+ } // class Animation
private Animation mAnimation = new Animation();
private TreeMap<String, Animation> mAnimationCache =
Modified: trunk/src/android/com/abb/Avatar.java
==============================================================================
--- trunk/src/android/com/abb/Avatar.java (original)
+++ trunk/src/android/com/abb/Avatar.java Tue Mar 10 21:26:27 2009
@@ -30,6 +30,10 @@
@Override
public void step(float time_step) {
+ if (life <= 0.0f) {
+ return;
+ }
+
ddy = kGravity;
super.step(time_step);
@@ -48,8 +52,13 @@
// The following is a poor hack to simulate "friction" against the
ground
// surface. The problem with this implementation is that it does not
account
// for the time_step. TODO: Fix this friction implementation.
- if (has_ground_contact && ddx == 0.0f) {
- dx *= (1.0f - kGroundKineticFriction);
+ if (has_ground_contact) {
+ if (Math.abs(dx) > kMaxGroundVelocity) {
+ dx *= 0.9f;
+ }
+ if (ddx == 0.0f) {
+ dx *= (1.0f - kGroundKineticFriction);
+ }
}
// Update the avatar animation.
@@ -75,6 +84,8 @@
if (mWeapon != null) {
mWeapon.x = x;
mWeapon.y = y;
+ mWeapon.dx = dx;
+ mWeapon.dy = dy;
mWeapon.has_ground_contact = has_ground_contact;
mWeapon.sprite_flipped_horizontal = sprite_flipped_horizontal;
mWeapon.step(time_step);
@@ -84,6 +95,10 @@
@Override
public void draw(Graphics graphics, float center_x, float center_y,
float zoom) {
+ if (life <= 0.0f) {
+ return;
+ }
+
// We intercept the draw method only to get the canvas dimensions. The
// drawing buffer dimensions are used to interpret the touch events.
mCanvasWidth = graphics.getWidth();
@@ -108,7 +123,7 @@
}
// Draw the avatar life and ammo meters.
- float meter_width = mCanvasWidth / 2.0f;
+ float meter_width = mCanvasWidth - 45;
mRect.set(0, 0, 28, 13);
mRectF.set(0, 0, 28, 13);
graphics.drawImage(mGameState.misc_sprites, mRect, mRectF, false,
false);
@@ -116,7 +131,7 @@
float life_meter_width =
meter_width * life;
mRect.set(0, 16, 64, 20);
- mRectF.set(30, 0, 30 + life_meter_width, 6);
+ mRectF.set(30, 1, 30 + life_meter_width, 6);
graphics.drawImage(mGameState.misc_sprites, mRect, mRectF, false,
false);
}
if (mWeapon != null) {
@@ -124,12 +139,16 @@
meter_width * mWeapon.getAmmo() / mWeapon.getMaxAmmo();
ammo_meter_width = Math.max(ammo_meter_width, 0.0f);
mRect.set(0, 23, 64, 27);
- mRectF.set(30, 8, 30 + ammo_meter_width, 14);
+ mRectF.set(30, 8, 30 + ammo_meter_width, 12);
graphics.drawImage(mGameState.misc_sprites, mRect, mRectF, false,
false);
}
}
public void setKeyState(int key_code, int state) {
+ if (life <= 0.0f) {
+ return;
+ }
+
if (key_code == kKeyLeft) {
ddx = -kGroundAcceleration * state;
} else if (key_code == kKeyRight) {
@@ -145,6 +164,10 @@
}
public void onMotionEvent(MotionEvent motion_event) {
+ if (life <= 0.0f) {
+ return;
+ }
+
// We translate motion events into key events and then pass it onto
the key
// event handler. Note: Pressure and size measurements are also
available
// from the API, but aren't yet used here.
@@ -157,10 +180,8 @@
setKeyState(kKeyRight, 0);
setKeyState(kKeyJump, 0);
setKeyState(kKeyShoot, 0);
- motion_event.recycle();
return;
} else {
- motion_event.recycle();
return;
}
@@ -189,7 +210,6 @@
setKeyState(kKeyShoot, 1);
}
}
- motion_event.recycle();
}
void setWeapon(Weapon weapon) {
@@ -200,29 +220,30 @@
mWeapon = null;
}
- private int mCanvasWidth;
- private int mCanvasHeight;
+ private int mCanvasWidth;
+ private int mCanvasHeight;
private GameState mGameState;
- public Weapon mWeapon;
+ public Weapon mWeapon;
- // To avoid allocations:
+ // To avoid allocations...
private float[] mArray9 = new float[9];
- private Rect mRect = new Rect();
- private RectF mRectF = new RectF();
+ private Rect mRect = new Rect();
+ private RectF mRectF = new RectF();
- private static final float kAirAcceleration = 40.0f;
+ private static final float kAirAcceleration = 40.0f;
private static final float kAnimationStopThreshold = 40.0f;
- private static final float kDrawingScale = 0.4f;
- private static final float kGravity = 300.0f;
- private static final float kGroundAcceleration = 700.0f;
- private static final float kGroundAnimationSpeed = 1.0f / 1500.0f;
- private static final float kGroundKineticFriction = 0.3f;
- private static final float kJumpVelocity = 275.0f;
- private static final int kKeyLeft = KeyEvent.KEYCODE_A;
- private static final int kKeyRight = KeyEvent.KEYCODE_S;
- private static final int kKeyJump = KeyEvent.KEYCODE_K;
- private static final int kKeyShoot = KeyEvent.KEYCODE_J;
- private static final float kRadius = 25.0f;
- private static final int kSpriteSize = 64;
- private static final int kTouchMovementHeight = 30;
+ private static final float kDrawingScale = 0.4f;
+ private static final float kGravity = 300.0f;
+ private static final float kGroundAcceleration = 700.0f;
+ private static final float kGroundAnimationSpeed = 1.0f / 1500.0f;
+ private static final float kGroundKineticFriction = 0.3f;
+ private static final float kMaxGroundVelocity = 200.0f;
+ private static final float kJumpVelocity = 275.0f;
+ private static final int kKeyLeft = KeyEvent.KEYCODE_A;
+ private static final int kKeyRight = KeyEvent.KEYCODE_S;
+ private static final int kKeyJump = KeyEvent.KEYCODE_K;
+ private static final int kKeyShoot = KeyEvent.KEYCODE_J;
+ private static final float kRadius = 25.0f;
+ private static final int kSpriteSize = 64;
+ private static final int kTouchMovementHeight = 30;
}
Modified: trunk/src/android/com/abb/Enemy.java
==============================================================================
--- trunk/src/android/com/abb/Enemy.java (original)
+++ trunk/src/android/com/abb/Enemy.java Tue Mar 10 21:26:27 2009
@@ -34,12 +34,6 @@
super.step(time_step);
super.stepAnimation(time_step);
- // If we have moved close enough to our target, mark it dead.
- if (Math.abs(mTarget.x - x) < radius && Math.abs(mTarget.y - y) <
radius) {
- mTarget.life -= mDamage;
- life -= mDamage;
- }
-
// If the target has moved far enough away from this entity, destroy
it.
// This may happen if the client leaves an enemy behind on the map. We
want
// to release resources allocated to it.
@@ -90,7 +84,7 @@
// Now that the user defined enemy parameters have been parsed and
merged,
// we can initialize the enemy instance state accordingly.
mAcceleration =
((Float)parameters.get(kParameterAcceleration)).floatValue();
- mDamage = ((Float)parameters.get(kParameterDamage)).floatValue();
+ damage = ((Float)parameters.get(kParameterDamage)).floatValue();
setDrawingScale(((Float)parameters.get(kParameterDrawingScale)).floatValue());
mGravity = ((Float)parameters.get(kParameterGravity)).floatValue();
life = ((Float)parameters.get(kParameterLife)).floatValue();
@@ -108,28 +102,29 @@
return super.clone();
}
+ public float damage;
+
private float mAcceleration;
- private float mDamage;
private float mGravity;
private float mJumpVelocity;
private Entity mTarget;
private static final float kDefaultAcceleration = 40.0f;
- private static final float kDefaultDamage = 0.34f;
+ private static final float kDefaultDamage = 0.34f;
private static final float kDefaultDrawingScale = 1.0f;
private static final float kDefaultJumpVelocity = 100.0f;
- private static final float kDefaultGravity = 100.0f;
- private static final float kDefaultLife = 1.0f;
- private static final float kDefaultRadius = 32.0f;
- private static final float kRange = 1000.0f;
+ private static final float kDefaultGravity = 100.0f;
+ private static final float kDefaultLife = 1.0f;
+ private static final float kDefaultRadius = 32.0f;
+ private static final float kRange = 1000.0f;
private static final String kParameterAcceleration = "acceleration";
- private static final String kParameterAnimation = "animation";
- private static final String kParameterDamage = "damage";
+ private static final String kParameterAnimation = "animation";
+ private static final String kParameterDamage = "damage";
private static final String kParameterDrawingScale = "drawing_scale";
- private static final String kParameterEntity = "entity";
+ private static final String kParameterEntity = "entity";
private static final String kParameterJumpVelocity = "jump_velocity";
- private static final String kParameterGravity = "gravity";
- private static final String kParameterLife = "life";
- private static final String kParameterRadius = "radius";
+ private static final String kParameterGravity = "gravity";
+ private static final String kParameterLife = "life";
+ private static final String kParameterRadius = "radius";
}
Modified: trunk/src/android/com/abb/Entity.java
==============================================================================
--- trunk/src/android/com/abb/Entity.java (original)
+++ trunk/src/android/com/abb/Entity.java Tue Mar 10 21:26:27 2009
@@ -11,23 +11,26 @@
package android.com.abb;
-import android.graphics.Canvas;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.RectF;
import java.lang.CloneNotSupportedException;
import java.lang.Math;
import java.util.Random;
+import java.util.Stack;
/** The Entity class is intended to be lowest level, drawable, physical
in-game
- * object. */
+ * object. For example weapon projectiles, blood particles, and the avatar
are
+ * represented by Entities. */
public class Entity implements Cloneable {
+ public float damage;
public boolean has_ground_contact;
- public float life = 1.0f;
+ public boolean is_flame;
+ public float life = 1.0f;
public float radius;
- public int sprite_image;
- public Rect sprite_rect;
+ public int sprite_image = -1;
+ public Rect sprite_rect = new Rect();
public boolean sprite_flipped_horizontal;
public boolean sprite_flipped_vertical;
@@ -38,6 +41,19 @@
public float ddx; // Acceleration.
public float ddy;
+ public Entity reset() {
+ damage = 0.0f;
+ has_ground_contact = false;
+ is_flame = false;
+ life = 1.0f;
+ radius = 0.0f;
+ sprite_image = -1;
+ sprite_flipped_horizontal = false;
+ sprite_flipped_vertical = false;
+ x = y = dx = dy = ddx = ddy = 0.0f;
+ return this;
+ }
+
public void stop() {
dx = dy = ddx = ddy = 0.0f;
}
@@ -48,10 +64,19 @@
dx += ddx * time_step;
dy += ddy * time_step;
- dx = Math.max(dx, -kMaxVelocity);
- dx = Math.min(dx, kMaxVelocity);
- dy = Math.max(dy, -2.0f * kMaxVelocity);
- dy = Math.min(dy, 2.0f * kMaxVelocity);
+ dx = Math.min(Math.max(dx, -kMaxHorizontalVelocity),
kMaxHorizontalVelocity);
+ dy = Math.min(Math.max(dy, -kMaxVerticalVelocity),
kMaxVerticalVelocity);
+
+ // Flames are a special case of the Entity class. For performance
reasons it
+ // is benefitial to share a free-list with normal projectiles, but the
+ // sprite animation requires extra handling.
+ if (is_flame) {
+ int frame = (int)(kFlameFrames - life * kFlameFrameRate);
+ sprite_rect.left = 0;
+ sprite_rect.right = kFlameSpriteWidth;
+ sprite_rect.top = kFlameSpriteBase + kFlameSpriteHeight * frame;
+ sprite_rect.bottom = kFlameSpriteBase + kFlameSpriteHeight * (frame
+ 1);
+ }
}
/** Draw the entity to the canvas such that the specified coordinates are
@@ -80,6 +105,18 @@
Math.abs(entity.y - y) < radius + entity.radius);
}
+ static public Entity obtain() {
+ if (!mFreeList.empty()) {
+ return mFreeList.pop().reset();
+ } else {
+ return new Entity();
+ }
+ }
+
+ public void release() {
+ mFreeList.push(this);
+ }
+
@Override
public Object clone() {
try {
@@ -92,7 +129,15 @@
// The following allocations are made here to avoid allocating anything
during
// the game. They are intended to be used by this an any child class.
protected static Random mRandom = new Random();
- protected static RectF mRectF = new RectF();
+ protected static RectF mRectF = new RectF();
+
+ static private Stack<Entity> mFreeList = new Stack<Entity>();
- private static final float kMaxVelocity = 200.0f;
+ private static final int kFlameFrames = 13;
+ private static final float kFlameFrameRate = 10.0f; // Frames /
sec.
+ private static final int kFlameSpriteBase = 521;
+ private static final int kFlameSpriteWidth = 64;
+ private static final int kFlameSpriteHeight = 36;
+ private static final float kMaxHorizontalVelocity = 300.0f;
+ private static final float kMaxVerticalVelocity = 400.0f;
}
Modified: trunk/src/android/com/abb/GameState.java
==============================================================================
--- trunk/src/android/com/abb/GameState.java (original)
+++ trunk/src/android/com/abb/GameState.java Tue Mar 10 21:26:27 2009
@@ -21,6 +21,7 @@
import android.os.Bundle;
import android.os.Vibrator;
import android.util.Log;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import java.util.ArrayList;
import java.util.Iterator;
@@ -30,12 +31,12 @@
public class GameState implements Game {
- public Avatar avatar = new Avatar(this);
- public ArrayList<Enemy> enemies = new ArrayList<Enemy>();
- public Map map = new Map(this);
- public int misc_sprites;
- public ArrayList<Entity> particles = new ArrayList<Entity>();
- public ArrayList<Projectile> projectiles = new ArrayList<Projectile>();
+ public Avatar avatar = new Avatar(this);
+ public ArrayList<Enemy> enemies = new ArrayList<Enemy>();
+ public Map map = new Map(this);
+ public int misc_sprites;
+ public ArrayList<Entity> particles = new ArrayList<Entity>();
+ public ArrayList<Entity> projectiles = new ArrayList<Entity>();
public GameState(Context context) {
mContext = context;
@@ -67,6 +68,12 @@
}
public boolean onKeyDown(int key_code) {
+ // Developement level navigation.
+ if (key_code == KeyEvent.KEYCODE_B) {
+ map.advanceLevel();
+ avatar.life = 0.0f;
+ }
+
avatar.setKeyState(key_code, 1);
return false; // False to indicate not handled.
}
@@ -137,7 +144,14 @@
Enemy enemy = enemies.get(index);
enemy.step(time_step);
map.collideEntity(enemy);
+ if (enemy.collidesWith(avatar) && avatar.life > 0.0f) {
+ avatar.life -= enemy.damage;
+ enemy.life = 0.0f;
+ vibrate(kEnemyAttackVibrateLength);
+ createBloodParticle(avatar.x, avatar.y, enemy.dx, enemy.dy);
+ }
if (enemy.life <= 0.0f) {
+ enemies.remove(index);
vibrate(kEnemyDeathVibrateLength);
for (int n = 0; n < kBloodBathSize; n++) {
createBloodParticle(
@@ -145,26 +159,27 @@
kBloodBathVelocity * (0.5f - mRandom.nextFloat()) + enemy.dx,
kBloodBathVelocity * (0.5f - mRandom.nextFloat()) +
enemy.dy);
}
- enemies.remove(index);
}
}
// Step the projectiles and collide them against the enemies.
for (int index = 0; index < projectiles.size(); ++index) {
- Projectile projectile = projectiles.get(index);
+ Entity projectile = projectiles.get(index);
projectile.step(time_step);
projectile.life -= time_step;
for (int enemy_index = 0; enemy_index < enemies.size();
++enemy_index) {
Enemy enemy = enemies.get(enemy_index);
if (projectile.collidesWith(enemy)) {
- createBloodParticle(
- enemy.x, enemy.y, projectile.dx / 2.0f, projectile.dy /
2.0f);
+ createBloodParticle((enemy.x + projectile.x) / 2.0f,
+ (enemy.y + projectile.y) / 2.0f,
+ projectile.dx / 2.0f, projectile.dy / 2.0f);
projectile.life = 0.0f;
enemy.life -= projectile.damage;
break;
}
}
if (projectile.life <= 0.0f) {
+ projectile.release();
projectiles.remove(index);
}
}
@@ -172,8 +187,10 @@
// Step the particles.
for (int index = 0; index < particles.size(); ++index) {
Entity particle = particles.get(index);
+ particle.life -= time_step;
particle.step(time_step);
if (particle.life <= 0.0f) {
+ particle.release();
particles.remove(index);
}
}
@@ -191,9 +208,7 @@
}
// Draw the avatar.
- if (avatar.life > 0.0f) {
- avatar.draw(graphics, mViewX, mViewY, mZoom);
- }
+ avatar.draw(graphics, mViewX, mViewY, mZoom);
// Draw the projectiles.
for (int index = 0; index < projectiles.size(); ++index) {
@@ -207,11 +222,11 @@
}
synchronized public void addNotification(String notification) {
- pending_notifications_.add(notification);
+ mPendingNotifications.add(notification);
}
synchronized public String getPendingNotification() {
- return pending_notifications_.poll();
+ return mPendingNotifications.poll();
}
public Entity createEnemyFromUri(Uri uri, float x, float y) {
@@ -230,8 +245,17 @@
}
public Entity createBloodParticle(float x, float y, float dx, float dy) {
- Entity blood = new Blood();
+ final float kTimeRemaining = 0.75f; // Seconds.
+ final int kSpriteBase = 1 * 64;
+ final int kSpriteWidth = 64;
+ final int kSpriteHeight = 64;
+
+ Entity blood = Entity.obtain();
+ blood.sprite_rect.set(
+ 0, kSpriteBase, kSpriteWidth, kSpriteBase + kSpriteHeight);
+ blood.sprite_flipped_horizontal = mRandom.nextBoolean();
blood.sprite_image = misc_sprites;
+ blood.life = kTimeRemaining;
blood.x = x;
blood.y = y;
blood.dx = dx;
@@ -255,7 +279,7 @@
float timeout, float damage,
int image_handle, Rect image_rect,
boolean sprite_flipped_horizontal) {
- Projectile projectile = new Projectile();
+ Entity projectile = Entity.obtain();
projectile.x = x;
projectile.y = y;
projectile.dx = dx;
@@ -263,26 +287,35 @@
projectile.life = timeout;
projectile.damage = damage;
projectile.sprite_image = image_handle;
- projectile.sprite_rect = image_rect;
+ projectile.sprite_rect.set(image_rect);
projectile.sprite_flipped_horizontal = sprite_flipped_horizontal;
projectile.radius = Math.min(image_rect.width(), image_rect.height());
projectiles.add(projectile);
}
- public Entity createFireProjectile(float x, float y, float dx, float dy)
{
- Projectile fire = new Fire();
+ public Entity createFireProjectile(float x, float y, float dx, float dy,
+ float damage,
+ boolean sprite_flipped_horizontal) {
+ Entity fire = Entity.obtain();
fire.sprite_image = misc_sprites;
fire.x = x;
fire.y = y;
fire.dx = dx;
fire.dy = dy;
fire.ddy = -50.0f; // Give fire a slight "up draft".
- fire.life = 100.0f; // Let the fire class choose its own death.
- fire.damage = 0.2f;
+ fire.life = 1.3f;
+ fire.damage = damage;
+ fire.is_flame = true;
+ fire.radius = 3.0f;
+ fire.sprite_flipped_horizontal = sprite_flipped_horizontal;
projectiles.add(fire);
return fire;
}
+ public Entity createFireProjectile(float x, float y, float dx, float dy)
{
+ return createFireProjectile(x, y, dx, dy, 0.2f, false);
+ }
+
public void vibrate(long vibrate_milliseconds) {
mVibrator.vibrate(vibrate_milliseconds);
}
@@ -328,29 +361,30 @@
return saved_instance_state;
}
- private Context mContext;
- private float mDeathTimer = kDeathTimer;
- private TreeMap<Uri, Enemy> mEnemyCache = new TreeMap<Uri, Enemy>();
- private LinkedList<String> pending_notifications_ = new
LinkedList<String>();
- private Random mRandom = new Random();
- private float mTargetViewX = 0.0f;
- private float mTargetViewY = 0.0f;
- private float mTargetZoom = kGroundZoom;
- private Vibrator mVibrator;
- private float mViewX = 0.0f;
- private float mViewY = 0.0f;
- private TreeMap<Uri, Weapon> mWeaponCache = new TreeMap<Uri, Weapon>();
- private float mZoom = kGroundZoom;
-
- private static final float kAirZoom = 0.6f;
- private static final int kBloodBathSize = 20; // Number of blood
particles.
- private static final float kBloodBathVelocity = 60.0f;
- private static final float kDeathTimer = 4.0f;
- private static final float kDeathZoom = 1.5f;
- private static final float kGravity = 200.0f;
- private static final float kGroundZoom = 0.8f;
- private static final long kEnemyDeathVibrateLength = 30; //
Milliseconds.
- private static final float kViewLead = 1.0f;
- private static final float kViewSpeed = 2.0f;
- private static final float kZoomSpeed = 1.0f;
+ private Context mContext;
+ private float mDeathTimer = kDeathTimer;
+ private TreeMap<Uri, Enemy> mEnemyCache = new TreeMap<Uri,
Enemy>();
+ private LinkedList<String> mPendingNotifications = new
LinkedList<String>();
+ private Random mRandom = new Random();
+ private float mTargetViewX = 0.0f;
+ private float mTargetViewY = 0.0f;
+ private float mTargetZoom = kGroundZoom;
+ private Vibrator mVibrator;
+ private float mViewX = 0.0f;
+ private float mViewY = 0.0f;
+ private TreeMap<Uri, Weapon> mWeaponCache = new TreeMap<Uri,
Weapon>();
+ private float mZoom = kGroundZoom;
+
+ private static final float kAirZoom = 0.6f;
+ private static final int kBloodBathSize = 20; // Particle
count.
+ private static final float kBloodBathVelocity = 60.0f;
+ private static final float kDeathTimer = 3.0f;
+ private static final float kDeathZoom = 1.5f;
+ private static final long kEnemyAttackVibrateLength = 50; //
Milliseconds.
+ private static final long kEnemyDeathVibrateLength = 30; //
Milliseconds.
+ private static final float kGravity = 200.0f;
+ private static final float kGroundZoom = 0.8f;
+ private static final float kViewLead = 1.0f;
+ private static final float kViewSpeed = 2.0f;
+ private static final float kZoomSpeed = 1.0f;
}
Modified: trunk/src/android/com/abb/GameView.java
==============================================================================
--- trunk/src/android/com/abb/GameView.java (original)
+++ trunk/src/android/com/abb/GameView.java Tue Mar 10 21:26:27 2009
@@ -243,6 +243,7 @@
synchronized (mGame) {
mGame.onMotionEvent(event);
}
+ event.recycle();
return true;
}
@@ -300,15 +301,15 @@
}
}
- private Context mContext;
- private Game mGame;
- private GameThread mGameThread;
- private boolean mGameThreadStarted = false;
- private Handler mHandler;
+ private Context mContext;
+ private Game mGame;
+ private GameThread mGameThread;
+ private boolean mGameThreadStarted;
+ private Handler mHandler;
private ProgressDialog mLoadingDialog;
- private boolean mProfiling = false;
+ private boolean mProfiling;
- private static final int kNotificationMessage = 666;
- private static final int kProfileKey = KeyEvent.KEYCODE_T;
- private static final String kProfilePath = "abb.trace";
+ private static final int kNotificationMessage = 666;
+ private static final int kProfileKey = KeyEvent.KEYCODE_T;
+ private static final String kProfilePath = "abb.trace";
}
Modified: trunk/src/android/com/abb/Graphics.java
==============================================================================
--- trunk/src/android/com/abb/Graphics.java (original)
+++ trunk/src/android/com/abb/Graphics.java Tue Mar 10 21:26:27 2009
@@ -29,6 +29,7 @@
import java.nio.IntBuffer;
import java.nio.FloatBuffer;
import java.util.ArrayList;
+import java.util.TreeMap;
import java.util.Vector;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGL11; // For EGL_CONTEXT_LOST
constant.
@@ -124,13 +125,23 @@
Assert.assertNotNull(
"Null bitmap specified in LoadImageFromBitmap", bitmap);
- switch (mBackendType) {
- case ANDROID2D:
- return loadImageFromBitmapAndroid2D(bitmap);
- case OPENGL:
- return loadImageFromBitmapOpenGL(bitmap);
+ int bitmap_hash = hashBitmap(bitmap);
+ Integer cached_image_handle = mImageCache.get(new
Integer(bitmap_hash));
+ if (cached_image_handle != null) {
+ return cached_image_handle.intValue();
+ } else {
+ int image_handle = -1;
+ switch (mBackendType) {
+ case ANDROID2D:
+ image_handle = loadImageFromBitmapAndroid2D(bitmap);
+ break;
+ case OPENGL:
+ image_handle = loadImageFromBitmapOpenGL(bitmap);
+ break;
+ }
+ mImageCache.put(new Integer(bitmap_hash), new Integer(image_handle));
+ return image_handle;
}
- return -1;
}
public void freeImage(int image_handle) {
@@ -283,22 +294,38 @@
* Private shared methods and state.
*/
- void determineBackendType() {
+ private void determineBackendType() {
// Determine which rendering back-end to use based off of the system
setup,
- // specifically the presence of rendering hardware. OpenGL appears to
be
+ // specifically the presence of any rendering hardware. OpenGL appears
to be
// faster on both the Emulator and the HTC Dream handset than the
Android2D
// back end. The software OpenGL rasterizer is faster than the
Android2D
// graphics API so it should be preferred in nearly all situations.
However,
// when using either software back-end, pixel fill rate has been
- // experimentally been shown to be bottleneck.
+ // experimentally been shown to be a bottleneck.
mBackendType = BackendType.OPENGL;
}
+ /** Determine a (generally) unique hash code from a Bitmap reference.
This is
+ * intended to be used to quickly identify exact images while only
examining a
+ * small subset of the pixels. */
+ static private int hashBitmap(Bitmap bitmap) {
+ int hash_result = 0;
+ hash_result = (hash_result << 7) ^ bitmap.getHeight();
+ hash_result = (hash_result << 7) ^ bitmap.getWidth();
+ for (int pixel = 0; pixel < 20; ++pixel) {
+ int x = (pixel * 50) % bitmap.getWidth();
+ int y = (pixel * 100) % bitmap.getHeight();
+ hash_result = (hash_result << 7) ^ bitmap.getPixel(x, y);
+ }
+ return hash_result;
+ }
+
private enum BackendType { ANDROID2D, OPENGL }
- private BackendType mBackendType;
- private SurfaceHolder mSurfaceHolder;
- private int mSurfaceHeight;
- private int mSurfaceWidth;
+ private BackendType mBackendType;
+ private TreeMap<Integer, Integer> mImageCache = new TreeMap<Integer,
Integer>();
+ private SurfaceHolder mSurfaceHolder;
+ private int mSurfaceHeight;
+ private int mSurfaceWidth;
/**
* Private Android 2D backend methods and state.
@@ -364,10 +391,10 @@
Assert.fail("Method not yet implemented.");
}
- private Canvas mCanvasAndroid2D;
+ private Canvas mCanvasAndroid2D;
private ArrayList<Bitmap> mImagesAndroid2D = new ArrayList<Bitmap>();
- private Paint mPaintAndroid2D = new Paint();
- private Matrix mTransformationAndroid2D = new Matrix();
+ private Paint mPaintAndroid2D = new Paint();
+ private Matrix mTransformationAndroid2D = new Matrix();
/**
* Private OpenGL backend methods and state.
@@ -609,22 +636,22 @@
}
}
- private int mCurrentTexture = -1;
- private Vector<Integer> mTextureWidths = new Vector<Integer>();
+ private int mCurrentTexture = -1;
+ private Vector<Integer> mTextureWidths = new Vector<Integer>();
private Vector<Integer> mTextureHeights = new Vector<Integer>();
- private EGL10 mEgl;
- private EGLConfig mEglConfig;
- private EGLContext mEglContext;
- private EGLDisplay mEglDisplay;
- private EGLSurface mEglSurface;
- private GL10 mGl;
- private boolean mGlStateInitialized = false;
- private boolean mGlSurfaceInitialized = false;
- private boolean mHasHardwareAcceleration = false;
+ private EGL10 mEgl;
+ private EGLConfig mEglConfig;
+ private EGLContext mEglContext;
+ private EGLDisplay mEglDisplay;
+ private EGLSurface mEglSurface;
+ private GL10 mGl;
+ private boolean mGlStateInitialized;
+ private boolean mGlSurfaceInitialized;
+ private boolean mHasHardwareAcceleration;
// The following matrix definitions are used to avoid any allocations
within
// the draw methods.
- private Matrix mScreenMatrix = new Matrix();
+ private Matrix mScreenMatrix = new Matrix();
private float[] mMatrix3x3 = new float[] {
1, 0, 0, 0, 1, 0, 0, 0, 1 };
private float[] mMatrix4x4 = new float[] {
Modified: trunk/src/android/com/abb/Map.java
==============================================================================
--- trunk/src/android/com/abb/Map.java (original)
+++ trunk/src/android/com/abb/Map.java Tue Mar 10 21:26:27 2009
@@ -61,19 +61,21 @@
// Maps are organized into package where each package is its own set of
// (ordered) levels, tiles, and tile definitions.
- // Load level tiles.
+ // Load level layout.
Uri level_uri =
Uri.withAppendedPath(mBaseUri, "level_" + mLevelOffset + ".txt");
String level_path = Content.getTemporaryFilePath(level_uri);
loadLevelFromFile(level_path);
- // Load level tile images.
+ // Load tile images.
Uri tiles_uri =
- Uri.withAppendedPath(mBaseUri, "tiles_" + mLevelOffset + ".png");
+ Uri.withAppendedPath(mBaseUri, "tiles_" + mLevelOffset + ".txt");
if (!Content.exists(tiles_uri))
- tiles_uri = Uri.withAppendedPath(mBaseUri, "tiles_default.png");
+ tiles_uri = Uri.withAppendedPath(mBaseUri, "tiles_default.txt");
String tiles_path = Content.getTemporaryFilePath(tiles_uri);
- loadTilesFromFile(tiles_path);
+ String tiles_image_path = Content.getTemporaryFilePath(
+ Uri.withAppendedPath(mBaseUri,
getTilesFromReferenceFile(tiles_path)));
+ loadTilesFromFile(tiles_image_path);
// Load tile effects.
Uri effects_uri =
@@ -108,6 +110,16 @@
}
}
+ public String getTilesFromReferenceFile(String file_path) {
+ if (file_path == null) {
+ Log.e("Map::loadTilesFromReferenceFile", "Invalid null argument.");
+ }
+ String[] tiles_file = Content.readFileTokens(file_path);
+ Assert.assertEquals("Map::loadTilesFromReferenceFile: Tiles file " +
+ "improperly formatted.", tiles_file.length, 1);
+ return tiles_file[0];
+ }
+
public void loadTilesFromFile(String file_path) {
if (file_path == null) {
Log.e("Map::loadTilesFromFile", "Invalid null argument.");
@@ -422,30 +434,30 @@
return saved_instance_state;
}
- private Uri mBaseUri;
+ private Uri mBaseUri;
private boolean[] mEffectsDeath;
private boolean[] mEffectsExplode;
private boolean[] mEffectsSolid;
private GameState mGameState;
- private int mLevelOffset = 0; // Level within the mBaseUri map package.
- private Random mRandom = new Random();
- private Rect mRectSource = new Rect();
- private RectF mRectDest = new RectF();
- private float mStartingX;
- private float mStartingY;
- private char[] mTiles;
- private Bitmap mTilesBitmap;
- private int mTilesImage = -1;
- private String[] mTriggers;
-
- private static final char kBaseValue = 'a';
- private static final int kEndingTile = 11;
- private static final int kExplodeVibrateLength = 40;
- private static final int kExplosionSize = 15; // Number of particles.
- private static final float kExplosionStrength = 200.0f;
- private static final int kMapHeight = 100;
- private static final int kMapWidth = 100;
- private static final int kMaxTileCount = 25;
- private static final int kStartingTile = 10;
- private static final int kTileSize = 64;
+ private int mLevelOffset = 0; // Level within the mBaseUri
package.
+ private Random mRandom = new Random();
+ private Rect mRectSource = new Rect();
+ private RectF mRectDest = new RectF();
+ private float mStartingX;
+ private float mStartingY;
+ private char[] mTiles;
+ private Bitmap mTilesBitmap;
+ private int mTilesImage = -1;
+ private String[] mTriggers;
+
+ private static final char kBaseValue = 'a';
+ private static final int kEndingTile = 11;
+ private static final int kExplodeVibrateLength = 40;
+ private static final int kExplosionSize = 15; // Particle
count.
+ private static final float kExplosionStrength = 200.0f;
+ private static final int kMapHeight = 100;
+ private static final int kMapWidth = 100;
+ private static final int kMaxTileCount = 25;
+ private static final int kStartingTile = 10;
+ private static final int kTileSize = 64;
}
Modified: trunk/src/android/com/abb/Weapon.java
==============================================================================
--- trunk/src/android/com/abb/Weapon.java (original)
+++ trunk/src/android/com/abb/Weapon.java Tue Mar 10 21:26:27 2009
@@ -45,6 +45,7 @@
parameters.put(kParameterProjectileRectLeft, new Integer(-1));
parameters.put(kParameterProjectileRectRight, new Integer(-1));
parameters.put(kParameterProjectileRectTop, new Integer(-1));
+ parameters.put(kParameterProjectileType, kDefaultProjectileType);
parameters.put(kParameterSpread, new Float(kDefaultSpread));
parameters.put(kParameterSprite, "none");
parameters.put(kParameterTimeout, new Float(kDefaultTimeout));
@@ -82,6 +83,7 @@
mAmmo = ((Integer)parameters.get(kParameterAmmo)).intValue();
mDamage = ((Float)parameters.get(kParameterDamage)).floatValue();
mDelay = ((Float)parameters.get(kParameterDelay)).floatValue();
+ mProjectileIsFlame =
parameters.get(kParameterProjectileType).equals("flame");
mSpread = ((Float)parameters.get(kParameterSpread)).floatValue();
mTimeout = ((Float)parameters.get(kParameterTimeout)).floatValue();
mVelocity = ((Float)parameters.get(kParameterVelocity)).floatValue();
@@ -131,7 +133,7 @@
float y_offset = -10.0f;
if (!has_ground_contact) {
- shot_angle = mPhase;
+ shot_angle = 6.28319f * mRandom.nextFloat();
x_offset = shot_distance * (float)Math.cos(shot_angle);
y_offset = shot_distance * (float)Math.sin(shot_angle);
} else {
@@ -146,11 +148,17 @@
dx_offset *= -1.0f;
}
- mGameState.createProjectile(x + x_offset, y + y_offset,
- dx + dx_offset, dy + dy_offset,
- mTimeout, mDamage,
- sprite_image, mProjectileRect,
- sprite_flipped_horizontal);
+ if (mProjectileIsFlame) {
+ mGameState.createFireProjectile(x + x_offset, y + y_offset,
+ dx + dx_offset, dy + dy_offset,
+ mDamage,
sprite_flipped_horizontal);
+ } else {
+ mGameState.createProjectile(x + x_offset, y + y_offset,
+ dx + dx_offset, dy + dy_offset,
+ mTimeout, mDamage,
+ sprite_image, mProjectileRect,
+ sprite_flipped_horizontal);
+ }
if (mVibration > 0) {
mGameState.vibrate(mVibration);
@@ -195,45 +203,48 @@
return super.clone();
}
- private int mAmmo;
- private float mCurrentDelay;
- private float mDamage;
- private float mDelay;
+ private int mAmmo;
+ private float mCurrentDelay;
+ private float mDamage;
+ private float mDelay;
private static Matrix mDrawingMatrix = new Matrix();
- private GameState mGameState; // Needed for projectile instantiation.
- private int mMaxAmmo = 25;
- private float mPhase;
- private Rect mProjectileRect;
- private boolean mShooting;
- private float mSpread;
- private Uri mSpriteUri;
- private float mTimeout;
- private float mVelocity;
- private int mVibration;
-
- private static final int kDefaultAmmo = 0;
- private static final float kDefaultDamage = 0.0f;
- private static final float kDefaultDelay = 0.2f; // Seconds between
shots.
- private static final float kDefaultSpread = 15.0f * (float)Math.PI /
180.0f;
- private static final float kDefaultTimeout = 1.0f; // Seconds.
- private static final float kDefaultVelocity = 60.0f;
- private static final int kDefaultVibration = 0;
-
- private static final String kParameterAmmo = "ammo";
- private static final String kParameterDamage = "damage";
- private static final String kParameterDelay = "delay";
+ private GameState mGameState;
+ private int mMaxAmmo = 25;
+ private float mPhase;
+ private boolean mProjectileIsFlame;
+ private Rect mProjectileRect;
+ private boolean mShooting;
+ private float mSpread;
+ private Uri mSpriteUri;
+ private float mTimeout;
+ private float mVelocity;
+ private int mVibration;
+
+ private static final int kDefaultAmmo = 0;
+ private static final float kDefaultDamage = 0.0f;
+ private static final float kDefaultDelay = 0.2f; // Seconds.
+ private static final String kDefaultProjectileType = "normal";
+ private static final float kDefaultSpread = 0.262f;
+ private static final float kDefaultTimeout = 1.0f; // Seconds.
+ private static final float kDefaultVelocity = 60.0f;
+ private static final int kDefaultVibration = 0;
+
+ private static final String kParameterAmmo = "ammo";
+ private static final String kParameterDamage = "damage";
+ private static final String kParameterDelay = "delay";
private static final String kParameterProjectileRectBottom
= "projectile_rect_bottom";
- private static final String kParameterProjectileRectLeft
= "projectile_rect_left";
- private static final String kParameterProjectileRectRight
= "projectile_rect_right";
- private static final String kParameterProjectileRectTop
= "projectile_rect_top";
- private static final String kParameterSpread = "spread";
- private static final String kParameterSprite = "sprite";
- private static final String kParameterTimeout = "timeout";
- private static final String kParameterWeaponRectBottom
= "weapon_rect_bottom";
- private static final String kParameterWeaponRectLeft
= "weapon_rect_left";
- private static final String kParameterWeaponRectRight
= "weapon_rect_right";
- private static final String kParameterWeaponRectTop = "weapon_rect_top";
- private static final String kParameterVerticalSpread = "vertical_spread";
- private static final String kParameterVelocity = "velocity";
- private static final String kParameterVibration = "vibration";
+ private static final String kParameterProjectileRectLeft
= "projectile_rect_left";
+ private static final String kParameterProjectileRectRight
= "projectile_rect_right";
+ private static final String kParameterProjectileRectTop
= "projectile_rect_top";
+ private static final String kParameterProjectileType
= "projectile_type";
+ private static final String kParameterSpread = "spread";
+ private static final String kParameterSprite = "sprite";
+ private static final String kParameterTimeout = "timeout";
+ private static final String kParameterWeaponRectBottom
= "weapon_rect_bottom";
+ private static final String kParameterWeaponRectLeft
= "weapon_rect_left";
+ private static final String kParameterWeaponRectRight
= "weapon_rect_right";
+ private static final String kParameterWeaponRectTop
= "weapon_rect_top";
+ private static final String kParameterVerticalSpread
= "vertical_spread";
+ private static final String kParameterVelocity = "velocity";
+ private static final String kParameterVibration = "vibration";
}