Example #1
0
  @Override
  public void update(float delta) {
    // Call the update method in the superclass (Scrollable)
    super.update(delta);

    // The set() method allows you to set the top left corner's x, y
    // coordinates,
    // along with the width and height of the rectangle

    barUp.set(position.x, position.y, width, height);
    barDown.set(
        position.x,
        position.y + height + VERTICAL_GAP,
        width,
        groundY - (position.y + height + VERTICAL_GAP));

    // Our skull width is 24. The bar is only 22 pixels wide. So the skull
    // must be shifted by 1 pixel to the left (so that the skull is centered
    // with respect to its bar).

    // This shift is equivalent to: (SKULL_WIDTH - width) / 2
    skullUp.set(
        position.x - (SKULL_WIDTH - width) / 2,
        position.y + height - SKULL_HEIGHT,
        SKULL_WIDTH,
        SKULL_HEIGHT);
    skullDown.set(position.x - (SKULL_WIDTH - width) / 2, barDown.y, SKULL_WIDTH, SKULL_HEIGHT);
  }
Example #2
0
  public void resize(int width, int height) {
    renderer.setSize(width, height);
    this.width = width;
    this.height = height;
    buttonSize = height / 6F;

    left.set(buttonSize / 2F, buttonSize / 2F, buttonSize, buttonSize);
    right.set(buttonSize * 2, buttonSize / 2F, buttonSize, buttonSize);

    jump.set(width - (buttonSize * 3 / 2), buttonSize / 2F, buttonSize, buttonSize);
  }
Example #3
0
  private void calculateHorizBoundsAndPositions() {
    Drawable handle = style.handle;

    float height = getHeight();

    float availWidth = getWidth() - handle.getMinWidth();
    float leftAreaWidth = (int) (availWidth * splitAmount);
    float rightAreaWidth = availWidth - leftAreaWidth;
    float handleWidth = handle.getMinWidth();

    firstWidgetBounds.set(0, 0, leftAreaWidth, height);
    secondWidgetBounds.set(leftAreaWidth + handleWidth, 0, rightAreaWidth, height);
    handleBounds.set(leftAreaWidth, 0, handleWidth, height);
  }
Example #4
0
  private void calculateVertBoundsAndPositions() {
    Drawable handle = style.handle;

    float width = getWidth();
    float height = getHeight();

    float availHeight = height - handle.getMinHeight();
    float topAreaHeight = (int) (availHeight * splitAmount);
    float bottomAreaHeight = availHeight - topAreaHeight;
    float handleHeight = handle.getMinHeight();

    firstWidgetBounds.set(0, height - topAreaHeight, width, topAreaHeight);
    secondWidgetBounds.set(0, 0, width, bottomAreaHeight);
    handleBounds.set(0, bottomAreaHeight, width, handleHeight);
  }
Example #5
0
  /**
   * Calculates the culling area of the bounding box after it has scaled, rotated and translates.
   * This bounding box contains a bunch of vertices. This way i don't have to merge hundreds of
   * vertices to get a reasonable culling area, just the four of the bounding box.
   */
  private Rectangle getCullingArea(
      Rectangle cullingArea,
      Rectangle boundingBox,
      float rotation,
      Vector2 translation,
      float scale) {

    tmp.set(boundingBox.x, boundingBox.y).scl(scale).rotateRad(rotation).add(translation);
    cullingArea.set(tmp.x, tmp.y, 0, 0);

    tmp.set(boundingBox.x + boundingBox.width, boundingBox.y)
        .scl(scale)
        .rotateRad(rotation)
        .add(translation);
    cullingArea.merge(tmp);

    tmp.set(boundingBox.x + boundingBox.width, boundingBox.y + boundingBox.height)
        .scl(scale)
        .rotateRad(rotation)
        .add(translation);
    cullingArea.merge(tmp);

    tmp.set(boundingBox.x, boundingBox.y + boundingBox.height)
        .scl(scale)
        .rotateRad(rotation)
        .add(translation);
    cullingArea.merge(tmp);

    return cullingArea;
  }
