Fix score counting and use a custom Scorer class
This commit is contained in:
parent
ec19c31fd6
commit
7888ac23b4
8 changed files with 201 additions and 21 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
73
core/src/io/github/lonamiwebs/klooni/game/Scorer.java
Normal file
73
core/src/io/github/lonamiwebs/klooni/game/Scorer.java
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue