Add sounds and animate taking pieces
This commit is contained in:
parent
83bf5b736b
commit
3f47e5474c
10 changed files with 77 additions and 8 deletions
BIN
android/assets/sound/game_over.mp3
Normal file
BIN
android/assets/sound/game_over.mp3
Normal file
Binary file not shown.
BIN
android/assets/sound/invalid_drop.mp3
Normal file
BIN
android/assets/sound/invalid_drop.mp3
Normal file
Binary file not shown.
BIN
android/assets/sound/piece_drop.mp3
Normal file
BIN
android/assets/sound/piece_drop.mp3
Normal file
Binary file not shown.
BIN
android/assets/sound/strip_clear.mp3
Normal file
BIN
android/assets/sound/strip_clear.mp3
Normal file
Binary file not shown.
BIN
android/assets/sound/take_pieces.mp3
Normal file
BIN
android/assets/sound/take_pieces.mp3
Normal file
Binary file not shown.
|
@ -2,6 +2,7 @@ package io.github.lonamiwebs.klooni;
|
||||||
|
|
||||||
import com.badlogic.gdx.Game;
|
import com.badlogic.gdx.Game;
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.Preferences;
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
import com.badlogic.gdx.graphics.g2d.NinePatch;
|
import com.badlogic.gdx.graphics.g2d.NinePatch;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||||
|
@ -14,6 +15,8 @@ public class Klooni extends Game {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void create() {
|
public void create() {
|
||||||
|
prefs = Gdx.app.getPreferences("io.github.lonamiwebs.klooni.game");
|
||||||
|
|
||||||
// TODO Better way to have this skin somewhere
|
// TODO Better way to have this skin somewhere
|
||||||
// Gotta create that darn .json…!
|
// Gotta create that darn .json…!
|
||||||
skin = new Skin(Gdx.files.internal("skin/uiskin.json"));
|
skin = new Skin(Gdx.files.internal("skin/uiskin.json"));
|
||||||
|
@ -46,4 +49,22 @@ public class Klooni extends Game {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
skin.dispose();
|
skin.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//region Settings
|
||||||
|
|
||||||
|
private static Preferences prefs;
|
||||||
|
|
||||||
|
public static int getMaxScore() {
|
||||||
|
return prefs.getInteger("maxScore", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setMaxScore(int score) {
|
||||||
|
prefs.putInteger("maxScore", score).flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean soundsEnabled() {
|
||||||
|
return !prefs.getBoolean("muteSound", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
package io.github.lonamiwebs.klooni.game;
|
package io.github.lonamiwebs.klooni.game;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.audio.Sound;
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
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.MathUtils;
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
|
||||||
|
import io.github.lonamiwebs.klooni.Klooni;
|
||||||
|
|
||||||
public class Board {
|
public class Board {
|
||||||
|
|
||||||
Cell[][] cells;
|
Cell[][] cells;
|
||||||
|
@ -18,6 +21,7 @@ public class Board {
|
||||||
final Vector2 pos;
|
final Vector2 pos;
|
||||||
|
|
||||||
public NinePatch cellPatch;
|
public NinePatch cellPatch;
|
||||||
|
private final Sound stripClearSound;
|
||||||
|
|
||||||
public Board(final GameLayout layout, int cellCount) {
|
public Board(final GameLayout layout, int cellCount) {
|
||||||
this.cellCount = cellCount;
|
this.cellCount = cellCount;
|
||||||
|
@ -25,6 +29,8 @@ public class Board {
|
||||||
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);
|
||||||
|
|
||||||
|
stripClearSound = Gdx.audio.newSound(Gdx.files.internal("sound/strip_clear.mp3"));
|
||||||
|
|
||||||
lastPutPiecePos = new Vector2();
|
lastPutPiecePos = new Vector2();
|
||||||
pos = new Vector2();
|
pos = new Vector2();
|
||||||
layout.update(this);
|
layout.update(this);
|
||||||
|
@ -120,6 +126,8 @@ public class Board {
|
||||||
clearCount++;
|
clearCount++;
|
||||||
}
|
}
|
||||||
if (clearCount > 0) {
|
if (clearCount > 0) {
|
||||||
|
float pan = 0;
|
||||||
|
|
||||||
// Do clear those rows and columns
|
// Do clear those rows and columns
|
||||||
for (int i = 0; i < cellCount; i++) {
|
for (int i = 0; i < cellCount; i++) {
|
||||||
if (clearedRows[i]) {
|
if (clearedRows[i]) {
|
||||||
|
@ -130,11 +138,19 @@ public class Board {
|
||||||
}
|
}
|
||||||
for (int j = 0; j < cellCount; j++) {
|
for (int j = 0; j < cellCount; j++) {
|
||||||
if (clearedCols[j]) {
|
if (clearedCols[j]) {
|
||||||
|
pan += 2f * (j - cellCount / 2) / (float)cellCount;
|
||||||
for (int i = 0; i < cellCount; i++) {
|
for (int i = 0; i < cellCount; i++) {
|
||||||
cells[i][j].vanish(lastPutPiecePos);
|
cells[i][j].vanish(lastPutPiecePos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Klooni.soundsEnabled()) {
|
||||||
|
long id = stripClearSound.play();
|
||||||
|
pan = MathUtils.clamp(pan, -1, 1);
|
||||||
|
stripClearSound.setPitch(id, MathUtils.random(0.8f, 1.2f));
|
||||||
|
stripClearSound.setPan(id, pan, MathUtils.random(0.7f, 1f));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return clearCount;
|
return clearCount;
|
||||||
|
|
|
@ -1,18 +1,26 @@
|
||||||
package io.github.lonamiwebs.klooni.game;
|
package io.github.lonamiwebs.klooni.game;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.audio.Sound;
|
||||||
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.Interpolation;
|
||||||
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
import com.badlogic.gdx.math.Rectangle;
|
import com.badlogic.gdx.math.Rectangle;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
|
||||||
|
import io.github.lonamiwebs.klooni.Klooni;
|
||||||
|
|
||||||
public class PieceHolder {
|
public class PieceHolder {
|
||||||
|
|
||||||
private final Piece[] pieces;
|
private final Piece[] pieces;
|
||||||
private final Rectangle[] originalPositions; // Needed after a piece is dropped
|
private final Rectangle[] originalPositions; // Needed after a piece is dropped
|
||||||
|
|
||||||
|
private final Sound pieceDropSound;
|
||||||
|
private final Sound invalidPieceDropSound;
|
||||||
|
private final Sound takePiecesSound;
|
||||||
|
|
||||||
private final int count;
|
private final int count;
|
||||||
|
|
||||||
private int heldPiece;
|
private int heldPiece;
|
||||||
|
@ -31,6 +39,10 @@ public class PieceHolder {
|
||||||
pieces = new Piece[count];
|
pieces = new Piece[count];
|
||||||
originalPositions = new Rectangle[count];
|
originalPositions = new Rectangle[count];
|
||||||
|
|
||||||
|
pieceDropSound = Gdx.audio.newSound(Gdx.files.internal("sound/piece_drop.mp3"));
|
||||||
|
invalidPieceDropSound = Gdx.audio.newSound(Gdx.files.internal("sound/invalid_drop.mp3"));
|
||||||
|
takePiecesSound = Gdx.audio.newSound(Gdx.files.internal("sound/take_pieces.mp3"));
|
||||||
|
|
||||||
heldPiece = -1;
|
heldPiece = -1;
|
||||||
this.pickedCellSize = pickedCellSize;
|
this.pickedCellSize = pickedCellSize;
|
||||||
|
|
||||||
|
@ -64,6 +76,13 @@ public class PieceHolder {
|
||||||
originalPositions[i] = new Rectangle(
|
originalPositions[i] = new Rectangle(
|
||||||
pieces[i].pos.x, pieces[i].pos.y,
|
pieces[i].pos.x, pieces[i].pos.y,
|
||||||
pieces[i].cellSize, pieces[i].cellSize);
|
pieces[i].cellSize, pieces[i].cellSize);
|
||||||
|
|
||||||
|
// Now that we have the original positions, reset the size so it animates and grows
|
||||||
|
pieces[i].cellSize = 0f;
|
||||||
|
}
|
||||||
|
if (Klooni.soundsEnabled()) {
|
||||||
|
// Random pitch so it's not always the same sound
|
||||||
|
takePiecesSound.setPitch(takePiecesSound.play(), MathUtils.random(0.8f, 1.2f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,8 +133,18 @@ public class PieceHolder {
|
||||||
public int dropPiece(Board board) {
|
public int dropPiece(Board board) {
|
||||||
if (heldPiece > -1) {
|
if (heldPiece > -1) {
|
||||||
boolean put = board.putScreenPiece(pieces[heldPiece]);
|
boolean put = board.putScreenPiece(pieces[heldPiece]);
|
||||||
if (put)
|
if (put) {
|
||||||
|
if (Klooni.soundsEnabled()) {
|
||||||
|
// The larger the piece size, the smaller the pitch
|
||||||
|
// Considering 10 cells to be the largest, 1.1 highest pitch, 0.7 lowest
|
||||||
|
float pitch = 1.104f - pieces[heldPiece].calculateArea() * 0.04f;
|
||||||
|
pieceDropSound.setPitch(pieceDropSound.play(), pitch);
|
||||||
|
}
|
||||||
pieces[heldPiece] = null;
|
pieces[heldPiece] = null;
|
||||||
|
} else {
|
||||||
|
if (Klooni.soundsEnabled())
|
||||||
|
invalidPieceDropSound.play();
|
||||||
|
}
|
||||||
|
|
||||||
heldPiece = -1;
|
heldPiece = -1;
|
||||||
if (handFinished())
|
if (handFinished())
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package io.github.lonamiwebs.klooni.game;
|
package io.github.lonamiwebs.klooni.game;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.Preferences;
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||||
|
@ -12,9 +11,10 @@ import com.badlogic.gdx.math.Rectangle;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||||
import com.badlogic.gdx.utils.Align;
|
import com.badlogic.gdx.utils.Align;
|
||||||
|
|
||||||
|
import io.github.lonamiwebs.klooni.Klooni;
|
||||||
|
|
||||||
public class Scorer {
|
public class Scorer {
|
||||||
|
|
||||||
private final Preferences prefs;
|
|
||||||
private int currentScore, maxScore;
|
private int currentScore, maxScore;
|
||||||
private boolean newRecord;
|
private boolean newRecord;
|
||||||
|
|
||||||
|
@ -28,10 +28,8 @@ public class Scorer {
|
||||||
final Rectangle cupArea;
|
final Rectangle cupArea;
|
||||||
|
|
||||||
public Scorer(GameLayout layout, int boardSize) {
|
public Scorer(GameLayout layout, int boardSize) {
|
||||||
prefs = Gdx.app.getPreferences("io.github.lonamiwebs.klooni.game");
|
|
||||||
|
|
||||||
currentScore = 0;
|
currentScore = 0;
|
||||||
maxScore = prefs.getInteger("maxScore", 0);
|
maxScore = Klooni.getMaxScore();
|
||||||
this.boardSize = boardSize;
|
this.boardSize = boardSize;
|
||||||
|
|
||||||
cupTexture = new Texture(Gdx.files.internal("ui/cup.png"));
|
cupTexture = new Texture(Gdx.files.internal("ui/cup.png"));
|
||||||
|
@ -69,8 +67,7 @@ public class Scorer {
|
||||||
|
|
||||||
public void saveScore() {
|
public void saveScore() {
|
||||||
if (newRecord) {
|
if (newRecord) {
|
||||||
prefs.putInteger("maxScore", currentScore);
|
Klooni.setMaxScore(currentScore);
|
||||||
prefs.flush();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.Input;
|
import com.badlogic.gdx.Input;
|
||||||
import com.badlogic.gdx.InputProcessor;
|
import com.badlogic.gdx.InputProcessor;
|
||||||
import com.badlogic.gdx.Screen;
|
import com.badlogic.gdx.Screen;
|
||||||
|
import com.badlogic.gdx.audio.Sound;
|
||||||
import com.badlogic.gdx.graphics.GL20;
|
import com.badlogic.gdx.graphics.GL20;
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||||
|
|
||||||
|
@ -21,6 +22,7 @@ public class GameScreen implements Screen, InputProcessor {
|
||||||
private PieceHolder holder;
|
private PieceHolder holder;
|
||||||
|
|
||||||
private final GameLayout layout;
|
private final GameLayout layout;
|
||||||
|
private final Sound gameOverSound;
|
||||||
|
|
||||||
private SpriteBatch batch;
|
private SpriteBatch batch;
|
||||||
|
|
||||||
|
@ -35,6 +37,8 @@ public class GameScreen implements Screen, InputProcessor {
|
||||||
board = new Board(layout, 10);
|
board = new Board(layout, 10);
|
||||||
holder = new PieceHolder(layout, 3, board.cellSize);
|
holder = new PieceHolder(layout, 3, board.cellSize);
|
||||||
pauseMenu = new PauseMenuStage(layout, game, scorer);
|
pauseMenu = new PauseMenuStage(layout, game, scorer);
|
||||||
|
|
||||||
|
gameOverSound = Gdx.audio.newSound(Gdx.files.internal("sound/game_over.mp3"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isGameOver() {
|
private boolean isGameOver() {
|
||||||
|
@ -139,6 +143,8 @@ public class GameScreen implements Screen, InputProcessor {
|
||||||
// After the piece was put, check if it's game over
|
// After the piece was put, check if it's game over
|
||||||
if (isGameOver()) {
|
if (isGameOver()) {
|
||||||
pauseMenu.show(true);
|
pauseMenu.show(true);
|
||||||
|
if (Klooni.soundsEnabled())
|
||||||
|
gameOverSound.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in a new issue