From 2a46837b2c28586829ebb66df62e4a0a385c54e2 Mon Sep 17 00:00:00 2001 From: "oskar.wiksten" Date: Mon, 17 Oct 2011 22:39:05 +0000 Subject: [PATCH] Smoother combat animations. Load maps resources of adjacent maps in the background while on a map (reduces load times when changing maps) Bugfix: Shop max hp and max ap on player overview screen. Bump version number to beta3. git-svn-id: https://andors-trail.googlecode.com/svn/trunk@185 08aca716-68be-ccc6-4d58-36f5abd142ac --- AndorsTrail/AndroidManifest.xml | 2 +- .../res/values/content_conversationlist.xml | 2 +- .../AndorsTrail/AndorsTrailApplication.java | 2 +- .../activity/HeroinfoActivity_Stats.java | 2 +- .../controller/ActorStatsController.java | 6 +- .../controller/CombatController.java | 103 ++++++++----- .../AndorsTrail/controller/Controller.java | 1 - .../controller/MovementController.java | 2 + .../controller/VisualEffectController.java | 141 +++++++++++------- .../resource/tiles/TileManager.java | 46 +++++- .../gpl/rpg/AndorsTrail/view/MainView.java | 21 ++- 11 files changed, 214 insertions(+), 114 deletions(-) diff --git a/AndorsTrail/AndroidManifest.xml b/AndorsTrail/AndroidManifest.xml index f53c0f8..28e0928 100644 --- a/AndorsTrail/AndroidManifest.xml +++ b/AndorsTrail/AndroidManifest.xml @@ -4,7 +4,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" package="com.gpl.rpg.AndorsTrail" android:versionCode="25" - android:versionName="0.6.10b2" + android:versionName="0.6.10b3" android:installLocation="auto" > { @Override - public void run() { - while (isAlive) { - update(); - try { - sleep(8); - } catch (InterruptedException e) { - isAlive = false; - } - } - view.redrawArea(area, MainView.REDRAW_AREA_EFFECT_COMPLETED); - VisualEffectController.this.currentEffect = null; + protected Void doInBackground(Void... arg0) { + final int sleepInterval = effect.millisecondPerFrame / 2; + try { + while (isAlive) { + update(); + Thread.sleep(sleepInterval); + if (isCancelled()) return null; + } + Thread.sleep(effect.millisecondPerFrame); + } catch (InterruptedException e) { } + + return null; } - public void killjoin() { + @Override + protected void onCancelled() { isAlive = false; - safejoin(); - } - public void safejoin() { - try { - join(); - } catch (InterruptedException e) {} } + + public void killjoin() { this.cancel(true); } + private void update() { int elapsed = (int)(System.currentTimeMillis() - startTime); if (elapsed > effect.duration) { @@ -61,24 +61,66 @@ public final class VisualEffectController { return; } - int currentFrame = (int) Math.floor((float)elapsed / effect.millisecondPerFrame); - setCurrentTile(currentFrame); - } + int currentFrame = (int) Math.floor(elapsed / effect.millisecondPerFrame); + + if (currentFrame > effect.lastFrame) currentFrame = effect.lastFrame; + if (currentFrame < 0) currentFrame = 0; + final boolean changed = currentFrame != this.lastFrame; + if (!changed) return; + + this.lastFrame = currentFrame; + this.publishProgress(currentFrame); + } + + @Override + protected void onProgressUpdate(Integer... progress) { + super.onProgressUpdate(progress); + redrawFrame(progress[0]); + } + private void redrawFrame(int frame) { + int tileID = effect.frameIconIDs[frame]; + int textYOffset = -2 * (frame); + if (frame >= beginFadeAtFrame && displayText != null) { + this.textPaint.setAlpha(255 * (effect.lastFrame - frame) / (effect.lastFrame - beginFadeAtFrame)); + } + view.redrawAreaWithEffect(area, this, tileID, textYOffset, this.textPaint); + } + + @Override + protected void onPostExecute(Void result) { + super.onPostExecute(result); + VisualEffectController.this.currentEffect = null; + view.redrawArea(area, MainView.REDRAW_AREA_EFFECT_COMPLETED); + if (callback != null) callback.onVisualEffectCompleted(callbackValue); + } + + @Override + protected void onPreExecute() { + super.onPreExecute(); + this.isAlive = true; + redrawFrame(0); + } + + private boolean isAlive = false; + private int lastFrame = 0; + private final VisualEffect effect; private final long startTime; private final MainView view; public final Coord position; - private final CoordRect area; public final String displayText; - public final Paint textPaint = new Paint(); - public int currentTileID = 0; - public int textYOffset = 0; - private boolean isAlive = false; + private final CoordRect area; + private final Paint textPaint = new Paint(); + private final int beginFadeAtFrame; + private final VisualEffectCompletedCallback callback; + private final int callbackValue; - public VisualEffectAnimation(VisualEffect effect, Coord position, MainView view, int displayValue) { + public VisualEffectAnimation(VisualEffect effect, Coord position, MainView view, int displayValue, VisualEffectCompletedCallback callback, int callbackValue) { this.position = position; + this.callback = callback; + this.callbackValue = callbackValue; this.area = new CoordRect(new Coord(position.x, position.y - 1), new Size(1, 2)); this.effect = effect; this.displayText = (displayValue == 0) ? null : String.valueOf(displayValue); @@ -87,40 +129,25 @@ public final class VisualEffectController { this.textPaint.setTextSize(view.scaledTileSize * 0.5f); // 32dp. this.textPaint.setAlpha(255); this.textPaint.setTextAlign(Align.CENTER); - this.isAlive = true; this.startTime = System.currentTimeMillis(); this.view = view; - setCurrentTile(0); - } - - private void setCurrentTile(int currentFrame) { - if (currentFrame > effect.lastFrame) currentFrame = effect.lastFrame; - if (currentFrame < 0) currentFrame = 0; - int newTileID = effect.frameIconIDs[currentFrame]; - final boolean changed = newTileID != this.currentTileID; - this.currentTileID = newTileID; - this.textYOffset = -2 * (currentFrame); - final int beginFadeAtFrame = effect.lastFrame / 2; - if (currentFrame >= beginFadeAtFrame) { - this.textPaint.setAlpha(255 * (effect.lastFrame - currentFrame) / (effect.lastFrame - beginFadeAtFrame)); - } - - if (changed) { - view.redrawAreaWithEffect(area, this); - } + this.beginFadeAtFrame = effect.lastFrame / 2; } } - - public void waitForCurrentEffect() { - VisualEffectAnimation e = currentEffect; - if (e != null) { - e.safejoin(); - } + + + public static interface VisualEffectCompletedCallback { + public void onVisualEffectCompleted(int callbackValue); } + public void killCurrentEffect() { VisualEffectAnimation e = currentEffect; if (e != null) { e.killjoin(); } } + + public boolean isRunningVisualEffect() { + return currentEffect != null; + } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/tiles/TileManager.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/tiles/TileManager.java index 7b7a1af..8b60fa3 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/tiles/TileManager.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/tiles/TileManager.java @@ -7,6 +7,7 @@ import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; +import android.os.AsyncTask; import android.widget.ImageView; import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences; @@ -19,8 +20,10 @@ import com.gpl.rpg.AndorsTrail.model.item.ItemContainer; import com.gpl.rpg.AndorsTrail.model.item.ItemType; import com.gpl.rpg.AndorsTrail.model.item.ItemContainer.ItemEntry; import com.gpl.rpg.AndorsTrail.model.map.LayeredTileMap; +import com.gpl.rpg.AndorsTrail.model.map.MapObject; import com.gpl.rpg.AndorsTrail.model.map.MonsterSpawnArea; import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap; +import com.gpl.rpg.AndorsTrail.model.map.TMXMapTranslator; public final class TileManager { public static final int CHAR_HERO = 1; @@ -46,6 +49,7 @@ public final class TileManager { public final TileCache tileCache = new TileCache(); public final TileCollection preloadedTiles = new TileCollection(72); public TileCollection currentMapTiles; + public TileCollection adjacentMapTiles; private final HashSet preloadedTileIDs = new HashSet(); @@ -69,6 +73,15 @@ public final class TileManager { } public TileCollection loadTilesFor(PredefinedMap map, LayeredTileMap tileMap, WorldContext world, Resources r) { + HashSet iconIDs = getTileIDsFor(map, tileMap, world); + TileCollection result = tileCache.loadTilesFor(iconIDs, r); + for(int i : preloadedTileIDs) { + result.setBitmap(i, preloadedTiles.getBitmap(i)); + } + return result; + } + + public HashSet getTileIDsFor(PredefinedMap map, LayeredTileMap tileMap, WorldContext world) { HashSet iconIDs = new HashSet(); for(MonsterSpawnArea a : map.spawnAreas) { for(String monsterTypeID : a.monsterTypeIDs) { @@ -76,12 +89,7 @@ public final class TileManager { } } iconIDs.addAll(tileMap.usedTileIDs); - - TileCollection result = tileCache.loadTilesFor(iconIDs, r); - for(int i : preloadedTileIDs) { - result.setBitmap(i, preloadedTiles.getBitmap(i)); - } - return result; + return iconIDs; } public void setDensity(Resources r) { @@ -125,7 +133,6 @@ public final class TileManager { } } - public void loadPreloadedTiles(Resources r) { int maxTileID = tileCache.getMaxTileID(); for(int i = TileManager.CHAR_HERO; i <= maxTileID; ++i) { @@ -133,4 +140,29 @@ public final class TileManager { } tileCache.loadTilesFor(preloadedTileIDs, r, preloadedTiles); } + + public void cacheAdjacentMaps(final Resources res, final WorldContext world, final PredefinedMap nextMap) { + (new AsyncTask() { + @Override + protected Void doInBackground(Void... arg0) { + adjacentMapTiles = null; + + HashSet adjacentMapNames = new HashSet(); + for (MapObject o : nextMap.eventObjects) { + if (o.type != MapObject.MAPEVENT_NEWMAP) continue; + adjacentMapNames.add(o.map); + } + + HashSet tileIDs = new HashSet(); + for (String mapName : adjacentMapNames) { + PredefinedMap adjacentMap = world.maps.findPredefinedMap(mapName); + LayeredTileMap adjacentMapTiles = TMXMapTranslator.readLayeredTileMap(res, tileCache, adjacentMap); + tileIDs.addAll(getTileIDsFor(adjacentMap, adjacentMapTiles, world)); + } + + adjacentMapTiles = tileCache.loadTilesFor(tileIDs, res); + return null; + } + }).execute(); + } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/MainView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/MainView.java index e85b26c..762c80e 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/MainView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/MainView.java @@ -173,7 +173,7 @@ public final class MainView extends SurfaceView implements SurfaceHolder.Callbac } private void redrawArea_(CoordRect area) { if (!hasSurface) return; - if (!preferences.optimizedDrawing) area = mapViewArea; + //if (!preferences.optimizedDrawing) area = mapViewArea; final PredefinedMap currentMap = model.currentMap; boolean b = currentMap.isOutside(area); @@ -198,10 +198,15 @@ public final class MainView extends SurfaceView implements SurfaceHolder.Callbac } } + private boolean shouldRedrawEverythingForVisualEffect() { + if (preferences.optimizedDrawing) return false; + if (model.uiSelections.isInCombat) return false; // Discard the "optimized drawing" setting while in combat. + return true; + } private final Rect redrawRect = new Rect(); - public void redrawAreaWithEffect(CoordRect area, final VisualEffectAnimation effect) { + public void redrawAreaWithEffect(CoordRect area, final VisualEffectAnimation effect, int tileID, int textYOffset, Paint textPaint) { if (!hasSurface) return; - if (!preferences.optimizedDrawing) area = mapViewArea; + if (shouldRedrawEverythingForVisualEffect()) area = mapViewArea; final PredefinedMap currentMap = model.currentMap; if (currentMap.isOutside(area)) return; @@ -214,9 +219,9 @@ public final class MainView extends SurfaceView implements SurfaceHolder.Callbac c.translate(screenOffset.x, screenOffset.y); c.scale(scale, scale); doDrawRect(c, area); - drawFromMapPosition(c, area, effect.position, effect.currentTileID); + drawFromMapPosition(c, area, effect.position, tileID); if (effect.displayText != null) { - drawEffectText(c, area, effect); + drawEffectText(c, area, effect, textYOffset, textPaint); } } } finally { @@ -328,10 +333,10 @@ public final class MainView extends SurfaceView implements SurfaceHolder.Callbac } } - private void drawEffectText(Canvas canvas, final CoordRect area, final VisualEffectAnimation e) { + private void drawEffectText(Canvas canvas, final CoordRect area, final VisualEffectAnimation e, int textYOffset, Paint textPaint) { int x = (e.position.x - mapViewArea.topLeft.x) * tileSize + tileSize/2; - int y = (e.position.y - mapViewArea.topLeft.y) * tileSize + tileSize/2 + e.textYOffset; - canvas.drawText(e.displayText, x, y, e.textPaint); + int y = (e.position.y - mapViewArea.topLeft.y) * tileSize + tileSize/2 + textYOffset; + canvas.drawText(e.displayText, x, y, textPaint); } public void notifyMapChanged() { -- 2.49.0