@Override
  public void act(float delta) {
    int acts = logic.advance2(delta);
    super.act(delta);

    boolean isGameOver = logic.isGameOver();
    if (isGameOver && !gameOverFired) {
      if (logic.isGameLost()) {
        gameOverFired = true;
        mGame.gameLost();
      } else {
        if (timeToFireWon > 0) timeToFireWon -= delta;
        else {
          gameOverFired = true;
          mGame.gameWon();
        }
      }
    } else if (!isGameOver && gameOverFired) {
      gameOverFired = false;
      timeToFireWon = TIME_TO_WAIT_FOR_WON;
    }

    sounds.act(delta, acts);
    // bangs.act(delta);
    snappers.act(delta);

    if (isHinting) hint.act(delta);

    if (isTutorialAvailable
        && !isHinting
        && !areSnappersTouched()
        && (System.currentTimeMillis() - logic.startTime) > WAIT_FOR_TUTORIAL) showHints(true);
  }
  public void showHints(boolean showText) {
    if (isHinting) return;

    if (areSnappersTouched()) restartLevel();

    if (hint == null) hint = new Hints(logic);
    else hint.updateLevel();
    logic.hintUsed = true;
    isHinting = true;
  }
  public void setLevel(Level level) {
    gameOverFired = false;
    timeToFireWon = TIME_TO_WAIT_FOR_WON;
    logic.startLevel(level);

    if (width != 0) snappers.defineSnapperViews();

    mGame.getAppListener().updateLevelInfo(level);
    isHinting = false;
    logicListener.tap();
    isTutorialAvailable = (level.number < 4 && level.packNumber == 1);
  }
 public void setViewport(int width, int height) {
   super.setViewport(width, height, true);
   logic.setScreen(width, height, defineGameRect(width, height));
   snappers.defineSnapperViews();
 }
 public void resizeGameRect(int marginBottom) {
   int marginTop = Math.round(Metrics.squareButtonSize * 1.1f);
   Rect gameRect = new Rect(0, (int) height - marginTop, (int) width, marginBottom);
   logic.setScreen((int) width, (int) height, gameRect);
   snappers.updatePositions();
 }