@Override public void show() { super.show(); // Reset data if (!game.isRestoredState()) { game.getState().reset(); } else { game.setRestoredState(false); if (game.getState().isTimeout()) { game.pushScreen(Screens.GAME_OVER); } } // The player is playing game.getState().setPlaying(true); score.setValue(game.getState().getScore()); timer.setSeconds(game.getState().getRemainingTime()); paused = running = askingLeave = false; if (!game.getState().isCountdownFinished()) { countdown( 2, new Runnable() { @Override public void run() { game.getState().setCountdownFinished(true); // Start the game unless the user is leaving or is paused. if (!paused && !askingLeave) { running = true; board.setColoured(true); timer.setRunning(true); board.setTouchable(Touchable.enabled); game.player.playSound(SoundCode.SUCCESS); } } }); } else { pauseGame(); } }
@Override public void onSelectionSucceeded(final List<BallActor> selection) { // Extract the data from the selection. List<Ball> balls = new ArrayList<>(); for (BallActor selectedBall : selection) balls.add(selectedBall.getBall()); final Bounds bounds = Bounds.fromBallList(balls); // Change the colors of the selected region. board.addAction( Actions.sequence( board.hideRegion(bounds), Actions.run( new Runnable() { @Override public void run() { for (BallActor selectedBall : selection) { selectedBall.setColor(Color.WHITE); } generate(bounds); // Reset the cheat game.getState().setCheatSeen(false); game.getState().setWiggledBounds(null); } }))); // Give some score to the user. ScoreCalculator calculator = new ScoreCalculator(game.getState().getBoard(), bounds); int givenScore = calculator.calculate(); game.getState().addScore(givenScore); score.giveScore(givenScore); // Put information about this combination in the stats. int rows = bounds.maxY - bounds.minY + 1; int cols = bounds.maxX - bounds.minX + 1; String size = Math.max(rows, cols) + "x" + Math.min(rows, cols); game.statistics.getSizesData().incrementValue(size); BallColor color = board.getBall(bounds.minX, bounds.minY).getBall().getColor(); game.statistics.getColorData().incrementValue(color.toString().toLowerCase()); game.statistics.getTotalData().incrementValue("balls", rows * cols); game.statistics.getTotalData().incrementValue("combinations"); // Now, display the score to the user. If the combination is a // PERFECT combination, just display PERFECT. int boardSize = game.getState().getBoard().getSize() - 1; if (bounds.equals(new Bounds(0, 0, boardSize, boardSize))) { // Give score Label label = new Label("PERFECT", game.getSkin(), "monospace"); label.setX((getStage().getViewport().getWorldWidth() - label.getWidth()) / 2); label.setY((getStage().getViewport().getWorldHeight() - label.getHeight()) / 2); label.setFontScale(3); label.setAlignment(Align.center); label.addAction(Actions.sequence(Actions.moveBy(0, 80, 0.5f), Actions.removeActor())); getStage().addActor(label); game.player.playSound(SoundCode.PERFECT); // Give time float givenTime = Constants.SECONDS - timer.getSeconds(); timer.giveTime(givenTime, 4f); } else { // Was special? boolean special = givenScore != rows * cols; // Give score showPartialScore(givenScore, bounds, special); game.player.playSound(SoundCode.SUCCESS); // Give time float givenTime = 4f; timer.giveTime(givenTime, 0.25f); } }
@Override public void setUpInterface(Table table) { // Create the actors for this screen. timer = new TimerActor(Constants.SECONDS, game.getSkin()); score = new ScoreActor(game.getSkin()); board = new BoardActor(game.getBallAtlas(), game.getState().getBoard()); // Add the help button. ImageButton help = new ImageButton(game.getSkin(), "blueHelp"); help.addListener( new ChangeListener() { @Override public void changed(ChangeEvent event, Actor actor) { // Don't act if the game hasn't started yet. if (!timer.isRunning() || game.getState().isTimeout()) { event.cancel(); return; } // Don't do anything if there are less than 5 seconds. if (timer.getSeconds() <= 5 && game.getState().getWiggledBounds() == null) { game.player.playSound(SoundCode.FAIL); event.cancel(); return; } // Wiggle a valid combination. if (game.getState().getWiggledBounds() == null) { CombinationFinder finder = CombinationFinder.create(game.getState().getBoard()); game.getState() .setWiggledBounds( finder .getPossibleBounds() .get(MathUtils.random(finder.getPossibleBounds().size() - 1))); } board.addAction(board.shake(game.getState().getWiggledBounds(), 10, 5, 0.1f)); if (!game.getState().isCheatSeen()) { // Subtract some time. float subtractedTime = 5f; final float step = subtractedTime / 10; getStage() .addAction( Actions.repeat( 10, Actions.delay( 0.01f, Actions.run( new Runnable() { @Override public void run() { timer.setSeconds(timer.getSeconds() - step); } })))); game.getState().setCheatSeen(true); } event.cancel(); } }); // Add the pause button. ImageButton pause = new ImageButton(game.getSkin(), "blueCross"); pause.addListener( new ChangeListener() { @Override public void changed(ChangeEvent event, Actor actor) { game.player.playSound(SoundCode.FAIL); pauseGame(); event.cancel(); } }); // Disable game until countdown ends. timer.setRunning(false); board.setTouchable(Touchable.disabled); // Add subscribers. timer.addSubscriber(this); board.addSubscriber(this); score.setScoreListener(this); /* * Fill the HUD, which is the display that appears over the board with * all the information. The HUD is generated differently depending on * the aspect ratio of the device. If the device is 4:3, the HUD is * compressed to avoid making the board small. Otherwise, it's expanded * to the usual size. */ boolean landscape = Gdx.graphics.getWidth() > Gdx.graphics.getHeight(); float aspectRatio = landscape ? (float) Gdx.graphics.getWidth() / Gdx.graphics.getHeight() : (float) Gdx.graphics.getHeight() / Gdx.graphics.getWidth(); hud = new Table(); if (aspectRatio < 1.5f) { // Compact layout: buttons and score in the same line. hud.add(new BorderedContainer(game.getSkin(), help)).size(50).padBottom(10); hud.add(new BorderedContainer(game.getSkin(), score)) .height(50) .width(Constants.VIEWPORT_WIDTH / 2) .space(10) .expandX() .fillX(); hud.add(new BorderedContainer(game.getSkin(), pause)).size(50).padBottom(10).row(); hud.add(new BorderedContainer(game.getSkin(), timer)) .colspan(3) .fillX() .height(40) .padBottom(20) .row(); } else { // Large layout: buttons above timer, score below timer (classic). hud.add(new BorderedContainer(game.getSkin(), help)) .size(50) .spaceLeft(10) .padBottom(10) .align(Align.left); hud.add(new BorderedContainer(game.getSkin(), pause)) .size(50) .spaceRight(10) .padBottom(10) .align(Align.right) .row(); hud.add(new BorderedContainer(game.getSkin(), timer)) .colspan(2) .fillX() .expandX() .height(40) .padBottom(10) .row(); hud.add(new BorderedContainer(game.getSkin(), score)) .colspan(2) .height(60) .width(Constants.VIEWPORT_WIDTH / 2) .align(Align.center) .padBottom(10) .row(); } if (aspectRatio > 1.6) { hud.padBottom(20); } table.add(hud).fillX().expandY().align(Align.top).row(); table.add(board).fill().expand().row(); }