diff --git a/core/src/io/github/lonamiwebs/klooni/actors/EffectCard.java b/core/src/io/github/lonamiwebs/klooni/actors/EffectCard.java index 2ceb5a3..f50e35d 100644 --- a/core/src/io/github/lonamiwebs/klooni/actors/EffectCard.java +++ b/core/src/io/github/lonamiwebs/klooni/actors/EffectCard.java @@ -20,9 +20,6 @@ package io.github.lonamiwebs.klooni.actors; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.Label; import io.github.lonamiwebs.klooni.Effect; import io.github.lonamiwebs.klooni.Klooni; @@ -31,49 +28,25 @@ import io.github.lonamiwebs.klooni.game.Cell; import io.github.lonamiwebs.klooni.game.GameLayout; // Card-like actor used to display information about a given theme -public class EffectCard extends Actor { +public class EffectCard extends ShopCard { //region Members - private final Klooni game; public final Effect effect; private final Texture background; private Color color; - private final Label nameLabel; - private final Label priceLabel; - - public final Rectangle nameBounds; - public final Rectangle priceBounds; - - public float cellSize; - //endregion //region Constructor public EffectCard(final Klooni game, final GameLayout layout, final Effect effect) { - this.game = game; - this.effect = effect; + super(game, layout, effect.getDisplay(), Klooni.theme.background); background = Theme.getBlankTexture(); - - Label.LabelStyle labelStyle = new Label.LabelStyle(); - labelStyle.font = game.skin.getFont("font_small"); - - priceLabel = new Label("", labelStyle); - nameLabel = new Label(effect.getDisplay(), labelStyle); - - Color labelColor = Theme.shouldUseWhite(Klooni.theme.background) ? Color.WHITE : Color.BLACK; - priceLabel.setColor(labelColor); - nameLabel.setColor(labelColor); - - priceBounds = new Rectangle(); - nameBounds = new Rectangle(); - - layout.update(this); - usedEffectUpdated(); - color = Klooni.theme.getRandomCellColor(); + + this.effect = effect; + usedItemUpdated(); } //endregion @@ -91,14 +64,11 @@ public class EffectCard extends Actor { // so it's becomes cellSize * 2 Cell.draw(color, batch, x + cellSize * 2, y + cellSize * 2, cellSize); - nameLabel.setBounds(x + nameBounds.x, y + nameBounds.y, nameBounds.width, nameBounds.height); - nameLabel.draw(batch, parentAlpha); - - priceLabel.setBounds(x + priceBounds.x, y + priceBounds.y, priceBounds.width, priceBounds.height); - priceLabel.draw(batch, parentAlpha); + super.draw(batch, parentAlpha); } - public void usedEffectUpdated() { + @Override + public void usedItemUpdated() { if (game.effect.name.equals(effect.name)) priceLabel.setText("currently used"); else if (Klooni.isEffectBought(effect)) @@ -107,16 +77,29 @@ public class EffectCard extends Actor { priceLabel.setText("buy for "+effect.price); } + @Override public void use() { game.updateEffect(effect); - usedEffectUpdated(); + usedItemUpdated(); } + @Override + public boolean isBought() { + return Klooni.isEffectBought(effect); + } + + @Override public boolean isUsed() { return game.effect.equals(effect.name); } - void performBuy() { + @Override + public float getPrice() { + return effect.price; + } + + @Override + public void performBuy() { Klooni.buyEffect(effect); use(); } diff --git a/core/src/io/github/lonamiwebs/klooni/actors/MoneyBuyBand.java b/core/src/io/github/lonamiwebs/klooni/actors/MoneyBuyBand.java index 89dbd2a..df46a86 100644 --- a/core/src/io/github/lonamiwebs/klooni/actors/MoneyBuyBand.java +++ b/core/src/io/github/lonamiwebs/klooni/actors/MoneyBuyBand.java @@ -43,7 +43,7 @@ public class MoneyBuyBand extends Table { // The theme card that is going to be bought next. We can't // only save the Theme because we need to tell the ThemeCard // that it was bought so it can reflect the new theme status. - private Object toBuy; // Either ThemeCard or EffectCard + private ShopCard toBuy; // Used to interpolate between strings private StringBuilder shownText; @@ -78,10 +78,7 @@ public class MoneyBuyBand extends Table { @Override public void changed(ChangeEvent event, Actor actor) { if (toBuy != null) { - if (toBuy instanceof ThemeCard) - ((ThemeCard)toBuy).performBuy(); - else if (toBuy instanceof EffectCard) - ((EffectCard)toBuy).performBuy(); + toBuy.performBuy(); } showCurrentMoney(); hideBuyButtons(); @@ -175,25 +172,10 @@ public class MoneyBuyBand extends Table { //region Public methods - // Asks the user to buy the given theme, or shows - // that they don't have enough money to buy it - public void askBuy(final ThemeCard toBuy) { - if (toBuy.theme.getPrice() > Klooni.getMoney()) { - setTempText("cannot buy!"); - confirmButton.setVisible(false); - cancelButton.setVisible(false); - } - else { - this.toBuy = toBuy; - setText("confirm?"); - confirmButton.setVisible(true); - cancelButton.setVisible(true); - } - } - - // TODO Make a generic card class so they all inherit - public void askBuy(final EffectCard toBuy) { - if (toBuy.effect.price > Klooni.getMoney()) { + // Asks the user to buy the given theme or effect, + // or shows that they don't have enough money to buy it + public void askBuy(final ShopCard toBuy) { + if (toBuy.getPrice() > Klooni.getMoney()) { setTempText("cannot buy!"); confirmButton.setVisible(false); cancelButton.setVisible(false); diff --git a/core/src/io/github/lonamiwebs/klooni/actors/ShopCard.java b/core/src/io/github/lonamiwebs/klooni/actors/ShopCard.java new file mode 100644 index 0000000..c9082ad --- /dev/null +++ b/core/src/io/github/lonamiwebs/klooni/actors/ShopCard.java @@ -0,0 +1,79 @@ +/* + 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.actors; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Label; + +import io.github.lonamiwebs.klooni.Klooni; +import io.github.lonamiwebs.klooni.Theme; +import io.github.lonamiwebs.klooni.game.GameLayout; + +public abstract class ShopCard extends Actor { + + final Klooni game; + + final Label nameLabel; + final Label priceLabel; + + public final Rectangle nameBounds; + public final Rectangle priceBounds; + + public float cellSize; + + public ShopCard(final Klooni game, final GameLayout layout, + final String itemName, final Color backgroundColor) { + this.game = game; + Label.LabelStyle labelStyle = new Label.LabelStyle(); + labelStyle.font = game.skin.getFont("font_small"); + + priceLabel = new Label("", labelStyle); + nameLabel = new Label(itemName, labelStyle); + + Color labelColor = Theme.shouldUseWhite(backgroundColor) ? Color.WHITE : Color.BLACK; + priceLabel.setColor(labelColor); + nameLabel.setColor(labelColor); + + priceBounds = new Rectangle(); + nameBounds = new Rectangle(); + + layout.update(this); + } + + @Override + public void draw(Batch batch, float parentAlpha) { + super.draw(batch, parentAlpha); + + final float x = getX(), y = getY(); + nameLabel.setBounds(x + nameBounds.x, y + nameBounds.y, nameBounds.width, nameBounds.height); + nameLabel.draw(batch, parentAlpha); + + priceLabel.setBounds(x + priceBounds.x, y + priceBounds.y, priceBounds.width, priceBounds.height); + priceLabel.draw(batch, parentAlpha); + } + + public abstract void usedItemUpdated(); + public abstract void use(); + public abstract boolean isBought(); + public abstract boolean isUsed(); + public abstract float getPrice(); + public abstract void performBuy(); +} diff --git a/core/src/io/github/lonamiwebs/klooni/actors/ThemeCard.java b/core/src/io/github/lonamiwebs/klooni/actors/ThemeCard.java index 9bcbd9a..1acfcde 100644 --- a/core/src/io/github/lonamiwebs/klooni/actors/ThemeCard.java +++ b/core/src/io/github/lonamiwebs/klooni/actors/ThemeCard.java @@ -17,12 +17,8 @@ */ package io.github.lonamiwebs.klooni.actors; -import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.Label; import io.github.lonamiwebs.klooni.Klooni; import io.github.lonamiwebs.klooni.Theme; @@ -30,21 +26,13 @@ import io.github.lonamiwebs.klooni.game.Cell; import io.github.lonamiwebs.klooni.game.GameLayout; // Card-like actor used to display information about a given theme -public class ThemeCard extends Actor { +public class ThemeCard extends ShopCard { //region Members public final Theme theme; private final Texture background; - private final Label nameLabel; - private final Label priceLabel; - - public final Rectangle nameBounds; - public final Rectangle priceBounds; - - public float cellSize; - private final static int colorsUsed[][] = { {0, 7, 7}, {8, 7, 3}, @@ -56,24 +44,11 @@ public class ThemeCard extends Actor { //region Constructor public ThemeCard(final Klooni game, final GameLayout layout, final Theme theme) { - this.theme = theme; + super(game, layout, theme.getDisplay(), theme.background); background = Theme.getBlankTexture(); - Label.LabelStyle labelStyle = new Label.LabelStyle(); - labelStyle.font = game.skin.getFont("font_small"); - - priceLabel = new Label("", labelStyle); - nameLabel = new Label(theme.getDisplay(), labelStyle); - - Color labelColor = Theme.shouldUseWhite(theme.background) ? Color.WHITE : Color.BLACK; - priceLabel.setColor(labelColor); - nameLabel.setColor(labelColor); - - priceBounds = new Rectangle(); - nameBounds = new Rectangle(); - - layout.update(this); - usedThemeUpdated(); + this.theme = theme; + usedItemUpdated(); } //endregion @@ -95,14 +70,11 @@ public class ThemeCard extends Actor { } } - nameLabel.setBounds(x + nameBounds.x, y + nameBounds.y, nameBounds.width, nameBounds.height); - nameLabel.draw(batch, parentAlpha); - - priceLabel.setBounds(x + priceBounds.x, y + priceBounds.y, priceBounds.width, priceBounds.height); - priceLabel.draw(batch, parentAlpha); + super.draw(batch, parentAlpha); } - public void usedThemeUpdated() { + @Override + public void usedItemUpdated() { if (Klooni.theme.getName().equals(theme.getName())) priceLabel.setText("currently used"); else if (Klooni.isThemeBought(theme)) @@ -111,16 +83,29 @@ public class ThemeCard extends Actor { priceLabel.setText("buy for "+theme.getPrice()); } + @Override public void use() { Klooni.updateTheme(theme); - usedThemeUpdated(); + usedItemUpdated(); } + @Override + public boolean isBought() { + return Klooni.isThemeBought(theme); + } + + @Override public boolean isUsed() { return Klooni.theme.getName().equals(theme.getName()); } - void performBuy() { + @Override + public float getPrice() { + return theme.getPrice(); + } + + @Override + public void performBuy() { Klooni.buyTheme(theme); use(); } diff --git a/core/src/io/github/lonamiwebs/klooni/game/GameLayout.java b/core/src/io/github/lonamiwebs/klooni/game/GameLayout.java index 709a444..2a912fb 100644 --- a/core/src/io/github/lonamiwebs/klooni/game/GameLayout.java +++ b/core/src/io/github/lonamiwebs/klooni/game/GameLayout.java @@ -23,8 +23,7 @@ import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.scenes.scene2d.ui.Label; import io.github.lonamiwebs.klooni.actors.Band; -import io.github.lonamiwebs.klooni.actors.EffectCard; -import io.github.lonamiwebs.klooni.actors.ThemeCard; +import io.github.lonamiwebs.klooni.actors.ShopCard; // Helper class to calculate the size of each element // @@ -35,7 +34,7 @@ public class GameLayout { //region Members private float screenWidth, marginWidth, availableWidth; - private float screenHeight, logoHeight, scoreHeight, boardHeight, pieceHolderHeight, themeCardHeight; + private float screenHeight, logoHeight, scoreHeight, boardHeight, pieceHolderHeight, shopCardHeight; //endregion @@ -63,7 +62,7 @@ public class GameLayout { boardHeight = screenHeight * 0.50f; pieceHolderHeight = screenHeight * 0.25f; - themeCardHeight = screenHeight * 0.15f; + shopCardHeight = screenHeight * 0.15f; } //endregion @@ -132,33 +131,18 @@ public class GameLayout { band.infoBounds.set(area.x, area.y + area.height * 0.10f, area.width, area.height * 0.35f); } - public void update(ThemeCard card) { - card.setSize(availableWidth - marginWidth, themeCardHeight); - card.cellSize = themeCardHeight * 0.2f; + public void update(ShopCard card) { + card.setSize(availableWidth - marginWidth, shopCardHeight); + card.cellSize = shopCardHeight * 0.2f; - // X offset from the cells (5 cells = themeCardHeight) + // X offset from the cells (5 cells = shopCardHeight) card.nameBounds.set( - themeCardHeight, card.cellSize, - availableWidth - themeCardHeight, themeCardHeight); + shopCardHeight, card.cellSize, + availableWidth - shopCardHeight, shopCardHeight); card.priceBounds.set( - themeCardHeight, -card.cellSize, - availableWidth - themeCardHeight, themeCardHeight); - } - - // TODO Probably a more generic class "card" that can hold any type (theme/effect) - public void update(EffectCard card) { - card.setSize(availableWidth - marginWidth, themeCardHeight); - card.cellSize = themeCardHeight * 0.2f; - - // X offset from the cells (5 cells = themeCardHeight) - card.nameBounds.set( - themeCardHeight, card.cellSize, - availableWidth - themeCardHeight, themeCardHeight); - - card.priceBounds.set( - themeCardHeight, -card.cellSize, - availableWidth - themeCardHeight, themeCardHeight); + shopCardHeight, -card.cellSize, + availableWidth - shopCardHeight, shopCardHeight); } //endregion diff --git a/core/src/io/github/lonamiwebs/klooni/screens/CustomizeScreen.java b/core/src/io/github/lonamiwebs/klooni/screens/CustomizeScreen.java index 1066ff5..580c3cd 100644 --- a/core/src/io/github/lonamiwebs/klooni/screens/CustomizeScreen.java +++ b/core/src/io/github/lonamiwebs/klooni/screens/CustomizeScreen.java @@ -37,6 +37,7 @@ import io.github.lonamiwebs.klooni.Klooni; import io.github.lonamiwebs.klooni.Theme; import io.github.lonamiwebs.klooni.actors.EffectCard; import io.github.lonamiwebs.klooni.actors.MoneyBuyBand; +import io.github.lonamiwebs.klooni.actors.ShopCard; import io.github.lonamiwebs.klooni.actors.SoftButton; import io.github.lonamiwebs.klooni.actors.ThemeCard; import io.github.lonamiwebs.klooni.game.GameLayout; @@ -189,110 +190,63 @@ class CustomizeScreen implements Screen { final GameLayout layout = new GameLayout(); shopGroup.clear(); - if (showingEffectsShop) { - for (Effect effect : Effect.getEffects()) { - final EffectCard card = new EffectCard(game, layout, effect); - card.addListener(new InputListener() { - @Override - public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { - shopDragStartX = x; - shopDragStartY = y; - return true; - } + if (showingEffectsShop) + for (Effect effect : Effect.getEffects()) + addCard(new EffectCard(game, layout, effect)); - // We could actually rely on touchDragged not being called, - // but perhaps it would be hard for some people not to move - // their fingers even the slightest bit, so we use a custom - // drag limit + else // showingThemesShop + for (Theme theme : Theme.getThemes()) + addCard(new ThemeCard(game, layout, theme)); - @Override - public void touchUp(InputEvent event, float x, float y, int pointer, int button) { - x -= shopDragStartX; - y -= shopDragStartY; - float distSq = x * x + y * y; - if (distSq < DRAG_LIMIT_SQ) { - if (Klooni.isEffectBought(card.effect)) - card.use(); - else - buyBand.askBuy(card); - - for (Actor a : shopGroup.getChildren()) { - EffectCard c = (EffectCard)a; - c.usedEffectUpdated(); - } - } - } - }); - - shopGroup.addActor(card); - - // Scroll to the currently selected theme - table.layout(); - for (Actor a : shopGroup.getChildren()) { - EffectCard c = (EffectCard)a; - if (c.isUsed()) { - shopScroll.scrollTo( - c.getX(), c.getY() + c.getHeight(), - c.getWidth(), c.getHeight()); - break; - } - c.usedEffectUpdated(); - } - } - } else { - // Showing themes shop otherwise - for (Theme theme : Theme.getThemes()) { - final ThemeCard card = new ThemeCard(game, layout, theme); - card.addListener(new InputListener() { - @Override - public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { - shopDragStartX = x; - shopDragStartY = y; - return true; - } - - // We could actually rely on touchDragged not being called, - // but perhaps it would be hard for some people not to move - // their fingers even the slightest bit, so we use a custom - // drag limit - - @Override - public void touchUp(InputEvent event, float x, float y, int pointer, int button) { - x -= shopDragStartX; - y -= shopDragStartY; - float distSq = x * x + y * y; - if (distSq < DRAG_LIMIT_SQ) { - if (Klooni.isThemeBought(card.theme)) - card.use(); - else - buyBand.askBuy(card); - - for (Actor a : shopGroup.getChildren()) { - ThemeCard c = (ThemeCard)a; - c.usedThemeUpdated(); - } - } - } - }); - - shopGroup.addActor(card); - - // Scroll to the currently selected theme - table.layout(); - for (Actor a : shopGroup.getChildren()) { - ThemeCard c = (ThemeCard)a; - if (c.isUsed()) { - shopScroll.scrollTo( - c.getX(), c.getY() + c.getHeight(), - c.getWidth(), c.getHeight()); - break; - } - c.usedThemeUpdated(); - } + // Scroll to the currently selected item + table.layout(); + for (Actor a : shopGroup.getChildren()) { + ShopCard c = (ShopCard)a; + if (c.isUsed()) { + shopScroll.scrollTo( + c.getX(), c.getY() + c.getHeight(), + c.getWidth(), c.getHeight()); + break; } + c.usedItemUpdated(); } } + private void addCard(final ShopCard card) { + card.addListener(new InputListener() { + @Override + public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { + shopDragStartX = x; + shopDragStartY = y; + return true; + } + + // We could actually rely on touchDragged not being called, + // but perhaps it would be hard for some people not to move + // their fingers even the slightest bit, so we use a custom + // drag limit + + @Override + public void touchUp(InputEvent event, float x, float y, int pointer, int button) { + x -= shopDragStartX; + y -= shopDragStartY; + float distSq = x * x + y * y; + if (distSq < DRAG_LIMIT_SQ) { + if (card.isBought()) + card.use(); + else + buyBand.askBuy(card); + + for (Actor a : shopGroup.getChildren()) { + ((ShopCard)a).usedItemUpdated(); + } + } + } + }); + + shopGroup.addActor(card); + } + //endregion //region Public methods