Merge branch 'master' into stoutford_tests

This commit is contained in:
Zukero
2018-02-27 18:38:27 +01:00
5 changed files with 124 additions and 120 deletions

View File

@@ -67,7 +67,7 @@ public final class VisualEffectController {
public final class SpriteMoveAnimation extends Handler implements Runnable {
private static final int millisecondsPerFrame=25;
// private static final int millisecondsPerFrame=25;
private final VisualEffectCompletedCallback callback;
private final int callbackValue;
@@ -80,12 +80,12 @@ public final class VisualEffectController {
@Override
public void run() {
update();
if (System.currentTimeMillis() - actor.vfxStartTime >= duration) {
onCompleted();
} else {
postDelayed(this, millisecondsPerFrame);
}
onCompleted();
// update();
// if (System.currentTimeMillis() - actor.vfxStartTime >= duration) {
// } else {
// postDelayed(this, millisecondsPerFrame);
// }
}
public SpriteMoveAnimation(Coord origin, Coord destination, int duration, Actor actor, VisualEffectCompletedCallback callback, int callbackValue) {
@@ -98,10 +98,10 @@ public final class VisualEffectController {
}
private void update() {
visualEffectFrameListeners.onNewSpriteMoveFrame(this);
}
// private void update() {
//
// visualEffectFrameListeners.onNewSpriteMoveFrame(this);
// }
private void onCompleted() {
--effectCount;
@@ -115,8 +115,11 @@ public final class VisualEffectController {
actor.hasVFXRunning = true;
actor.vfxDuration = duration;
actor.vfxStartTime = System.currentTimeMillis();
visualEffectFrameListeners.onSpriteMoveStarted(this);
if (duration == 0 || !controllers.preferences.enableUiAnimations) onCompleted();
else postDelayed(this, 0);
else {
postDelayed(this, duration);
}
}

View File

@@ -7,6 +7,7 @@ import com.gpl.rpg.AndorsTrail.util.CoordRect;
public interface VisualEffectFrameListener {
void onNewAnimationFrame(VisualEffectAnimation animation, int tileID, int textYOffset);
void onAnimationCompleted(VisualEffectAnimation animation);
void onSpriteMoveStarted(SpriteMoveAnimation animation);
void onNewSpriteMoveFrame(SpriteMoveAnimation animation);
void onSpriteMoveCompleted(SpriteMoveAnimation animation);
void onAsyncAreaUpdate(CoordRect area);

View File

@@ -15,6 +15,10 @@ public final class VisualEffectFrameListeners extends ListOfListeners<VisualEffe
@Override public void call(VisualEffectFrameListener listener, VisualEffectAnimation animation) { listener.onAnimationCompleted(animation); }
};
private final Function1<VisualEffectFrameListener, SpriteMoveAnimation> onSpriteMoveStarted = new Function1<VisualEffectFrameListener, SpriteMoveAnimation>() {
@Override public void call(VisualEffectFrameListener listener, SpriteMoveAnimation animation) { listener.onSpriteMoveStarted(animation); }
};
private final Function1<VisualEffectFrameListener, SpriteMoveAnimation> onNewSpriteMoveFrame = new Function1<VisualEffectFrameListener, SpriteMoveAnimation>() {
@Override public void call(VisualEffectFrameListener listener, SpriteMoveAnimation animation) { listener.onNewSpriteMoveFrame(animation); }
};
@@ -37,6 +41,11 @@ public final class VisualEffectFrameListeners extends ListOfListeners<VisualEffe
callAllListeners(this.onAnimationCompleted, animation);
}
@Override
public void onSpriteMoveStarted(SpriteMoveAnimation animation) {
callAllListeners(this.onSpriteMoveStarted, animation);
}
@Override
public void onNewSpriteMoveFrame(SpriteMoveAnimation animation) {
callAllListeners(this.onNewSpriteMoveFrame, animation);

View File

@@ -24,7 +24,11 @@ public final class MonsterTypeCollection {
for (MonsterType t : monsterTypesById.values()) {
if (t.spawnGroup.equalsIgnoreCase(spawnGroup)) result.add(t);
}
//If the spawnGroup is empty, it should be a direct reference to a MonsterType's id.
if (result.isEmpty()) {
MonsterType t = monsterTypesById.get(spawnGroup);
if (t != null) result.add(t);
}
return result;
}
@@ -38,9 +42,4 @@ public final class MonsterTypeCollection {
public void initialize(MonsterTypeParser parser, String input) {
parser.parseRows(input, monsterTypesById);
}
// Unit test method. Not part of the game logic.
public HashMap<String, MonsterType> UNITTEST_getAllMonsterTypes() {
return monsterTypesById;
}
}

View File

@@ -1,5 +1,7 @@
package com.gpl.rpg.AndorsTrail.view;
import java.lang.ref.WeakReference;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -40,6 +42,7 @@ import com.gpl.rpg.AndorsTrail.resource.tiles.TileCollection;
import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
import com.gpl.rpg.AndorsTrail.util.Coord;
import com.gpl.rpg.AndorsTrail.util.CoordRect;
import com.gpl.rpg.AndorsTrail.util.L;
import com.gpl.rpg.AndorsTrail.util.Size;
public final class MainView extends SurfaceView
@@ -91,9 +94,6 @@ public final class MainView extends SurfaceView
private LayeredTileMap currentTileMap;
private TileCollection tiles;
private Bitmap groundBitmap = null;
// private Bitmap objectsBitmap = null;
private Bitmap aboveBitmap = null;
private final Coord playerPosition = new Coord();
private Size surfaceSize;
private boolean redrawNextTick = false;
@@ -104,6 +104,9 @@ public final class MainView extends SurfaceView
//TODO restore private final modifiers before release
public static long SCROLL_DURATION = Constants.MINIMUM_INPUT_INTERVAL;
private int movingSprites = 0;
private SpriteMoveAnimationHandler movingSpritesRedrawTick = new SpriteMoveAnimationHandler(this);
public MainView(Context context, AttributeSet attr) {
super(context, attr);
@@ -178,6 +181,7 @@ public final class MainView extends SurfaceView
@Override
public void surfaceDestroyed(SurfaceHolder sh) {
hasSurface = false;
movingSpritesRedrawTick.stop();
}
@Override
@@ -208,7 +212,7 @@ public final class MainView extends SurfaceView
}
private static enum RedrawAllDebugReason {
SurfaceChanged, MapChanged, PlayerMoved, MapScrolling, FilterAnimation
SurfaceChanged, MapChanged, PlayerMoved, SpriteMoved, MapScrolling, FilterAnimation
}
private static enum RedrawAreaDebugReason {
MonsterMoved, MonsterKilled, EffectCompleted, AsyncRequest
@@ -219,6 +223,7 @@ public final class MainView extends SurfaceView
private void redrawAll(RedrawAllDebugReason why) {
if (scrolling && why != RedrawAllDebugReason.MapScrolling) return;
if (!scrolling && movingSprites > 0 && why != RedrawAllDebugReason.SpriteMoved) return;
redrawArea_(mapViewArea, null, 0, 0);
}
private void redrawTile(final Coord p, RedrawTileDebugReason why) {
@@ -435,11 +440,8 @@ public final class MainView extends SurfaceView
}
private void doDrawRect_Ground(Canvas canvas, CoordRect area) {
if (!tryDrawMapBitmap(canvas, area, groundBitmap)) {
drawMapLayer(canvas, area, currentTileMap.currentLayout.layerGround);
tryDrawMapLayer(canvas, area, currentTileMap.currentLayout.layerObjects);
}
drawMapLayer(canvas, area, currentTileMap.currentLayout.layerGround);
tryDrawMapLayer(canvas, area, currentTileMap.currentLayout.layerObjects);
}
private void doDrawRect_Objects(Canvas canvas, CoordRect area) {
@@ -494,18 +496,6 @@ public final class MainView extends SurfaceView
}
}
private boolean tryDrawMapBitmap(Canvas canvas, final CoordRect area, final Bitmap bitmap) {
if (bitmap != null) {
drawMapBitmap(canvas, area, bitmap);
return true;
}
return false;
}
private void drawMapBitmap(Canvas canvas, final CoordRect area, final Bitmap bitmap){
canvas.drawBitmap(bitmap, -mapViewArea.topLeft.x * tileSize, -mapViewArea.topLeft.y * tileSize, mPaint);
}
private void tryDrawMapLayer(Canvas canvas, final CoordRect area, final MapLayer layer) {
if (layer != null) drawMapLayer(canvas, area, layer);
}
@@ -529,25 +519,6 @@ public final class MainView extends SurfaceView
}
}
private void drawMapLayerOffscreen(Canvas canvas, final MapLayer layer) {
int my = 0;
int py = 0;
int px0 = 0;
for (int y = 0; y < currentMap.size.height; ++y, ++my, py += tileSize) {
int mx = 0;
if (my < 0) continue;
if (my >= currentMap.size.height) break;
int px = px0;
for (int x = 0; x < currentMap.size.width; ++x, ++mx, px += tileSize) {
if (mx < 0) continue;
if (mx >= currentMap.size.width) break;
final int tile = layer.tiles[mx][my];
if (tile == 0) continue;
tiles.drawTile(canvas, tile, px, py, mPaint);
}
}
}
private void drawFromMapPosition(Canvas canvas, final CoordRect area, final Coord p, final int tile) {
if (!area.contains(p)) return;
_drawFromMapPosition(canvas, area, p.x, p.y, tile);
@@ -573,11 +544,12 @@ public final class MainView extends SurfaceView
@Override
public void onPlayerEnteredNewMap(PredefinedMap map, Coord p) {
movingSpritesRedrawTick.start();
synchronized (holder) {
currentMap = map;
currentTileMap = model.currentTileMap;
tiles = world.tileManager.currentMapTiles;
movingSprites = 0;
Size visibleNumberOfTiles = new Size(
Math.min(screenSizeTileCount.width, currentMap.size.width)
,Math.min(screenSizeTileCount.height, currentMap.size.height)
@@ -603,8 +575,6 @@ public final class MainView extends SurfaceView
clearCanvas();
updateBitmaps();
recalculateMapTopLeft(model.player.position, false);
redrawAll(RedrawAllDebugReason.MapChanged);
}
@@ -628,7 +598,7 @@ public final class MainView extends SurfaceView
if (allowScrolling) {
if (mapTopLeft.x != oldX || mapTopLeft.y != oldY) {
scrollVector = new Coord(mapTopLeft.x - oldX, mapTopLeft.y - oldY);
new ScrollAnimationHandler().start();
new ScrollAnimationHandler(this).start();
}
} else {
scrolling = false;
@@ -640,63 +610,22 @@ public final class MainView extends SurfaceView
worldCoordsToScreenCords(mapViewArea, redrawClip);
}
// private void printMem() {
// Runtime r = Runtime.getRuntime();
// L.log("---------------------------------------");
// L.log("Max : "+r.maxMemory()/1024);
// L.log("Tot : "+r.totalMemory()/1024);
// L.log("Use : "+(r.totalMemory()-r.freeMemory())/1024);
// L.log("Fre : "+r.freeMemory()/1024);
// }
private void updateBitmaps() {
//CPU and pixel fill-rate optimization, but makes low heap-size devices throw an OutOfMemoryError... disabled for now.
// Canvas bitmapDrawingCanvas;
//
// printMem();
//
// if (groundBitmap != null) {
// groundBitmap.recycle();
// groundBitmap = null;
// }
// if (aboveBitmap != null) {
// aboveBitmap.recycle();
// aboveBitmap = null;
// }
//
// System.gc();
//
// long freeMemRequired = tileSize * tileSize * currentMap.size.width * currentMap.size.height * 4 /*RGBA_8888*/ * 3 /*Require three times the needed size, to leave room for others*/;
// Runtime r = Runtime.getRuntime();
//
// if (currentTileMap.currentLayout.layerGround != null && r.maxMemory() - r.totalMemory() > freeMemRequired) {
// groundBitmap = Bitmap.createBitmap(currentMap.size.width * tileSize, currentMap.size.height * tileSize, Config.ARGB_8888);
// bitmapDrawingCanvas = new Canvas(groundBitmap);
// drawMapLayerOffscreen(bitmapDrawingCanvas, currentTileMap.currentLayout.layerGround);
// if (currentTileMap.currentLayout.layerObjects != null) {
// drawMapLayerOffscreen(bitmapDrawingCanvas, currentTileMap.currentLayout.layerObjects);
// }
// }
//
//
// if (currentTileMap.currentLayout.layerAbove != null && r.maxMemory() - r.totalMemory() > freeMemRequired) {
// aboveBitmap = Bitmap.createBitmap(currentMap.size.width * tileSize, currentMap.size.height * tileSize, Config.ARGB_8888);
// bitmapDrawingCanvas = new Canvas(aboveBitmap);
// drawMapLayerOffscreen(bitmapDrawingCanvas, currentTileMap.currentLayout.layerAbove);
// }
// printMem();
//
}
public final class ScrollAnimationHandler extends Handler implements Runnable {
public static final class ScrollAnimationHandler extends Handler implements Runnable {
private static final int FRAME_DURATION = 40;
private final WeakReference<MainView> view;
public ScrollAnimationHandler(MainView view) {
this.view = new WeakReference<MainView>(view);
}
@Override
public void run() {
if (System.currentTimeMillis() - scrollStartTime >= SCROLL_DURATION) {
MainView v = view.get();
if (v == null) return;
if (System.currentTimeMillis() - v.scrollStartTime >= SCROLL_DURATION) {
onCompleted();
} else {
postDelayed(this, FRAME_DURATION);
@@ -705,22 +634,77 @@ public final class MainView extends SurfaceView
}
private void update() {
redrawAll(RedrawAllDebugReason.MapScrolling);
MainView v = view.get();
if (v == null) return;
v.redrawAll(RedrawAllDebugReason.MapScrolling);
}
private void onCompleted() {
scrolling = false;
scrollVector = null;
MainView v = view.get();
if (v == null) return;
v.scrolling = false;
v.scrollVector = null;
}
public void start() {
scrolling = true;
scrollStartTime = System.currentTimeMillis();
MainView v = view.get();
if (v == null) return;
v.scrolling = true;
v.scrollStartTime = System.currentTimeMillis();
postDelayed(this, 0);
}
}
public static final class SpriteMoveAnimationHandler extends Handler implements Runnable {
private static final int FRAME_DURATION = 40;
private final WeakReference<MainView> view;
private boolean stop = true;
public SpriteMoveAnimationHandler(MainView view) {
this.view = new WeakReference<MainView>(view);
}
@Override
public void run() {
if (!stop) postDelayed(this, FRAME_DURATION);
update();
}
private void update() {
// L.log("stop="+stop+" - scroll="+scrolling+" - moving="+movingSprites);
if (stop) return;
MainView v = view.get();
if (v == null) return;
if (!v.scrolling) {
if (v.movingSprites > 0) {
//TODO : limit redraw area when shouldRedrawEverything() returns false.
//Implies keeping track of the animation bounding box in a thread-safe way... :'(
v.redrawAll(RedrawAllDebugReason.SpriteMoved);
}
}
synchronized (this) {
if (v.movingSprites <= 0) stop();
}
}
public void start() {
if (stop) {
stop = false;
MainView v = view.get();
if (v == null) return;
if (v.controllers.preferences.enableUiAnimations) postDelayed(this, 0);
}
}
public void stop() {
stop = true;
}
}
@Override
public void onPlayerMoved(Coord newPosition, Coord previousPosition) {
recalculateMapTopLeft(newPosition, preferences.enableUiAnimations);
@@ -828,7 +812,6 @@ public final class MainView extends SurfaceView
@Override
public void onMapTilesChanged(PredefinedMap map, LayeredTileMap tileMap) {
if (map != currentMap) return;
updateBitmaps();
currentTileMap.setColorFilter(this.mPaint);
redrawAll(RedrawAllDebugReason.MapChanged);
}
@@ -842,14 +825,23 @@ public final class MainView extends SurfaceView
public void onAnimationCompleted(VisualEffectAnimation animation) {
redrawArea(animation.area, RedrawAreaDebugReason.EffectCompleted);
}
@Override
public void onSpriteMoveStarted(SpriteMoveAnimation animation) {
synchronized (movingSpritesRedrawTick) {
movingSprites++;
movingSpritesRedrawTick.start();
}
}
@Override
public void onNewSpriteMoveFrame(SpriteMoveAnimation animation) {
redrawMoveArea_(CoordRect.getBoundingRect(animation.origin, animation.destination, animation.actor.tileSize), animation);
//redrawMoveArea_(CoordRect.getBoundingRect(animation.origin, animation.destination, animation.actor.tileSize), animation);
}
@Override
public void onSpriteMoveCompleted(SpriteMoveAnimation animation) {
movingSprites--;
redrawArea(CoordRect.getBoundingRect(animation.origin, animation.destination, animation.actor.tileSize), RedrawAreaDebugReason.EffectCompleted);
}