From d7db9b8f82c1111e752c6a91523865b2e5805f03 Mon Sep 17 00:00:00 2001
From: andidevi <35863827+andidevi@users.noreply.github.com>
Date: Mon, 5 Feb 2018 10:23:12 +0100
Subject: [PATCH] Refactor effects to use the Factory pattern (#43)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This shows several advantages:
- No need for several switchs with hardcoded names.
- Easier and better control per theme (name, price…).
- Easier to keep track of available effects and their order.
---
.../io/github/lonamiwebs/klooni/Effect.java | 142 ------------------
.../io/github/lonamiwebs/klooni/Klooni.java | 86 +++++++++--
.../github/lonamiwebs/klooni/SkinLoader.java | 1 +
.../lonamiwebs/klooni/actors/EffectCard.java | 14 +-
.../klooni/effects/EvaporateEffect.java | 72 ---------
.../effects/EvaporateEffectFactory.java | 117 +++++++++++++++
.../klooni/effects/ExplodeEffect.java | 66 --------
.../klooni/effects/ExplodeEffectFactory.java | 112 ++++++++++++++
.../lonamiwebs/klooni/effects/SpinEffect.java | 59 --------
.../klooni/effects/SpinEffectFactory.java | 105 +++++++++++++
.../klooni/effects/VanishEffect.java | 72 ---------
.../klooni/effects/VanishEffectFatory.java | 117 +++++++++++++++
.../klooni/effects/WaterdropEffect.java | 74 ---------
.../effects/WaterdropEffectFactory.java | 121 +++++++++++++++
.../github/lonamiwebs/klooni/game/Board.java | 8 +-
.../{effects => interfaces}/IEffect.java | 2 +-
.../klooni/interfaces/IEffectFactory.java | 36 +++++
.../klooni/screens/CustomizeScreen.java | 4 +-
.../lonamiwebs/klooni/screens/GameScreen.java | 2 +-
19 files changed, 694 insertions(+), 516 deletions(-)
delete mode 100644 core/src/io/github/lonamiwebs/klooni/Effect.java
delete mode 100644 core/src/io/github/lonamiwebs/klooni/effects/EvaporateEffect.java
create mode 100644 core/src/io/github/lonamiwebs/klooni/effects/EvaporateEffectFactory.java
delete mode 100644 core/src/io/github/lonamiwebs/klooni/effects/ExplodeEffect.java
create mode 100644 core/src/io/github/lonamiwebs/klooni/effects/ExplodeEffectFactory.java
delete mode 100644 core/src/io/github/lonamiwebs/klooni/effects/SpinEffect.java
create mode 100644 core/src/io/github/lonamiwebs/klooni/effects/SpinEffectFactory.java
delete mode 100644 core/src/io/github/lonamiwebs/klooni/effects/VanishEffect.java
create mode 100644 core/src/io/github/lonamiwebs/klooni/effects/VanishEffectFatory.java
delete mode 100644 core/src/io/github/lonamiwebs/klooni/effects/WaterdropEffect.java
create mode 100644 core/src/io/github/lonamiwebs/klooni/effects/WaterdropEffectFactory.java
rename core/src/io/github/lonamiwebs/klooni/{effects => interfaces}/IEffect.java (84%)
create mode 100644 core/src/io/github/lonamiwebs/klooni/interfaces/IEffectFactory.java
diff --git a/core/src/io/github/lonamiwebs/klooni/Effect.java b/core/src/io/github/lonamiwebs/klooni/Effect.java
deleted file mode 100644
index 7ca67b3..0000000
--- a/core/src/io/github/lonamiwebs/klooni/Effect.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- 1010! Klooni, a free customizable puzzle game for Android and Desktop
- Copyright (C) 2017 Lonami Exo | LonamiWebs
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-package io.github.lonamiwebs.klooni;
-
-import com.badlogic.gdx.Gdx;
-import com.badlogic.gdx.audio.Sound;
-import com.badlogic.gdx.files.FileHandle;
-import com.badlogic.gdx.math.MathUtils;
-import com.badlogic.gdx.math.Vector2;
-
-import io.github.lonamiwebs.klooni.effects.EvaporateEffect;
-import io.github.lonamiwebs.klooni.effects.ExplodeEffect;
-import io.github.lonamiwebs.klooni.effects.IEffect;
-import io.github.lonamiwebs.klooni.effects.SpinEffect;
-import io.github.lonamiwebs.klooni.effects.VanishEffect;
-import io.github.lonamiwebs.klooni.effects.WaterdropEffect;
-import io.github.lonamiwebs.klooni.game.Cell;
-
-public class Effect {
-
- //region Members
-
- private final int effectId;
- private final Sound effectSound;
- public final String name;
- public final int price;
-
- //endregion
-
- //region Constructor
-
- // This method will load the sound "sound/effect_{effectName}.mp3"
- public Effect(final String effectName) {
- this(effectName, effectNameToInt(effectName));
- }
-
- public Effect(final String effectName, final int id) {
- name = effectName;
- effectId = id;
-
- FileHandle soundFile = Gdx.files.internal("sound/effect_" + name + ".mp3");
- if (!soundFile.exists())
- soundFile = Gdx.files.internal("sound/effect_vanish.mp3");
-
- effectSound = Gdx.audio.newSound(soundFile);
- price = effectId == 0 ? 0 : 200; // TODO For now they're all 200 coins except the first
- }
-
- //endregion
-
- //region Public methods
-
- public void playSound() {
- effectSound.play(MathUtils.random(0.7f, 1f), MathUtils.random(0.8f, 1.2f), 0);
- }
-
- public String getDisplay() {
- // TODO For now, uppercase the first letter
- return name.substring(0, 1).toUpperCase() + name.substring(1);
- }
-
- //endregion
-
- //region Static methods
-
- public static Effect[] getEffects() {
- int id = 0;
- return new Effect[] {
- new Effect("vanish", id++),
- new Effect("waterdrop", id++),
- new Effect("evaporate", id++),
- new Effect("spin", id++),
- new Effect("explode", id++)
- };
- }
-
- //endregion
-
- //region Name <-> ID <-> IEffect
-
- // Effects used when clearing a row
- public IEffect create(final Cell deadCell, final Vector2 culprit) {
- final IEffect effect;
- switch (effectId) {
- default:
- case 0:
- effect = new VanishEffect();
- break;
- case 1:
- effect = new WaterdropEffect();
- break;
- case 2:
- effect = new EvaporateEffect();
- break;
- case 3:
- effect = new SpinEffect();
- break;
- case 4:
- effect = new ExplodeEffect();
- break;
- }
- effect.setInfo(deadCell, culprit);
- return effect;
- }
-
- private static int effectNameToInt(final String name) {
- // String comparision is more expensive compared to a single integer one,
- // and when creating instances of a lot of effects it's better if we can
- // save some processor cycles.
- if (name.equals("vanish")) return 0;
- if (name.equals("waterdrop")) return 1;
- if (name.equals("evaporate")) return 2;
- if (name.equals("spin")) return 3;
- if (name.equals("explode")) return 4;
- return -1;
- }
-
- //endregion
-
- //region Disposal
-
- void dispose() {
- effectSound.dispose();
- }
-
- //endregion
-}
diff --git a/core/src/io/github/lonamiwebs/klooni/Klooni.java b/core/src/io/github/lonamiwebs/klooni/Klooni.java
index c1ad166..ce67cd3 100644
--- a/core/src/io/github/lonamiwebs/klooni/Klooni.java
+++ b/core/src/io/github/lonamiwebs/klooni/Klooni.java
@@ -22,18 +22,59 @@
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.Screen;
+import com.badlogic.gdx.audio.Sound;
+import com.badlogic.gdx.files.FileHandle;
+import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
+import java.util.HashMap;
+import java.util.Map;
+
+import io.github.lonamiwebs.klooni.effects.EvaporateEffectFactory;
+import io.github.lonamiwebs.klooni.effects.ExplodeEffectFactory;
+import io.github.lonamiwebs.klooni.effects.SpinEffectFactory;
+import io.github.lonamiwebs.klooni.effects.VanishEffectFatory;
+import io.github.lonamiwebs.klooni.effects.WaterdropEffectFactory;
+import io.github.lonamiwebs.klooni.interfaces.IEffectFactory;
import io.github.lonamiwebs.klooni.screens.MainMenuScreen;
import io.github.lonamiwebs.klooni.screens.TransitionScreen;
public class Klooni extends Game {
+ // region Effects
+
+ // ordered list of effects. index 0 will get default if VanishEffectFactory is removed from list
+ public final static IEffectFactory[] EFFECTS = {
+ new VanishEffectFatory(),
+ new WaterdropEffectFactory(),
+ new EvaporateEffectFactory(),
+ new SpinEffectFactory(),
+ new ExplodeEffectFactory(),
+ };
+
+
+ private Map effectSounds;
+
+ private void loadEffectSound(final String effectName) {
+ FileHandle soundFile = Gdx.files.internal("sound/effect_" + effectName + ".mp3");
+ if (!soundFile.exists())
+ soundFile = Gdx.files.internal("sound/effect_vanish.mp3");
+
+ effectSounds.put(effectName, Gdx.audio.newSound(soundFile));
+ }
+
+ public void playEffectSound() {
+ effectSounds.get(effect.getName())
+ .play(MathUtils.random(0.7f, 1f), MathUtils.random(0.8f, 1.2f), 0);
+ }
+
+ // endregion
//region Members
- // TODO Not sure whether the theme should be static or not since it might load textures
+ // FIXME theme should NOT be static as it might load textures which will expose it to the race condition iff GDX got initialized before or not
public static Theme theme;
- public Effect effect;
+ public IEffectFactory effect;
+
public Skin skin;
@@ -74,13 +115,21 @@ public void create() {
Gdx.input.setCatchBackKey(true); // To show the pause menu
setScreen(new MainMenuScreen(this));
- effect = new Effect(prefs.getString("effectName", "vanish"));
+ String effectName = prefs.getString("effectName", "vanish");
+ effectSounds = new HashMap(EFFECTS.length);
+ effect = EFFECTS[0];
+ for (IEffectFactory e : EFFECTS) {
+ loadEffectSound(e.getName());
+ if (e.getName().equals(effectName)) {
+ effect = e;
+ }
+ }
}
//endregion
//region Screen
-
+
// TransitionScreen will also dispose by default the previous screen
public void transitionTo(Screen screen) {
transitionTo(screen, true);
@@ -99,7 +148,12 @@ public void dispose() {
super.dispose();
skin.dispose();
theme.dispose();
- effect.dispose();
+ if (effectSounds != null) {
+ for (Sound s : effectSounds.values()) {
+ s.dispose();
+ }
+ effectSounds = null;
+ }
}
//endregion
@@ -183,40 +237,40 @@ public static void updateTheme(Theme newTheme) {
}
// Effects related
- public static boolean isEffectBought(Effect effect) {
- if (effect.price == 0)
+ public static boolean isEffectBought(IEffectFactory effect) {
+ if (effect.getPrice() == 0)
return true;
String[] effects = prefs.getString("boughtEffects", "").split(":");
for (String e : effects)
- if (e.equals(effect.name))
+ if (e.equals(effect.getName()))
return true;
return false;
}
- public static boolean buyEffect(Effect effect) {
+ public static boolean buyEffect(IEffectFactory effect) {
final float money = getRealMoney();
- if (effect.price > money)
+ if (effect.getPrice() > money)
return false;
- setMoney(money - effect.price);
+ setMoney(money - effect.getPrice());
String bought = prefs.getString("boughtEffects", "");
if (bought.equals(""))
- bought = effect.name;
+ bought = effect.getName();
else
- bought += ":" + effect.name;
+ bought += ":" + effect.getName();
prefs.putString("boughtEffects", bought);
return true;
}
- public void updateEffect(Effect newEffect) {
- prefs.putString("effectName", newEffect.name).flush();
+ public void updateEffect(IEffectFactory newEffect) {
+ prefs.putString("effectName", newEffect.getName()).flush();
// Create a new effect, since the one passed through the parameter may dispose later
- effect = new Effect(newEffect.name);
+ effect = newEffect;
}
// Money related
diff --git a/core/src/io/github/lonamiwebs/klooni/SkinLoader.java b/core/src/io/github/lonamiwebs/klooni/SkinLoader.java
index 4e5a08f..a1042b1 100644
--- a/core/src/io/github/lonamiwebs/klooni/SkinLoader.java
+++ b/core/src/io/github/lonamiwebs/klooni/SkinLoader.java
@@ -33,6 +33,7 @@ public class SkinLoader {
private final static float bestMultiplier;
+ // FIXME this static code is exposed to a race condition and will fail if called class gets loaded before execution of Klooni.create
static {
// Use the height to determine the best match
// We cannot use a size which is over the device height,
diff --git a/core/src/io/github/lonamiwebs/klooni/actors/EffectCard.java b/core/src/io/github/lonamiwebs/klooni/actors/EffectCard.java
index 2ae2136..31b0f95 100644
--- a/core/src/io/github/lonamiwebs/klooni/actors/EffectCard.java
+++ b/core/src/io/github/lonamiwebs/klooni/actors/EffectCard.java
@@ -21,19 +21,19 @@
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.math.Rectangle;
-import io.github.lonamiwebs.klooni.Effect;
import io.github.lonamiwebs.klooni.Klooni;
import io.github.lonamiwebs.klooni.Theme;
import io.github.lonamiwebs.klooni.game.Board;
import io.github.lonamiwebs.klooni.game.GameLayout;
import io.github.lonamiwebs.klooni.game.Piece;
+import io.github.lonamiwebs.klooni.interfaces.IEffectFactory;
// Card-like actor used to display information about a given theme
public class EffectCard extends ShopCard {
//region Members
- private final Effect effect;
+ private final IEffectFactory effect;
private final Board board;
// We want to create an effect from the beginning
@@ -45,7 +45,7 @@ public class EffectCard extends ShopCard {
//region Constructor
- public EffectCard(final Klooni game, final GameLayout layout, final Effect effect) {
+ public EffectCard(final Klooni game, final GameLayout layout, final IEffectFactory effect) {
super(game, layout, effect.getDisplay(), Klooni.theme.background);
background = Theme.getBlankTexture();
this.effect = effect;
@@ -118,12 +118,12 @@ public boolean showcase(Batch batch, float yDisplacement) {
@Override
public void usedItemUpdated() {
- if (game.effect.name.equals(effect.name))
+ if (game.effect.getName().equals(effect.getName()))
priceLabel.setText("currently used");
else if (Klooni.isEffectBought(effect))
priceLabel.setText("bought");
else
- priceLabel.setText("buy for "+effect.price);
+ priceLabel.setText("buy for "+effect.getPrice());
}
@Override
@@ -139,12 +139,12 @@ public boolean isBought() {
@Override
public boolean isUsed() {
- return game.effect.name.equals(effect.name);
+ return game.effect.getName().equals(effect.getName());
}
@Override
public float getPrice() {
- return effect.price;
+ return effect.getPrice();
}
@Override
diff --git a/core/src/io/github/lonamiwebs/klooni/effects/EvaporateEffect.java b/core/src/io/github/lonamiwebs/klooni/effects/EvaporateEffect.java
deleted file mode 100644
index 1fb5d90..0000000
--- a/core/src/io/github/lonamiwebs/klooni/effects/EvaporateEffect.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package io.github.lonamiwebs.klooni.effects;
-
-
-import com.badlogic.gdx.Gdx;
-import com.badlogic.gdx.graphics.Color;
-import com.badlogic.gdx.graphics.g2d.Batch;
-import com.badlogic.gdx.math.Interpolation;
-import com.badlogic.gdx.math.MathUtils;
-import com.badlogic.gdx.math.Vector2;
-
-import io.github.lonamiwebs.klooni.game.Cell;
-
-public class EvaporateEffect implements IEffect {
- private Vector2 pos;
- private float originalX;
-
- private float size;
-
- private Color vanishColor;
- private float vanishSize;
- private float vanishElapsed;
- private float driftMagnitude;
- private float randomOffset;
-
- private static final float UP_SPEED = 100.0f;
- private static final float LIFETIME = 3.0f;
- private static final float INV_LIFETIME = 1.0f / 3.0f;
-
- public EvaporateEffect() {
- vanishElapsed = Float.POSITIVE_INFINITY;
- }
-
- @Override
- public void setInfo(Cell deadCell, Vector2 culprit) {
- pos = deadCell.pos.cpy();
- originalX = pos.x;
- size = deadCell.size;
-
- vanishSize = deadCell.size;
- vanishColor = deadCell.getColorCopy();
- driftMagnitude = Gdx.graphics.getWidth() * 0.05f;
- vanishElapsed = 0;
- randomOffset = MathUtils.random(MathUtils.PI2);
- }
-
- @Override
- public void draw(Batch batch) {
- vanishElapsed += Gdx.graphics.getDeltaTime();
-
- // Update the size as we fade away
- final float progress = vanishElapsed * INV_LIFETIME;
- vanishSize = Interpolation.fade.apply(size, 0, progress);
-
- // Fade away depending on the time
- vanishColor.set(vanishColor.r, vanishColor.g, vanishColor.b, 1.0f - progress);
-
- // Ghostly fade upwards, by doing a lerp from our current position to the wavy one
- pos.x = MathUtils.lerp(
- pos.x,
- originalX + MathUtils.sin(randomOffset + vanishElapsed * 3f) * driftMagnitude,
- 0.3f
- );
- pos.y += UP_SPEED * Gdx.graphics.getDeltaTime();
-
- Cell.draw(vanishColor, batch, pos.x, pos.y, vanishSize);
- }
-
- @Override
- public boolean isDone() {
- return vanishElapsed > LIFETIME;
- }
-}
diff --git a/core/src/io/github/lonamiwebs/klooni/effects/EvaporateEffectFactory.java b/core/src/io/github/lonamiwebs/klooni/effects/EvaporateEffectFactory.java
new file mode 100644
index 0000000..0487044
--- /dev/null
+++ b/core/src/io/github/lonamiwebs/klooni/effects/EvaporateEffectFactory.java
@@ -0,0 +1,117 @@
+/*
+ 1010! Klooni, a free customizable puzzle game for Android and Desktop
+ Copyright (C) 2017 Lonami Exo | LonamiWebs
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+package io.github.lonamiwebs.klooni.effects;
+
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.graphics.g2d.Batch;
+import com.badlogic.gdx.math.Interpolation;
+import com.badlogic.gdx.math.MathUtils;
+import com.badlogic.gdx.math.Vector2;
+
+import io.github.lonamiwebs.klooni.game.Cell;
+import io.github.lonamiwebs.klooni.interfaces.IEffect;
+import io.github.lonamiwebs.klooni.interfaces.IEffectFactory;
+
+
+public class EvaporateEffectFactory implements IEffectFactory {
+ @Override
+ public String getName() {
+ return "evaporate";
+ }
+
+ @Override
+ public String getDisplay() {
+ return "Evaporate";
+ }
+
+ @Override
+ public int getPrice() {
+ return 200;
+ }
+
+ @Override
+ public IEffect create(Cell deadCell, Vector2 culprit) {
+ IEffect effect = new EvaporateEffect();
+ effect.setInfo(deadCell, culprit);
+ return effect;
+ }
+
+
+ private class EvaporateEffect implements IEffect {
+ private Vector2 pos;
+ private float originalX;
+
+ private float size;
+
+ private Color vanishColor;
+ private float vanishSize;
+ private float vanishElapsed;
+ private float driftMagnitude;
+ private float randomOffset;
+
+ private static final float UP_SPEED = 100.0f;
+ private static final float LIFETIME = 3.0f;
+ private static final float INV_LIFETIME = 1.0f / 3.0f;
+
+ EvaporateEffect() {
+ vanishElapsed = Float.POSITIVE_INFINITY;
+ }
+
+ @Override
+ public void setInfo(Cell deadCell, Vector2 culprit) {
+ pos = deadCell.pos.cpy();
+ originalX = pos.x;
+ size = deadCell.size;
+
+ vanishSize = deadCell.size;
+ vanishColor = deadCell.getColorCopy();
+ driftMagnitude = Gdx.graphics.getWidth() * 0.05f;
+ vanishElapsed = 0;
+ randomOffset = MathUtils.random(MathUtils.PI2);
+ }
+
+ @Override
+ public void draw(Batch batch) {
+ vanishElapsed += Gdx.graphics.getDeltaTime();
+
+ // Update the size as we fade away
+ final float progress = vanishElapsed * INV_LIFETIME;
+ vanishSize = Interpolation.fade.apply(size, 0, progress);
+
+ // Fade away depending on the time
+ vanishColor.set(vanishColor.r, vanishColor.g, vanishColor.b, 1.0f - progress);
+
+ // Ghostly fade upwards, by doing a lerp from our current position to the wavy one
+ pos.x = MathUtils.lerp(
+ pos.x,
+ originalX + MathUtils.sin(randomOffset + vanishElapsed * 3f) * driftMagnitude,
+ 0.3f
+ );
+ pos.y += UP_SPEED * Gdx.graphics.getDeltaTime();
+
+ Cell.draw(vanishColor, batch, pos.x, pos.y, vanishSize);
+ }
+
+ @Override
+ public boolean isDone() {
+ return vanishElapsed > LIFETIME;
+ }
+ }
+
+}
diff --git a/core/src/io/github/lonamiwebs/klooni/effects/ExplodeEffect.java b/core/src/io/github/lonamiwebs/klooni/effects/ExplodeEffect.java
deleted file mode 100644
index 55578d1..0000000
--- a/core/src/io/github/lonamiwebs/klooni/effects/ExplodeEffect.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package io.github.lonamiwebs.klooni.effects;
-
-import com.badlogic.gdx.Gdx;
-import com.badlogic.gdx.graphics.Color;
-import com.badlogic.gdx.graphics.g2d.Batch;
-import com.badlogic.gdx.math.MathUtils;
-import com.badlogic.gdx.math.Vector2;
-import com.badlogic.gdx.math.Vector3;
-
-import io.github.lonamiwebs.klooni.game.Cell;
-
-public class ExplodeEffect implements IEffect {
- private Color color;
- boolean dead;
-
- private final static float EXPLOSION_X_RANGE = 0.25f;
- private final static float EXPLOSION_Y_RANGE = 0.30f;
- private final static float GRAVITY_PERCENTAGE = -0.60f;
-
- class Shard {
- final Vector2 pos, vel, acc;
- final float size;
-
- public Shard(final Vector2 pos, final float size) {
- final float xRange = Gdx.graphics.getWidth() * EXPLOSION_X_RANGE;
- final float yRange = Gdx.graphics.getHeight() * EXPLOSION_Y_RANGE;
- vel = new Vector2(MathUtils.random(-xRange, +xRange), MathUtils.random(-yRange * 0.2f, +yRange));
- acc = new Vector2(0f, Gdx.graphics.getHeight() * GRAVITY_PERCENTAGE);
-
- this.size = size * MathUtils.random(0.40f, 0.60f);
- this.pos = pos.cpy().add(this.size * 0.5f, this.size * 0.5f);
- }
-
- public void draw(final Batch batch, final float dt) {
- vel.add(acc.x * dt, acc.y * dt).scl(0.99f);
- pos.add(vel.x * dt, vel.y * dt);
- Cell.draw(color, batch, pos.x, pos.y, size);
- }
- }
-
- private Shard[] shards;
-
- @Override
- public void setInfo(Cell deadCell, Vector2 culprit) {
- color = deadCell.getColorCopy();
-
- shards = new Shard[MathUtils.random(4, 6)];
- for (int i = 0; i != shards.length; ++i)
- shards[i] = new Shard(deadCell.pos, deadCell.size);
- }
-
- @Override
- public void draw(Batch batch) {
- dead = true; // assume we're death
- final Vector3 translation = batch.getTransformMatrix().getTranslation(new Vector3());
- for (int i = shards.length; i-- != 0; ) {
- shards[i].draw(batch, Gdx.graphics.getDeltaTime());
- dead &= translation.y + shards[i].pos.y + shards[i].size < 0; // all must be dead
- }
- }
-
- @Override
- public boolean isDone() {
- return dead;
- }
-}
diff --git a/core/src/io/github/lonamiwebs/klooni/effects/ExplodeEffectFactory.java b/core/src/io/github/lonamiwebs/klooni/effects/ExplodeEffectFactory.java
new file mode 100644
index 0000000..72138ec
--- /dev/null
+++ b/core/src/io/github/lonamiwebs/klooni/effects/ExplodeEffectFactory.java
@@ -0,0 +1,112 @@
+/*
+ 1010! Klooni, a free customizable puzzle game for Android and Desktop
+ Copyright (C) 2017 Lonami Exo | LonamiWebs
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+package io.github.lonamiwebs.klooni.effects;
+
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.graphics.g2d.Batch;
+import com.badlogic.gdx.math.MathUtils;
+import com.badlogic.gdx.math.Vector2;
+import com.badlogic.gdx.math.Vector3;
+
+import io.github.lonamiwebs.klooni.game.Cell;
+import io.github.lonamiwebs.klooni.interfaces.IEffect;
+import io.github.lonamiwebs.klooni.interfaces.IEffectFactory;
+
+
+public class ExplodeEffectFactory implements IEffectFactory {
+ @Override
+ public String getName() {
+ return "explode";
+ }
+
+ @Override
+ public String getDisplay() {
+ return "Explode";
+ }
+
+ @Override
+ public int getPrice() {
+ return 200;
+ }
+
+ @Override
+ public IEffect create(Cell deadCell, Vector2 culprit) {
+ IEffect effect = new ExplodeEffect();
+ effect.setInfo(deadCell, culprit);
+ return effect;
+ }
+
+
+ private class ExplodeEffect implements IEffect {
+ private Color color;
+ boolean dead;
+
+ private final static float EXPLOSION_X_RANGE = 0.25f;
+ private final static float EXPLOSION_Y_RANGE = 0.30f;
+ private final static float GRAVITY_PERCENTAGE = -0.60f;
+
+ private class Shard {
+ final Vector2 pos, vel, acc;
+ final float size;
+
+ Shard(final Vector2 pos, final float size) {
+ final float xRange = Gdx.graphics.getWidth() * EXPLOSION_X_RANGE;
+ final float yRange = Gdx.graphics.getHeight() * EXPLOSION_Y_RANGE;
+ vel = new Vector2(MathUtils.random(-xRange, +xRange), MathUtils.random(-yRange * 0.2f, +yRange));
+ acc = new Vector2(0f, Gdx.graphics.getHeight() * GRAVITY_PERCENTAGE);
+
+ this.size = size * MathUtils.random(0.40f, 0.60f);
+ this.pos = pos.cpy().add(this.size * 0.5f, this.size * 0.5f);
+ }
+
+ public void draw(final Batch batch, final float dt) {
+ vel.add(acc.x * dt, acc.y * dt).scl(0.99f);
+ pos.add(vel.x * dt, vel.y * dt);
+ Cell.draw(color, batch, pos.x, pos.y, size);
+ }
+ }
+
+ private Shard[] shards;
+
+ @Override
+ public void setInfo(Cell deadCell, Vector2 culprit) {
+ color = deadCell.getColorCopy();
+
+ shards = new Shard[MathUtils.random(4, 6)];
+ for (int i = 0; i != shards.length; ++i)
+ shards[i] = new Shard(deadCell.pos, deadCell.size);
+ }
+
+ @Override
+ public void draw(Batch batch) {
+ dead = true; // assume we're death
+ final Vector3 translation = batch.getTransformMatrix().getTranslation(new Vector3());
+ for (int i = shards.length; i-- != 0; ) {
+ shards[i].draw(batch, Gdx.graphics.getDeltaTime());
+ dead &= translation.y + shards[i].pos.y + shards[i].size < 0; // all must be dead
+ }
+ }
+
+ @Override
+ public boolean isDone() {
+ return dead;
+ }
+ }
+
+}
diff --git a/core/src/io/github/lonamiwebs/klooni/effects/SpinEffect.java b/core/src/io/github/lonamiwebs/klooni/effects/SpinEffect.java
deleted file mode 100644
index 8485647..0000000
--- a/core/src/io/github/lonamiwebs/klooni/effects/SpinEffect.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package io.github.lonamiwebs.klooni.effects;
-
-import com.badlogic.gdx.Gdx;
-import com.badlogic.gdx.graphics.Color;
-import com.badlogic.gdx.graphics.g2d.Batch;
-import com.badlogic.gdx.math.Interpolation;
-import com.badlogic.gdx.math.Matrix4;
-import com.badlogic.gdx.math.Vector2;
-
-import io.github.lonamiwebs.klooni.game.Cell;
-
-public class SpinEffect implements IEffect {
- private float age;
- private Vector2 pos;
- private float size;
- private Color color;
-
- private static final float LIFETIME = 2.0f;
- private static final float INV_LIFETIME = 1.0f / LIFETIME;
-
- private static final float TOTAL_ROTATION = 600;
-
- @Override
- public void setInfo(Cell deadCell, Vector2 culprit) {
- age = 0;
- pos = deadCell.pos.cpy();
- size = deadCell.size;
- color = deadCell.getColorCopy();
- }
-
- @Override
- public void draw(Batch batch) {
- age += Gdx.graphics.getDeltaTime();
-
- final float progress = age * INV_LIFETIME;
- final float currentSize = Interpolation.pow2In.apply(size, 0, progress);
- final float currentRotation = Interpolation.sine.apply(0, TOTAL_ROTATION, progress);
-
- final Matrix4 original = batch.getTransformMatrix().cpy();
- final Matrix4 rotated = batch.getTransformMatrix();
-
- final float disp =
- + 0.5f * (size - currentSize) // the smaller, the more we need to "push" to center
- + currentSize * 0.5f; // center the cell for rotation
-
- rotated.translate(pos.x + disp, pos.y + disp, 0);
- rotated.rotate(0, 0, 1, currentRotation);
- rotated.translate(currentSize * -0.5f, currentSize * -0.5f, 0); // revert centering for rotation
-
- batch.setTransformMatrix(rotated);
- Cell.draw(color, batch, 0, 0, currentSize);
- batch.setTransformMatrix(original);
- }
-
- @Override
- public boolean isDone() {
- return age > LIFETIME;
- }
-}
diff --git a/core/src/io/github/lonamiwebs/klooni/effects/SpinEffectFactory.java b/core/src/io/github/lonamiwebs/klooni/effects/SpinEffectFactory.java
new file mode 100644
index 0000000..13d18f0
--- /dev/null
+++ b/core/src/io/github/lonamiwebs/klooni/effects/SpinEffectFactory.java
@@ -0,0 +1,105 @@
+/*
+ 1010! Klooni, a free customizable puzzle game for Android and Desktop
+ Copyright (C) 2017 Lonami Exo | LonamiWebs
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+package io.github.lonamiwebs.klooni.effects;
+
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.graphics.g2d.Batch;
+import com.badlogic.gdx.math.Interpolation;
+import com.badlogic.gdx.math.Matrix4;
+import com.badlogic.gdx.math.Vector2;
+
+import io.github.lonamiwebs.klooni.game.Cell;
+import io.github.lonamiwebs.klooni.interfaces.IEffect;
+import io.github.lonamiwebs.klooni.interfaces.IEffectFactory;
+
+
+public class SpinEffectFactory implements IEffectFactory {
+ @Override
+ public String getName() {
+ return "spin";
+ }
+
+ @Override
+ public String getDisplay() {
+ return "Spin";
+ }
+
+ @Override
+ public int getPrice() {
+ return 200;
+ }
+
+ @Override
+ public IEffect create(Cell deadCell, Vector2 culprit) {
+ IEffect effect = new SpinEffect();
+ effect.setInfo(deadCell, culprit);
+ return effect;
+ }
+
+
+ private class SpinEffect implements IEffect {
+ private float age;
+ private Vector2 pos;
+ private float size;
+ private Color color;
+
+ private static final float LIFETIME = 2.0f;
+ private static final float INV_LIFETIME = 1.0f / LIFETIME;
+
+ private static final float TOTAL_ROTATION = 600;
+
+ @Override
+ public void setInfo(Cell deadCell, Vector2 culprit) {
+ age = 0;
+ pos = deadCell.pos.cpy();
+ size = deadCell.size;
+ color = deadCell.getColorCopy();
+ }
+
+ @Override
+ public void draw(Batch batch) {
+ age += Gdx.graphics.getDeltaTime();
+
+ final float progress = age * INV_LIFETIME;
+ final float currentSize = Interpolation.pow2In.apply(size, 0, progress);
+ final float currentRotation = Interpolation.sine.apply(0, TOTAL_ROTATION, progress);
+
+ final Matrix4 original = batch.getTransformMatrix().cpy();
+ final Matrix4 rotated = batch.getTransformMatrix();
+
+ final float disp =
+ +0.5f * (size - currentSize) // the smaller, the more we need to "push" to center
+ + currentSize * 0.5f; // center the cell for rotation
+
+ rotated.translate(pos.x + disp, pos.y + disp, 0);
+ rotated.rotate(0, 0, 1, currentRotation);
+ rotated.translate(currentSize * -0.5f, currentSize * -0.5f, 0); // revert centering for rotation
+
+ batch.setTransformMatrix(rotated);
+ Cell.draw(color, batch, 0, 0, currentSize);
+ batch.setTransformMatrix(original);
+ }
+
+ @Override
+ public boolean isDone() {
+ return age > LIFETIME;
+ }
+ }
+
+}
diff --git a/core/src/io/github/lonamiwebs/klooni/effects/VanishEffect.java b/core/src/io/github/lonamiwebs/klooni/effects/VanishEffect.java
deleted file mode 100644
index 1bedff2..0000000
--- a/core/src/io/github/lonamiwebs/klooni/effects/VanishEffect.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package io.github.lonamiwebs.klooni.effects;
-
-
-import com.badlogic.gdx.Gdx;
-import com.badlogic.gdx.graphics.Color;
-import com.badlogic.gdx.graphics.g2d.Batch;
-import com.badlogic.gdx.math.Interpolation;
-import com.badlogic.gdx.math.MathUtils;
-import com.badlogic.gdx.math.Vector2;
-
-import io.github.lonamiwebs.klooni.game.Cell;
-
-public class VanishEffect implements IEffect {
- private Cell cell;
-
- private Color vanishColor;
- private float vanishSize;
- private float vanishElapsed;
- private float vanishLifetime;
-
- private final static float MINIMUM_SIZE = 0.3f;
-
- public VanishEffect() {
- vanishElapsed = Float.POSITIVE_INFINITY;
- }
-
- @Override
- public void setInfo(Cell deadCell, Vector2 culprit) {
- cell = deadCell;
-
- vanishSize = cell.size;
- vanishColor = cell.getColorCopy();
- vanishLifetime = 1f;
-
- // The vanish distance is this measure (distance² + size³ * 20% size)
- // because it seems good enough. The more the distance, the more the
- // delay, but we decrease the delay depending on the cell size too or
- // it would be way too high
- Vector2 center = new Vector2(cell.pos.x + cell.size * 0.5f, cell.pos.y + 0.5f);
- float vanishDist = Vector2.dst2(
- culprit.x, culprit.y, center.x, center.y) / ((float)Math.pow(cell.size, 4.0f) * 0.2f);
-
- // Negative time = delay, + 0.4*lifetime because elastic interpolation has that delay
- vanishElapsed = vanishLifetime * 0.4f - vanishDist;
- }
-
- @Override
- public void draw(Batch batch) {
- vanishElapsed += Gdx.graphics.getDeltaTime();
-
- // vanishElapsed might be < 0 (delay), so clamp to 0
- float progress = Math.min(1f,
- Math.max(vanishElapsed, 0f) / vanishLifetime);
-
- // If one were to plot the elasticIn function, they would see that the slope increases
- // a lot towards the end- a linear interpolation between the last size + the desired
- // size at 20% seems to look a lot better.
- vanishSize = MathUtils.lerp(
- vanishSize,
- Interpolation.elasticIn.apply(cell.size, 0, progress),
- 0.2f
- );
-
- float centerOffset = cell.size * 0.5f - vanishSize * 0.5f;
- Cell.draw(vanishColor, batch, cell.pos.x + centerOffset, cell.pos.y + centerOffset, vanishSize);
- }
-
- @Override
- public boolean isDone() {
- return vanishSize < MINIMUM_SIZE;
- }
-}
diff --git a/core/src/io/github/lonamiwebs/klooni/effects/VanishEffectFatory.java b/core/src/io/github/lonamiwebs/klooni/effects/VanishEffectFatory.java
new file mode 100644
index 0000000..cbacb8c
--- /dev/null
+++ b/core/src/io/github/lonamiwebs/klooni/effects/VanishEffectFatory.java
@@ -0,0 +1,117 @@
+/*
+ 1010! Klooni, a free customizable puzzle game for Android and Desktop
+ Copyright (C) 2017 Lonami Exo | LonamiWebs
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+package io.github.lonamiwebs.klooni.effects;
+
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.graphics.g2d.Batch;
+import com.badlogic.gdx.math.Interpolation;
+import com.badlogic.gdx.math.MathUtils;
+import com.badlogic.gdx.math.Vector2;
+
+import io.github.lonamiwebs.klooni.game.Cell;
+import io.github.lonamiwebs.klooni.interfaces.IEffect;
+import io.github.lonamiwebs.klooni.interfaces.IEffectFactory;
+
+
+public class VanishEffectFatory implements IEffectFactory {
+ @Override
+ public String getName() {
+ return "vanish";
+ }
+
+ @Override
+ public String getDisplay() {
+ return "Vanish";
+ }
+
+ @Override
+ public int getPrice() {
+ return 0;
+ }
+
+ @Override
+ public IEffect create(Cell deadCell, Vector2 culprit) {
+ IEffect effect = new VanishEffect();
+ effect.setInfo(deadCell, culprit);
+ return effect;
+ }
+
+
+ private class VanishEffect implements IEffect {
+ private Cell cell;
+
+ private Color vanishColor;
+ private float vanishSize;
+ private float vanishElapsed;
+ private float vanishLifetime;
+
+ private final static float MINIMUM_SIZE = 0.3f;
+
+ VanishEffect() {
+ vanishElapsed = Float.POSITIVE_INFINITY;
+ }
+
+ @Override
+ public void setInfo(Cell deadCell, Vector2 culprit) {
+ cell = deadCell;
+
+ vanishSize = cell.size;
+ vanishColor = cell.getColorCopy();
+ vanishLifetime = 1f;
+
+ // The vanish distance is this measure (distance² + size³ * 20% size)
+ // because it seems good enough. The more the distance, the more the
+ // delay, but we decrease the delay depending on the cell size too or
+ // it would be way too high
+ Vector2 center = new Vector2(cell.pos.x + cell.size * 0.5f, cell.pos.y + 0.5f);
+ float vanishDist = Vector2.dst2(
+ culprit.x, culprit.y, center.x, center.y) / ((float) Math.pow(cell.size, 4.0f) * 0.2f);
+
+ // Negative time = delay, + 0.4*lifetime because elastic interpolation has that delay
+ vanishElapsed = vanishLifetime * 0.4f - vanishDist;
+ }
+
+ @Override
+ public void draw(Batch batch) {
+ vanishElapsed += Gdx.graphics.getDeltaTime();
+
+ // vanishElapsed might be < 0 (delay), so clamp to 0
+ float progress = Math.min(1f,
+ Math.max(vanishElapsed, 0f) / vanishLifetime);
+
+ // If one were to plot the elasticIn function, they would see that the slope increases
+ // a lot towards the end- a linear interpolation between the last size + the desired
+ // size at 20% seems to look a lot better.
+ vanishSize = MathUtils.lerp(
+ vanishSize,
+ Interpolation.elasticIn.apply(cell.size, 0, progress),
+ 0.2f
+ );
+
+ float centerOffset = cell.size * 0.5f - vanishSize * 0.5f;
+ Cell.draw(vanishColor, batch, cell.pos.x + centerOffset, cell.pos.y + centerOffset, vanishSize);
+ }
+
+ @Override
+ public boolean isDone() {
+ return vanishSize < MINIMUM_SIZE;
+ }
+ }
+
+}
diff --git a/core/src/io/github/lonamiwebs/klooni/effects/WaterdropEffect.java b/core/src/io/github/lonamiwebs/klooni/effects/WaterdropEffect.java
deleted file mode 100644
index 58f6f47..0000000
--- a/core/src/io/github/lonamiwebs/klooni/effects/WaterdropEffect.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package io.github.lonamiwebs.klooni.effects;
-
-
-import com.badlogic.gdx.Gdx;
-import com.badlogic.gdx.graphics.Color;
-import com.badlogic.gdx.graphics.Texture;
-import com.badlogic.gdx.graphics.g2d.Batch;
-import com.badlogic.gdx.math.MathUtils;
-import com.badlogic.gdx.math.Vector2;
-import com.badlogic.gdx.math.Vector3;
-
-import io.github.lonamiwebs.klooni.SkinLoader;
-import io.github.lonamiwebs.klooni.game.Cell;
-
-public class WaterdropEffect implements IEffect {
- private Vector2 pos;
- private boolean dead;
-
- private Color cellColor;
- private Color dropColor;
- private float cellSize;
-
- private final float fallAcceleration;
- private float fallSpeed;
-
- private static final float FALL_ACCELERATION = 500.0f;
- private static final float FALL_VARIATION = 50.0f;
- private static final float COLOR_SPEED = 7.5f;
-
- private final static Texture dropTexture;
-
- static {
- dropTexture = SkinLoader.loadPng("cells/drop.png");
- }
-
- public WaterdropEffect() {
- fallAcceleration = FALL_ACCELERATION + MathUtils.random(-FALL_VARIATION, FALL_VARIATION);
- }
-
- @Override
- public void setInfo(Cell deadCell, Vector2 culprit) {
- pos = deadCell.pos.cpy();
- cellSize = deadCell.size;
- cellColor = deadCell.getColorCopy();
- dropColor = new Color(cellColor.r, cellColor.g, cellColor.b, 0.0f);
- }
-
- @Override
- public void draw(Batch batch) {
- final float dt = Gdx.graphics.getDeltaTime();
- fallSpeed += fallAcceleration * dt;
- pos.y -= fallSpeed * dt;
-
- cellColor.set(
- cellColor.r, cellColor.g, cellColor.b,
- Math.max(cellColor.a - COLOR_SPEED * dt, 0.0f)
- );
- dropColor.set(
- cellColor.r, cellColor.g, cellColor.b,
- Math.min(dropColor.a + COLOR_SPEED * dt, 1.0f)
- );
-
- Cell.draw(cellColor, batch, pos.x, pos.y, cellSize);
- Cell.draw(dropTexture, dropColor, batch, pos.x, pos.y, cellSize);
-
- final Vector3 translation = batch.getTransformMatrix().getTranslation(new Vector3());
- dead = translation.y + pos.y + dropTexture.getHeight() < 0;
- }
-
- @Override
- public boolean isDone() {
- return dead;
- }
-}
diff --git a/core/src/io/github/lonamiwebs/klooni/effects/WaterdropEffectFactory.java b/core/src/io/github/lonamiwebs/klooni/effects/WaterdropEffectFactory.java
new file mode 100644
index 0000000..d43e80b
--- /dev/null
+++ b/core/src/io/github/lonamiwebs/klooni/effects/WaterdropEffectFactory.java
@@ -0,0 +1,121 @@
+/*
+ 1010! Klooni, a free customizable puzzle game for Android and Desktop
+ Copyright (C) 2017 Lonami Exo | LonamiWebs
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+package io.github.lonamiwebs.klooni.effects;
+
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.graphics.Texture;
+import com.badlogic.gdx.graphics.g2d.Batch;
+import com.badlogic.gdx.math.MathUtils;
+import com.badlogic.gdx.math.Vector2;
+import com.badlogic.gdx.math.Vector3;
+
+import io.github.lonamiwebs.klooni.SkinLoader;
+import io.github.lonamiwebs.klooni.game.Cell;
+import io.github.lonamiwebs.klooni.interfaces.IEffect;
+import io.github.lonamiwebs.klooni.interfaces.IEffectFactory;
+
+
+public class WaterdropEffectFactory implements IEffectFactory {
+ private Texture dropTexture;
+
+
+ private void init() {
+ if(dropTexture == null)
+ dropTexture = SkinLoader.loadPng("cells/drop.png");
+ }
+
+ @Override
+ public String getName() {
+ return "waterdrop";
+ }
+
+ @Override
+ public String getDisplay() {
+ return "Waterdrop";
+ }
+
+ @Override
+ public int getPrice() {
+ return 200;
+ }
+
+ @Override
+ public IEffect create(Cell deadCell, Vector2 culprit) {
+ init();
+ IEffect effect = new WaterdropEffect();
+ effect.setInfo(deadCell, culprit);
+ return effect;
+ }
+
+
+ private class WaterdropEffect implements IEffect {
+ private Vector2 pos;
+ private boolean dead;
+
+ private Color cellColor;
+ private Color dropColor;
+ private float cellSize;
+
+ private final float fallAcceleration;
+ private float fallSpeed;
+
+ private static final float FALL_ACCELERATION = 500.0f;
+ private static final float FALL_VARIATION = 50.0f;
+ private static final float COLOR_SPEED = 7.5f;
+
+ WaterdropEffect() {
+ fallAcceleration = FALL_ACCELERATION + MathUtils.random(-FALL_VARIATION, FALL_VARIATION);
+ }
+
+ @Override
+ public void setInfo(Cell deadCell, Vector2 culprit) {
+ pos = deadCell.pos.cpy();
+ cellSize = deadCell.size;
+ cellColor = deadCell.getColorCopy();
+ dropColor = new Color(cellColor.r, cellColor.g, cellColor.b, 0.0f);
+ }
+
+ @Override
+ public void draw(Batch batch) {
+ final float dt = Gdx.graphics.getDeltaTime();
+ fallSpeed += fallAcceleration * dt;
+ pos.y -= fallSpeed * dt;
+
+ cellColor.set(
+ cellColor.r, cellColor.g, cellColor.b,
+ Math.max(cellColor.a - COLOR_SPEED * dt, 0.0f)
+ );
+ dropColor.set(
+ cellColor.r, cellColor.g, cellColor.b,
+ Math.min(dropColor.a + COLOR_SPEED * dt, 1.0f)
+ );
+
+ Cell.draw(cellColor, batch, pos.x, pos.y, cellSize);
+ Cell.draw(dropTexture, dropColor, batch, pos.x, pos.y, cellSize);
+
+ final Vector3 translation = batch.getTransformMatrix().getTranslation(new Vector3());
+ dead = translation.y + pos.y + dropTexture.getHeight() < 0;
+ }
+
+ @Override
+ public boolean isDone() {
+ return dead;
+ }
+ }
+}
diff --git a/core/src/io/github/lonamiwebs/klooni/game/Board.java b/core/src/io/github/lonamiwebs/klooni/game/Board.java
index 545092f..d5b4605 100644
--- a/core/src/io/github/lonamiwebs/klooni/game/Board.java
+++ b/core/src/io/github/lonamiwebs/klooni/game/Board.java
@@ -27,8 +27,8 @@
import java.io.DataOutputStream;
import java.io.IOException;
-import io.github.lonamiwebs.klooni.Effect;
-import io.github.lonamiwebs.klooni.effects.IEffect;
+import io.github.lonamiwebs.klooni.interfaces.IEffect;
+import io.github.lonamiwebs.klooni.interfaces.IEffectFactory;
import io.github.lonamiwebs.klooni.serializer.BinSerializable;
// Represents the on screen board, with all the put cells
@@ -183,7 +183,7 @@ Vector2 snapToGrid(final Piece piece, final Vector2 position) {
//
// If the piece is put on the top left corner, all the cells will be cleared.
// If we first cleared the columns, then the rows wouldn't have been cleared.
- public int clearComplete(final Effect effect) {
+ public int clearComplete(final IEffectFactory effect) {
int clearCount = 0;
boolean[] clearedRows = new boolean[cellCount];
boolean[] clearedCols = new boolean[cellCount];
@@ -235,7 +235,7 @@ public int clearComplete(final Effect effect) {
return clearCount;
}
- public void clearAll(final int clearFromX, final int clearFromY, final Effect effect) {
+ public void clearAll(final int clearFromX, final int clearFromY, final IEffectFactory effect) {
final Vector2 culprit = cells[clearFromY][clearFromX].pos;
for (int i = 0; i < cellCount; ++i) {
diff --git a/core/src/io/github/lonamiwebs/klooni/effects/IEffect.java b/core/src/io/github/lonamiwebs/klooni/interfaces/IEffect.java
similarity index 84%
rename from core/src/io/github/lonamiwebs/klooni/effects/IEffect.java
rename to core/src/io/github/lonamiwebs/klooni/interfaces/IEffect.java
index 4a15a7c..ad5fb50 100644
--- a/core/src/io/github/lonamiwebs/klooni/effects/IEffect.java
+++ b/core/src/io/github/lonamiwebs/klooni/interfaces/IEffect.java
@@ -1,4 +1,4 @@
-package io.github.lonamiwebs.klooni.effects;
+package io.github.lonamiwebs.klooni.interfaces;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.math.Vector2;
diff --git a/core/src/io/github/lonamiwebs/klooni/interfaces/IEffectFactory.java b/core/src/io/github/lonamiwebs/klooni/interfaces/IEffectFactory.java
new file mode 100644
index 0000000..4a6f364
--- /dev/null
+++ b/core/src/io/github/lonamiwebs/klooni/interfaces/IEffectFactory.java
@@ -0,0 +1,36 @@
+/*
+ 1010! Klooni, a free customizable puzzle game for Android and Desktop
+ Copyright (C) 2017 Lonami Exo | LonamiWebs
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+package io.github.lonamiwebs.klooni.interfaces;
+
+import com.badlogic.gdx.math.Vector2;
+
+import io.github.lonamiwebs.klooni.game.Cell;
+
+/**
+ * IEffectEfactory interface has to be implemented for each effect.
+ *
+ * It tells the name and the price of the effect and will create it, when needed.
+ *
+ * @see IEffect
+ */
+public interface IEffectFactory {
+ public String getName();
+ public String getDisplay();
+ public int getPrice();
+ public IEffect create(final Cell deadCell, final Vector2 culprit);
+}
diff --git a/core/src/io/github/lonamiwebs/klooni/screens/CustomizeScreen.java b/core/src/io/github/lonamiwebs/klooni/screens/CustomizeScreen.java
index fe7c330..2b92802 100644
--- a/core/src/io/github/lonamiwebs/klooni/screens/CustomizeScreen.java
+++ b/core/src/io/github/lonamiwebs/klooni/screens/CustomizeScreen.java
@@ -34,7 +34,6 @@
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.SnapshotArray;
-import io.github.lonamiwebs.klooni.Effect;
import io.github.lonamiwebs.klooni.Klooni;
import io.github.lonamiwebs.klooni.Theme;
import io.github.lonamiwebs.klooni.actors.EffectCard;
@@ -43,6 +42,7 @@
import io.github.lonamiwebs.klooni.actors.SoftButton;
import io.github.lonamiwebs.klooni.actors.ThemeCard;
import io.github.lonamiwebs.klooni.game.GameLayout;
+import io.github.lonamiwebs.klooni.interfaces.IEffectFactory;
// Screen where the user can customize the look and feel of the game
class CustomizeScreen implements Screen {
@@ -200,7 +200,7 @@ private void loadShop() {
shopGroup.clear();
if (showingEffectsShop)
- for (Effect effect : Effect.getEffects())
+ for (IEffectFactory effect : Klooni.EFFECTS)
addCard(new EffectCard(game, layout, effect));
else // showingThemesShop
diff --git a/core/src/io/github/lonamiwebs/klooni/screens/GameScreen.java b/core/src/io/github/lonamiwebs/klooni/screens/GameScreen.java
index c7c006f..943118f 100644
--- a/core/src/io/github/lonamiwebs/klooni/screens/GameScreen.java
+++ b/core/src/io/github/lonamiwebs/klooni/screens/GameScreen.java
@@ -241,7 +241,7 @@ public boolean touchUp(int screenX, int screenY, int pointer, int button) {
if (bonus > 0) {
bonusParticleHandler.addBonus(result.pieceCenter, bonus);
if (Klooni.soundsEnabled()) {
- game.effect.playSound();
+ game.playEffectSound();
}
}