mirror of
https://github.com/OMGeeky/andors-trail.git
synced 2026-01-17 09:07:49 +01:00
Pull Request #75: Visual Glitch Fix
This commit is contained in:
@@ -19,11 +19,15 @@ import com.gpl.rpg.AndorsTrail.resource.VisualEffectCollection.VisualEffect;
|
||||
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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class VisualEffectController {
|
||||
private int effectCount = 0;
|
||||
|
||||
private final List<VisualEffectAnimation> activeAnimations = new ArrayList<>();
|
||||
private final ControllerContext controllers;
|
||||
private final WorldContext world;
|
||||
private final VisualEffectCollection effectTypes;
|
||||
@@ -38,8 +42,24 @@ public final class VisualEffectController {
|
||||
|
||||
public void startEffect(Coord position, VisualEffectCollection.VisualEffectID effectID, String displayValue, VisualEffectCompletedCallback callback, int callbackValue) {
|
||||
++effectCount;
|
||||
(new VisualEffectAnimation(effectTypes.getVisualEffect(effectID), position, displayValue, callback, callbackValue))
|
||||
.start();
|
||||
VisualEffectAnimation animation = new VisualEffectAnimation(effectTypes.getVisualEffect(effectID), position, displayValue, callback, callbackValue);
|
||||
activeAnimations.add(animation);
|
||||
animation.start();
|
||||
}
|
||||
|
||||
public void collectAndSendAnimations(VisualEffectAnimation animation) {
|
||||
List<Integer> tileIDs = new ArrayList<>();
|
||||
List<Integer> yOffsets = new ArrayList<>();
|
||||
//There are more elegant ways to fix this, but to get multiple effects to work, this is the quickest fix: increase all other effects that are being played
|
||||
//TODO: if someone got time to make this look nice, be my guest
|
||||
for (VisualEffectAnimation vanimation : activeAnimations) {
|
||||
if (vanimation != animation && vanimation.currentFrame < vanimation.effect.lastFrame) vanimation.currentFrame++;
|
||||
tileIDs.add(vanimation.effect.frameIconIDs[vanimation.currentFrame]);
|
||||
yOffsets.add(-2 * vanimation.currentFrame);
|
||||
L.log("VisualEffectController: collectAndSendAnimations: " + vanimation.currentFrame + " currentFrame, effectCount = " + effectCount);
|
||||
}
|
||||
L.log("VisualEffectController: collectAndSendAnimations: " + activeAnimations.size() + " animations to send, effectCount = " + effectCount);
|
||||
visualEffectFrameListeners.onNewAnimationFrames(activeAnimations, tileIDs, yOffsets);
|
||||
}
|
||||
|
||||
private VisualEffectCollection.VisualEffectID enqueuedEffectID = null;
|
||||
@@ -111,7 +131,7 @@ public final class VisualEffectController {
|
||||
if (callback != null) callback.onVisualEffectCompleted(callbackValue);
|
||||
visualEffectFrameListeners.onSpriteMoveCompleted(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void start() {
|
||||
actor.hasVFXRunning = true;
|
||||
@@ -134,7 +154,19 @@ public final class VisualEffectController {
|
||||
textPaint.setAlpha(255);
|
||||
textPaint.setTextAlign(Align.CENTER);
|
||||
}
|
||||
|
||||
|
||||
public static class VisualEffectData {
|
||||
public final VisualEffectAnimation effect;
|
||||
public final int tileID;
|
||||
public final int textYOffset;
|
||||
|
||||
public VisualEffectData(VisualEffectAnimation effect, int tileID, int textYOffset) {
|
||||
this.effect = effect;
|
||||
this.tileID = tileID;
|
||||
this.textYOffset = textYOffset;
|
||||
}
|
||||
}
|
||||
|
||||
public final class VisualEffectAnimation extends Handler implements Runnable {
|
||||
|
||||
@Override
|
||||
@@ -151,17 +183,23 @@ public final class VisualEffectController {
|
||||
++currentFrame;
|
||||
int frame = currentFrame;
|
||||
|
||||
int tileID = effect.frameIconIDs[frame];
|
||||
int textYOffset = -2 * (frame);
|
||||
// int tileID = effect.frameIconIDs[frame];
|
||||
// int textYOffset = -2 * (frame);
|
||||
|
||||
if (frame >= beginFadeAtFrame && displayText != null) {
|
||||
textPaint.setAlpha(255 * (effect.lastFrame - frame) / (effect.lastFrame - beginFadeAtFrame));
|
||||
}
|
||||
|
||||
area.topLeft.y = position.y - 1;
|
||||
visualEffectFrameListeners.onNewAnimationFrame(this, tileID, textYOffset);
|
||||
|
||||
//Fall back to onNewAnimationFrame if the new effect handle process is no longer desired
|
||||
// visualEffectFrameListeners.onNewAnimationFrame(this, tileID, textYOffset);
|
||||
collectAndSendAnimations(this);
|
||||
}
|
||||
|
||||
private void onCompleted() {
|
||||
--effectCount;
|
||||
activeAnimations.remove(this);
|
||||
visualEffectFrameListeners.onAnimationCompleted(this);
|
||||
if (callback != null) callback.onVisualEffectCompleted(callbackValue);
|
||||
}
|
||||
|
||||
@@ -4,8 +4,11 @@ import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.SpriteMoveAnima
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.VisualEffectAnimation;
|
||||
import com.gpl.rpg.AndorsTrail.util.CoordRect;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface VisualEffectFrameListener {
|
||||
void onNewAnimationFrame(VisualEffectAnimation animation, int tileID, int textYOffset);
|
||||
void onNewAnimationFrames(List<VisualEffectAnimation> animations, List<Integer> tileIDs, List<Integer> textYOffsets);
|
||||
void onAnimationCompleted(VisualEffectAnimation animation);
|
||||
void onSpriteMoveStarted(SpriteMoveAnimation animation);
|
||||
void onNewSpriteMoveFrame(SpriteMoveAnimation animation);
|
||||
|
||||
@@ -5,12 +5,18 @@ import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.VisualEffectAni
|
||||
import com.gpl.rpg.AndorsTrail.util.CoordRect;
|
||||
import com.gpl.rpg.AndorsTrail.util.ListOfListeners;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class VisualEffectFrameListeners extends ListOfListeners<VisualEffectFrameListener> implements VisualEffectFrameListener {
|
||||
|
||||
private final Function3<VisualEffectFrameListener, VisualEffectAnimation, Integer, Integer> onNewAnimationFrame = new Function3<VisualEffectFrameListener, VisualEffectAnimation, Integer, Integer>() {
|
||||
@Override public void call(VisualEffectFrameListener listener, VisualEffectAnimation animation, Integer tileID, Integer textYOffset) { listener.onNewAnimationFrame(animation, tileID, textYOffset); }
|
||||
};
|
||||
|
||||
private final Function3<VisualEffectFrameListener, List<VisualEffectAnimation>, List<Integer>, List<Integer>> onNewAnimationFrames = new Function3<VisualEffectFrameListener, List<VisualEffectAnimation>, List<Integer>, List<Integer>>() {
|
||||
@Override public void call(VisualEffectFrameListener listener, List<VisualEffectAnimation> animations, List<Integer> tileIDs, List<Integer> textYOffsets) { listener.onNewAnimationFrames(animations, tileIDs, textYOffsets); }
|
||||
};
|
||||
|
||||
private final Function1<VisualEffectFrameListener, VisualEffectAnimation> onAnimationCompleted = new Function1<VisualEffectFrameListener, VisualEffectAnimation>() {
|
||||
@Override public void call(VisualEffectFrameListener listener, VisualEffectAnimation animation) { listener.onAnimationCompleted(animation); }
|
||||
};
|
||||
@@ -36,6 +42,11 @@ public final class VisualEffectFrameListeners extends ListOfListeners<VisualEffe
|
||||
callAllListeners(this.onNewAnimationFrame, animation, tileID, textYOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewAnimationFrames(List<VisualEffectAnimation> animations, List<Integer> tileIDs, List<Integer> textYOffsets) {
|
||||
callAllListeners(this.onNewAnimationFrames, animations, tileIDs, textYOffsets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCompleted(VisualEffectAnimation animation) {
|
||||
callAllListeners(this.onAnimationCompleted, animation);
|
||||
|
||||
@@ -30,6 +30,18 @@ public final class CoordRect {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static CoordRect union(CoordRect r1, CoordRect r2) {
|
||||
int left = Math.min(r1.topLeft.x, r2.topLeft.x);
|
||||
int top = Math.min(r1.topLeft.y, r2.topLeft.y);
|
||||
int right = Math.max(r1.topLeft.x + r1.size.width, r2.topLeft.x + r2.size.width);
|
||||
int bottom = Math.max(r1.topLeft.y + r1.size.height, r2.topLeft.y + r2.size.height);
|
||||
|
||||
int width = right - left;
|
||||
int height = bottom - top;
|
||||
|
||||
return new CoordRect(new Coord(left, top), new Size(width, height));
|
||||
}
|
||||
|
||||
/*
|
||||
public static boolean contains(final int x, final int y, final Size size, final Coord p) {
|
||||
if (p.x < x) return false;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.gpl.rpg.AndorsTrail.view;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences;
|
||||
@@ -8,6 +10,7 @@ import com.gpl.rpg.AndorsTrail.context.ControllerContext;
|
||||
import com.gpl.rpg.AndorsTrail.context.WorldContext;
|
||||
import com.gpl.rpg.AndorsTrail.controller.Constants;
|
||||
import com.gpl.rpg.AndorsTrail.controller.InputController;
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController;
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.BloodSplatter;
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.SpriteMoveAnimation;
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.VisualEffectAnimation;
|
||||
@@ -29,6 +32,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;
|
||||
|
||||
import android.content.Context;
|
||||
@@ -76,6 +80,8 @@ public final class MainView extends SurfaceView
|
||||
private final int[] debugColors = {Color.MAGENTA, Color.BLUE, Color.CYAN, Color.GREEN, Color.YELLOW, Color.RED, Color.WHITE};
|
||||
private final CoordRect p1x1 = new CoordRect(new Coord(), new Size(1,1));
|
||||
private boolean hasSurface = false;
|
||||
|
||||
private List<VisualEffectController.VisualEffectData> activeEffects = new ArrayList<>();
|
||||
|
||||
//DEBUG
|
||||
// private Coord touchedTile = null;
|
||||
@@ -301,6 +307,68 @@ public final class MainView extends SurfaceView
|
||||
if (c != null) holder.unlockCanvasAndPost(c);
|
||||
}
|
||||
}
|
||||
|
||||
private void redrawArea_(CoordRect area, final List<VisualEffectAnimation> effects, List<Integer> tileIDs, List<Integer> textYOffsets) {
|
||||
if (!hasSurface) return;
|
||||
|
||||
|
||||
if (!currentMap.intersects(area)) return;
|
||||
if (!mapViewArea.intersects(area)) return;
|
||||
|
||||
if (shouldRedrawEverything()) {
|
||||
area = mapViewArea;
|
||||
}
|
||||
|
||||
calculateRedrawRect(area);
|
||||
redrawRect.intersect(redrawClip);
|
||||
Canvas c = null;
|
||||
try {
|
||||
c = holder.lockCanvas(redrawRect);
|
||||
if (area != mapViewArea) {
|
||||
if (isRedrawRectWholeScreen(redrawRect)) {
|
||||
area = mapViewArea;
|
||||
}
|
||||
}
|
||||
if (area == mapViewArea) {
|
||||
area = adaptAreaToScrolling(area);
|
||||
}
|
||||
|
||||
synchronized (holder) { synchronized (tiles) {
|
||||
int xScroll = 0;
|
||||
int yScroll = 0;
|
||||
if (scrolling && scrollVector != null) {
|
||||
xScroll = (int) (tileSize - (tileSize * (System.currentTimeMillis() - scrollStartTime) / SCROLL_DURATION));
|
||||
xScroll = Math.max(0, Math.min(tileSize, xScroll)) * scrollVector.x;
|
||||
yScroll = (int) (tileSize - (tileSize * (System.currentTimeMillis() - scrollStartTime) / SCROLL_DURATION));
|
||||
yScroll = Math.max(0, Math.min(tileSize, yScroll)) * scrollVector.y;
|
||||
}
|
||||
c.clipRect(redrawClip);
|
||||
c.translate(screenOffset.x + xScroll, screenOffset.y + yScroll);
|
||||
doDrawRect(c, area);
|
||||
// Render each effect
|
||||
renderEffects(c);
|
||||
} }
|
||||
} finally {
|
||||
if (c != null) holder.unlockCanvasAndPost(c);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderEffects(Canvas canvas) {
|
||||
for (VisualEffectController.VisualEffectData data : activeEffects) {
|
||||
VisualEffectAnimation effect = data.effect;
|
||||
int tileID = data.tileID;
|
||||
int textYOffset = data.textYOffset;
|
||||
|
||||
L.log("Rendering effect at position: " + effect.position + " with tileID: " + tileID + " and textYOffset: " + textYOffset);
|
||||
|
||||
drawFromMapPosition(canvas, effect.area, effect.position, tileID);
|
||||
if (effect.displayText != null) {
|
||||
drawEffectText(canvas, effect.area, effect, textYOffset, effect.getTextPaint());
|
||||
}
|
||||
}
|
||||
L.log("Total effects rendered: " + activeEffects.size());
|
||||
activeEffects.clear();
|
||||
}
|
||||
|
||||
private boolean isRedrawRectWholeScreen(Rect redrawRect) {
|
||||
// if (redrawRect.width() < mapViewArea.size.width * scaledTileSize) return false;
|
||||
@@ -322,6 +390,22 @@ public final class MainView extends SurfaceView
|
||||
// if (shouldRedrawEverythingForVisualEffect()) area = mapViewArea;
|
||||
redrawArea_(area, effect, tileID, textYOffset);
|
||||
}
|
||||
private void redrawAreaWithEffect(List<VisualEffectAnimation> effects, List<Integer> tileIDs, List<Integer> textYOffsets) {
|
||||
CoordRect area = null;
|
||||
for (int i = 0; i < effects.size(); i++) {
|
||||
VisualEffectAnimation effect = effects.get(i);
|
||||
activeEffects.add(new VisualEffectController.VisualEffectData(effect, tileIDs.get(i), textYOffsets.get(i)));
|
||||
if (area == null) {
|
||||
area = effect.area;
|
||||
} else {
|
||||
area = CoordRect.union(area, effect.area);
|
||||
}
|
||||
}
|
||||
if (area != null) {
|
||||
redrawArea_(area, effects, tileIDs, textYOffsets);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearCanvas() {
|
||||
if (!hasSurface) return;
|
||||
Canvas c = null;
|
||||
@@ -798,6 +882,12 @@ public final class MainView extends SurfaceView
|
||||
redrawAreaWithEffect(animation, tileID, textYOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewAnimationFrames(List<VisualEffectAnimation> animations, List<Integer> tileIDs, List<Integer> textYOffsets) {
|
||||
L.log("Rendering " + animations.size() + " effects");
|
||||
redrawAreaWithEffect(animations, tileIDs, textYOffsets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCompleted(VisualEffectAnimation animation) {
|
||||
redrawArea(animation.area, RedrawAreaDebugReason.EffectCompleted);
|
||||
|
||||
Reference in New Issue
Block a user