Example #6
0
 @Override
 public void setView(OrthographicCamera camera) {
   spriteBatch.setProjectionMatrix(camera.combined);
   float width = camera.viewportWidth * camera.zoom;
   float height = camera.viewportHeight * camera.zoom;
   viewBounds.set(camera.position.x - width / 2, camera.position.y - height / 2, width, height);
 }
  @Override
  public void touchDragged(InputEvent event, float x, float y, int pointer) {
    super.touchDragged(event, x, y, pointer);

    if (selecting) {
      selectionBox.set(
          Math.min(x, selectionBoxPivot.x),
          Math.min(y, selectionBoxPivot.y),
          Math.abs(x - selectionBoxPivot.x),
          Math.abs(y - selectionBoxPivot.y));
      Service.eventQueue().enqueue(new Event(EventName.SELECTING, selectionBox));
    }
  }
Example #8
0
  public void update(float runtime) {
    x -= 1 / 10f;
    rectNemici.set(x, y, 35, 35);

    batch.begin();
    batch.draw(nemiciAnimation.getKeyFrame(runtime, true), x, y);
    // batch.draw(nemiciAnimation.getKeyFrame(runtime, true), 400, 300);
    batch.end();

    shapeRenderer.begin(ShapeType.Filled);
    shapeRenderer.setColor(55 / 255.0f, 80 / 255.0f, 100 / 255.0f, 1);
    shapeRenderer.rect(x, y, 35, 35);
    shapeRenderer.end();
  }
Example #9
0
  public Rectangle getBoundingRectangle() {
    Rectangle rectangle = new Rectangle();
    boolean initialized = false;

    for (BoundingBox boundingBox : boundingBoxes) {
      updateBoxCulling(boundingBox);

      Rectangle cullingArea =
          getCullingArea(tmpRectangle, boundingBox.rectangle, angleRad, position, scale);

      if (!initialized) {
        rectangle.set(cullingArea);
        initialized = true;
      } else rectangle.merge(cullingArea);
    }

    return rectangle;
  }
 public SnailInfoButtons(float x, float y) {
   tempPic = new Texture("images/buttons/level10.png");
   sprite = new Sprite(new TextureRegion(new Texture("images/buttons/snailInfo.png")));
   xPos = x + (Gdx.graphics.getWidth() - sprite.getWidth()) / 2;
   yPos = y + (Gdx.graphics.getHeight() - sprite.getHeight()) / 2;
   position = new Vector2();
   bound = new Rectangle();
   bound.set(getXPos(), getYPos(), this.buttonGetWidth(), this.buttonGetHeight());
   snailImages = new ArrayList<TextureRegion>();
   for (int b = 0; b < SnailAssalt.numberOfTypes; b++) {
     if (b < 5) {
       snailImages.add(
           new TextureRegion(sprite, b * 200, 0, tempPic.getWidth(), tempPic.getHeight()));
     } else if (b >= 5) {
       snailImages.add(
           new TextureRegion(sprite, (b - 5) * 200, 200, tempPic.getWidth(), tempPic.getHeight()));
     }
   }
 }
Example #11
0
 @Override
 public void setBounds(Rectangle newBounds) {
   bounds.set(newBounds);
 }
Example #12
0
 public void update(double delta) {
   position.y += delta * SPEED;
   boundingRectangle.set(position.x, position.y, width, height);
 }
