Add cool vanish effect to cleared strips
This commit is contained in:
parent
7888ac23b4
commit
65d3c8d1a0
3 changed files with 92 additions and 25 deletions
|
@ -13,6 +13,8 @@ public class Board {
|
|||
public final int cellCount;
|
||||
public float cellSize;
|
||||
|
||||
private final Vector2 lastPutPiecePos; // Used to animate cleared cells vanishing
|
||||
|
||||
final Vector2 pos;
|
||||
|
||||
public NinePatch cellPatch;
|
||||
|
@ -20,18 +22,21 @@ public class Board {
|
|||
public Board(final GameLayout layout, int cellCount) {
|
||||
this.cellCount = cellCount;
|
||||
|
||||
cells = new Cell[this.cellCount][this.cellCount];
|
||||
for (int i = 0; i < this.cellCount; i++) {
|
||||
for (int j = 0; j < this.cellCount; j++) {
|
||||
cells[i][j] = new Cell();
|
||||
}
|
||||
}
|
||||
|
||||
cellPatch = new NinePatch(
|
||||
new Texture(Gdx.files.internal("ui/cells/basic.png")), 4, 4, 4, 4);
|
||||
|
||||
lastPutPiecePos = new Vector2();
|
||||
pos = new Vector2();
|
||||
layout.update(this);
|
||||
|
||||
// Cell size depends on the layout to be updated
|
||||
cells = new Cell[this.cellCount][this.cellCount];
|
||||
for (int i = 0; i < this.cellCount; i++) {
|
||||
for (int j = 0; j < this.cellCount; j++) {
|
||||
cells[i][j] = new Cell(
|
||||
pos.x + j * cellSize, pos.y + i * cellSize, cellSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean inBounds(int x, int y) {
|
||||
|
@ -119,14 +124,14 @@ public class Board {
|
|||
for (int i = 0; i < cellCount; i++) {
|
||||
if (clearedRows[i]) {
|
||||
for (int j = 0; j < cellCount; j++) {
|
||||
cells[i][j].setEmpty();
|
||||
cells[i][j].vanish(lastPutPiecePos);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < cellCount; j++) {
|
||||
if (clearedCols[j]) {
|
||||
for (int i = 0; i < cellCount; i++) {
|
||||
cells[i][j].setEmpty();
|
||||
cells[i][j].vanish(lastPutPiecePos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,6 +144,7 @@ public class Board {
|
|||
if (!canPutPiece(piece, x, y))
|
||||
return false;
|
||||
|
||||
lastPutPiecePos.set(piece.calculateGravityCenter());
|
||||
for (int i = 0; i < piece.cellRows; i++) {
|
||||
for (int j = 0; j < piece.cellCols; j++) {
|
||||
if (piece.filled(i, j)) {
|
||||
|
@ -153,8 +159,7 @@ public class Board {
|
|||
public void draw(SpriteBatch batch) {
|
||||
for (int i = 0; i < cellCount; i++) {
|
||||
for (int j = 0; j < cellCount; j++) {
|
||||
cells[i][j].draw(batch, cellPatch,
|
||||
pos.x + j * cellSize, pos.y + i * cellSize, cellSize);
|
||||
cells[i][j].draw(batch, cellPatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,33 @@
|
|||
package io.github.lonamiwebs.klooni.game;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.g2d.NinePatch;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.math.Interpolation;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
|
||||
class Cell {
|
||||
|
||||
private boolean empty;
|
||||
private Color color;
|
||||
|
||||
Cell() {
|
||||
setEmpty();
|
||||
Vector2 pos;
|
||||
float size;
|
||||
|
||||
private Color vanishColor;
|
||||
private float vanishSize;
|
||||
private float vanishElapsed;
|
||||
private float vanishLifetime;
|
||||
|
||||
private static float vanishDelta = 0.1f;
|
||||
|
||||
Cell(float x, float y, float cellSize) {
|
||||
pos = new Vector2(x, y);
|
||||
size = cellSize;
|
||||
|
||||
empty = true;
|
||||
color = Color.WHITE;
|
||||
}
|
||||
|
||||
void set(Color c) {
|
||||
|
@ -18,18 +35,31 @@ class Cell {
|
|||
color = c;
|
||||
}
|
||||
|
||||
void setEmpty() {
|
||||
empty = true;
|
||||
color = Color.WHITE;
|
||||
}
|
||||
|
||||
void draw(SpriteBatch batch, NinePatch patch, float x, float y, float size) {
|
||||
draw(color, batch, patch, x, y, size);
|
||||
void draw(SpriteBatch batch, NinePatch patch) {
|
||||
draw(color, batch, patch, pos.x, pos.y, size);
|
||||
|
||||
// Draw the previous vanishing cell
|
||||
if (vanishSize > vanishDelta) {
|
||||
vanishElapsed += Gdx.graphics.getDeltaTime();
|
||||
|
||||
// vanishElapsed might be < 0 (delay), so clamp to 0
|
||||
float progress = Math.min(1f,
|
||||
Math.max(vanishElapsed, 0f) / vanishLifetime);
|
||||
|
||||
vanishSize = Interpolation.elasticIn.apply(size, 0, progress);
|
||||
|
||||
float centerOffset = size * 0.5f - vanishSize * 0.5f;
|
||||
draw(vanishColor, batch, patch, pos.x + centerOffset, pos.y + centerOffset, vanishSize);
|
||||
|
||||
if (progress == 1f) {
|
||||
vanishSize = 0f; // Stop vanishing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Use skin atlas
|
||||
static void draw(Color color, SpriteBatch batch, NinePatch patch,
|
||||
float x, float y, float size) {
|
||||
// TODO Use skin atlas
|
||||
batch.setColor(color);
|
||||
patch.draw(batch, x, y, size, size);
|
||||
}
|
||||
|
@ -38,10 +68,26 @@ class Cell {
|
|||
return empty;
|
||||
}
|
||||
|
||||
// TODO Use vanish with a pretty animation instead .setEmpty()
|
||||
// It would be AWESOME if the delay from vanishing (bounce -> big -> small -> gone)
|
||||
// was delayed by how far this cell is from the cleared piece, I mean cool!!
|
||||
public void vanish() {
|
||||
// Vanish from indicates the point which caused the vanishing to happen,
|
||||
// in this case, a piece was put. The closer it was put, the faster
|
||||
// this piece will vanish.
|
||||
void vanish(Vector2 vanishFrom) {
|
||||
empty = true;
|
||||
|
||||
vanishSize = size;
|
||||
vanishColor = color.cpy();
|
||||
vanishLifetime = 1.5f;
|
||||
|
||||
// Square the size when calculating the vanish distance
|
||||
// because it will be used as delay, and without squaring,
|
||||
// the delay would be too large
|
||||
Vector2 center = new Vector2(pos.x + size * 0.5f, pos.y + 0.5f);
|
||||
float vanishDist = Vector2.dst(
|
||||
vanishFrom.x, vanishFrom.y, center.x, center.y) / (size * size);
|
||||
|
||||
// Negative time indicates delay, + half lifetime because elastic has that delay
|
||||
vanishElapsed = vanishLifetime * 0.5f - vanishDist;
|
||||
|
||||
color = Color.WHITE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,6 +114,22 @@ public class Piece {
|
|||
return area;
|
||||
}
|
||||
|
||||
Vector2 calculateGravityCenter() {
|
||||
int filledCount = 0;
|
||||
Vector2 result = new Vector2();
|
||||
for (int i = 0; i < cellRows; i++) {
|
||||
for (int j = 0; j < cellCols; j++) {
|
||||
if (shape[i][j]) {
|
||||
filledCount++;
|
||||
result.add(
|
||||
pos.x + j * cellSize - cellSize * 0.5f,
|
||||
pos.y + i * cellSize - cellSize * 0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.scl(1f / filledCount);
|
||||
}
|
||||
|
||||
void draw(SpriteBatch batch, NinePatch patch) {
|
||||
for (int i = 0; i < cellRows; i++) {
|
||||
for (int j = 0; j < cellCols; j++) {
|
||||
|
|
Loading…
Reference in a new issue