@Override
  public void step(double elapsedTime) {
    Random rand = new Random();
    if (getTimeRemaining() < 0 && getGameStarted()) {
      exitLevel("You got beat, you didn't defeat Goodman!!");
    }
    if (getGameStarted()) {
      getMyRoot().getChildren().remove(getTimerLabel());
      setTimeRemaining(getTimeRemaining() - elapsedTime);
      Label timerLabel = new Label(Long.toString(Math.round(getTimeRemaining() - elapsedTime)));
      timerLabel.setTextFill(Color.BLACK);
      timerLabel.setStyle("-fx-font-size: 4em;");
      timerLabel.setLayoutX(getMyWidth() / 2 - getMyWidth() * .04);
      timerLabel.setLayoutY(getMyHeight() * .15);
      setTimerLabel(timerLabel);
      getMyRoot().getChildren().add(getTimerLabel());
      if (myDodgeball == null && rand.nextInt(100) == 0) {

        myDodgeball =
            new Dodgeball(
                getMyWidth() * .45,
                getMyHeight() * 2 / 3,
                villainPlayerIV.getX(),
                villainPlayerIV.getY(),
                20,
                Color.RED,
                false,
                false);

        getBallsInFlightList().add(myDodgeball);
        getMyRoot().getChildren().add(myDodgeball);
      }
      if (tossBall()) {
        int highOrLow = rand.nextInt(3) * 20;
        Dodgeball newEnemyBall =
            new Dodgeball(
                villainPlayerIV.getX(),
                villainPlayerIV.getY(),
                getMyPlayerIV().getX(),
                getMyPlayerIV().getY() + highOrLow,
                20,
                Color.PURPLE,
                true,
                true);

        getBallsInFlightList().add(newEnemyBall);
        getMyRoot().getChildren().add(newEnemyBall);
      }
      Iterator<Dodgeball> iter = getBallsInFlightList().iterator();
      while (iter.hasNext()) {
        Dodgeball currBall = iter.next();

        if (currBall.isBeingThrown()) {
          if (!currBall.isEnemyBall()) {
            currBall.setCenterX(currBall.getCenterX() + villainPlayer.getMyTossSpeed());
            currBall.setCenterY(
                currBall.getCenterX() * currBall.getTrajectorySlope()
                    + currBall.getTrajectoryYIntercept());
            // check for collisions
            if (villainPlayerIV.getBoundsInParent().intersects(currBall.getBoundsInParent())) {
              int currLives = enemyLivesHBox.getChildren().size();
              getMyRoot().getChildren().removeAll(currBall, enemyLivesHBox);
              setEnemyLivesHBox(currLives - 1);
              getMyRoot().getChildren().add(getEnemyLivesHBox());
              iter.remove();
              myDodgeball = null;
              if (enemyLivesHBox.getChildren().size() == 0) {
                exitLevel("You won!!");
              }
            }
          } else {
            currBall.setCenterX(currBall.getCenterX() - villainPlayer.getMyTossSpeed());
            currBall.setCenterY(
                currBall.getCenterX() * currBall.getTrajectorySlope()
                    + currBall.getTrajectoryYIntercept());
            //                     check for collisions
            if (getMyPlayerIV().getBoundsInParent().intersects(currBall.getBoundsInParent())) {
              iter.remove();
              getMyRoot().getChildren().removeAll(currBall, getMyLivesHBox());

              setMyLivesHBox(getMyLivesHBox().getChildren().size() - 1);
              getMyRoot().getChildren().add(getMyLivesHBox());
              if (getMyLivesHBox().getChildren().size() == 0) {
                exitLevel("You got beat!!");
              }
            }
          }
          double currX = currBall.getCenterX();
          if (currX < 0) {
            iter.remove();
            getMyRoot().getChildren().remove(currBall);
          }
        }
      }
    }
  }
  @Override
  public void handleKeyInput(KeyCode code) {
    double xLoc = getMyPlayerIV().getBoundsInParent().getMinX();
    double yLoc = getMyPlayerIV().getY();
    double yLocBottom = yLoc + getMyPlayerIV().getBoundsInParent().getHeight() / 2;
    double moveSpeed = getMyPlayer().getMyMoveSpeed();
    switch (code) {
      case RIGHT:
        // Check to see if crossed half court or ducking
        if (xLoc + getMyPlayerIV().getBoundsInLocal().getWidth() + moveSpeed < getMyWidth() / 2
            && !isDucking()) {
          getMyPlayerIV().setX(xLoc + moveSpeed);
        }
        // Check to see if player picks up ball
        if (myDodgeball != null) {
          if (getMyPlayerIV().getBoundsInParent().intersects(myDodgeball.getBoundsInParent())) {
            getMyRoot().getChildren().remove(getMyDodgeball());
            getMyPlayer().setHoldingBall(true);
            getMyRoot().getChildren().get(0).setVisible(true);
          }
        }

        break;
      case LEFT:
        // Make sure not too far out of window or ducking
        if (xLoc - moveSpeed > 0 && !isDucking()) {
          getMyPlayerIV().setX(xLoc - moveSpeed);
        }
        break;
      case UP:
        // Joe Jumps, prevents jump if already in the middle of one
        if (getJumpTransition() == null
            || getJumpTransition().getStatus() == Animation.Status.STOPPED) {
          setJumpTransition(new TranslateTransition(Duration.millis(300), getMyPlayerIV()));
          getJumpTransition().interpolatorProperty().set(Interpolator.SPLINE(.1, .1, .7, .7));
          getJumpTransition().setByY(-getMyPlayerIV().getY());
          getJumpTransition().setAutoReverse(true);
          getJumpTransition().setCycleCount(2);
          getJumpTransition().play();
        }
        break;
      case DOWN:
        // Prevents "duck" if already ducking
        if (!isDucking()) {
          Boolean wasHoldingBall = getMyPlayer().isHoldingBall();
          getMyRoot().getChildren().removeAll(getMyPlayerIV());
          Image duck =
              new Image(
                  getClass()
                      .getClassLoader()
                      .getResourceAsStream("main/resources/images/duck.png"));
          setMyPlayer(new MyDodgeballer(getMyStartLives(), getMyMoveSpeed(), new ImageView(duck)));
          getMyPlayer().setHoldingBall(wasHoldingBall);
          setMyPlayerIV(getMyPlayer().getMyImageView());
          getMyPlayer().getMyImageView().setX(xLoc);
          getMyPlayer().getMyImageView().setY(yLocBottom);
          getMyRoot().getChildren().add(getMyPlayerIV());
          setDucking(true);
        }
        break;
      case SPACE:
        if (getMyPlayer().isHoldingBall()) {
          setMyDodgeball(
              new Dodgeball(
                  getMyPlayerIV().getX(),
                  getMyPlayerIV().getY(),
                  villainPlayerIV.getX(),
                  villainPlayerIV.getY(),
                  20,
                  Color.RED,
                  false,
                  true));
          getMyPlayer().setHoldingBall(false);
          getBallsInFlightList().add(getMyDodgeball());
          getThrowBalllbl().setVisible(false);
          getMyRoot().getChildren().add(getMyDodgeball());
        }
        break;
      case L:
        if (getGameStarted() == false) {
          setMyStartLives(getMyStartLives() + 1);
          getMyRoot().getChildren().remove(getMyLivesHBox());
          setMyLivesHBox(getMyStartLives());
          getMyRoot().getChildren().add(getMyLivesHBox());
        }
        break;
      case D:
        if (getGameStarted() == false && getMyStartLives() > 1) {
          setMyStartLives(getMyStartLives() - 1);
          getMyRoot().getChildren().remove(getMyLivesHBox());
          setMyLivesHBox(getMyStartLives());
          getMyRoot().getChildren().add(getMyLivesHBox());
        }
        break;
      case T:
        if (getGameStarted() == false) {
          setMyStartTime(getMyStartTime() + 5);
          setTimeRemaining(getMyStartTime());
          getTimerButtonVBox();
          getMyRoot().getChildren().remove(getTimerLabel());

          Label timerLabel = new Label(Double.toString(getTimeRemaining()));
          timerLabel.setTextFill(Color.BLACK);
          timerLabel.setStyle("-fx-font-size: 4em;");
          timerLabel.setLayoutX(getMyWidth() / 2 - getMyWidth() * .05);
          timerLabel.setLayoutY(getMyHeight() * .2);
          setTimerLabel(timerLabel);
          getMyRoot().getChildren().add(getTimerLabel());
        }
        break;
      case Y:
        if (getGameStarted() == false && getMyStartTime() > 5) {
          setMyStartTime(getMyStartTime() - 5);
          setTimeRemaining(getMyStartTime());
          getTimerButtonVBox();
          getMyRoot().getChildren().remove(getTimerLabel());

          Label timerLabel = new Label(Double.toString(getTimeRemaining()));
          timerLabel.setTextFill(Color.BLACK);
          timerLabel.setStyle("-fx-font-size: 4em;");
          timerLabel.setLayoutX(getMyWidth() / 2 - getMyWidth() * .05);
          timerLabel.setLayoutY(getMyHeight() * .2);
          setTimerLabel(timerLabel);
          getMyRoot().getChildren().add(getTimerLabel());
        }
        break;
      default:
    }
  }