private synchronized void render(Graphics g) {
    if (level != null) {
      int xScroll = (int) (player.pos.x - screen.w / 2);
      int yScroll = (int) (player.pos.y - (screen.h - 24) / 2);
      soundPlayer.setListenerPosition((float) player.pos.x, (float) player.pos.y);
      level.render(screen, xScroll, yScroll);
    }
    if (!menuStack.isEmpty()) {
      menuStack.peek().render(screen);
    }

    Font.draw(screen, "FPS: " + fps, 10, 10);
    // for (int p = 0; p < players.length; p++) {
    // if (players[p] != null) {
    // String msg = "P" + (p + 1) + ": " + players[p].getScore();
    // Font.draw(screen, msg, 320, screen.h - 24 + p * 8);
    // }
    // }
    if (player != null && menuStack.size() == 0) {
      Font.draw(screen, player.health + " / 10", 340, screen.h - 19);
      Font.draw(screen, "" + player.score, 340, screen.h - 33);
    }

    g.setColor(Color.BLACK);

    g.fillRect(0, 0, getWidth(), getHeight());
    g.translate((getWidth() - GAME_WIDTH * SCALE) / 2, (getHeight() - GAME_HEIGHT * SCALE) / 2);
    g.clipRect(0, 0, GAME_WIDTH * SCALE, GAME_HEIGHT * SCALE);

    if (!menuStack.isEmpty() || level != null) {

      // render mouse
      renderMouse(screen, mouseButtons);

      g.drawImage(screen.image, 0, 0, GAME_WIDTH * SCALE, GAME_HEIGHT * SCALE, null);
    }

    // String msg = "FPS: " + fps;
    // g.setColor(Color.LIGHT_GRAY);
    // g.drawString(msg, 11, 11);
    // g.setColor(Color.WHITE);
    // g.drawString(msg, 10, 10);

  }
 public void keyTyped(KeyEvent e) {
   if (!menuStack.isEmpty()) {
     menuStack.peek().keyTyped(e);
   }
 }
 private void popMenu() {
   if (!menuStack.isEmpty()) {
     menuStack.pop();
   }
 }
 private void addMenu(GuiMenu menu) {
   menuStack.add(menu);
   menu.addButtonListener(this);
 }
 private void clearMenus() {
   while (!menuStack.isEmpty()) {
     menuStack.pop();
   }
 }
  public void buttonPressed(Button button) {
    if (button.getId() == TitleMenu.RESTART_GAME_ID) {
      clearMenus();
      TitleMenu menu = new TitleMenu(GAME_WIDTH, GAME_HEIGHT);
      addMenu(menu);

    } else if (button.getId() == TitleMenu.START_GAME_ID) {
      clearMenus();
      isMultiplayer = false;

      localId = 0;
      synchronizer = new TurnSynchronizer(this, null, 0, 1);
      synchronizer.setStarted(true);

      createLevel(TitleMenu.level);
    } else if (button.getId() == TitleMenu.SELECT_LEVEL_ID) {
      addMenu(new LevelSelect(false));
    } else if (button.getId() == TitleMenu.SELECT_HOST_LEVEL_ID) {
      addMenu(new LevelSelect(true));
    } else if (button.getId() == TitleMenu.HOST_GAME_ID) {
      addMenu(new HostingWaitMenu());
      isMultiplayer = true;
      isServer = true;
      try {
        if (isServer) {
          localId = 0;
          serverSocket = new ServerSocket(3000);
          serverSocket.setSoTimeout(1000);

          hostThread =
              new Thread() {

                public void run() {
                  boolean fail = true;
                  try {
                    while (!isInterrupted()) {
                      Socket socket = null;
                      try {
                        socket = serverSocket.accept();
                      } catch (SocketTimeoutException e) {

                      }
                      if (socket == null) {
                        System.out.println("asdf");
                        continue;
                      }
                      fail = false;

                      packetLink = new NetworkPacketLink(socket);

                      createServerState = 1;
                      break;
                    }
                  } catch (Exception e) {
                    e.printStackTrace();
                  }
                  if (fail) {
                    try {
                      serverSocket.close();
                    } catch (IOException e) {
                    }
                  }
                };
              };
          hostThread.start();
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
    } else if (button.getId() == TitleMenu.JOIN_GAME_ID) {
      addMenu(new JoinGameMenu());
    } else if (button.getId() == TitleMenu.CANCEL_JOIN_ID) {
      popMenu();
      if (hostThread != null) {
        hostThread.interrupt();
        hostThread = null;
      }
    } else if (button.getId() == TitleMenu.PERFORM_JOIN_ID) {
      menuStack.clear();
      isMultiplayer = true;
      isServer = false;

      try {
        localId = 1;
        packetLink = new ClientSidePacketLink(TitleMenu.ip, 3000);
        synchronizer = new TurnSynchronizer(this, packetLink, localId, 2);
        packetLink.setPacketListener(this);
      } catch (Exception e) {
        e.printStackTrace();
        // System.exit(1);
        addMenu(new TitleMenu(GAME_WIDTH, GAME_HEIGHT));
      }
    } else if (button.getId() == TitleMenu.SELECT_DIFFICULTY_ID) {
      addMenu(new DifficultySelect());
    } else if (button.getId() == TitleMenu.EXIT_GAME_ID) {
      System.exit(0);
    }
  }
  private void tick() {
    if (level != null) {
      if (level.player1Score >= Level.TARGET_SCORE) {
        addMenu(new WinMenu(GAME_WIDTH, GAME_HEIGHT, 1));
        level = null;
        return;
      }
      if (level.player2Score >= Level.TARGET_SCORE) {
        addMenu(new WinMenu(GAME_WIDTH, GAME_HEIGHT, 2));
        level = null;
        return;
      }
      if (keys.escape.wasPressed()) {
        clearMenus();
        addMenu(new TitleMenu(GAME_WIDTH, GAME_HEIGHT));
        level = null;
        return;
      }
    }
    if (packetLink != null) {
      packetLink.tick();
    }

    mouseButtons.setPosition(getMousePosition());
    if (!menuStack.isEmpty()) {
      menuStack.peek().tick(mouseButtons);
    }
    if (mouseMoved) {
      mouseMoved = false;
      mouseHideTime = 0;
      if (mouseHidden) {
        mouseHidden = false;
      }
    }
    if (mouseHideTime < 60) {
      mouseHideTime++;
      if (mouseHideTime == 60) {
        mouseHidden = true;
      }
    }
    mouseButtons.tick();

    if (level != null) {
      if (synchronizer.preTurn()) {
        synchronizer.postTurn();
        for (int index = 0; index < keys.getAll().size(); index++) {
          Keys.Key key = keys.getAll().get(index);
          boolean nextState = key.nextState;
          if (key.isDown != nextState) {
            synchronizer.addCommand(new ChangeKeyCommand(index, nextState));
          }
        }
        if (keys.save.isDown) {
          level.save();
        }
        keys.tick();
        for (Keys skeys : synchedKeys) {
          skeys.tick();
        }

        // if mouse is in use, update player orientation before level
        // tick
        if (!mouseHidden) {

          // update player mouse, in world pixels relative to player
          player.setAimByMouse(
              ((mouseButtons.getX() / SCALE) - (screen.w / 2)),
              (((mouseButtons.getY() / SCALE) + 24) - (screen.h / 2)));
        } else {
          player.setAimByKeyboard();
        }

        level.tick();
      }
    }

    if (createServerState == 1) {
      createServerState = 2;

      synchronizer = new TurnSynchronizer(MojamComponent.this, packetLink, localId, 2);

      clearMenus();
      createLevel(TitleMenu.level);

      synchronizer.setStarted(true);
      packetLink.sendPacket(new StartGamePacket(TurnSynchronizer.synchedSeed, TitleMenu.level));
      packetLink.setPacketListener(MojamComponent.this);
    }
  }