Fix score counting and use a custom Scorer class

This commit is contained in:
Lonami Exo 2017-01-27 11:19:53 +01:00
parent ec19c31fd6
commit 7888ac23b4
8 changed files with 201 additions and 21 deletions

View file

@ -39,6 +39,8 @@ class Cell {
}
// 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() {
empty = true;
}

View file

@ -2,6 +2,7 @@ package io.github.lonamiwebs.klooni.game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.Rectangle;
// Helper class to calculate the size of each element
//
@ -10,7 +11,7 @@ import com.badlogic.gdx.Gdx;
public class GameLayout {
// Widths
private float screenWidth, marginWidth;
private float screenWidth, marginWidth, availableWidth;
// Heights
private float screenHeight, logoHeight, scoreHeight, boardHeight, pieceHolderHeight;
@ -25,6 +26,7 @@ public class GameLayout {
// Widths
marginWidth = screenWidth * 0.05f;
availableWidth = screenWidth - marginWidth * 2f;
// Heights
logoHeight = screenHeight * 0.10f;
@ -34,19 +36,37 @@ public class GameLayout {
}
// Note that we're now using Y-up coordinates
void update(Scorer scorer) {
float cupSize = Math.min(scoreHeight, scorer.cupTexture.getHeight());
final Rectangle area = new Rectangle(
marginWidth, pieceHolderHeight + boardHeight,
availableWidth, scoreHeight);
scorer.cupArea.set(
area.x + area.width * 0.5f - cupSize * 0.5f, area.y,
cupSize, cupSize);
scorer.currentScoreLabel.setBounds(
area.x, area.y,
area.width * 0.5f - cupSize * 0.5f, area.height);
scorer.maxScoreLabel.setBounds(
area.x + area.width * 0.5f + cupSize * 0.5f, area.y,
area.width * 0.5f - cupSize * 0.5f, area.height);
}
void update(Board board) {
// We can't leave our area, so pick the minimum between available
// height and width to determine an appropriated cell size
float availableWidth = screenWidth - marginWidth * 2f;
float boardSize = Math.min(availableWidth, boardHeight);
board.cellSize = boardSize / board.cellCount;
// Now that we know the board size, we can center the board on the screen
board.pos.set(screenWidth * 0.5f - boardSize * 0.5f, pieceHolderHeight);
board.pos.set(
screenWidth * 0.5f - boardSize * 0.5f, pieceHolderHeight);
}
void update(PieceHolder holder) {
float availableWidth = screenWidth - marginWidth * 2f;
holder.area.set(
marginWidth, 0f,
availableWidth, pieceHolderHeight);

View file

@ -87,17 +87,17 @@ public class PieceHolder {
}
public boolean dropPiece(Board board) {
boolean put = false;
if (heldPiece > -1) {
if (board.putScreenPiece(pieces[heldPiece])) {
pieces[heldPiece] = null;
put = true;
}
heldPiece = -1;
if (handFinished())
takeMore();
return true;
}
return false;
return put;
}
public void update(float cellSizeOnBoard) {

View file

@ -0,0 +1,73 @@
package io.github.lonamiwebs.klooni.game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.utils.Align;
public class Scorer {
private int currentScore;
private float shownScore; // To interpolate between shown score -> real score
private final int boardSize;
final Label currentScoreLabel;
final Label maxScoreLabel;
final Texture cupTexture;
final Rectangle cupArea;
public Scorer(GameLayout layout, int boardSize) {
currentScore = 0;
this.boardSize = boardSize;
cupTexture = new Texture(Gdx.files.internal("ui/cup.png"));
cupArea = new Rectangle();
Label.LabelStyle scoreStyle = new Label.LabelStyle();
scoreStyle.font = new BitmapFont(Gdx.files.internal("font/geosans-light.fnt"));
currentScoreLabel = new Label("0", scoreStyle);
currentScoreLabel.setAlignment(Align.right);
maxScoreLabel = new Label("0", scoreStyle);
layout.update(this);
}
public void addPieceScore(int areaPut) {
currentScore += areaPut;
}
public void addBoardScore(int stripsCleared) {
currentScore += calculateClearScore(stripsCleared);
}
int calculateClearScore(int stripsCleared) {
// The original game seems to work as follows:
// If < 1 were cleared, score = 0
// If = 1 was cleared, score = cells cleared
// If > 1 were cleared, score = cells cleared + score(cleared - 1)
if (stripsCleared < 1) return 0;
if (stripsCleared == 1) return boardSize;
else return boardSize * stripsCleared + calculateClearScore(stripsCleared - 1);
}
public void draw(SpriteBatch batch) {
int roundShown = MathUtils.round(shownScore);
if (roundShown != currentScore) {
shownScore = Interpolation.linear.apply(shownScore, currentScore, 0.1f);
currentScoreLabel.setText(Integer.toString(MathUtils.round(shownScore)));
}
batch.setColor(Color.WHITE);
batch.draw(cupTexture, cupArea.x, cupArea.y, cupArea.width, cupArea.height);
currentScoreLabel.draw(batch, 1f);
maxScoreLabel.draw(batch, 1f);
}
}

View file

@ -13,10 +13,13 @@ import io.github.lonamiwebs.klooni.game.Board;
import io.github.lonamiwebs.klooni.game.GameLayout;
import io.github.lonamiwebs.klooni.game.Piece;
import io.github.lonamiwebs.klooni.game.PieceHolder;
import io.github.lonamiwebs.klooni.game.Scorer;
public class GameScreen implements Screen, InputProcessor {
private Klooni game;
private Scorer scorer;
private Board board;
private PieceHolder holder;
@ -35,6 +38,7 @@ public class GameScreen implements Screen, InputProcessor {
layout = new GameLayout();
scorer = new Scorer(layout, 10);
board = new Board(layout, 10);
holder = new PieceHolder(layout, 3);
@ -44,16 +48,6 @@ public class GameScreen implements Screen, InputProcessor {
}
}
int calculateClearScore(int cleared) {
// The original game seems to work as follows:
// If < 1 were cleared, score = 0
// If = 1 was cleared, score = cells cleared
// If > 1 were cleared, score = cells cleared + score(cleared - 1)
if (cleared < 1) return 0;
if (cleared == 1) return board.cellCount;
else return board.cellCount * cleared + calculateClearScore(cleared - 1);
}
boolean isGameOver() {
for (Piece piece : holder.getAvailablePieces()) {
if (board.canPutPiece(piece)) {
@ -76,8 +70,9 @@ public class GameScreen implements Screen, InputProcessor {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
board.draw(batch);
scorer.draw(batch);
board.draw(batch);
holder.update(board.cellSize);
holder.draw(batch, board.cellPatch);
@ -137,13 +132,13 @@ public class GameScreen implements Screen, InputProcessor {
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
int area = holder.calculateHeldPieceArea();
if (holder.dropPiece(board)) {
int cleared = board.clearComplete();
score += area + calculateClearScore(cleared);
scorer.addPieceScore(area);
scorer.addBoardScore(board.clearComplete());
// After the piece was put, check if it's game over
if (isGameOver()) {
clearColor.set(0.4f, 0.1f, 0.1f, 1f);
}
return true;
} else {
return false;