From bd0ee9713d9bae5171f8c5ed234aa3c596ad0bb1 Mon Sep 17 00:00:00 2001 From: Oskar Wiksten Date: Sat, 28 Jul 2012 21:51:35 +0200 Subject: [PATCH 1/4] WIP display duration & magnitude on condition icons. --- AndorsTrail/res/anim/scalebeat.xml | 28 ++ AndorsTrail/res/anim/scaledown.xml | 12 + AndorsTrail/res/anim/scaleup.xml | 12 + AndorsTrail/res/layout/main.xml | 3 +- .../AndorsTrail/activity/MainActivity.java | 12 +- .../controller/ActorStatsController.java | 57 ++-- .../model/ability/ActorCondition.java | 2 +- .../rpg/AndorsTrail/model/actor/Actor.java | 2 + .../listeners/ActorConditionListener.java | 12 + .../listeners/ActorConditionListeners.java | 48 ++++ .../model/listeners/ListOfListeners.java | 52 ++++ .../DisplayActiveActorConditionIcons.java | 260 ++++++++++++++++++ .../gpl/rpg/AndorsTrail/view/StatusView.java | 49 ---- 13 files changed, 475 insertions(+), 74 deletions(-) create mode 100644 AndorsTrail/res/anim/scalebeat.xml create mode 100644 AndorsTrail/res/anim/scaledown.xml create mode 100644 AndorsTrail/res/anim/scaleup.xml create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorConditionListener.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorConditionListeners.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ListOfListeners.java create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java diff --git a/AndorsTrail/res/anim/scalebeat.xml b/AndorsTrail/res/anim/scalebeat.xml new file mode 100644 index 000000000..3471f26ab --- /dev/null +++ b/AndorsTrail/res/anim/scalebeat.xml @@ -0,0 +1,28 @@ + + + + + + + diff --git a/AndorsTrail/res/anim/scaledown.xml b/AndorsTrail/res/anim/scaledown.xml new file mode 100644 index 000000000..0c15c5a1c --- /dev/null +++ b/AndorsTrail/res/anim/scaledown.xml @@ -0,0 +1,12 @@ + + diff --git a/AndorsTrail/res/anim/scaleup.xml b/AndorsTrail/res/anim/scaleup.xml new file mode 100644 index 000000000..138d2a36b --- /dev/null +++ b/AndorsTrail/res/anim/scaleup.xml @@ -0,0 +1,12 @@ + + diff --git a/AndorsTrail/res/layout/main.xml b/AndorsTrail/res/layout/main.xml index fb98625f9..9be5d0193 100644 --- a/AndorsTrail/res/layout/main.xml +++ b/AndorsTrail/res/layout/main.xml @@ -54,13 +54,12 @@ android:shadowColor="#000" /> - diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java index badc06f6a..5e0384a1c 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java @@ -16,6 +16,7 @@ import com.gpl.rpg.AndorsTrail.model.actor.Player; import com.gpl.rpg.AndorsTrail.model.item.ItemContainer.ItemEntry; import com.gpl.rpg.AndorsTrail.util.Coord; import com.gpl.rpg.AndorsTrail.view.CombatView; +import com.gpl.rpg.AndorsTrail.view.DisplayActiveActorConditionIcons; import com.gpl.rpg.AndorsTrail.view.MainView; import com.gpl.rpg.AndorsTrail.view.VirtualDpadView; import com.gpl.rpg.AndorsTrail.view.QuickButton.QuickButtonContextMenuInfo; @@ -33,7 +34,7 @@ import android.view.View; import android.view.ContextMenu.ContextMenuInfo; import android.view.MenuItem.OnMenuItemClickListener; import android.view.View.OnClickListener; -import android.widget.LinearLayout; +import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; @@ -59,7 +60,7 @@ public final class MainActivity extends Activity { public StatusView statusview; public CombatView combatview; public QuickitemView quickitemview; - private LinearLayout activeConditions; + private DisplayActiveActorConditionIcons activeConditions; private VirtualDpadView dpad; private static final int NUM_MESSAGES = 3; @@ -84,7 +85,7 @@ public final class MainActivity extends Activity { statusview = (StatusView) findViewById(R.id.main_statusview); combatview = (CombatView) findViewById(R.id.main_combatview); quickitemview = (QuickitemView) findViewById(R.id.main_quickitemview); - activeConditions = (LinearLayout) findViewById(R.id.statusview_activeconditions); + activeConditions = new DisplayActiveActorConditionIcons(world.tileManager, this, (RelativeLayout) findViewById(R.id.statusview_activeconditions)); dpad = (VirtualDpadView) findViewById(R.id.main_virtual_dpad); statusText = (TextView) findViewById(R.id.statusview_statustext); @@ -165,6 +166,8 @@ public final class MainActivity extends Activity { view.gameRoundController.pause(); view.movementController.stopMovement(); + activeConditions.unsubscribe(world); + save(Savegames.SLOT_QUICKSAVE); } @@ -173,6 +176,8 @@ public final class MainActivity extends Activity { super.onResume(); if (!AndorsTrailApplication.getApplicationFromActivity(this).setup.isSceneReady) return; + activeConditions.subscribe(world); + view.gameRoundController.resume(); if (world.model.uiSelections.isInCombat) { @@ -257,7 +262,6 @@ public final class MainActivity extends Activity { public void updateStatus() { statusview.updateStatus(); - statusview.updateActiveConditions(this, activeConditions); quickitemview.refreshQuickitems(); combatview.updateStatus(); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java index 0d53eab0e..8937faaaf 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java @@ -59,10 +59,12 @@ public class ActorStatsController { if (!type.conditionTypeID.equals(c.conditionType.conditionTypeID)) continue; if (c.duration != duration) continue; - actor.conditions.remove(i); - magnitude = c.magnitude - magnitude; - if (magnitude > 0) { - actor.conditions.add(new ActorCondition(type, magnitude, duration)); + if (c.magnitude > magnitude) { + c.magnitude -= magnitude; + actor.conditionListener.onActorConditionMagnitudeChanged(actor, c); + } else { + actor.conditions.remove(i); + actor.conditionListener.onActorConditionRemoved(actor, c); } break; } @@ -109,12 +111,14 @@ public class ActorStatsController { if (!type.conditionTypeID.equals(c.conditionType.conditionTypeID)) continue; if (c.duration == duration) { // If the actor already has a condition of this type and the same duration, just increase the magnitude instead. - actor.conditions.remove(i); - magnitude += c.magnitude; - break; + c.magnitude += magnitude; + actor.conditionListener.onActorConditionMagnitudeChanged(actor, c); + return; } } - actor.conditions.add(new ActorCondition(type, magnitude, duration)); + ActorCondition c = new ActorCondition(type, magnitude, duration); + actor.conditions.add(c); + actor.conditionListener.onActorConditionAdded(actor, c); } private static void addNonStackableActorCondition(Actor actor, ActorConditionEffect e, int duration) { final ActorConditionType type = e.conditionType; @@ -123,24 +127,34 @@ public class ActorStatsController { ActorCondition c = actor.conditions.get(i); if (!type.conditionTypeID.equals(c.conditionType.conditionTypeID)) continue; if (c.magnitude > e.magnitude) return; + else if (c.magnitude == e.magnitude) { + if (c.duration >= duration) return; + } // If the actor already has this condition, but of a lower magnitude, we remove the old one and add this higher magnitude. actor.conditions.remove(i); + actor.conditionListener.onActorConditionRemoved(actor, c); } - actor.conditions.add(e.createCondition(duration)); + + ActorCondition c = e.createCondition(duration); + actor.conditions.add(c); + actor.conditionListener.onActorConditionAdded(actor, c); } public static void removeAllTemporaryConditions(final Actor actor) { for(int i = actor.conditions.size() - 1; i >= 0; --i) { - if (!actor.conditions.get(i).isTemporaryEffect()) continue; + ActorCondition c = actor.conditions.get(i); + if (!c.isTemporaryEffect()) continue; actor.conditions.remove(i); + actor.conditionListener.onActorConditionRemoved(actor, c); } } private static void removeAllConditionsOfType(final Actor actor, final String conditionTypeID) { for(int i = actor.conditions.size() - 1; i >= 0; --i) { - if (actor.conditions.get(i).conditionType.conditionTypeID.equals(conditionTypeID)) { - actor.conditions.remove(i); - } + ActorCondition c = actor.conditions.get(i); + if (!c.conditionType.conditionTypeID.equals(conditionTypeID)) continue; + actor.conditions.remove(i); + actor.conditionListener.onActorConditionRemoved(actor, c); } } @@ -210,10 +224,13 @@ public class ActorStatsController { if (SkillController.rollForSkillChance(player, SkillCollection.SKILL_REJUVENATION, SkillCollection.PER_SKILLPOINT_INCREASE_REJUVENATION_CHANCE)) { int i = getRandomConditionForRejuvenate(player); if (i >= 0) { - ActorCondition c = player.conditions.remove(i); + ActorCondition c = player.conditions.get(i); if (c.magnitude > 1) { - int magnitude = c.magnitude - 1; - player.conditions.add(i, new ActorCondition(c.conditionType, magnitude, c.duration)); + c.magnitude -= 1; + player.conditionListener.onActorConditionMagnitudeChanged(player, c); + } else { + player.conditions.remove(i); + player.conditionListener.onActorConditionRemoved(player, c); } recalculateActorCombatTraits(player); } @@ -258,6 +275,7 @@ public class ActorStatsController { for (ActorCondition c : actor.conditions) { StatsModifierTraits effect = isFullRound ? c.conditionType.statsEffect_everyFullRound : c.conditionType.statsEffect_everyRound; effectToStart = applyStatsModifierEffect(actor, effect, c.magnitude, effectToStart); + if (effect != null) actor.conditionListener.onActorConditionRoundEffectApplied(actor, c); } startVisualEffect(actor, effectToStart); } @@ -267,10 +285,13 @@ public class ActorStatsController { for(int i = actor.conditions.size() - 1; i >= 0; --i) { ActorCondition c = actor.conditions.get(i); if (!c.isTemporaryEffect()) continue; - c.duration -= 1; - if (c.duration <= 0) { + if (c.duration <= 1) { actor.conditions.remove(i); + actor.conditionListener.onActorConditionRemoved(actor, c); removedAnyConditions = true; + } else { + c.duration -= 1; + actor.conditionListener.onActorConditionDurationChanged(actor, c); } } if (removedAnyConditions) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ability/ActorCondition.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ability/ActorCondition.java index 772a48f4b..bb0848e6f 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ability/ActorCondition.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ability/ActorCondition.java @@ -11,7 +11,7 @@ public class ActorCondition { public static final int DURATION_FOREVER = 999; public final ActorConditionType conditionType; - public final int magnitude; + public int magnitude; public int duration; public ActorCondition(ActorConditionType conditionType, int magnitude, int duration) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java index bec0b1035..20efe7490 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.model.CombatTraits; import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; +import com.gpl.rpg.AndorsTrail.model.listeners.ActorConditionListeners; import com.gpl.rpg.AndorsTrail.util.Coord; import com.gpl.rpg.AndorsTrail.util.CoordRect; import com.gpl.rpg.AndorsTrail.util.Range; @@ -20,6 +21,7 @@ public class Actor { public final Coord position; public final CoordRect rectPosition; public final ArrayList conditions = new ArrayList(); + public final ActorConditionListeners conditionListener = new ActorConditionListeners(); public final boolean isPlayer; public final boolean isImmuneToCriticalHits; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorConditionListener.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorConditionListener.java new file mode 100644 index 000000000..6db177052 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorConditionListener.java @@ -0,0 +1,12 @@ +package com.gpl.rpg.AndorsTrail.model.listeners; + +import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; +import com.gpl.rpg.AndorsTrail.model.actor.Actor; + +public interface ActorConditionListener { + public void onActorConditionAdded(Actor actor, ActorCondition condition); + public void onActorConditionRemoved(Actor actor, ActorCondition condition); + public void onActorConditionDurationChanged(Actor actor, ActorCondition condition); + public void onActorConditionMagnitudeChanged(Actor actor, ActorCondition condition); + public void onActorConditionRoundEffectApplied(Actor actor, ActorCondition condition); +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorConditionListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorConditionListeners.java new file mode 100644 index 000000000..3ea927190 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorConditionListeners.java @@ -0,0 +1,48 @@ +package com.gpl.rpg.AndorsTrail.model.listeners; + +import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; +import com.gpl.rpg.AndorsTrail.model.actor.Actor; + +public class ActorConditionListeners extends ListOfListeners implements ActorConditionListener { + + private final Function2 onActorConditionAdded = new Function2() { + @Override public void call(ActorConditionListener listener, Actor actor, ActorCondition condition) { listener.onActorConditionAdded(actor, condition); } + }; + private final Function2 onActorConditionRemoved = new Function2() { + @Override public void call(ActorConditionListener listener, Actor actor, ActorCondition condition) { listener.onActorConditionRemoved(actor, condition); } + }; + private final Function2 onActorConditionDurationChanged = new Function2() { + @Override public void call(ActorConditionListener listener, Actor actor, ActorCondition condition) { listener.onActorConditionDurationChanged(actor, condition); } + }; + private final Function2 onActorConditionMagnitudeChanged = new Function2() { + @Override public void call(ActorConditionListener listener, Actor actor, ActorCondition condition) { listener.onActorConditionMagnitudeChanged(actor, condition); } + }; + private final Function2 onActorConditionRoundEffectApplied = new Function2() { + @Override public void call(ActorConditionListener listener, Actor actor, ActorCondition condition) { listener.onActorConditionRoundEffectApplied(actor, condition); } + }; + + @Override + public void onActorConditionAdded(Actor actor, ActorCondition condition) { + callAllListeners(this.onActorConditionAdded, actor, condition); + } + + @Override + public void onActorConditionRemoved(Actor actor, ActorCondition condition) { + callAllListeners(this.onActorConditionRemoved, actor, condition); + } + + @Override + public void onActorConditionDurationChanged(Actor actor, ActorCondition condition) { + callAllListeners(this.onActorConditionDurationChanged, actor, condition); + } + + @Override + public void onActorConditionMagnitudeChanged(Actor actor, ActorCondition condition) { + callAllListeners(this.onActorConditionMagnitudeChanged, actor, condition); + } + + @Override + public void onActorConditionRoundEffectApplied(Actor actor, ActorCondition condition) { + callAllListeners(this.onActorConditionRoundEffectApplied, actor, condition); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ListOfListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ListOfListeners.java new file mode 100644 index 000000000..c51c05fbc --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ListOfListeners.java @@ -0,0 +1,52 @@ +package com.gpl.rpg.AndorsTrail.model.listeners; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; + +public class ListOfListeners { + private final ArrayList> listeners = new ArrayList>(); + + public void add(T listener) { + listeners.add(new WeakReference(listener)); + } + public void remove(T listenerToRemove) { + for (int i = listeners.size()-1; i >= 0; --i) { + T listener = listeners.get(i).get(); + if (listener == null || listener == listenerToRemove) { + listeners.remove(i); + } + } + } + + protected void callAllListeners(Function e) { + for (int i = listeners.size()-1; i >= 0; --i) { + T listener = listeners.get(i).get(); + if (listener == null) listeners.remove(i); + else e.call(listener); + } + } + protected void callAllListeners(Function1 e, Arg1 arg) { + for (int i = listeners.size()-1; i >= 0; --i) { + T listener = listeners.get(i).get(); + if (listener == null) listeners.remove(i); + else e.call(listener, arg); + } + } + protected void callAllListeners(Function2 e, Arg1 arg1, Arg2 arg2) { + for (int i = listeners.size()-1; i >= 0; --i) { + T listener = listeners.get(i).get(); + if (listener == null) listeners.remove(i); + else e.call(listener, arg1, arg2); + } + } + + protected static interface Function { + public void call(Listener listener); + } + protected static interface Function1 { + public void call(Listener listener, Arg1 arg1); + } + protected static interface Function2 { + public void call(Listener listener, Arg1 arg1, Arg2 arg2); + } +} \ No newline at end of file diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java new file mode 100644 index 000000000..37a30ad00 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java @@ -0,0 +1,260 @@ +package com.gpl.rpg.AndorsTrail.view; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; + +import android.content.Context; +import android.content.res.Resources; +import android.view.View; +import android.view.animation.Animation; +import android.view.animation.Animation.AnimationListener; +import android.view.animation.AnimationUtils; +import android.widget.ImageView; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.RelativeLayout.LayoutParams; + +import com.gpl.rpg.AndorsTrail.R; +import com.gpl.rpg.AndorsTrail.context.WorldContext; +import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; +import com.gpl.rpg.AndorsTrail.model.actor.Actor; +import com.gpl.rpg.AndorsTrail.model.listeners.ActorConditionListener; +import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager; + +public class DisplayActiveActorConditionIcons implements ActorConditionListener { + + private final TileManager tileManager; + private final RelativeLayout activeConditions; + private final ArrayList currentConditionIcons = new ArrayList(); + private final WeakReference androidContext; + + public DisplayActiveActorConditionIcons(final TileManager tileManager, Context androidContext, RelativeLayout activeConditions) { + this.tileManager = tileManager; + this.androidContext = new WeakReference(androidContext); + this.activeConditions = activeConditions; + } + + private ActiveConditionIcon getIconFor(ActorCondition condition) { + for (ActiveConditionIcon icon : currentConditionIcons) { + if (icon.condition == condition) return icon; + } + return null; + } + private ActiveConditionIcon getFirstFreeIcon() { + for (ActiveConditionIcon icon : currentConditionIcons) { + if (!icon.isVisible()) return icon; + } + return addNewActiveConditionIcon(); + } + + private RelativeLayout.LayoutParams getLayoutParamsForIconIndex(int index) { + RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + layout.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); + if (index == 0) { + layout.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); + } else { + layout.addRule(RelativeLayout.LEFT_OF, currentConditionIcons.get(index-1).id); + } + return layout; + } + + private ActiveConditionIcon addNewActiveConditionIcon() { + int index = currentConditionIcons.size(); + + ActiveConditionIcon icon = new ActiveConditionIcon(androidContext.get(), index+1); + + activeConditions.addView(icon.image, getLayoutParamsForIconIndex(index)); + + RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + layout.addRule(RelativeLayout.ALIGN_RIGHT, icon.id); + layout.addRule(RelativeLayout.ALIGN_BOTTOM, icon.id); + activeConditions.addView(icon.text, layout); + + /* + layout = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + layout.addRule(RelativeLayout.ALIGN_RIGHT, icon.image.getId()); + layout.addRule(RelativeLayout.ALIGN_BOTTOM, icon.image.getId()); + activeConditions.addView(icon.duration, layout); + */ + + currentConditionIcons.add(icon); + + return icon; + } + + private final class ActiveConditionIcon implements AnimationListener { + public final int id; + public ActorCondition condition; + public final ImageView image; + public final TextView text; + //public final TextView duration; + private final Animation onNewIconAnimation; + private final Animation onRemovedIconAnimation; + private final Animation onAppliedEffectAnimation; + + public ActiveConditionIcon(Context context, int id) { + this.id = id; + this.image = new ImageView(context); + this.image.setId(id); + this.text = new TextView(context); + this.onNewIconAnimation = AnimationUtils.loadAnimation(context, R.anim.scaleup); + this.onRemovedIconAnimation = AnimationUtils.loadAnimation(context, R.anim.scaledown); + this.onAppliedEffectAnimation = AnimationUtils.loadAnimation(context, R.anim.scalebeat); + this.onRemovedIconAnimation.setAnimationListener(this); + //duration = new TextView(context); + + final Resources res = context.getResources(); + + //float textSize = ; + //magnitude.setTextSize(res.getDimension(R.dimen.smalltext)); + /* + duration.setTextSize(res.getDimension(R.dimen.smalltext)); + + int textColor = res.getColor(android.R.color.white); + int shadowColor = res.getColor(android.R.color.black); + magnitude.setTextColor(textColor); + duration.setTextColor(textColor); + + magnitude.setShadowLayer(1, 1, 1, shadowColor); + duration.setShadowLayer(2, 1, 1, shadowColor); + */ + + text.setTextColor(res.getColor(android.R.color.white)); + text.setShadowLayer(1, 1, 1, res.getColor(android.R.color.black)); + } + + private void setActiveCondition(ActorCondition condition) { + this.condition = condition; + tileManager.setImageViewTile(image, condition.conditionType); + image.setVisibility(View.VISIBLE); + setIconText(); + } + + public void setIconText() { + boolean showMagnitude = (condition.magnitude != 1); + boolean showDuration = condition.isTemporaryEffect(); + if (showMagnitude/* || showDuration*/) { + /*if (showMagnitude && showDuration) { + icon.text.setText(condition.duration + "x" + condition.magnitude); + } else if (showDuration) { + icon.text.setText(condition.duration); + } else if (showMagnitude) { + icon.text.setText("x" + condition.magnitude); + }*/ + text.setText(Integer.toString(condition.magnitude)); + text.setVisibility(View.VISIBLE); + } else { + text.setVisibility(View.GONE); + } + /* + if (condition.magnitude != 1) { + icon.magnitude.setText(Integer.toString(condition.magnitude)); + icon.magnitude.setVisibility(View.VISIBLE); + } else { + icon.magnitude.setVisibility(View.GONE); + } + if (condition.isTemporaryEffect()) { + icon.duration.setText(Integer.toString(condition.duration)); + icon.duration.setVisibility(View.VISIBLE); + } else { + icon.duration.setVisibility(View.GONE); + } + */ + } + + public void hide(boolean useAnimation) { + if (useAnimation) { + image.startAnimation(onRemovedIconAnimation); + } else { + image.setVisibility(View.GONE); + condition = null; + } + text.setVisibility(View.GONE); + } + public void show() { + image.startAnimation(onNewIconAnimation); + if (text.getVisibility() == View.VISIBLE) text.startAnimation(onNewIconAnimation); + } + + public void pulseAnimate() { + image.startAnimation(onAppliedEffectAnimation); + } + + public boolean isVisible() { + return condition != null; + } + + @Override + public void onAnimationEnd(Animation animation) { + if (animation == this.onRemovedIconAnimation) { + hide(false); + rearrangeIconsLeftOf(this); + } + } + + @Override public void onAnimationRepeat(Animation animation) { } + @Override public void onAnimationStart(Animation animation) { } + } + + protected void rearrangeIconsLeftOf(ActiveConditionIcon icon) { + int i = currentConditionIcons.indexOf(icon); + currentConditionIcons.remove(i); + currentConditionIcons.add(icon); + for(; i < currentConditionIcons.size(); ++i) { + ActiveConditionIcon aci = currentConditionIcons.get(i); + aci.image.setLayoutParams(getLayoutParamsForIconIndex(i)); + } + } + + @Override + public void onActorConditionAdded(Actor actor, ActorCondition condition) { + ActiveConditionIcon icon = getFirstFreeIcon(); + icon.setActiveCondition(condition); + icon.show(); + } + + @Override + public void onActorConditionRemoved(Actor actor, ActorCondition condition) { + ActiveConditionIcon icon = getIconFor(condition); + if (icon == null) return; + icon.hide(true); + } + + @Override + public void onActorConditionDurationChanged(Actor actor, ActorCondition condition) { + ActiveConditionIcon icon = getIconFor(condition); + if (icon == null) return; + icon.setIconText(); + } + + @Override + public void onActorConditionMagnitudeChanged(Actor actor, ActorCondition condition) { + ActiveConditionIcon icon = getIconFor(condition); + if (icon == null) return; + icon.setIconText(); + } + + @Override + public void onActorConditionRoundEffectApplied(Actor actor, ActorCondition condition) { + ActiveConditionIcon icon = getIconFor(condition); + if (icon == null) return; + icon.pulseAnimate(); + } + + public void unsubscribe(final WorldContext world) { + world.model.player.conditionListener.remove(this); + hideAllIcons(); + } + + public void subscribe(final WorldContext world) { + hideAllIcons(); + for (ActorCondition condition : world.model.player.conditions) { + getFirstFreeIcon().setActiveCondition(condition); + } + world.model.player.conditionListener.add(this); + } + + private void hideAllIcons() { + for (ActiveConditionIcon icon : currentConditionIcons) icon.hide(false); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java index c6d0a36a8..f2897c781 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java @@ -6,7 +6,6 @@ import com.gpl.rpg.AndorsTrail.activity.MainActivity; import com.gpl.rpg.AndorsTrail.activity.HeroinfoActivity; import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; -import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; import com.gpl.rpg.AndorsTrail.model.actor.Player; import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager; @@ -17,8 +16,6 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.util.AttributeSet; import android.view.View; -import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.ImageButton; @@ -97,15 +94,6 @@ public final class StatusView extends RelativeLayout { world.tileManager.setImageViewTile(heroImage, player); } } - - public void updateActiveConditions(Context androidContext, LinearLayout activeConditions) { - GreedyImageViewAppender t = new GreedyImageViewAppender(androidContext, activeConditions); - for (ActorCondition condition : player.conditions) { - ImageView iv = t.getNextImage(); - world.tileManager.setImageViewTile(iv, condition.conditionType); - } - t.removeOtherImages(); - } public void updateQuickItemImage(boolean visible){ if(visible){ @@ -114,41 +102,4 @@ public final class StatusView extends RelativeLayout { world.tileManager.setImageViewTileForUIIcon(quickToggle, TileManager.iconID_boxclosed); } } - - private static class GreedyImageViewAppender { - private final LinearLayout container; - private final Context context; - private int currentChildIndex = 0; - private final int previousChildCount; - private final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); - - public GreedyImageViewAppender(Context context, LinearLayout container) { - this.container = container; - this.context = context; - this.previousChildCount = container.getChildCount(); - } - public ImageView getNextImage() { - // Since this is called a lot, we do not want to recreate the view objects every time. - // Therefore, we reuse existing ImageView:s if they are present, but just change the image on them. - ImageView iv; - if (currentChildIndex < previousChildCount) { - // There already is a create dimage on this position, reuse it. - iv = (ImageView) container.getChildAt(currentChildIndex); - iv.setVisibility(View.VISIBLE); - } else { - // The player has never had this many conditions, create a new ImageView to hold the condition image. - iv = new ImageView(context); - container.addView(iv, layoutParams); - } - ++currentChildIndex; - return iv; - } - public void removeOtherImages() { - for(int i = previousChildCount - 1; i >= currentChildIndex; --i) { - //container.removeViewAt(i); - // Don't actually remove them, just hide them (so we won't have to recreate them next time the player get a condition) - container.getChildAt(i).setVisibility(View.GONE); - } - } - } } From bcead230b5538b29a7a3a9683ec790fed2024560 Mon Sep 17 00:00:00 2001 From: Oskar Wiksten Date: Sun, 29 Jul 2012 10:51:33 +0200 Subject: [PATCH 2/4] Code cleanup for displaying magnitude on actor condition icons. --- .../controller/MovementController.java | 6 +- .../model/listeners/ListOfListeners.java | 9 + .../DisplayActiveActorConditionIcons.java | 219 +++++++----------- 3 files changed, 93 insertions(+), 141 deletions(-) diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java index 32a061c5e..ce7fbe663 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MovementController.java @@ -241,16 +241,12 @@ public final class MovementController implements TimedMessageTask.Callback { if (!world.model.currentMap.isWalkable(world.model.player.position)) { // If the player somehow spawned on an unwalkable tile, we move the player to the first mapchange area. // This could happen if we change some tile to non-walkable in a future version. - MapObject dest = null; for (MapObject o : model.currentMap.eventObjects) { if (o.type == MapObject.MAPEVENT_NEWMAP) { - dest = o; + model.player.position.set(o.position.topLeft); break; } } - if (dest != null) { - model.player.position.set(dest.position.topLeft); - } } // If any monsters somehow spawned on an unwalkable tile, we move the monster to a new position on the spawnarea diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ListOfListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ListOfListeners.java index c51c05fbc..c968e3e46 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ListOfListeners.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ListOfListeners.java @@ -3,10 +3,19 @@ package com.gpl.rpg.AndorsTrail.model.listeners; import java.lang.ref.WeakReference; import java.util.ArrayList; +import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; + public class ListOfListeners { private final ArrayList> listeners = new ArrayList>(); public void add(T listener) { + if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) { + for (WeakReference ref : listeners) { + if (ref.get() == listener) { + throw new IndexOutOfBoundsException("FAIL: listener added twice to ListOfListeners."); + } + } + } listeners.add(new WeakReference(listener)); } public void remove(T listenerToRemove) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java index 37a30ad00..a3bcc1e88 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java @@ -33,53 +33,50 @@ public class DisplayActiveActorConditionIcons implements ActorConditionListener this.androidContext = new WeakReference(androidContext); this.activeConditions = activeConditions; } - - private ActiveConditionIcon getIconFor(ActorCondition condition) { - for (ActiveConditionIcon icon : currentConditionIcons) { - if (icon.condition == condition) return icon; - } - return null; - } - private ActiveConditionIcon getFirstFreeIcon() { - for (ActiveConditionIcon icon : currentConditionIcons) { - if (!icon.isVisible()) return icon; - } - return addNewActiveConditionIcon(); - } - - private RelativeLayout.LayoutParams getLayoutParamsForIconIndex(int index) { - RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); - layout.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); - if (index == 0) { - layout.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); - } else { - layout.addRule(RelativeLayout.LEFT_OF, currentConditionIcons.get(index-1).id); - } - return layout; + + @Override + public void onActorConditionAdded(Actor actor, ActorCondition condition) { + ActiveConditionIcon icon = getFirstFreeIcon(); + icon.setActiveCondition(condition); + icon.show(); } - private ActiveConditionIcon addNewActiveConditionIcon() { - int index = currentConditionIcons.size(); - - ActiveConditionIcon icon = new ActiveConditionIcon(androidContext.get(), index+1); - - activeConditions.addView(icon.image, getLayoutParamsForIconIndex(index)); - - RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); - layout.addRule(RelativeLayout.ALIGN_RIGHT, icon.id); - layout.addRule(RelativeLayout.ALIGN_BOTTOM, icon.id); - activeConditions.addView(icon.text, layout); - - /* - layout = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); - layout.addRule(RelativeLayout.ALIGN_RIGHT, icon.image.getId()); - layout.addRule(RelativeLayout.ALIGN_BOTTOM, icon.image.getId()); - activeConditions.addView(icon.duration, layout); - */ - - currentConditionIcons.add(icon); - - return icon; + @Override + public void onActorConditionRemoved(Actor actor, ActorCondition condition) { + ActiveConditionIcon icon = getIconFor(condition); + if (icon == null) return; + icon.hide(true); + } + + @Override + public void onActorConditionDurationChanged(Actor actor, ActorCondition condition) { + } + + @Override + public void onActorConditionMagnitudeChanged(Actor actor, ActorCondition condition) { + ActiveConditionIcon icon = getIconFor(condition); + if (icon == null) return; + icon.setIconText(); + } + + @Override + public void onActorConditionRoundEffectApplied(Actor actor, ActorCondition condition) { + ActiveConditionIcon icon = getIconFor(condition); + if (icon == null) return; + icon.pulseAnimate(); + } + + public void unsubscribe(final WorldContext world) { + world.model.player.conditionListener.remove(this); + for (ActiveConditionIcon icon : currentConditionIcons) icon.condition = null; + } + + public void subscribe(final WorldContext world) { + for (ActiveConditionIcon icon : currentConditionIcons) icon.hide(false); + for (ActorCondition condition : world.model.player.conditions) { + getFirstFreeIcon().setActiveCondition(condition); + } + world.model.player.conditionListener.add(this); } private final class ActiveConditionIcon implements AnimationListener { @@ -87,7 +84,6 @@ public class DisplayActiveActorConditionIcons implements ActorConditionListener public ActorCondition condition; public final ImageView image; public final TextView text; - //public final TextView duration; private final Animation onNewIconAnimation; private final Animation onRemovedIconAnimation; private final Animation onAppliedEffectAnimation; @@ -101,24 +97,9 @@ public class DisplayActiveActorConditionIcons implements ActorConditionListener this.onRemovedIconAnimation = AnimationUtils.loadAnimation(context, R.anim.scaledown); this.onAppliedEffectAnimation = AnimationUtils.loadAnimation(context, R.anim.scalebeat); this.onRemovedIconAnimation.setAnimationListener(this); - //duration = new TextView(context); final Resources res = context.getResources(); - //float textSize = ; - //magnitude.setTextSize(res.getDimension(R.dimen.smalltext)); - /* - duration.setTextSize(res.getDimension(R.dimen.smalltext)); - - int textColor = res.getColor(android.R.color.white); - int shadowColor = res.getColor(android.R.color.black); - magnitude.setTextColor(textColor); - duration.setTextColor(textColor); - - magnitude.setShadowLayer(1, 1, 1, shadowColor); - duration.setShadowLayer(2, 1, 1, shadowColor); - */ - text.setTextColor(res.getColor(android.R.color.white)); text.setShadowLayer(1, 1, 1, res.getColor(android.R.color.black)); } @@ -132,34 +113,12 @@ public class DisplayActiveActorConditionIcons implements ActorConditionListener public void setIconText() { boolean showMagnitude = (condition.magnitude != 1); - boolean showDuration = condition.isTemporaryEffect(); - if (showMagnitude/* || showDuration*/) { - /*if (showMagnitude && showDuration) { - icon.text.setText(condition.duration + "x" + condition.magnitude); - } else if (showDuration) { - icon.text.setText(condition.duration); - } else if (showMagnitude) { - icon.text.setText("x" + condition.magnitude); - }*/ + if (showMagnitude) { text.setText(Integer.toString(condition.magnitude)); text.setVisibility(View.VISIBLE); } else { text.setVisibility(View.GONE); } - /* - if (condition.magnitude != 1) { - icon.magnitude.setText(Integer.toString(condition.magnitude)); - icon.magnitude.setVisibility(View.VISIBLE); - } else { - icon.magnitude.setVisibility(View.GONE); - } - if (condition.isTemporaryEffect()) { - icon.duration.setText(Integer.toString(condition.duration)); - icon.duration.setVisibility(View.VISIBLE); - } else { - icon.duration.setVisibility(View.GONE); - } - */ } public void hide(boolean useAnimation) { @@ -201,60 +160,48 @@ public class DisplayActiveActorConditionIcons implements ActorConditionListener currentConditionIcons.remove(i); currentConditionIcons.add(icon); for(; i < currentConditionIcons.size(); ++i) { - ActiveConditionIcon aci = currentConditionIcons.get(i); - aci.image.setLayoutParams(getLayoutParamsForIconIndex(i)); + currentConditionIcons.get(i).image.setLayoutParams(getLayoutParamsForIconIndex(i)); } } - - @Override - public void onActorConditionAdded(Actor actor, ActorCondition condition) { - ActiveConditionIcon icon = getFirstFreeIcon(); - icon.setActiveCondition(condition); - icon.show(); - } - - @Override - public void onActorConditionRemoved(Actor actor, ActorCondition condition) { - ActiveConditionIcon icon = getIconFor(condition); - if (icon == null) return; - icon.hide(true); - } - - @Override - public void onActorConditionDurationChanged(Actor actor, ActorCondition condition) { - ActiveConditionIcon icon = getIconFor(condition); - if (icon == null) return; - icon.setIconText(); - } - - @Override - public void onActorConditionMagnitudeChanged(Actor actor, ActorCondition condition) { - ActiveConditionIcon icon = getIconFor(condition); - if (icon == null) return; - icon.setIconText(); - } - - @Override - public void onActorConditionRoundEffectApplied(Actor actor, ActorCondition condition) { - ActiveConditionIcon icon = getIconFor(condition); - if (icon == null) return; - icon.pulseAnimate(); - } - - public void unsubscribe(final WorldContext world) { - world.model.player.conditionListener.remove(this); - hideAllIcons(); - } - - public void subscribe(final WorldContext world) { - hideAllIcons(); - for (ActorCondition condition : world.model.player.conditions) { - getFirstFreeIcon().setActiveCondition(condition); - } - world.model.player.conditionListener.add(this); - } - private void hideAllIcons() { - for (ActiveConditionIcon icon : currentConditionIcons) icon.hide(false); + private ActiveConditionIcon getIconFor(ActorCondition condition) { + for (ActiveConditionIcon icon : currentConditionIcons) { + if (icon.condition == condition) return icon; + } + return null; + } + private ActiveConditionIcon getFirstFreeIcon() { + for (ActiveConditionIcon icon : currentConditionIcons) { + if (!icon.isVisible()) return icon; + } + return addNewActiveConditionIcon(); + } + + private RelativeLayout.LayoutParams getLayoutParamsForIconIndex(int index) { + RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + layout.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); + if (index == 0) { + layout.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); + } else { + layout.addRule(RelativeLayout.LEFT_OF, currentConditionIcons.get(index-1).id); + } + return layout; + } + + private ActiveConditionIcon addNewActiveConditionIcon() { + int index = currentConditionIcons.size(); + + ActiveConditionIcon icon = new ActiveConditionIcon(androidContext.get(), index+1); + + activeConditions.addView(icon.image, getLayoutParamsForIconIndex(index)); + + RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + layout.addRule(RelativeLayout.ALIGN_RIGHT, icon.id); + layout.addRule(RelativeLayout.ALIGN_BOTTOM, icon.id); + activeConditions.addView(icon.text, layout); + + currentConditionIcons.add(icon); + + return icon; } } From c90d7c4ef0350544b8b344a4718c63bbbc0827cf Mon Sep 17 00:00:00 2001 From: Oskar Wiksten Date: Mon, 6 Aug 2012 18:35:29 +0200 Subject: [PATCH 3/4] Use animations when changing visibility of the combat bar. --- AndorsTrail/res/anim/hidecombatbar.xml | 8 ++++++ AndorsTrail/res/anim/showcombatbar.xml | 8 ++++++ .../controller/CombatController.java | 6 ++--- .../gpl/rpg/AndorsTrail/view/CombatView.java | 26 +++++++++++++++++++ 4 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 AndorsTrail/res/anim/hidecombatbar.xml create mode 100644 AndorsTrail/res/anim/showcombatbar.xml diff --git a/AndorsTrail/res/anim/hidecombatbar.xml b/AndorsTrail/res/anim/hidecombatbar.xml new file mode 100644 index 000000000..77f471c13 --- /dev/null +++ b/AndorsTrail/res/anim/hidecombatbar.xml @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/AndorsTrail/res/anim/showcombatbar.xml b/AndorsTrail/res/anim/showcombatbar.xml new file mode 100644 index 000000000..aa6461964 --- /dev/null +++ b/AndorsTrail/res/anim/showcombatbar.xml @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java index a0911b735..ebc2da269 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java @@ -6,7 +6,6 @@ import android.content.res.Resources; import android.os.Handler; import android.os.Message; import android.util.FloatMath; -import android.view.View; import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences; import com.gpl.rpg.AndorsTrail.Dialogs; @@ -49,8 +48,7 @@ public final class CombatController implements VisualEffectCompletedCallback { public static final int BEGIN_TURN_CONTINUE = 2; public void enterCombat(int beginTurnAs) { - context.mainActivity.combatview.setVisibility(View.VISIBLE); - context.mainActivity.combatview.bringToFront(); + context.mainActivity.combatview.show(); model.uiSelections.isInCombat = true; killedMonsterBags.clear(); context.mainActivity.clearMessages(); @@ -61,7 +59,7 @@ public final class CombatController implements VisualEffectCompletedCallback { } public void exitCombat(boolean pickupLootBags) { setCombatSelection(null, null); - context.mainActivity.combatview.setVisibility(View.GONE); + context.mainActivity.combatview.hide(); model.uiSelections.isInCombat = false; context.mainActivity.clearMessages(); currentActiveMonster = null; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java index a34722494..c981c2e9e 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java @@ -5,6 +5,9 @@ import android.content.Context; import android.content.res.Resources; import android.util.AttributeSet; import android.view.View; +import android.view.animation.Animation; +import android.view.animation.Animation.AnimationListener; +import android.view.animation.AnimationUtils; import android.widget.Button; import android.widget.ImageButton; import android.widget.RelativeLayout; @@ -34,6 +37,8 @@ public final class CombatView extends RelativeLayout { private final ViewContext view; private final Resources res; private final Player player; + private final Animation displayAnimation; + private final Animation hideAnimation; private Monster currentMonster; public CombatView(final Context context, AttributeSet attr) { @@ -90,6 +95,16 @@ public final class CombatView extends RelativeLayout { monsterBar.setBackgroundColor(res.getColor(color.transparent)); actionBar.setBackgroundColor(res.getColor(color.transparent)); + + displayAnimation = AnimationUtils.loadAnimation(context, R.anim.showcombatbar); + hideAnimation = AnimationUtils.loadAnimation(context, R.anim.hidecombatbar); + hideAnimation.setAnimationListener(new AnimationListener() { + @Override public void onAnimationStart(Animation animation) {} + @Override public void onAnimationRepeat(Animation animation) {} + @Override public void onAnimationEnd(Animation arg0) { + CombatView.this.setVisibility(View.GONE); + } + }); } public void updateTurnInfo(Monster currentActiveMonster) { @@ -135,4 +150,15 @@ public final class CombatView extends RelativeLayout { } updateCombatSelection(world.model.uiSelections.selectedMonster, world.model.uiSelections.selectedPosition); } + + public void show() { + setVisibility(View.VISIBLE); + bringToFront(); + startAnimation(displayAnimation); + } + + public void hide() { + startAnimation(hideAnimation); + //setVisibility(View.GONE); + } } From a358fdf344d6a99e6eab1bff431e0e86602c4a99 Mon Sep 17 00:00:00 2001 From: Oskar Wiksten Date: Sun, 7 Oct 2012 17:25:14 +0200 Subject: [PATCH 4/4] Provide setting to disable UI animations, such as the combat bar. --- AndorsTrail/res/values/strings.xml | 3 +++ AndorsTrail/res/xml/preferences.xml | 8 ++++++++ .../rpg/AndorsTrail/AndorsTrailPreferences.java | 3 +++ .../rpg/AndorsTrail/activity/MainActivity.java | 2 +- .../gpl/rpg/AndorsTrail/view/CombatView.java | 15 ++++++++++++--- .../view/DisplayActiveActorConditionIcons.java | 17 +++++++++++++++-- 6 files changed, 42 insertions(+), 6 deletions(-) diff --git a/AndorsTrail/res/values/strings.xml b/AndorsTrail/res/values/strings.xml index 1fcb53d3c..c8a2de429 100644 --- a/AndorsTrail/res/values/strings.xml +++ b/AndorsTrail/res/values/strings.xml @@ -504,5 +504,8 @@ When making an attack on a target whose block chance (BC) is at least %1$d lower than your attack chance (AC), there is a %2$d %% chance that the hit will cause a concussion on the target. A concussion will severely lower the target\'s offensive combat abilities, making the target less able to land successful attacks. About + Interface + Enable animations + Show animations for various interface elements, such as the combat bar. diff --git a/AndorsTrail/res/xml/preferences.xml b/AndorsTrail/res/xml/preferences.xml index 1102f6a2b..656df7d0a 100644 --- a/AndorsTrail/res/xml/preferences.xml +++ b/AndorsTrail/res/xml/preferences.xml @@ -72,4 +72,12 @@ android:summary="@string/preferences_movement_dpad_minimizeable" android:key="dpadMinimizeable" /> + + + diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailPreferences.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailPreferences.java index 0e84f3ec5..3993bb796 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailPreferences.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailPreferences.java @@ -34,6 +34,7 @@ public class AndorsTrailPreferences { public int dpadPosition; public boolean dpadMinimizeable = true; public boolean optimizedDrawing = false; + public boolean enableUiAnimations = true; public static void read(final Context androidContext, AndorsTrailPreferences dest) { try { @@ -48,6 +49,7 @@ public class AndorsTrailPreferences { dest.dpadPosition = Integer.parseInt(prefs.getString("dpadposition", Integer.toString(DPAD_POSITION_DISABLED))); dest.dpadMinimizeable = prefs.getBoolean("dpadMinimizeable", true); dest.optimizedDrawing = prefs.getBoolean("optimized_drawing", false); + dest.enableUiAnimations = prefs.getBoolean("enableUiAnimations", true); // This might be implemented as a skill in the future. //dest.movementAggressiveness = Integer.parseInt(prefs.getString("movementaggressiveness", Integer.toString(MOVEMENTAGGRESSIVENESS_NORMAL))); @@ -63,6 +65,7 @@ public class AndorsTrailPreferences { dest.dpadPosition = DPAD_POSITION_DISABLED; dest.dpadMinimizeable = true; dest.optimizedDrawing = false; + dest.enableUiAnimations = true; } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java index 5e0384a1c..0f70c143d 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java @@ -85,7 +85,7 @@ public final class MainActivity extends Activity { statusview = (StatusView) findViewById(R.id.main_statusview); combatview = (CombatView) findViewById(R.id.main_combatview); quickitemview = (QuickitemView) findViewById(R.id.main_quickitemview); - activeConditions = new DisplayActiveActorConditionIcons(world.tileManager, this, (RelativeLayout) findViewById(R.id.statusview_activeconditions)); + activeConditions = new DisplayActiveActorConditionIcons(app.preferences, world.tileManager, this, (RelativeLayout) findViewById(R.id.statusview_activeconditions)); dpad = (VirtualDpadView) findViewById(R.id.main_virtual_dpad); statusText = (TextView) findViewById(R.id.statusview_statustext); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java index c981c2e9e..db6102635 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/CombatView.java @@ -13,6 +13,7 @@ import android.widget.ImageButton; import android.widget.RelativeLayout; import android.widget.TextView; +import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences; import com.gpl.rpg.AndorsTrail.Dialogs; import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; import com.gpl.rpg.AndorsTrail.R; @@ -36,17 +37,20 @@ public final class CombatView extends RelativeLayout { private final WorldContext world; private final ViewContext view; private final Resources res; + private final AndorsTrailPreferences preferences; private final Player player; private final Animation displayAnimation; private final Animation hideAnimation; private Monster currentMonster; + public CombatView(final Context context, AttributeSet attr) { super(context, attr); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivityContext(context); this.world = app.world; this.player = world.model.player; this.view = app.currentView.get(); + this.preferences = app.preferences; this.res = getResources(); setFocusable(false); @@ -154,11 +158,16 @@ public final class CombatView extends RelativeLayout { public void show() { setVisibility(View.VISIBLE); bringToFront(); - startAnimation(displayAnimation); + if (preferences.enableUiAnimations) { + startAnimation(displayAnimation); + } } public void hide() { - startAnimation(hideAnimation); - //setVisibility(View.GONE); + if (preferences.enableUiAnimations) { + startAnimation(hideAnimation); + } else { + setVisibility(View.GONE); + } } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java index a3bcc1e88..c14864707 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java @@ -14,6 +14,7 @@ import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.RelativeLayout.LayoutParams; +import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences; import com.gpl.rpg.AndorsTrail.R; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; @@ -23,12 +24,18 @@ import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager; public class DisplayActiveActorConditionIcons implements ActorConditionListener { + private final AndorsTrailPreferences preferences; private final TileManager tileManager; private final RelativeLayout activeConditions; private final ArrayList currentConditionIcons = new ArrayList(); private final WeakReference androidContext; - public DisplayActiveActorConditionIcons(final TileManager tileManager, Context androidContext, RelativeLayout activeConditions) { + public DisplayActiveActorConditionIcons( + final AndorsTrailPreferences preferences, + final TileManager tileManager, + Context androidContext, + RelativeLayout activeConditions) { + this.preferences = preferences; this.tileManager = tileManager; this.androidContext = new WeakReference(androidContext); this.activeConditions = activeConditions; @@ -123,7 +130,11 @@ public class DisplayActiveActorConditionIcons implements ActorConditionListener public void hide(boolean useAnimation) { if (useAnimation) { - image.startAnimation(onRemovedIconAnimation); + if (preferences.enableUiAnimations) { + image.startAnimation(onRemovedIconAnimation); + } else { + onAnimationEnd(onRemovedIconAnimation); + } } else { image.setVisibility(View.GONE); condition = null; @@ -131,11 +142,13 @@ public class DisplayActiveActorConditionIcons implements ActorConditionListener text.setVisibility(View.GONE); } public void show() { + if (!preferences.enableUiAnimations) return; image.startAnimation(onNewIconAnimation); if (text.getVisibility() == View.VISIBLE) text.startAnimation(onNewIconAnimation); } public void pulseAnimate() { + if (!preferences.enableUiAnimations) return; image.startAnimation(onAppliedEffectAnimation); }