Example #13
0
  public void layout() {
    final Drawable bg = style.background;
    final Drawable hScrollKnob = style.hScrollKnob;
    final Drawable vScrollKnob = style.vScrollKnob;

    float bgLeftWidth = 0, bgRightWidth = 0, bgTopHeight = 0, bgBottomHeight = 0;
    if (bg != null) {
      bgLeftWidth = bg.getLeftWidth();
      bgRightWidth = bg.getRightWidth();
      bgTopHeight = bg.getTopHeight();
      bgBottomHeight = bg.getBottomHeight();
    }

    float width = getWidth();
    float height = getHeight();

    float scrollbarHeight = 0;
    if (hScrollKnob != null) scrollbarHeight = hScrollKnob.getMinHeight();
    if (style.hScroll != null)
      scrollbarHeight = Math.max(scrollbarHeight, style.hScroll.getMinHeight());
    float scrollbarWidth = 0;
    if (vScrollKnob != null) scrollbarWidth = vScrollKnob.getMinWidth();
    if (style.vScroll != null)
      scrollbarWidth = Math.max(scrollbarWidth, style.vScroll.getMinWidth());

    // Get available space size by subtracting background's padded area.
    areaWidth = width - bgLeftWidth - bgRightWidth;
    areaHeight = height - bgTopHeight - bgBottomHeight;

    if (widget == null) return;

    // Get widget's desired width.
    float widgetWidth, widgetHeight;
    if (widget instanceof Layout) {
      Layout layout = (Layout) widget;
      widgetWidth = layout.getPrefWidth();
      widgetHeight = layout.getPrefHeight();
    } else {
      widgetWidth = widget.getWidth();
      widgetHeight = widget.getHeight();
    }

    // Determine if horizontal/vertical scrollbars are needed.
    scrollX = forceScrollX || (widgetWidth > areaWidth && !disableX);
    scrollY = forceScrollY || (widgetHeight > areaHeight && !disableY);

    boolean fade = fadeScrollBars;
    if (!fade) {
      // Check again, now taking into account the area that's taken up by any enabled scrollbars.
      if (scrollY) {
        areaWidth -= scrollbarWidth;
        if (!scrollX && widgetWidth > areaWidth && !disableX) {
          scrollX = true;
        }
      }
      if (scrollX) {
        areaHeight -= scrollbarHeight;
        if (!scrollY && widgetHeight > areaHeight && !disableY) {
          scrollY = true;
          areaWidth -= scrollbarWidth;
        }
      }
    }

    // Set the widget area bounds.
    widgetAreaBounds.set(bgLeftWidth, bgBottomHeight, areaWidth, areaHeight);

    if (fade) {
      // Make sure widget is drawn under fading scrollbars.
      if (scrollX) areaHeight -= scrollbarHeight;
      if (scrollY) areaWidth -= scrollbarWidth;
    } else {
      if (scrollbarsOnTop) {
        // Make sure widget is drawn under non-fading scrollbars.
        if (scrollX) widgetAreaBounds.height += scrollbarHeight;
        if (scrollY) widgetAreaBounds.width += scrollbarWidth;
      } else {
        // Offset widget area y for horizontal scrollbar.
        if (scrollX) {
          if (hScrollOnBottom) {
            widgetAreaBounds.y += scrollbarHeight;
          } else {
            widgetAreaBounds.y = 0;
          }
        }
        // Offset widget area x for vertical scrollbar.
        if (scrollY) {
          if (vScrollOnRight) {
            widgetAreaBounds.x = 0;
          } else {
            widgetAreaBounds.x += scrollbarWidth;
          }
        }
      }
    }

    // If the widget is smaller than the available space, make it take up the available space.
    widgetWidth = disableX ? width : Math.max(areaWidth, widgetWidth);
    widgetHeight = disableY ? height : Math.max(areaHeight, widgetHeight);

    maxX = widgetWidth - areaWidth;
    maxY = widgetHeight - areaHeight;
    if (fade) {
      // Make sure widget is drawn under fading scrollbars.
      if (scrollX) maxY -= scrollbarHeight;
      if (scrollY) maxX -= scrollbarWidth;
    }
    scrollX(MathUtils.clamp(amountX, 0, maxX));
    scrollY(MathUtils.clamp(amountY, 0, maxY));

    // Set the bounds and scroll knob sizes if scrollbars are needed.
    if (scrollX) {
      if (hScrollKnob != null) {
        float hScrollHeight =
            style.hScroll != null ? style.hScroll.getMinHeight() : hScrollKnob.getMinHeight();
        // the small gap where the two scroll bars intersect might have to flip from right to left
        float boundsX, boundsY;
        if (vScrollOnRight) {
          boundsX = bgLeftWidth;
        } else {
          boundsX = bgLeftWidth + scrollbarWidth;
        }
        // bar on the top or bottom
        if (hScrollOnBottom) {
          boundsY = bgBottomHeight;
        } else {
          boundsY = height - bgTopHeight - hScrollHeight;
        }
        hScrollBounds.set(boundsX, boundsY, areaWidth, hScrollHeight);
        hKnobBounds.width =
            Math.max(
                hScrollKnob.getMinWidth(), (int) (hScrollBounds.width * areaWidth / widgetWidth));
        hKnobBounds.height = hScrollKnob.getMinHeight();
        hKnobBounds.x =
            hScrollBounds.x
                + (int) ((hScrollBounds.width - hKnobBounds.width) * getScrollPercentX());
        hKnobBounds.y = hScrollBounds.y;
      } else {
        hScrollBounds.set(0, 0, 0, 0);
        hKnobBounds.set(0, 0, 0, 0);
      }
    }
    if (scrollY) {
      if (vScrollKnob != null) {
        float vScrollWidth =
            style.vScroll != null ? style.vScroll.getMinWidth() : vScrollKnob.getMinWidth();
        // the small gap where the two scroll bars intersect might have to flip from bottom to top
        float boundsX, boundsY;
        if (hScrollOnBottom) {
          boundsY = height - bgTopHeight - areaHeight;
        } else {
          boundsY = bgBottomHeight;
        }
        // bar on the left or right
        if (vScrollOnRight) {
          boundsX = width - bgRightWidth - vScrollWidth;
        } else {
          boundsX = bgLeftWidth;
        }
        vScrollBounds.set(boundsX, boundsY, vScrollWidth, areaHeight);
        vKnobBounds.width = vScrollKnob.getMinWidth();
        vKnobBounds.height =
            Math.max(
                vScrollKnob.getMinHeight(),
                (int) (vScrollBounds.height * areaHeight / widgetHeight));
        if (vScrollOnRight) {
          vKnobBounds.x = width - bgRightWidth - vScrollKnob.getMinWidth();
        } else {
          vKnobBounds.x = bgLeftWidth;
        }
        vKnobBounds.y =
            vScrollBounds.y
                + (int) ((vScrollBounds.height - vKnobBounds.height) * (1 - getScrollPercentY()));
      } else {
        vScrollBounds.set(0, 0, 0, 0);
        vKnobBounds.set(0, 0, 0, 0);
      }
    }

    widget.setSize(widgetWidth, widgetHeight);
    if (widget instanceof Layout) ((Layout) widget).validate();
  }
