mirror of
https://github.com/OMGeeky/andors-trail.git
synced 2026-02-23 15:38:29 +01:00
Animated movements !
Enhancements in debug map graphics, and more monster to better test animations. Player slides from tile to tile in MIN_INPUT_DEPLAY / 2 ms. Mobs slide at a speed proportional to their Move cost / Max AP ratio. Animation refresh rate is 25ms.
This commit is contained in:
@@ -62,7 +62,7 @@
|
||||
"monsterClass": "insect",
|
||||
"maxHP": 10,
|
||||
"maxAP": 10,
|
||||
"moveCost": 10,
|
||||
"moveCost": 5,
|
||||
"attackCost": 10,
|
||||
"attackChance": 50,
|
||||
"droplistID": "debuglist1",
|
||||
|
||||
@@ -122,12 +122,12 @@
|
||||
</tileset>
|
||||
<layer name="Ground" width="10" height="10">
|
||||
<data encoding="base64" compression="zlib">
|
||||
eJw7ysbAcHSQ4ydUNOsEEqalultkmgcAw35PpQ==
|
||||
eJw7ysbAcHQQ4wYOBoYnVDTvBBKmpbpbZJoHAISsT2I=
|
||||
</data>
|
||||
</layer>
|
||||
<layer name="Objects" width="10" height="10">
|
||||
<data encoding="base64" compression="zlib">
|
||||
eJxjYMAOktlxSNAYSFDRXlsm6plFLwAA6HwAyQ==
|
||||
eJyby88AB7FI7JvMDBSDbDLMyOQnrIZYYMtEPbNIBfPI9AcAQ5QDxw==
|
||||
</data>
|
||||
</layer>
|
||||
<layer name="Above" width="10" height="10">
|
||||
@@ -140,7 +140,7 @@
|
||||
eJxjYBi+wFVgoF1AOgAAPUQAVg==
|
||||
</data>
|
||||
</layer>
|
||||
<objectgroup name="Object Layer 1">
|
||||
<objectgroup name="Object Layer 1" width="0" height="0">
|
||||
<object name="debugsign" type="sign" x="192" y="96" width="32" height="32"/>
|
||||
<object name="start" type="rest" x="96" y="64" width="32" height="32"/>
|
||||
<object name="Unopenable key area" type="key" x="32" y="128" width="32" height="32">
|
||||
@@ -181,10 +181,10 @@
|
||||
</properties>
|
||||
</object>
|
||||
</objectgroup>
|
||||
<objectgroup name="Spawn">
|
||||
<objectgroup name="Spawn" width="0" height="0">
|
||||
<object name="insect" type="spawn" x="96" y="128" width="192" height="160">
|
||||
<properties>
|
||||
<property name="quantity" value="2"/>
|
||||
<property name="quantity" value="15"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object name="troll" type="spawn" x="256" y="256" width="64" height="64">
|
||||
|
||||
@@ -32,7 +32,7 @@ public final class Constants {
|
||||
public static final int TICKS_PER_FULLROUND = FULLROUND_DURATION / TICK_DELAY;
|
||||
public static final int SPLATTER_DURATION_MS = 20000;
|
||||
|
||||
public static final ConstRange monsterWaitTurns = new ConstRange(30,4);
|
||||
public static final ConstRange monsterWaitTurns = new ConstRange(5,1);
|
||||
public static final long MAP_UNVISITED_RESPAWN_DURATION_MS = 3 * 60 * 1000; // 3 min in milliseconds
|
||||
|
||||
public static final String PREFERENCE_MODEL_LASTRUNVERSION = "lastversion";
|
||||
|
||||
@@ -74,7 +74,7 @@ public final class MonsterMovementController implements EvaluateWalkable {
|
||||
private void moveMonster(final Monster m, final MonsterSpawnArea area) {
|
||||
PredefinedMap map = world.model.currentMap;
|
||||
LayeredTileMap tileMap = world.model.currentTileMap;
|
||||
m.nextActionTime += getMillisecondsPerMove(m);
|
||||
m.nextActionTime = System.currentTimeMillis() + getMillisecondsPerMove(m);
|
||||
if (m.movementDestination == null) {
|
||||
// Monster has waited and should start to move again.
|
||||
m.movementDestination = new Coord(m.position);
|
||||
@@ -128,7 +128,7 @@ public final class MonsterMovementController implements EvaluateWalkable {
|
||||
|
||||
private static void cancelCurrentMonsterMovement(final Monster m) {
|
||||
m.movementDestination = null;
|
||||
m.nextActionTime += getMillisecondsPerMove(m) * Constants.rollValue(Constants.monsterWaitTurns);
|
||||
m.nextActionTime = System.currentTimeMillis() + (getMillisecondsPerMove(m) * Constants.rollValue(Constants.monsterWaitTurns));
|
||||
}
|
||||
|
||||
private static int getMillisecondsPerMove(Monster m) {
|
||||
@@ -151,9 +151,17 @@ public final class MonsterMovementController implements EvaluateWalkable {
|
||||
return monsterCanMoveTo(world.model.currentMap, world.model.currentTileMap, r);
|
||||
}
|
||||
|
||||
public void moveMonsterToNextPosition(Monster m, PredefinedMap map) {
|
||||
CoordRect previousPosition = new CoordRect(new Coord(m.position), m.rectPosition.size);
|
||||
public void moveMonsterToNextPosition(final Monster m, final PredefinedMap map) {
|
||||
final CoordRect previousPosition = new CoordRect(new Coord(m.position), m.rectPosition.size);
|
||||
m.lastPosition.set(previousPosition.topLeft);
|
||||
m.position.set(m.nextPosition.topLeft);
|
||||
monsterMovementListeners.onMonsterMoved(map, m, previousPosition);
|
||||
controllers.effectController.startActorMoveEffect(m, previousPosition.topLeft, m.position, getMillisecondsPerMove(m) / 4, new VisualEffectController.VisualEffectCompletedCallback() {
|
||||
|
||||
@Override
|
||||
public void onVisualEffectCompleted(int callbackValue) {
|
||||
|
||||
monsterMovementListeners.onMonsterMoved(map, m, previousPosition);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,15 +228,24 @@ public final class MovementController implements TimedMessageTask.Callback {
|
||||
player.lastPosition.set(player.position);
|
||||
player.position.set(newPosition);
|
||||
controllers.combatController.setCombatSelection(null, null);
|
||||
playerMovementListeners.onPlayerMoved(newPosition, player.lastPosition);
|
||||
|
||||
controllers.effectController.startActorMoveEffect(player, player.lastPosition, newPosition, (int) (Constants.MINIMUM_INPUT_INTERVAL / 2), new VisualEffectController.VisualEffectCompletedCallback() {
|
||||
|
||||
@Override
|
||||
public void onVisualEffectCompleted(int callbackValue) {
|
||||
playerMovementListeners.onPlayerMoved(newPosition, player.lastPosition);
|
||||
|
||||
controllers.mapController.handleMapEventsAfterMovement(currentMap, newPosition, player.lastPosition);
|
||||
controllers.mapController.handleMapEventsAfterMovement(currentMap, newPosition, player.lastPosition);
|
||||
|
||||
if (!world.model.uiSelections.isInCombat) {
|
||||
//currentMap can be outdated due to mapchange events processed above.
|
||||
Loot loot = world.model.currentMap.getBagAt(newPosition);
|
||||
if (loot != null) controllers.itemController.playerSteppedOnLootBag(loot);
|
||||
}
|
||||
if (!world.model.uiSelections.isInCombat) {
|
||||
//currentMap can be outdated due to mapchange events processed above.
|
||||
Loot loot = world.model.currentMap.getBagAt(newPosition);
|
||||
if (loot != null) controllers.itemController.playerSteppedOnLootBag(loot);
|
||||
}
|
||||
}
|
||||
}, 0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void respawnPlayer(Resources res) {
|
||||
|
||||
@@ -4,9 +4,11 @@ import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Align;
|
||||
import android.os.Handler;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
|
||||
import com.gpl.rpg.AndorsTrail.context.WorldContext;
|
||||
import com.gpl.rpg.AndorsTrail.controller.listeners.VisualEffectFrameListeners;
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Actor;
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.MonsterType;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
|
||||
@@ -54,7 +56,70 @@ public final class VisualEffectController {
|
||||
enqueuedEffectID = null;
|
||||
enqueuedEffectValue = 0;
|
||||
}
|
||||
|
||||
public void startActorMoveEffect(Actor actor, Coord origin, Coord destination, int duration, VisualEffectCompletedCallback callback, int callbackValue) {
|
||||
++effectCount;
|
||||
(new SpriteMoveAnimation(origin, destination, duration, actor, callback, callbackValue))
|
||||
.start();
|
||||
}
|
||||
|
||||
public final class SpriteMoveAnimation extends Handler implements Runnable {
|
||||
|
||||
private static final int millisecondsPerFrame=25;
|
||||
|
||||
private final VisualEffectCompletedCallback callback;
|
||||
private final int callbackValue;
|
||||
|
||||
public final int duration;
|
||||
public final Actor actor;
|
||||
public final Coord origin;
|
||||
public final Coord destination;
|
||||
|
||||
public int timeElapsed;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
update();
|
||||
if (System.currentTimeMillis() - actor.vfxStartTime >= duration) {
|
||||
onCompleted();
|
||||
} else {
|
||||
postDelayed(this, millisecondsPerFrame);
|
||||
}
|
||||
}
|
||||
|
||||
public SpriteMoveAnimation(Coord origin, Coord destination, int duration, Actor actor, VisualEffectCompletedCallback callback, int callbackValue) {
|
||||
this.callback = callback;
|
||||
this.callbackValue = callbackValue;
|
||||
this.duration = duration;
|
||||
this.actor = actor;
|
||||
this.origin = origin;
|
||||
this.destination = destination;
|
||||
this.timeElapsed = 0;
|
||||
|
||||
}
|
||||
|
||||
private void update() {
|
||||
|
||||
visualEffectFrameListeners.onNewSpriteMoveFrame(this);
|
||||
}
|
||||
|
||||
private void onCompleted() {
|
||||
--effectCount;
|
||||
actor.hasVFXRunning = false;
|
||||
if (callback != null) callback.onVisualEffectCompleted(callbackValue);
|
||||
visualEffectFrameListeners.onSpriteMoveCompleted(this);
|
||||
}
|
||||
|
||||
|
||||
public void start() {
|
||||
actor.hasVFXRunning = true;
|
||||
actor.vfxDuration = duration;
|
||||
actor.vfxStartTime = System.currentTimeMillis();
|
||||
postDelayed(this, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public final class VisualEffectAnimation extends Handler implements Runnable {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.SpriteMoveAnimation;
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.VisualEffectAnimation;
|
||||
|
||||
public interface VisualEffectFrameListener {
|
||||
void onNewAnimationFrame(VisualEffectAnimation animation, int tileID, int textYOffset);
|
||||
void onAnimationCompleted(VisualEffectAnimation animation);
|
||||
void onNewSpriteMoveFrame(SpriteMoveAnimation animation);
|
||||
void onSpriteMoveCompleted(SpriteMoveAnimation animation);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.SpriteMoveAnimation;
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.VisualEffectAnimation;
|
||||
import com.gpl.rpg.AndorsTrail.util.ListOfListeners;
|
||||
|
||||
@@ -12,6 +13,14 @@ public final class VisualEffectFrameListeners extends ListOfListeners<VisualEffe
|
||||
private final Function1<VisualEffectFrameListener, VisualEffectAnimation> onAnimationCompleted = new Function1<VisualEffectFrameListener, VisualEffectAnimation>() {
|
||||
@Override public void call(VisualEffectFrameListener listener, VisualEffectAnimation animation) { listener.onAnimationCompleted(animation); }
|
||||
};
|
||||
|
||||
private final Function1<VisualEffectFrameListener, SpriteMoveAnimation> onNewSpriteMoveFrame = new Function1<VisualEffectFrameListener, SpriteMoveAnimation>() {
|
||||
@Override public void call(VisualEffectFrameListener listener, SpriteMoveAnimation animation) { listener.onNewSpriteMoveFrame(animation); }
|
||||
};
|
||||
|
||||
private final Function1<VisualEffectFrameListener, SpriteMoveAnimation> onSpriteMoveCompleted = new Function1<VisualEffectFrameListener, SpriteMoveAnimation>() {
|
||||
@Override public void call(VisualEffectFrameListener listener, SpriteMoveAnimation animation) { listener.onSpriteMoveCompleted(animation); }
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onNewAnimationFrame(VisualEffectAnimation animation, int tileID, int textYOffset) {
|
||||
@@ -22,4 +31,14 @@ public final class VisualEffectFrameListeners extends ListOfListeners<VisualEffe
|
||||
public void onAnimationCompleted(VisualEffectAnimation animation) {
|
||||
callAllListeners(this.onAnimationCompleted, animation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewSpriteMoveFrame(SpriteMoveAnimation animation) {
|
||||
callAllListeners(this.onNewSpriteMoveFrame, animation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpriteMoveCompleted(SpriteMoveAnimation animation) {
|
||||
callAllListeners(this.onSpriteMoveCompleted, animation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,10 @@ public class Actor {
|
||||
public int blockChance;
|
||||
public int damageResistance;
|
||||
public ItemTraits_OnUse[] onHitEffects;
|
||||
public boolean hasVFXRunning = false;
|
||||
public long vfxStartTime = 0;
|
||||
public int vfxDuration = 0;
|
||||
public final Coord lastPosition = new Coord();
|
||||
|
||||
public Actor(
|
||||
Size tileSize
|
||||
|
||||
@@ -29,7 +29,6 @@ import com.gpl.rpg.AndorsTrail.util.Size;
|
||||
public final class Player extends Actor {
|
||||
|
||||
public static final int DEFAULT_PLAYER_ATTACKCOST = 4;
|
||||
public final Coord lastPosition;
|
||||
public final Coord nextPosition;
|
||||
|
||||
// TODO: Should be privates
|
||||
@@ -87,7 +86,6 @@ public final class Player extends Actor {
|
||||
, true // isPlayer
|
||||
, false // isImmuneToCriticalHits
|
||||
);
|
||||
this.lastPosition = new Coord();
|
||||
this.nextPosition = new Coord();
|
||||
this.levelExperience = new Range();
|
||||
this.inventory = new Inventory();
|
||||
|
||||
@@ -72,4 +72,24 @@ public final class CoordRect {
|
||||
public String toString() {
|
||||
return '{' + topLeft.toString() + ", " + size.toString() + '}';
|
||||
}
|
||||
|
||||
public static CoordRect getBoundingRect(Coord c1, Coord c2) {
|
||||
int x, y, w, h;
|
||||
if (c2.x < c1.x) {
|
||||
x = c2.x;
|
||||
w = 1 + c1.x - c2.x;
|
||||
} else {
|
||||
x = c1.x;
|
||||
w = 1 + c2.x - c1.x;
|
||||
}
|
||||
if (c2.y < c1.y) {
|
||||
y = c2.y;
|
||||
h = 1 + c1.y - c2.y;
|
||||
} else {
|
||||
y = c1.y;
|
||||
h = 1 + c2.y - c1.y;
|
||||
}
|
||||
|
||||
return new CoordRect(new Coord(x, y), new Size(w, h));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,12 +10,14 @@ import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences;
|
||||
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
|
||||
import com.gpl.rpg.AndorsTrail.context.WorldContext;
|
||||
import com.gpl.rpg.AndorsTrail.controller.InputController;
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.BloodSplatter;
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.SpriteMoveAnimation;
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.VisualEffectAnimation;
|
||||
import com.gpl.rpg.AndorsTrail.controller.listeners.*;
|
||||
import com.gpl.rpg.AndorsTrail.model.ModelContainer;
|
||||
@@ -29,6 +31,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
|
||||
@@ -49,7 +52,8 @@ public final class MainView extends SurfaceView
|
||||
private final Coord screenOffset = new Coord(); // pixel offset where the image begins
|
||||
private final Coord mapTopLeft = new Coord(); // Map coords of visible map
|
||||
private CoordRect mapViewArea; // Area in mapcoordinates containing the visible map. topleft == this.topleft
|
||||
|
||||
private Rect redrawClip = new Rect(); //Area in screen coordinates containing the visible map.
|
||||
|
||||
private final ModelContainer model;
|
||||
private final WorldContext world;
|
||||
private final ControllerContext controllers;
|
||||
@@ -199,6 +203,7 @@ public final class MainView extends SurfaceView
|
||||
}
|
||||
}
|
||||
synchronized (holder) { synchronized (tiles) {
|
||||
c.clipRect(redrawClip);
|
||||
c.translate(screenOffset.x, screenOffset.y);
|
||||
c.scale(scale, scale);
|
||||
doDrawRect(c, area);
|
||||
@@ -213,6 +218,34 @@ public final class MainView extends SurfaceView
|
||||
if (c != null) holder.unlockCanvasAndPost(c);
|
||||
}
|
||||
}
|
||||
|
||||
private void redrawMoveArea_(CoordRect area, final SpriteMoveAnimation effect) {
|
||||
if (!hasSurface) return;
|
||||
|
||||
if (currentMap.isOutside(area)) return;
|
||||
if (!mapViewArea.intersects(area)) return;
|
||||
|
||||
calculateRedrawRect(area);
|
||||
Canvas c = null;
|
||||
try {
|
||||
c = holder.lockCanvas(redrawRect);
|
||||
// lockCanvas sometimes changes redrawRect, when the double-buffer has not been
|
||||
// sufficiently filled beforehand. In those cases, we need to redraw the whole scene.
|
||||
if (area != mapViewArea) {
|
||||
if (isRedrawRectWholeScreen(redrawRect)) {
|
||||
area = mapViewArea;
|
||||
}
|
||||
}
|
||||
synchronized (holder) { synchronized (tiles) {
|
||||
c.clipRect(redrawClip);
|
||||
c.translate(screenOffset.x, screenOffset.y);
|
||||
c.scale(scale, scale);
|
||||
doDrawRect(c, area);
|
||||
} }
|
||||
} finally {
|
||||
if (c != null) holder.unlockCanvasAndPost(c);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRedrawRectWholeScreen(Rect redrawRect) {
|
||||
if (redrawRect.width() < mapViewArea.size.width * scaledTileSize) return false;
|
||||
@@ -256,13 +289,25 @@ public final class MainView extends SurfaceView
|
||||
}
|
||||
|
||||
private void doDrawRect(Canvas canvas, CoordRect area) {
|
||||
|
||||
doDrawRect_Below(canvas, area);
|
||||
doDrawRect_Objects(canvas, area);
|
||||
doDrawRect_Above(canvas, area);
|
||||
|
||||
}
|
||||
|
||||
private void doDrawRect_Below(Canvas canvas, CoordRect area) {
|
||||
drawMapLayer(canvas, area, currentTileMap.currentLayout.layerGround);
|
||||
tryDrawMapLayer(canvas, area, currentTileMap.currentLayout.layerObjects);
|
||||
|
||||
for (BloodSplatter splatter : currentMap.splatters) {
|
||||
drawFromMapPosition(canvas, area, splatter.position, splatter.iconID);
|
||||
}
|
||||
}
|
||||
|
||||
private void doDrawRect_Objects(Canvas canvas, CoordRect area) {
|
||||
for (BloodSplatter splatter : currentMap.splatters) {
|
||||
drawFromMapPosition(canvas, area, splatter.position, splatter.iconID);
|
||||
}
|
||||
|
||||
for (Loot l : currentMap.groundBags) {
|
||||
if (l.isVisible) {
|
||||
@@ -270,13 +315,31 @@ public final class MainView extends SurfaceView
|
||||
}
|
||||
}
|
||||
|
||||
drawFromMapPosition(canvas, area, playerPosition, model.player.iconID);
|
||||
if (!model.player.hasVFXRunning) {
|
||||
drawFromMapPosition(canvas, area, playerPosition, model.player.iconID);
|
||||
} else if (area.contains(playerPosition)) {
|
||||
int vfxElapsedTime = (int) (System.currentTimeMillis() - model.player.vfxStartTime);
|
||||
if (vfxElapsedTime > model.player.vfxDuration) vfxElapsedTime = model.player.vfxDuration;
|
||||
int x = ((model.player.position.x - mapViewArea.topLeft.x) * tileSize * vfxElapsedTime + ((model.player.lastPosition.x - mapViewArea.topLeft.x) * tileSize * (model.player.vfxDuration - vfxElapsedTime))) / model.player.vfxDuration;
|
||||
int y = ((model.player.position.y - mapViewArea.topLeft.y) * tileSize * vfxElapsedTime + ((model.player.lastPosition.y - mapViewArea.topLeft.y) * tileSize * (model.player.vfxDuration - vfxElapsedTime))) / model.player.vfxDuration;
|
||||
tiles.drawTile(canvas, model.player.iconID, x, y, mPaint);
|
||||
}
|
||||
for (MonsterSpawnArea a : currentMap.spawnAreas) {
|
||||
for (Monster m : a.monsters) {
|
||||
drawFromMapPosition(canvas, area, m.rectPosition, m.iconID);
|
||||
if (!m.hasVFXRunning) {
|
||||
drawFromMapPosition(canvas, area, m.rectPosition, m.iconID);
|
||||
} else if (area.intersects(m.rectPosition) || area.contains(m.lastPosition)) {
|
||||
int vfxElapsedTime = (int) (System.currentTimeMillis() - m.vfxStartTime);
|
||||
if (vfxElapsedTime > m.vfxDuration) vfxElapsedTime = m.vfxDuration;
|
||||
int x = ((m.position.x - mapViewArea.topLeft.x) * tileSize * vfxElapsedTime + ((m.lastPosition.x - mapViewArea.topLeft.x) * tileSize * (m.vfxDuration - vfxElapsedTime))) / m.vfxDuration;
|
||||
int y = ((m.position.y - mapViewArea.topLeft.y) * tileSize * vfxElapsedTime + ((m.lastPosition.y - mapViewArea.topLeft.y) * tileSize * (m.vfxDuration - vfxElapsedTime))) / m.vfxDuration;
|
||||
tiles.drawTile(canvas, m.iconID, x, y, mPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void doDrawRect_Above(Canvas canvas, CoordRect area) {
|
||||
tryDrawMapLayer(canvas, area, currentTileMap.currentLayout.layerAbove);
|
||||
|
||||
if (model.uiSelections.selectedPosition != null) {
|
||||
@@ -342,6 +405,7 @@ public final class MainView extends SurfaceView
|
||||
,Math.min(screenSizeTileCount.height, currentMap.size.height)
|
||||
);
|
||||
mapViewArea = new CoordRect(mapTopLeft, visibleNumberOfTiles);
|
||||
updateClip();
|
||||
|
||||
screenOffset.set(
|
||||
(surfaceSize.width - scaledTileSize * visibleNumberOfTiles.width) / 2
|
||||
@@ -370,8 +434,13 @@ public final class MainView extends SurfaceView
|
||||
mapTopLeft.y = Math.max(0, playerPosition.y - mapViewArea.size.height/2);
|
||||
mapTopLeft.y = Math.min(mapTopLeft.y, currentMap.size.height - mapViewArea.size.height);
|
||||
}
|
||||
updateClip();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateClip() {
|
||||
worldCoordsToScreenCords(mapViewArea, redrawClip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerMoved(Coord newPosition, Coord previousPosition) {
|
||||
@@ -492,6 +561,16 @@ public final class MainView extends SurfaceView
|
||||
public void onAnimationCompleted(VisualEffectAnimation animation) {
|
||||
redrawArea(animation.area, RedrawAreaDebugReason.EffectCompleted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewSpriteMoveFrame(SpriteMoveAnimation animation) {
|
||||
redrawMoveArea_(CoordRect.getBoundingRect(animation.origin, animation.destination), animation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpriteMoveCompleted(SpriteMoveAnimation animation) {
|
||||
redrawArea(CoordRect.getBoundingRect(animation.origin, animation.destination), RedrawAreaDebugReason.EffectCompleted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewTick() {
|
||||
|
||||
Reference in New Issue
Block a user