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.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;
import io.github.lonamiwebs.klooni.Klooni;
import io.github.lonamiwebs.klooni.SkinLoader;
import io.github.lonamiwebs.klooni.serializer.BinSerializable;
public abstract class BaseScorer implements BinSerializable {
//region Members
int currentScore;
final Label currentScoreLabel;
final Label highScoreLabel;
final Texture cupTexture;
final Rectangle cupArea;
private final Color cupColor;
// To interpolate between shown score -> real score
private float shownScore;
//endregion
//region Constructor
// The board size is required when calculating the score
BaseScorer(final Klooni game, GameLayout layout, int highScore) {
cupTexture = SkinLoader.loadPng("cup.png");
cupColor = Klooni.theme.currentScore.cpy();
cupArea = new Rectangle();
Label.LabelStyle labelStyle = new Label.LabelStyle();
labelStyle.font = game.skin.getFont("font");
currentScoreLabel = new Label("0", labelStyle);
currentScoreLabel.setAlignment(Align.right);
highScoreLabel = new Label(Integer.toString(highScore), labelStyle);
layout.update(this);
}
//endregion
//region Private methods
// 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)
final int calculateClearScore(int stripsCleared, int boardSize) {
if (stripsCleared < 1) return 0;
if (stripsCleared == 1) return boardSize;
else return boardSize * stripsCleared + calculateClearScore(stripsCleared - 1, boardSize);
}
//endregion
//region Public methods
// Adds the score a given piece would give
public int addPieceScore(int areaPut) {
currentScore += areaPut;
return areaPut;
}
// Adds the score given by the board, this is, the count of cleared strips
public int addBoardScore(int stripsCleared, int boardSize) {
int score = calculateClearScore(stripsCleared, boardSize);
currentScore += score;
return score;
}
public int getCurrentScore() {
return currentScore;
}
public void pause() { }
public void resume() { }
abstract public boolean isGameOver();
abstract protected boolean isNewRecord();
public String gameOverReason() { return ""; }
abstract public void saveScore();
public void draw(SpriteBatch batch) {
// If we beat a new record, the cup color will linear interpolate to the high score color
cupColor.lerp(isNewRecord() ? Klooni.theme.highScore : Klooni.theme.currentScore, 0.05f);
batch.setColor(cupColor);
batch.draw(cupTexture, cupArea.x, cupArea.y, cupArea.width, cupArea.height);
int roundShown = MathUtils.round(shownScore);
if (roundShown != currentScore) {
shownScore = Interpolation.linear.apply(shownScore, currentScore, 0.1f);
currentScoreLabel.setText(Integer.toString(MathUtils.round(shownScore)));
}
currentScoreLabel.setColor(Klooni.theme.currentScore);
currentScoreLabel.draw(batch, 1f);
highScoreLabel.setColor(Klooni.theme.highScore);
highScoreLabel.draw(batch, 1f);
}
//endregion
}