Example #14
0
  @Override
  public void render(float delta) {
    super.render(delta);

    if (incZoom != 0) {
      changeZoom(incZoom * delta);
    }

    camera.zoom = gameZoom;

    // TODO only calculate one? do not reset position of the cam when drawing hud? use different
    // cam?
    camera.position.x = player.getX() + player.getOriginX();
    camera.position.y = player.getY() + player.getOriginY();

    avaiableToLandOnThisFrame = null;
    if (player.life <= 0) {
      SpaceGame.screen(Res.gameover);
      // Gdx.app.exit(); // GAME OVER
    }

    // control the player via acceleration
    if (controls == ControlScheme.ACCELERATION) {
      if (Gdx.input.isPeripheralAvailable(Peripheral.Accelerometer)) {
        // TODO add option to switch axis and invert them
        float accelX = Gdx.input.getAccelerometerX();
        float accelY = Gdx.input.getAccelerometerY();
        Gdx.app.log("ACCELERATION", accelX + "," + accelY);
        player.speed = 200; // (float) Math.sqrt(accelX*accelX+accelY*accelY);
        player.angle = MathUtils.atan2(-accelX, accelY);
        // rotate the player acording to his angle
        player.setRotation(MathUtils.radDeg * player.angle - 90);
      }
    }

    player.act(getChunk(player.getX(), player.getY()), delta);

    // check if the player gets outside all loaded chunks
    checkChunks();

    // keep player inside the game field
    // if(player.getX()<0){player.setX(0);}else
    // if(player.getX()>chunk.width){player.setX(chunk.width);}
    // if(player.getY()<0){player.setY(0);}else
    // if(player.getY()>chunk.height){player.setY(chunk.height);}

    for (int i = 0; i < chunks.size(); i++) {
      chunks
          .get(i)
          .checkRemove(); // check wheter ships, shots or whatsoever have to be moved to another
      // chunk
    }
    for (int i = 0; i < chunks.size(); i++) {
      chunks.get(i).act(delta);
    }

    // System.out.println("chunks: "+chunks.size());

    // scrolling
    camera.position.x = player.getX() + player.getOriginX();
    camera.position.y = player.getY() + player.getOriginY();

    camera.update();
    camera.activate(batch);
    cameraRect.set(
        camera.position.x - camera.getWidth() / 2,
        camera.position.y - camera.getHeight() / 2,
        camera.getWidth(),
        camera.getHeight());

    batch.begin();
    batch.draw(
        background,
        camera.position.x - camera.getWidth() / 2,
        camera.position.y - camera.getHeight() / 2,
        camera.getWidth(),
        camera.getHeight());

    // draw only visible chunks
    for (int i = 0; i < chunks.size(); i++) {
      if (chunks.get(i).rect.overlaps(cameraRect)) {
        // this chunk is in the visible drawarea
        chunks.get(i).draw(cameraRect, batch);

        //// DEBUG
        // Resources.font.draw(batch, "chunk "+i, chunks.get(i).x,chunks.get(i).y+40);
      }
    }

    player.draw(batch, 1);

    // draw control-visuals
    if (psX != -1) {
      batch.draw(
          point_start,
          psX * camera.zoom + camera.position.x - 32,
          psY * camera.zoom + camera.position.y - 32);
      batch.draw(
          point_end,
          peX * camera.zoom + camera.position.x - 16,
          peY * camera.zoom + camera.position.y - 16);
    }

    for (int i = 0; i < marker.size(); i++) {
      marker.get(i).draw(cameraRect, batch);
    }
    batch.end();

    ///// DEBUG RENDERER /////
    /*	ShapeRenderer renderer=new ShapeRenderer();
    renderer.begin(ShapeType.Rectangle);
    renderer.setProjectionMatrix(camera.combined);
    renderer.setColor(255,0,0,10);
    for(int i=0;i<chunks.size();i++){
    	if(chunks.get(i).rect.overlaps(cameraRect)){
    		renderer.rect(chunks.get(i).x, chunks.get(i).y, Chunk.width, Chunk.height);
    	}
    }

    renderer.setColor(0,255,0,10);
    renderer.rect(camera.position.x-camera.getWidth()/2  +1 , camera.position.y-camera.getHeight()/2 +1, camera.getWidth()-2, camera.getHeight()-2);
    //for(float y=player.getY()-camera.getHeight()/2;y<player.getY()+camera.getHeight()/2;y+=Chunk.height){
    //	for(float x=player.getX()-camera.getWidth()/2;x<player.getX()+camera.getWidth()/2;x+=Chunk.width){


    renderer.setColor(0,0,255,10);
    for(float y=camera.position.y-camera.getHeight()/2 - Chunk.height ;y<camera.position.y+camera.getHeight()/2 +Chunk.height;y+=Chunk.height){
    	for(float x=camera.position.x-camera.getWidth()/2 - Chunk.width ;x<camera.position.x+camera.getWidth()/2 +Chunk.width;x+=Chunk.width){
    		if(getChunk(x, y)==null){
    			renderer.setColor(0,0,255,10);
    		}else{
    			renderer.setColor(0,0,0,10);
    		}
    		renderer.rect(x,y,Chunk.width,Chunk.height);
    	}
    }
    renderer.end();*/

    ///// HUD //////

    camera.position.x = 0;
    camera.position.y = 0;
    camera.zoom = guiZoom;
    camera.update();
    batch.setProjectionMatrix(camera.combined);
    batch.begin();
    int padding = 10;
    if (player.weapon.maxAmmo == -1) {
      Res.font.draw(batch, "ammo inf", -camera.getWidth() / 2 + padding, camera.getHeight() / 2);
    } else {
      Res.font.draw(
          batch,
          "ammo " + player.weapon.ammo,
          -camera.getWidth() / 2 + padding,
          camera.getHeight() / 2);
    }

    Res.font.drawWrapped(
        batch,
        "money: " + (int) player.money,
        -camera.getWidth() / 2,
        camera.getHeight() / 2,
        camera.getWidth() - padding,
        HAlignment.CENTER);

    //		Resources.font.drawWrapped(batch, "life "+(int)player.life,
    // -camera.getWidth()/2,camera.getHeight()/2,camera.getWidth()-padding,HAlignment.RIGHT);
    // a really cool life bar
    lifefill.setRegionWidth((int) (player.life * 2));
    batch.draw(
        lifefill,
        camera.getWidth() / 2 - 200 - padding,
        camera.getHeight() / 2 - 40,
        player.life * 2,
        32); // , originX, originY, width, height, scaleX, scaleY, rotation)

    batch.draw(
        lifeborder,
        camera.getWidth() / 2 - 200 - padding,
        camera.getHeight() / 2
            - 40); // , originX, originY, width, height, scaleX, scaleY, rotation)

    if (avaiableToLandOnThisFrame != null) {
      Res.font.drawWrapped(
          batch,
          "land on this planet",
          -camera.getWidth() / 2,
          -camera.getHeight() / 2 + 40,
          camera.getWidth() - padding,
          HAlignment.RIGHT);
    } else {
      batch.draw(switchWeapons, camera.getWidth() / 2 - 62, -camera.getHeight() / 2);
    }

    Res.font.drawWrapped(
        batch,
        "FPS " + Gdx.graphics.getFramesPerSecond(),
        padding - camera.getWidth() / 2,
        -camera.getHeight() / 2 + 40,
        camera.getWidth(),
        HAlignment.LEFT);

    batch.end();
  }
