Add sounds and animate taking pieces

This commit is contained in:
Lonami Exo 2017-01-29 13:50:13 +01:00
parent 83bf5b736b
commit 3f47e5474c
10 changed files with 77 additions and 8 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -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
} }

View file

@ -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;

View file

@ -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())

View file

@ -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();
} }
} }

View file

@ -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;