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;
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.Matrix4;
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.effects.IEffect;
import io.github.lonamiwebs.klooni.game.Cell;
import io.github.lonamiwebs.klooni.game.Board;
import io.github.lonamiwebs.klooni.game.GameLayout;
import io.github.lonamiwebs.klooni.game.Piece;
@ -37,11 +34,12 @@ public class EffectCard extends ShopCard {
//region Members
public final Effect effect;
private final Cell cell;
private IEffect currentEffect;
private final Board board;
// We want to create an effect from the beginning
private boolean needCreateEffect = true;
private final Texture background;
private Color color;
//endregion
@ -50,13 +48,29 @@ public class EffectCard extends ShopCard {
public EffectCard(final Klooni game, final GameLayout layout, final Effect effect) {
super(game, layout, effect.getDisplay(), Klooni.theme.background);
background = Theme.getBlankTexture();
color = Klooni.theme.getRandomCellColor();
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();
}
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
//region Public methods
@ -68,31 +82,37 @@ public class EffectCard extends ShopCard {
batch.setColor(Klooni.theme.background);
batch.draw(background, x, y, getWidth(), getHeight());
// Avoid drawing on the borders by adding +1 cell padding +1 to center it
// so it's becomes cellSize * 2
cell.pos.set(x + cellSize * 2, y + cellSize * 2);
// Avoid drawing on the borders by adding +1 cell padding
board.pos.set(x + cellSize * 1, y + cellSize * 1);
// If we're not showcasing (currentEffect == null), show the cell alone
if (currentEffect == null)
cell.draw(batch);
// Draw only if effects are done, i.e. not showcasing
if (board.effectsDone())
board.draw(batch);
super.draw(batch, parentAlpha);
}
@Override
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 (currentEffect == null) {
currentEffect = effect.create(cell, cell.pos);
} else if (currentEffect.isDone()) {
// Set to null so it's created the next time
currentEffect = null;
// If no effect is running
if (board.effectsDone()) {
// And we want to create a new one
if (needCreateEffect) {
// Clear at cells[1][1], the center one
board.clearAll(1, 1, effect);
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;
}

View file

@ -17,8 +17,9 @@
*/
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.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
@ -39,12 +40,12 @@ public class Board implements BinSerializable {
public final int cellCount;
public float cellSize;
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
private final Vector2 lastPutPiecePos;
private final Vector2 lastPutPiecePos = new Vector2();
//endregion
@ -53,12 +54,21 @@ public class Board implements BinSerializable {
public Board(final GameLayout layout, int 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
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];
for (int i = 0; i < this.cellCount; ++i) {
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
private boolean putPiece(Piece piece, int x, int y) {
public boolean putPiece(Piece piece, int x, int y) {
if (!canPutPiece(piece, x, y))
return false;
@ -112,7 +122,7 @@ public class Board implements BinSerializable {
//region Public methods
public void draw(SpriteBatch batch) {
public void draw(final Batch batch) {
batch.setTransformMatrix(batch.getTransformMatrix().translate(pos.x, pos.y, 0));
for (int i = 0; i < cellCount; ++i)
@ -137,7 +147,7 @@ public class Board implements BinSerializable {
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
// This is done by subtracting the piece coordinates from the board coordinates
Vector2 local = piece.pos.cpy().sub(pos);
@ -225,6 +235,25 @@ public class Board implements BinSerializable {
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
//region Serialization

View file

@ -37,10 +37,10 @@ public class Piece {
//region Members
final Vector2 pos;
final int colorIndex;
public final int colorIndex;
private final int rotation;
final int cellCols, cellRows;
public final int cellCols, cellRows;
private boolean shape[][];
// Default arbitrary value
@ -112,16 +112,8 @@ public class Piece {
//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
static Piece random() {
public static Piece random() {
// 9 pieces [08]; 4 possible rotations [03]
return fromIndex(MathUtils.random(8), MathUtils.random(4));
}