Example #15
0
  // TODO Comment
  private void updateBoxCulling(BoundingBox box) {
    Rectangle rectangle = box.rectangle;

    box.dataCount = 0;

    boolean initialized = false;
    for (int n = box.begin; n < box.begin + box.count; n++) {

      Array<Float> inside = vertexDataArray.items[n].insideVertexData;
      Array<Float> outside = vertexDataArray.items[n].outsideVertexData;

      if (!initialized) {
        if (inside.size > 0 && drawInside) {
          rectangle.set(inside.items[0], inside.items[1], 0, 0);
        } else if (outside.size > 0 && drawOutside) {
          rectangle.set(outside.items[0], outside.items[1], 0, 0);
        }

        if (closedPolygon || n > 0) {
          int k = (box.begin - 1 + vertices.size) % vertices.size;

          if (drawInside) {
            Array<Float> _inside = vertexDataArray.items[k].insideVertexData;
            for (int i = 0; i < _inside.size; i += 3) {
              rectangle.merge(_inside.items[i], _inside.items[i + 1]);
              box.dataCount++;
            }
          }

          if (drawOutside) {
            Array<Float> _outside = vertexDataArray.items[k].outsideVertexData;
            for (int i = 0; i < _outside.size; i += 3) {
              rectangle.merge(_outside.items[i], _outside.items[i + 1]);
              box.dataCount++;
            }
          }
        }

        if (closedPolygon || n < vertices.size) {
          int k = (box.begin + box.count + vertices.size) % vertices.size;

          if (drawInside) {
            Array<Float> _inside = vertexDataArray.items[k].insideVertexData;
            for (int i = 0; i < _inside.size; i += 3) {
              rectangle.merge(_inside.items[i], _inside.items[i + 1]);
              box.dataCount++;
            }
          }

          if (drawOutside) {
            Array<Float> _outside = vertexDataArray.items[k].outsideVertexData;
            for (int i = 0; i < _outside.size; i += 3) {
              rectangle.merge(_outside.items[i], _outside.items[i + 1]);
              box.dataCount++;
            }
          }
        }

        initialized = true;
      }

      if (drawInside)
        for (int i = 0; i < inside.size; i += 3) {
          rectangle.merge(inside.items[i], inside.items[i + 1]);
          box.dataCount++;
        }

      if (drawOutside)
        for (int i = 0; i < outside.size; i += 3) {
          rectangle.merge(outside.items[i], outside.items[i + 1]);
          box.dataCount++;
        }
    }
  }
