mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Merge branch 'master' into 'master'
[Mobile] Add Player Avatar Animation See merge request core-developers/forge!5388
This commit is contained in:
@@ -781,6 +781,8 @@ public class Game {
|
||||
}
|
||||
|
||||
public void onPlayerLost(Player p) {
|
||||
//set for Avatar
|
||||
p.setHasLost(true);
|
||||
// Rule 800.4 Losing a Multiplayer game
|
||||
CardCollectionView cards = this.getCardsInGame();
|
||||
boolean planarControllerLost = false;
|
||||
|
||||
@@ -1306,6 +1306,7 @@ public class GameAction {
|
||||
orderedNoRegCreats = true;
|
||||
}
|
||||
for (Card c : noRegCreats) {
|
||||
c.updateWasDestroyed(true);
|
||||
sacrificeDestroy(c, null, table, null);
|
||||
}
|
||||
}
|
||||
@@ -1444,6 +1445,7 @@ public class GameAction {
|
||||
|
||||
// cleanup aura
|
||||
if (c.isAura() && c.isInPlay() && !c.isEnchanting()) {
|
||||
c.updateWasDestroyed(true);
|
||||
sacrificeDestroy(c, null, table, null);
|
||||
checkAgain = true;
|
||||
}
|
||||
@@ -1596,6 +1598,8 @@ public class GameAction {
|
||||
|
||||
for (Card c : list) {
|
||||
if (c.getCounters(CounterEnumType.LOYALTY) <= 0) {
|
||||
//for animation
|
||||
c.updateWasDestroyed(true);
|
||||
sacrificeDestroy(c, null, table, null);
|
||||
// Play the Destroy sound
|
||||
game.fireEvent(new GameEventCardDestroyed());
|
||||
@@ -1659,6 +1663,8 @@ public class GameAction {
|
||||
"You have multiple legendary permanents named \""+name+"\" in play.\n\nChoose the one to stay on battlefield (the rest will be moved to graveyard)", null);
|
||||
for (Card c: cc) {
|
||||
if (c != toKeep) {
|
||||
//for animation
|
||||
c.updateWasDestroyed(true);
|
||||
sacrificeDestroy(c, null, table, null);
|
||||
}
|
||||
}
|
||||
@@ -1693,6 +1699,8 @@ public class GameAction {
|
||||
}
|
||||
|
||||
for (Card c : worlds) {
|
||||
//for animation
|
||||
c.updateWasDestroyed(true);
|
||||
sacrificeDestroy(c, null, table, null);
|
||||
game.fireEvent(new GameEventCardDestroyed());
|
||||
}
|
||||
@@ -1707,6 +1715,7 @@ public class GameAction {
|
||||
|
||||
c.getController().addSacrificedThisTurn(c, source);
|
||||
|
||||
c.updateWasDestroyed(true);
|
||||
return sacrificeDestroy(c, source, table, params);
|
||||
}
|
||||
|
||||
@@ -1733,6 +1742,8 @@ public class GameAction {
|
||||
activator = sa.getActivatingPlayer();
|
||||
}
|
||||
|
||||
//for animation
|
||||
c.updateWasDestroyed(true);
|
||||
// Play the Destroy sound
|
||||
game.fireEvent(new GameEventCardDestroyed());
|
||||
|
||||
|
||||
@@ -3029,6 +3029,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
view.updateTokenCard(this);
|
||||
}
|
||||
|
||||
public void updateWasDestroyed(boolean value) {
|
||||
view.updateWasDestroyed(value);
|
||||
}
|
||||
|
||||
public final Card getCopiedPermanent() {
|
||||
return copiedPermanent;
|
||||
}
|
||||
|
||||
@@ -411,6 +411,15 @@ public class CardView extends GameEntityView {
|
||||
set(TrackableProperty.CurrentRoom, c.getCurrentRoom());
|
||||
}
|
||||
|
||||
public boolean wasDestroyed() {
|
||||
if (get(TrackableProperty.WasDestroyed) == null)
|
||||
return false;
|
||||
return get(TrackableProperty.WasDestroyed);
|
||||
}
|
||||
void updateWasDestroyed(boolean value) {
|
||||
set(TrackableProperty.WasDestroyed, value);
|
||||
}
|
||||
|
||||
public int getClassLevel() {
|
||||
return get(TrackableProperty.ClassLevel);
|
||||
}
|
||||
|
||||
@@ -559,6 +559,8 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
return 0;
|
||||
}
|
||||
life -= toLose;
|
||||
//for Avatar animation
|
||||
view.setAvatarWasDamaged(true);
|
||||
view.updateLife(this);
|
||||
lifeLost = toLose;
|
||||
if (manaBurn) {
|
||||
@@ -2636,6 +2638,8 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
public void updateAvatar() {
|
||||
view.updateAvatarIndex(this);
|
||||
view.updateAvatarCardImageKey(this);
|
||||
view.setAvatarWasDamaged(false);
|
||||
view.setHasLost(false);
|
||||
}
|
||||
|
||||
public void updateSleeve() {
|
||||
@@ -2848,6 +2852,14 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
view.setIsExtraTurn(b);
|
||||
}
|
||||
|
||||
public void setHasLost(boolean b) {
|
||||
view.setHasLost(b);
|
||||
}
|
||||
|
||||
public void setAvatarWasDamaged(boolean val) {
|
||||
view.setAvatarWasDamaged(val);
|
||||
}
|
||||
|
||||
public int getExtraTurnCount() {
|
||||
return view.getExtraTurnCount();
|
||||
}
|
||||
|
||||
@@ -214,6 +214,26 @@ public class PlayerView extends GameEntityView {
|
||||
set(TrackableProperty.IsExtraTurn, val);
|
||||
}
|
||||
|
||||
public boolean getHasLost() {
|
||||
if (get(TrackableProperty.HasLost) == null)
|
||||
return false;
|
||||
return get(TrackableProperty.HasLost);
|
||||
}
|
||||
|
||||
public void setHasLost(final boolean val) {
|
||||
set(TrackableProperty.HasLost, val);
|
||||
}
|
||||
|
||||
public boolean getAvatarWasDamaged() {
|
||||
if (get(TrackableProperty.WasAvatarDamaged) == null)
|
||||
return false;
|
||||
return get(TrackableProperty.WasAvatarDamaged);
|
||||
}
|
||||
|
||||
public void setAvatarWasDamaged(final boolean val) {
|
||||
set(TrackableProperty.WasAvatarDamaged, val);
|
||||
}
|
||||
|
||||
public int getExtraTurnCount() {
|
||||
return get(TrackableProperty.ExtraTurnCount);
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ public enum TrackableProperty {
|
||||
GainControlTargets(TrackableTypes.CardViewCollectionType),
|
||||
CloneOrigin(TrackableTypes.CardViewType),
|
||||
ExiledWith(TrackableTypes.CardViewType),
|
||||
WasDestroyed(TrackableTypes.BooleanType),
|
||||
|
||||
ImprintedCards(TrackableTypes.CardViewCollectionType),
|
||||
HauntedBy(TrackableTypes.CardViewCollectionType),
|
||||
@@ -199,6 +200,8 @@ public enum TrackableProperty {
|
||||
ExtraTurnCount(TrackableTypes.IntegerType),
|
||||
HasPriority(TrackableTypes.BooleanType),
|
||||
HasDelirium(TrackableTypes.BooleanType),
|
||||
WasAvatarDamaged(TrackableTypes.BooleanType),
|
||||
HasLost(TrackableTypes.BooleanType),
|
||||
|
||||
//SpellAbility
|
||||
HostCard(TrackableTypes.CardViewType),
|
||||
|
||||
@@ -39,7 +39,7 @@ public class Graphics {
|
||||
private int failedClipCount;
|
||||
private float alphaComposite = 1;
|
||||
private int transformCount = 0;
|
||||
private String sVertex = "uniform mat4 u_projTrans;\n" +
|
||||
private final String sVertex = "uniform mat4 u_projTrans;\n" +
|
||||
"\n" +
|
||||
"attribute vec4 a_position;\n" +
|
||||
"attribute vec2 a_texCoord0;\n" +
|
||||
@@ -55,7 +55,7 @@ public class Graphics {
|
||||
" v_texCoord = a_texCoord0;\n" +
|
||||
" v_color = a_color;\n" +
|
||||
"}";
|
||||
private String sFragment = "#ifdef GL_ES\n" +
|
||||
private final String sFragment = "#ifdef GL_ES\n" +
|
||||
"precision mediump float;\n" +
|
||||
"precision mediump int;\n" +
|
||||
"#endif\n" +
|
||||
@@ -103,8 +103,38 @@ public class Graphics {
|
||||
"\n" +
|
||||
" gl_FragColor = vec4(u_color,alpha);\n" +
|
||||
"}";
|
||||
private final String vertexShaderGray = "attribute vec4 a_position;\n" +
|
||||
"attribute vec4 a_color;\n" +
|
||||
"attribute vec2 a_texCoord0;\n" +
|
||||
"\n" +
|
||||
"uniform mat4 u_projTrans;\n" +
|
||||
"\n" +
|
||||
"varying vec4 v_color;\n" +
|
||||
"varying vec2 v_texCoords;\n" +
|
||||
"\n" +
|
||||
"void main() {\n" +
|
||||
" v_color = a_color;\n" +
|
||||
" v_texCoords = a_texCoord0;\n" +
|
||||
" gl_Position = u_projTrans * a_position;\n" +
|
||||
"}";
|
||||
private final String fragmentShaderGray = "#ifdef GL_ES\n" +
|
||||
" precision mediump float;\n" +
|
||||
"#endif\n" +
|
||||
"\n" +
|
||||
"varying vec4 v_color;\n" +
|
||||
"varying vec2 v_texCoords;\n" +
|
||||
"uniform sampler2D u_texture;\n" +
|
||||
"uniform float u_grayness;\n" +
|
||||
"\n" +
|
||||
"void main() {\n" +
|
||||
" vec4 c = v_color * texture2D(u_texture, v_texCoords);\n" +
|
||||
" float grey = dot( c.rgb, vec3(0.22, 0.707, 0.071) );\n" +
|
||||
" vec3 blendedColor = mix(c.rgb, vec3(grey), u_grayness);\n" +
|
||||
" gl_FragColor = vec4(blendedColor.rgb, c.a);\n" +
|
||||
"}";
|
||||
|
||||
private final ShaderProgram shaderOutline = new ShaderProgram(sVertex, sFragment);
|
||||
private final ShaderProgram shaderGrayscale = new ShaderProgram(vertexShaderGray, fragmentShaderGray);
|
||||
|
||||
public Graphics() {
|
||||
ShaderProgram.pedantic = false;
|
||||
@@ -632,6 +662,16 @@ public class Graphics {
|
||||
shapeRenderer.end();
|
||||
}
|
||||
|
||||
public void setColorRGBA(float r, float g, float b, float alphaComposite0) {
|
||||
alphaComposite = alphaComposite0;
|
||||
batch.setColor(new Color(r, g, b, alphaComposite));
|
||||
}
|
||||
|
||||
public void resetColorRGBA(float alphaComposite0) {
|
||||
alphaComposite = alphaComposite0;
|
||||
batch.setColor(Color.WHITE);
|
||||
}
|
||||
|
||||
public void setAlphaComposite(float alphaComposite0) {
|
||||
alphaComposite = alphaComposite0;
|
||||
batch.setColor(new Color(1, 1, 1, alphaComposite));
|
||||
@@ -662,6 +702,76 @@ public class Graphics {
|
||||
image.draw(this, x, y, w, h);
|
||||
fillRoundRect(borderColor, x+1, y+1, w-1.5f, h-1.5f, (h-w)/10);//used by zoom let some edges show...
|
||||
}
|
||||
public void drawAvatarImage(FImage image, float x, float y, float w, float h, boolean drawGrayscale) {
|
||||
if (!drawGrayscale) {
|
||||
image.draw(this, x, y, w, h);
|
||||
} else {
|
||||
batch.end();
|
||||
shaderGrayscale.bind();
|
||||
shaderGrayscale.setUniformf("u_grayness", 1f);
|
||||
batch.setShader(shaderGrayscale);
|
||||
batch.begin();
|
||||
//draw gray
|
||||
image.draw(this, x, y, w, h);
|
||||
//reset
|
||||
batch.end();
|
||||
batch.setShader(null);
|
||||
batch.begin();
|
||||
}
|
||||
}
|
||||
public void drawCardImage(FImage image, float x, float y, float w, float h, boolean drawGrayscale) {
|
||||
if (!drawGrayscale) {
|
||||
image.draw(this, x, y, w, h);
|
||||
} else {
|
||||
batch.end();
|
||||
shaderGrayscale.bind();
|
||||
shaderGrayscale.setUniformf("u_grayness", 1f);
|
||||
batch.setShader(shaderGrayscale);
|
||||
batch.begin();
|
||||
//draw gray
|
||||
image.draw(this, x, y, w, h);
|
||||
//reset
|
||||
batch.end();
|
||||
batch.setShader(null);
|
||||
batch.begin();
|
||||
}
|
||||
}
|
||||
public void drawCardImage(Texture image, float x, float y, float w, float h, boolean drawGrayscale) {
|
||||
if (!drawGrayscale) {
|
||||
batch.draw(image, adjustX(x), adjustY(y, h), w, h);
|
||||
} else {
|
||||
batch.end();
|
||||
shaderGrayscale.bind();
|
||||
shaderGrayscale.setUniformf("u_grayness", 1f);
|
||||
batch.setShader(shaderGrayscale);
|
||||
batch.begin();
|
||||
//draw gray
|
||||
batch.draw(image, adjustX(x), adjustY(y, h), w, h);
|
||||
//reset
|
||||
batch.end();
|
||||
batch.setShader(null);
|
||||
batch.begin();
|
||||
}
|
||||
}
|
||||
public void drawCardImage(TextureRegion image, float x, float y, float w, float h, boolean drawGrayscale) {
|
||||
if (image != null) {
|
||||
if (!drawGrayscale) {
|
||||
batch.draw(image, adjustX(x), adjustY(y, h), w, h);
|
||||
} else {
|
||||
batch.end();
|
||||
shaderGrayscale.bind();
|
||||
shaderGrayscale.setUniformf("u_grayness", 1f);
|
||||
batch.setShader(shaderGrayscale);
|
||||
batch.begin();
|
||||
//draw gray
|
||||
batch.draw(image, adjustX(x), adjustY(y, h), w, h);
|
||||
//reset
|
||||
batch.end();
|
||||
batch.setShader(null);
|
||||
batch.begin();
|
||||
}
|
||||
}
|
||||
}
|
||||
public void drawImage(FImage image, float x, float y, float w, float h) {
|
||||
drawImage(image, x, y, w, h, false);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ public class FSkin {
|
||||
private static boolean loaded = false;
|
||||
public static Texture hdLogo = null;
|
||||
public static Texture overlay_alpha = null;
|
||||
public static Texture scratch = null;
|
||||
|
||||
public static void changeSkin(final String skinName) {
|
||||
final ForgePreferences prefs = FModel.getPreferences();
|
||||
@@ -142,6 +143,14 @@ public class FSkin {
|
||||
} else {
|
||||
overlay_alpha = null;
|
||||
}
|
||||
final FileHandle scratch_overlay = getDefaultSkinFile("scratch.png");
|
||||
if (scratch_overlay.exists()) {
|
||||
Texture txScratch = new Texture(scratch_overlay, true);
|
||||
txScratch.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
|
||||
scratch = txScratch;
|
||||
} else {
|
||||
scratch = null;
|
||||
}
|
||||
|
||||
if (splashScreen != null) {
|
||||
final FileHandle f = getSkinFile("bg_splash.png");
|
||||
|
||||
@@ -590,9 +590,9 @@ public class CardRenderer {
|
||||
g.setAlphaComposite(oldAlpha);
|
||||
} else if (showsleeves) {
|
||||
if (!card.isForeTold())
|
||||
g.drawImage(sleeves, x, y, w, h);
|
||||
g.drawCardImage(sleeves, x, y, w, h, card.wasDestroyed());
|
||||
else
|
||||
g.drawImage(image, x, y, w, h);
|
||||
g.drawCardImage(image, x, y, w, h, card.wasDestroyed());
|
||||
} else {
|
||||
if(FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ROTATE_PLANE_OR_PHENOMENON)
|
||||
&& (card.getCurrentState().isPhenomenon() || card.getCurrentState().isPlane()) && rotate){
|
||||
@@ -610,19 +610,19 @@ public class CardRenderer {
|
||||
} else {
|
||||
if (Forge.enableUIMask.equals("Full") && canshow) {
|
||||
if (ImageCache.isBorderlessCardArt(image))
|
||||
g.drawImage(image, x, y, w, h);
|
||||
g.drawCardImage(image, x, y, w, h, card.wasDestroyed());
|
||||
else {
|
||||
boolean t = (card.getCurrentState().getOriginalColors() != card.getCurrentState().getColors()) || card.getCurrentState().hasChangeColors();
|
||||
g.drawBorderImage(ImageCache.getBorderImage(image.toString(), canshow), ImageCache.borderColor(image), ImageCache.getTint(card, image), x, y, w, h, t); //tint check for changed colors
|
||||
g.drawImage(ImageCache.croppedBorderImage(image), x + radius / 2.4f-minusxy, y + radius / 2-minusxy, w * croppedArea, h * croppedArea);
|
||||
g.drawCardImage(ImageCache.croppedBorderImage(image), x + radius / 2.4f-minusxy, y + radius / 2-minusxy, w * croppedArea, h * croppedArea, card.wasDestroyed());
|
||||
}
|
||||
} else if (Forge.enableUIMask.equals("Crop") && canshow) {
|
||||
g.drawImage(ImageCache.croppedBorderImage(image), x, y, w, h);
|
||||
g.drawCardImage(ImageCache.croppedBorderImage(image), x, y, w, h, card.wasDestroyed());
|
||||
} else {
|
||||
if (canshow)
|
||||
g.drawImage(image, x, y, w, h);
|
||||
g.drawCardImage(image, x, y, w, h, card.wasDestroyed());
|
||||
else // draw card back sleeves
|
||||
g.drawImage(sleeves, x, y, w, h);
|
||||
g.drawCardImage(sleeves, x, y, w, h, card.wasDestroyed());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package forge.screens.match.views;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
|
||||
import forge.Forge;
|
||||
import forge.Graphics;
|
||||
import forge.animation.ForgeAnimation;
|
||||
import forge.assets.FImage;
|
||||
import forge.assets.FSkin;
|
||||
import forge.assets.FSkinFont;
|
||||
import forge.game.card.CounterEnumType;
|
||||
import forge.game.player.PlayerView;
|
||||
@@ -21,19 +24,61 @@ public class VAvatar extends FDisplayObject {
|
||||
|
||||
private final PlayerView player;
|
||||
private final FImage image;
|
||||
private AvatarAnimation avatarAnimation;
|
||||
|
||||
public VAvatar(PlayerView player0) {
|
||||
player = player0;
|
||||
image = MatchController.getPlayerAvatar(player);
|
||||
setSize(WIDTH, HEIGHT);
|
||||
avatarAnimation = new AvatarAnimation();
|
||||
}
|
||||
|
||||
public VAvatar(PlayerView player0, float size) {
|
||||
player = player0;
|
||||
image = MatchController.getPlayerAvatar(player);
|
||||
setSize(size, size);
|
||||
avatarAnimation = new AvatarAnimation();
|
||||
}
|
||||
private class AvatarAnimation extends ForgeAnimation {
|
||||
private static final float DURATION = 0.6f;
|
||||
private float progress = 0;
|
||||
private boolean finished;
|
||||
Texture scratch = FSkin.scratch;
|
||||
|
||||
private void drawAvatar(Graphics g, FImage image, float x, float y, float w, float h) {
|
||||
float percentage = progress / DURATION;
|
||||
if (percentage < 0) {
|
||||
percentage = 0;
|
||||
} else if (percentage > 1) {
|
||||
percentage = 1;
|
||||
//animation finished clear avatar red overlay
|
||||
player.setAvatarWasDamaged(false);
|
||||
}
|
||||
float mod = w/2f;
|
||||
if (scratch == null) {
|
||||
g.setColorRGBA(1, percentage, percentage, g.getfloatAlphaComposite());
|
||||
g.drawAvatarImage(image, x, y, w, h, player.getHasLost());
|
||||
g.resetColorRGBA(g.getfloatAlphaComposite());
|
||||
} else {
|
||||
g.drawAvatarImage(image, x, y, w, h, player.getHasLost());
|
||||
g.setAlphaComposite(1-(percentage*1));
|
||||
g.drawImage(scratch, x-mod/2, y-mod/2, w+mod, h+mod);
|
||||
g.resetAlphaComposite();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean advance(float dt) {
|
||||
progress += dt;
|
||||
return progress < DURATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEnd(boolean endingAll) {
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean tap(float x, float y, int count) {
|
||||
ThreadUtil.invokeInGameThread(new Runnable() { //must invoke in game thread in case a dialog needs to be shown
|
||||
@@ -68,7 +113,19 @@ public class VAvatar extends FDisplayObject {
|
||||
public void draw(Graphics g) {
|
||||
float w = getWidth();
|
||||
float h = getHeight();
|
||||
g.drawImage(image, 0, 0, w, h);
|
||||
|
||||
if (avatarAnimation != null && !MatchController.instance.getGameView().isMatchOver()) {
|
||||
if (player.getAvatarWasDamaged() && avatarAnimation.progress < 1) {
|
||||
avatarAnimation.start();
|
||||
avatarAnimation.drawAvatar(g, image, 0, 0, w, h);
|
||||
} else {
|
||||
avatarAnimation.progress = 0;
|
||||
g.drawAvatarImage(image, 0, 0, w, h, player.getHasLost());
|
||||
}
|
||||
} else {
|
||||
g.drawAvatarImage(image, 0, 0, w, h, player.getHasLost());
|
||||
}
|
||||
|
||||
|
||||
if (Forge.altPlayerLayout && !Forge.altZoneTabs && Forge.isLandscapeMode())
|
||||
return;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package forge.toolbox;
|
||||
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import forge.Forge;
|
||||
import forge.Graphics;
|
||||
import forge.animation.ForgeAnimation;
|
||||
import forge.assets.FSkin;
|
||||
import forge.card.CardRenderer;
|
||||
import forge.card.CardRenderer.CardStackPosition;
|
||||
import forge.game.card.CardView;
|
||||
@@ -22,6 +24,7 @@ public class FCardPanel extends FDisplayObject {
|
||||
private boolean wasTapped;
|
||||
CardTapAnimation tapAnimation;
|
||||
CardUnTapAnimation untapAnimation;
|
||||
CardDestroyedAnimation cardDestroyedAnimation;
|
||||
|
||||
public FCardPanel() {
|
||||
this(null);
|
||||
@@ -30,6 +33,7 @@ public class FCardPanel extends FDisplayObject {
|
||||
card = card0;
|
||||
tapAnimation = new CardTapAnimation();
|
||||
untapAnimation = new CardUnTapAnimation();
|
||||
cardDestroyedAnimation = new CardDestroyedAnimation();
|
||||
}
|
||||
|
||||
public CardView getCard() {
|
||||
@@ -84,7 +88,46 @@ public class FCardPanel extends FDisplayObject {
|
||||
protected CardStackPosition getStackPosition() {
|
||||
return CardStackPosition.Top;
|
||||
}
|
||||
private class CardDestroyedAnimation extends ForgeAnimation {
|
||||
private static final float DURATION = 0.6f;
|
||||
private float progress = 0;
|
||||
private boolean finished;
|
||||
private Texture scratch = FSkin.scratch;
|
||||
|
||||
private void drawCard(Graphics g, CardView card, float x, float y, float w, float h, float edgeOffset) {
|
||||
float percentage = progress / DURATION;
|
||||
if (percentage < 0) {
|
||||
percentage = 0;
|
||||
} else if (percentage > 1) {
|
||||
percentage = 1;
|
||||
}
|
||||
float mod = (w/3f)*percentage;
|
||||
float oldAlpha = g.getfloatAlphaComposite();
|
||||
if (tapped) {
|
||||
g.startRotateTransform(x + edgeOffset, y + h - edgeOffset, getTappedAngle());
|
||||
}
|
||||
CardRenderer.drawCardWithOverlays(g, card, x-mod/2, y-mod/2, w+mod, h+mod, getStackPosition());
|
||||
if (scratch != null) {
|
||||
g.setAlphaComposite(0.6f);
|
||||
g.drawCardImage(scratch, x-mod/2, y-mod/2, w+mod, h+mod, true);
|
||||
g.setAlphaComposite(oldAlpha);
|
||||
}
|
||||
if (tapped) {
|
||||
g.endTransform();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean advance(float dt) {
|
||||
progress += dt;
|
||||
return progress < DURATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEnd(boolean endingAll) {
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
private class CardUnTapAnimation extends ForgeAnimation {
|
||||
private static final float DURATION = 0.14f;
|
||||
private float progress = 0;
|
||||
@@ -163,8 +206,21 @@ public class FCardPanel extends FDisplayObject {
|
||||
w = h / ASPECT_RATIO;
|
||||
}
|
||||
float edgeOffset = w / 2f;
|
||||
if (isGameFast) {
|
||||
//don't animate if fast
|
||||
|
||||
if (card.wasDestroyed()) {
|
||||
if (cardDestroyedAnimation != null) {
|
||||
if (cardDestroyedAnimation.progress < 1) {
|
||||
cardDestroyedAnimation.start();
|
||||
cardDestroyedAnimation.drawCard(g, card, x, y, w, h, edgeOffset);
|
||||
} else {
|
||||
cardDestroyedAnimation.progress = 0;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (isGameFast || MatchController.instance.getGameView().isMatchOver()) {
|
||||
//don't animate if game is fast or match is over
|
||||
if (tapped) {
|
||||
g.startRotateTransform(x + edgeOffset, y + h - edgeOffset, getTappedAngle());
|
||||
}
|
||||
@@ -198,12 +254,14 @@ public class FCardPanel extends FDisplayObject {
|
||||
tapAnimation.progress = 0;
|
||||
}
|
||||
//draw untapped
|
||||
if (untapAnimation.progress < 1 && animate) {
|
||||
untapAnimation.start();
|
||||
untapAnimation.drawCard(g, card, x, y, w, h, edgeOffset);
|
||||
} else {
|
||||
wasTapped = false;
|
||||
CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition());
|
||||
if (untapAnimation != null) {
|
||||
if (untapAnimation.progress < 1 && animate) {
|
||||
untapAnimation.start();
|
||||
untapAnimation.drawCard(g, card, x, y, w, h, edgeOffset);
|
||||
} else {
|
||||
wasTapped = false;
|
||||
CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
forge-gui/res/skins/default/scratch.png
Normal file
BIN
forge-gui/res/skins/default/scratch.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 127 KiB |
@@ -306,6 +306,7 @@ public class HostedMatch {
|
||||
game = null;
|
||||
|
||||
for (final PlayerControllerHuman humanController : humanControllers) {
|
||||
humanController.getGui().setGameSpeed(false);
|
||||
if (FModel.getPreferences().getPref(FPref.UI_AUTO_YIELD_MODE).equals(ForgeConstants.AUTO_YIELD_PER_CARD) || isMatchOver()) {
|
||||
// when autoyielding per card, we need to clear auto yields between games since card IDs change
|
||||
humanController.getGui().clearAutoYields();
|
||||
|
||||
@@ -13,41 +13,7 @@ import forge.game.Game;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardView;
|
||||
import forge.game.event.GameEvent;
|
||||
import forge.game.event.GameEventAnteCardsSelected;
|
||||
import forge.game.event.GameEventAttackersDeclared;
|
||||
import forge.game.event.GameEventBlockersDeclared;
|
||||
import forge.game.event.GameEventCardAttachment;
|
||||
import forge.game.event.GameEventCardChangeZone;
|
||||
import forge.game.event.GameEventCardCounters;
|
||||
import forge.game.event.GameEventCardDamaged;
|
||||
import forge.game.event.GameEventCardPhased;
|
||||
import forge.game.event.GameEventCardStatsChanged;
|
||||
import forge.game.event.GameEventCardTapped;
|
||||
import forge.game.event.GameEventCombatChanged;
|
||||
import forge.game.event.GameEventCombatEnded;
|
||||
import forge.game.event.GameEventCombatUpdate;
|
||||
import forge.game.event.GameEventGameFinished;
|
||||
import forge.game.event.GameEventGameOutcome;
|
||||
import forge.game.event.GameEventLandPlayed;
|
||||
import forge.game.event.GameEventManaBurn;
|
||||
import forge.game.event.GameEventManaPool;
|
||||
import forge.game.event.GameEventPlayerControl;
|
||||
import forge.game.event.GameEventPlayerCounters;
|
||||
import forge.game.event.GameEventPlayerLivesChanged;
|
||||
import forge.game.event.GameEventPlayerPoisoned;
|
||||
import forge.game.event.GameEventPlayerPriority;
|
||||
import forge.game.event.GameEventPlayerStatsChanged;
|
||||
import forge.game.event.GameEventShuffle;
|
||||
import forge.game.event.GameEventSpellAbilityCast;
|
||||
import forge.game.event.GameEventSpellRemovedFromStack;
|
||||
import forge.game.event.GameEventSpellResolved;
|
||||
import forge.game.event.GameEventSubgameEnd;
|
||||
import forge.game.event.GameEventTokenStateUpdate;
|
||||
import forge.game.event.GameEventTurnBegan;
|
||||
import forge.game.event.GameEventTurnPhase;
|
||||
import forge.game.event.GameEventZone;
|
||||
import forge.game.event.IGameEventVisitor;
|
||||
import forge.game.event.*;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerView;
|
||||
import forge.game.zone.Zone;
|
||||
@@ -506,6 +472,13 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
return processPlayer(event.receiver, livesUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(final GameEventPlayerDamaged event) {
|
||||
//for avatar animation
|
||||
event.target.setAvatarWasDamaged(event.amount > 0);
|
||||
return processEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(final GameEventPlayerCounters event) {
|
||||
return processPlayer(event.receiver, livesUpdate);
|
||||
|
||||
Reference in New Issue
Block a user