Show a random piece instead a single cell when showcasing effects

This commit is contained in:
Lonami Exo 2017-07-26 11:02:33 +02:00
parent 70f696eebd
commit e51f27d091
3 changed files with 89 additions and 48 deletions

View file

@ -17,17 +17,14 @@
*/ */
package io.github.lonamiwebs.klooni.actors; package io.github.lonamiwebs.klooni.actors;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.math.Matrix4; import com.badlogic.gdx.math.Rectangle;
import io.github.lonamiwebs.klooni.Effect; import io.github.lonamiwebs.klooni.Effect;
import io.github.lonamiwebs.klooni.Klooni; import io.github.lonamiwebs.klooni.Klooni;
import io.github.lonamiwebs.klooni.Theme; import io.github.lonamiwebs.klooni.Theme;
import io.github.lonamiwebs.klooni.effects.IEffect; import io.github.lonamiwebs.klooni.game.Board;
import io.github.lonamiwebs.klooni.game.Cell;
import io.github.lonamiwebs.klooni.game.GameLayout; import io.github.lonamiwebs.klooni.game.GameLayout;
import io.github.lonamiwebs.klooni.game.Piece; import io.github.lonamiwebs.klooni.game.Piece;
@ -37,11 +34,12 @@ public class EffectCard extends ShopCard {
//region Members //region Members
public final Effect effect; public final Effect effect;
private final Cell cell; private final Board board;
private IEffect currentEffect;
// We want to create an effect from the beginning
private boolean needCreateEffect = true;
private final Texture background; private final Texture background;
private Color color;
//endregion //endregion
@ -50,13 +48,29 @@ public class EffectCard extends ShopCard {
public EffectCard(final Klooni game, final GameLayout layout, final Effect effect) { public EffectCard(final Klooni game, final GameLayout layout, final Effect effect) {
super(game, layout, effect.getDisplay(), Klooni.theme.background); super(game, layout, effect.getDisplay(), Klooni.theme.background);
background = Theme.getBlankTexture(); background = Theme.getBlankTexture();
color = Klooni.theme.getRandomCellColor();
this.effect = effect; this.effect = effect;
cell = Piece.randomCell(0, 0, cellSize);
// Let the board have room for 3 cells, so cellSize * 3
board = new Board(new Rectangle(0, 0, cellSize * 3, cellSize * 3), 3);
setRandomPiece();
usedItemUpdated(); usedItemUpdated();
} }
private void setRandomPiece() {
while (true) {
final Piece piece = Piece.random();
if (piece.cellCols > 3 || piece.cellRows > 3)
continue;
// Try to center it (max size is 3, so center is the second grid bit unless max size)
int x = piece.cellCols == 3 ? 0 : 1;
int y = piece.cellRows == 3 ? 0 : 1;
if (board.putPiece(piece, x, y))
break; // Should not fail, but if it does, don't break
}
}
//endregion //endregion
//region Public methods //region Public methods
@ -68,31 +82,37 @@ public class EffectCard extends ShopCard {
batch.setColor(Klooni.theme.background); batch.setColor(Klooni.theme.background);
batch.draw(background, x, y, getWidth(), getHeight()); batch.draw(background, x, y, getWidth(), getHeight());
// Avoid drawing on the borders by adding +1 cell padding +1 to center it // Avoid drawing on the borders by adding +1 cell padding
// so it's becomes cellSize * 2 board.pos.set(x + cellSize * 1, y + cellSize * 1);
cell.pos.set(x + cellSize * 2, y + cellSize * 2);
// If we're not showcasing (currentEffect == null), show the cell alone // Draw only if effects are done, i.e. not showcasing
if (currentEffect == null) if (board.effectsDone())
cell.draw(batch); board.draw(batch);
super.draw(batch, parentAlpha); super.draw(batch, parentAlpha);
} }
@Override @Override
public boolean showcase(Batch batch, float yDisplacement) { public boolean showcase(Batch batch, float yDisplacement) {
cell.pos.y += yDisplacement; board.pos.y += yDisplacement;
// If it's null, create it, then we want to render // If no effect is running
if (currentEffect == null) { if (board.effectsDone()) {
currentEffect = effect.create(cell, cell.pos); // And we want to create a new one
} else if (currentEffect.isDone()) { if (needCreateEffect) {
// Set to null so it's created the next time // Clear at cells[1][1], the center one
currentEffect = null; board.clearAll(1, 1, effect);
return false; needCreateEffect = false;
} else {
// Otherwise, the previous effect finished, so return false because we're done
// We also want to draw the next time so set the flag to true
setRandomPiece();
needCreateEffect = true;
return false;
}
} }
currentEffect.draw(batch); board.draw(batch);
return true; return true;
} }

View file

@ -17,8 +17,9 @@
*/ */
package io.github.lonamiwebs.klooni.game; package io.github.lonamiwebs.klooni.game;
import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
@ -39,12 +40,12 @@ public class Board implements BinSerializable {
public final int cellCount; public final int cellCount;
public float cellSize; public float cellSize;
private Cell[][] cells; private Cell[][] cells;
private final Array<IEffect> effects; // Particle effects once they vanish private final Array<IEffect> effects = new Array<IEffect>(); // Particle effects once they vanish
final Vector2 pos; public final Vector2 pos = new Vector2();
// Used to animate cleared cells vanishing // Used to animate cleared cells vanishing
private final Vector2 lastPutPiecePos; private final Vector2 lastPutPiecePos = new Vector2();
//endregion //endregion
@ -53,12 +54,21 @@ public class Board implements BinSerializable {
public Board(final GameLayout layout, int cellCount) { public Board(final GameLayout layout, int cellCount) {
this.cellCount = cellCount; this.cellCount = cellCount;
lastPutPiecePos = new Vector2();
pos = new Vector2();
effects = new Array<IEffect>(32); // 32 capacity for 3 rows (most common)
// Cell size depends on the layout to be updated first // Cell size depends on the layout to be updated first
layout.update(this); layout.update(this);
createCells();
}
public Board(final Rectangle area, int cellCount) {
this.cellCount = cellCount;
// Cell size depends on the layout to be updated first
pos.set(area.x, area.y);
cellSize = Math.min(area.height, area.width) / cellCount;
createCells();
}
private void createCells() {
cells = new Cell[this.cellCount][this.cellCount]; cells = new Cell[this.cellCount][this.cellCount];
for (int i = 0; i < this.cellCount; ++i) { for (int i = 0; i < this.cellCount; ++i) {
for (int j = 0; j < this.cellCount; ++j) { for (int j = 0; j < this.cellCount; ++j) {
@ -95,7 +105,7 @@ public class Board implements BinSerializable {
} }
// Returns true iff the piece was put on the board // Returns true iff the piece was put on the board
private boolean putPiece(Piece piece, int x, int y) { public boolean putPiece(Piece piece, int x, int y) {
if (!canPutPiece(piece, x, y)) if (!canPutPiece(piece, x, y))
return false; return false;
@ -112,7 +122,7 @@ public class Board implements BinSerializable {
//region Public methods //region Public methods
public void draw(SpriteBatch batch) { public void draw(final Batch batch) {
batch.setTransformMatrix(batch.getTransformMatrix().translate(pos.x, pos.y, 0)); batch.setTransformMatrix(batch.getTransformMatrix().translate(pos.x, pos.y, 0));
for (int i = 0; i < cellCount; ++i) for (int i = 0; i < cellCount; ++i)
@ -137,7 +147,7 @@ public class Board implements BinSerializable {
return false; return false;
} }
boolean putScreenPiece(Piece piece) { public boolean putScreenPiece(final Piece piece) {
// Convert the on screen coordinates of the piece to the local-board-space coordinates // Convert the on screen coordinates of the piece to the local-board-space coordinates
// This is done by subtracting the piece coordinates from the board coordinates // This is done by subtracting the piece coordinates from the board coordinates
Vector2 local = piece.pos.cpy().sub(pos); Vector2 local = piece.pos.cpy().sub(pos);
@ -225,6 +235,25 @@ public class Board implements BinSerializable {
return clearCount; return clearCount;
} }
public int clearAll(final int clearFromX, final int clearFromY, final Effect effect) {
int clearCount = 0;
final Vector2 culprit = cells[clearFromY][clearFromX].pos;
for (int i = 0; i < cellCount; ++i) {
for (int j = 0; j < cellCount; ++j) {
if (!cells[i][j].isEmpty()) {
clearCount++;
effects.add(effect.create(cells[i][j], culprit));
cells[i][j].set(-1);
}
}
}
return clearCount;
}
public boolean effectsDone() { return effects.size == 0; }
//endregion //endregion
//region Serialization //region Serialization

View file

@ -37,10 +37,10 @@ public class Piece {
//region Members //region Members
final Vector2 pos; final Vector2 pos;
final int colorIndex; public final int colorIndex;
private final int rotation; private final int rotation;
final int cellCols, cellRows; public final int cellCols, cellRows;
private boolean shape[][]; private boolean shape[][];
// Default arbitrary value // Default arbitrary value
@ -112,16 +112,8 @@ public class Piece {
//region Static methods //region Static methods
// Only the pieces know how many colors there are, so the method for
// creating cells belongs here as a public static one.
public static Cell randomCell(final float x, final float y, final float size) {
final Cell cell = new Cell(x, y, size);
cell.set(MathUtils.random(8));
return cell;
}
// Generates a random piece with always the same color for the generated shape // Generates a random piece with always the same color for the generated shape
static Piece random() { public static Piece random() {
// 9 pieces [08]; 4 possible rotations [03] // 9 pieces [08]; 4 possible rotations [03]
return fromIndex(MathUtils.random(8), MathUtils.random(4)); return fromIndex(MathUtils.random(8), MathUtils.random(4));
} }