Example #16
0
 @Override
 public void setView(Matrix4 projection, float x, float y, float width, float height) {
   spriteBatch.setProjectionMatrix(projection);
   viewBounds.set(x, y, width, height);
 }
Example #17
0
 public void update() {
   bounds.set(position.x, position.y, size.x, size.y);
 }
Example #18
0
 public void setBounds(float x, float y, float width, float height) {
   bounds.set(x, y, width, height);
 }
Example #19
0
 @Override
 public Rectangle getBounds(Rectangle bounds) {
   return bounds.set(this.bounds);
 }
  private void updateWorld() {
    float deltaTime = Gdx.graphics.getDeltaTime();
    planeStateTime += deltaTime;

    if (Gdx.input.justTouched()) {
      if (gameState == GameState.Start) {
        gameState = GameState.Running;
      }
      if (gameState == GameState.Running) {
        planeVelocity.set(PLANE_VELOCITY_X, PLANE_JUMP_IMPULSE);
      }
      if (gameState == GameState.GameOver) {
        gameState = GameState.Start;
        resetWorld();
      }
    }

    if (gameState != GameState.Start) planeVelocity.add(gravity);

    planePosition.mulAdd(planeVelocity, deltaTime);

    camera.position.x = planePosition.x + 350;
    if (camera.position.x - groundOffsetX > ground.getRegionWidth() + 400) {
      groundOffsetX += ground.getRegionWidth();
    }

    rect1.set(
        planePosition.x + 20,
        planePosition.y,
        plane.getKeyFrames()[0].getRegionWidth() - 20,
        plane.getKeyFrames()[0].getRegionHeight());
    for (Rock r : rocks) {
      if (camera.position.x - r.position.x > 400 + r.image.getRegionWidth()) {
        boolean isDown = MathUtils.randomBoolean();
        r.position.x += 5 * 200;
        r.position.y = isDown ? 480 - rock.getRegionHeight() : 0;
        r.image = isDown ? rockDown : rock;
        r.counted = false;
      }
      rect2.set(
          r.position.x + (r.image.getRegionWidth() - 30) / 2 + 20,
          r.position.y,
          20,
          r.image.getRegionHeight() - 10);
      if (rect1.overlaps(rect2)) {
        if (gameState != GameState.GameOver) explode.play();
        gameState = GameState.GameOver;
        planeVelocity.x = 0;
      }
      if (r.position.x < planePosition.x && !r.counted) {
        score++;
        r.counted = true;
      }
    }

    if (planePosition.y < ground.getRegionHeight() - 20
        || planePosition.y + plane.getKeyFrames()[0].getRegionHeight()
            > 480 - ground.getRegionHeight() + 20) {
      if (gameState != GameState.GameOver) explode.play();
      gameState = GameState.GameOver;
      planeVelocity.x = 0;
    }
  }