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 final int cellCount;
|
||||||
public float cellSize;
|
public float cellSize;
|
||||||
|
|
||||||
|
private final Vector2 lastPutPiecePos; // Used to animate cleared cells vanishing
|
||||||
|
|
||||||
final Vector2 pos;
|
final Vector2 pos;
|
||||||
|
|
||||||
public NinePatch cellPatch;
|
public NinePatch cellPatch;
|
||||||
|
@ -20,18 +22,21 @@ public class Board {
|
||||||
public Board(final GameLayout layout, int cellCount) {
|
public Board(final GameLayout layout, int cellCount) {
|
||||||
this.cellCount = 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(
|
cellPatch = new NinePatch(
|
||||||
new Texture(Gdx.files.internal("ui/cells/basic.png")), 4, 4, 4, 4);
|
new Texture(Gdx.files.internal("ui/cells/basic.png")), 4, 4, 4, 4);
|
||||||
|
|
||||||
|
lastPutPiecePos = new Vector2();
|
||||||
pos = new Vector2();
|
pos = new Vector2();
|
||||||
layout.update(this);
|
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) {
|
private boolean inBounds(int x, int y) {
|
||||||
|
@ -119,14 +124,14 @@ public class Board {
|
||||||
for (int i = 0; i < cellCount; i++) {
|
for (int i = 0; i < cellCount; i++) {
|
||||||
if (clearedRows[i]) {
|
if (clearedRows[i]) {
|
||||||
for (int j = 0; j < cellCount; j++) {
|
for (int j = 0; j < cellCount; j++) {
|
||||||
cells[i][j].setEmpty();
|
cells[i][j].vanish(lastPutPiecePos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int j = 0; j < cellCount; j++) {
|
for (int j = 0; j < cellCount; j++) {
|
||||||
if (clearedCols[j]) {
|
if (clearedCols[j]) {
|
||||||
for (int i = 0; i < cellCount; i++) {
|
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))
|
if (!canPutPiece(piece, x, y))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
lastPutPiecePos.set(piece.calculateGravityCenter());
|
||||||
for (int i = 0; i < piece.cellRows; i++) {
|
for (int i = 0; i < piece.cellRows; i++) {
|
||||||
for (int j = 0; j < piece.cellCols; j++) {
|
for (int j = 0; j < piece.cellCols; j++) {
|
||||||
if (piece.filled(i, j)) {
|
if (piece.filled(i, j)) {
|
||||||
|
@ -153,8 +159,7 @@ public class Board {
|
||||||
public void draw(SpriteBatch batch) {
|
public void draw(SpriteBatch batch) {
|
||||||
for (int i = 0; i < cellCount; i++) {
|
for (int i = 0; i < cellCount; i++) {
|
||||||
for (int j = 0; j < cellCount; j++) {
|
for (int j = 0; j < cellCount; j++) {
|
||||||
cells[i][j].draw(batch, cellPatch,
|
cells[i][j].draw(batch, cellPatch);
|
||||||
pos.x + j * cellSize, pos.y + i * cellSize, cellSize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,33 @@
|
||||||
package io.github.lonamiwebs.klooni.game;
|
package io.github.lonamiwebs.klooni.game;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
import com.badlogic.gdx.graphics.g2d.NinePatch;
|
import com.badlogic.gdx.graphics.g2d.NinePatch;
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||||
|
import com.badlogic.gdx.math.Interpolation;
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
|
||||||
class Cell {
|
class Cell {
|
||||||
|
|
||||||
private boolean empty;
|
private boolean empty;
|
||||||
private Color color;
|
private Color color;
|
||||||
|
|
||||||
Cell() {
|
Vector2 pos;
|
||||||
setEmpty();
|
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) {
|
void set(Color c) {
|
||||||
|
@ -18,18 +35,31 @@ class Cell {
|
||||||
color = c;
|
color = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setEmpty() {
|
void draw(SpriteBatch batch, NinePatch patch) {
|
||||||
empty = true;
|
draw(color, batch, patch, pos.x, pos.y, size);
|
||||||
color = Color.WHITE;
|
|
||||||
}
|
// Draw the previous vanishing cell
|
||||||
|
if (vanishSize > vanishDelta) {
|
||||||
void draw(SpriteBatch batch, NinePatch patch, float x, float y, float size) {
|
vanishElapsed += Gdx.graphics.getDeltaTime();
|
||||||
draw(color, batch, patch, x, y, size);
|
|
||||||
|
// 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,
|
static void draw(Color color, SpriteBatch batch, NinePatch patch,
|
||||||
float x, float y, float size) {
|
float x, float y, float size) {
|
||||||
// TODO Use skin atlas
|
|
||||||
batch.setColor(color);
|
batch.setColor(color);
|
||||||
patch.draw(batch, x, y, size, size);
|
patch.draw(batch, x, y, size, size);
|
||||||
}
|
}
|
||||||
|
@ -38,10 +68,26 @@ class Cell {
|
||||||
return empty;
|
return empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Use vanish with a pretty animation instead .setEmpty()
|
// Vanish from indicates the point which caused the vanishing to happen,
|
||||||
// It would be AWESOME if the delay from vanishing (bounce -> big -> small -> gone)
|
// in this case, a piece was put. The closer it was put, the faster
|
||||||
// was delayed by how far this cell is from the cleared piece, I mean cool!!
|
// this piece will vanish.
|
||||||
public void vanish() {
|
void vanish(Vector2 vanishFrom) {
|
||||||
empty = true;
|
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;
|
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) {
|
void draw(SpriteBatch batch, NinePatch patch) {
|
||||||
for (int i = 0; i < cellRows; i++) {
|
for (int i = 0; i < cellRows; i++) {
|
||||||
for (int j = 0; j < cellCols; j++) {
|
for (int j = 0; j < cellCols; j++) {
|
||||||
|
|
Loading…
Reference in a new issue