diff --git a/core/src/io/github/lonamiwebs/klooni/game/Board.java b/core/src/io/github/lonamiwebs/klooni/game/Board.java index 75ad057..d2d728c 100644 --- a/core/src/io/github/lonamiwebs/klooni/game/Board.java +++ b/core/src/io/github/lonamiwebs/klooni/game/Board.java @@ -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); } } } diff --git a/core/src/io/github/lonamiwebs/klooni/game/Cell.java b/core/src/io/github/lonamiwebs/klooni/game/Cell.java index 3d09f74..58d05ae 100644 --- a/core/src/io/github/lonamiwebs/klooni/game/Cell.java +++ b/core/src/io/github/lonamiwebs/klooni/game/Cell.java @@ -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; } } diff --git a/core/src/io/github/lonamiwebs/klooni/game/Piece.java b/core/src/io/github/lonamiwebs/klooni/game/Piece.java index 2a8f2cf..d20871c 100644 --- a/core/src/io/github/lonamiwebs/klooni/game/Piece.java +++ b/core/src/io/github/lonamiwebs/klooni/game/Piece.java @@ -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++) {