Java tutorial
/******************************************************************************* * Copyright 2013 Andreas Oehlke * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.packtpub.libgdx.canyonbunny.game; import com.badlogic.gdx.Application.ApplicationType; import com.badlogic.gdx.Game; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.InputAdapter; import com.badlogic.gdx.math.Rectangle; import com.packtpub.libgdx.canyonbunny.game.objects.BunnyHead; import com.packtpub.libgdx.canyonbunny.game.objects.BunnyHead.JUMP_STATE; import com.packtpub.libgdx.canyonbunny.game.objects.Feather; import com.packtpub.libgdx.canyonbunny.game.objects.GoldCoin; import com.packtpub.libgdx.canyonbunny.game.objects.Rock; import com.packtpub.libgdx.canyonbunny.screens.MenuScreen; import com.packtpub.libgdx.canyonbunny.util.CameraHelper; import com.packtpub.libgdx.canyonbunny.util.Constants; public class WorldController extends InputAdapter { private static final String TAG = WorldController.class.getName(); private Game game; public Level level; public int lives; public float livesVisual; public int score; public float scoreVisual; public CameraHelper cameraHelper; // Rectangles for collision detection private Rectangle r1 = new Rectangle(); private Rectangle r2 = new Rectangle(); private float timeLeftGameOverDelay; public WorldController(Game game) { this.game = game; init(); } private void init() { Gdx.input.setInputProcessor(this); cameraHelper = new CameraHelper(); lives = Constants.LIVES_START; livesVisual = lives; timeLeftGameOverDelay = 0; initLevel(); } private void initLevel() { score = 0; scoreVisual = score; level = new Level(Constants.LEVEL_01); cameraHelper.setTarget(level.bunnyHead); } public void update(float deltaTime) { handleDebugInput(deltaTime); if (isGameOver()) { timeLeftGameOverDelay -= deltaTime; if (timeLeftGameOverDelay < 0) backToMenu(); } else { handleInputGame(deltaTime); } level.update(deltaTime); testCollisions(); cameraHelper.update(deltaTime); if (!isGameOver() && isPlayerInWater()) { lives--; if (isGameOver()) timeLeftGameOverDelay = Constants.TIME_DELAY_GAME_OVER; else initLevel(); } level.mountains.updateScrollPosition(cameraHelper.getPosition()); if (livesVisual > lives) livesVisual = Math.max(lives, livesVisual - 1 * deltaTime); if (scoreVisual < score) scoreVisual = Math.min(score, scoreVisual + 250 * deltaTime); } public boolean isGameOver() { return lives < 0; } public boolean isPlayerInWater() { return level.bunnyHead.position.y < -5; } private void testCollisions() { r1.set(level.bunnyHead.position.x, level.bunnyHead.position.y, level.bunnyHead.bounds.width, level.bunnyHead.bounds.height); // Test collision: Bunny Head <-> Rocks for (Rock rock : level.rocks) { r2.set(rock.position.x, rock.position.y, rock.bounds.width, rock.bounds.height); if (!r1.overlaps(r2)) continue; onCollisionBunnyHeadWithRock(rock); // IMPORTANT: must do all collisions for valid edge testing on // rocks. } // Test collision: Bunny Head <-> Gold Coins for (GoldCoin goldcoin : level.goldcoins) { if (goldcoin.collected) continue; r2.set(goldcoin.position.x, goldcoin.position.y, goldcoin.bounds.width, goldcoin.bounds.height); if (!r1.overlaps(r2)) continue; onCollisionBunnyWithGoldCoin(goldcoin); break; } // Test collision: Bunny Head <-> Feathers for (Feather feather : level.feathers) { if (feather.collected) continue; r2.set(feather.position.x, feather.position.y, feather.bounds.width, feather.bounds.height); if (!r1.overlaps(r2)) continue; onCollisionBunnyWithFeather(feather); break; } } private void onCollisionBunnyHeadWithRock(Rock rock) { BunnyHead bunnyHead = level.bunnyHead; float heightDifference = Math.abs(bunnyHead.position.y - (rock.position.y + rock.bounds.height)); if (heightDifference > 0.25f) { boolean hitRightEdge = bunnyHead.position.x > (rock.position.x + rock.bounds.width / 2.0f); if (hitRightEdge) { bunnyHead.position.x = rock.position.x + rock.bounds.width; } else { bunnyHead.position.x = rock.position.x - bunnyHead.bounds.width; } return; } switch (bunnyHead.jumpState) { case GROUNDED: break; case FALLING: case JUMP_FALLING: bunnyHead.position.y = rock.position.y + bunnyHead.bounds.height + bunnyHead.origin.y; bunnyHead.jumpState = JUMP_STATE.GROUNDED; break; case JUMP_RISING: bunnyHead.position.y = rock.position.y + bunnyHead.bounds.height + bunnyHead.origin.y; break; } } private void onCollisionBunnyWithGoldCoin(GoldCoin goldcoin) { goldcoin.collected = true; score += goldcoin.getScore(); Gdx.app.log(TAG, "Gold coin collected"); } private void onCollisionBunnyWithFeather(Feather feather) { feather.collected = true; score += feather.getScore(); level.bunnyHead.setFeatherPowerup(true); Gdx.app.log(TAG, "Feather collected"); } private void handleDebugInput(float deltaTime) { if (Gdx.app.getType() != ApplicationType.Desktop) return; if (!cameraHelper.hasTarget(level.bunnyHead)) { // Camera Controls (move) float camMoveSpeed = 5 * deltaTime; float camMoveSpeedAccelerationFactor = 5; if (Gdx.input.isKeyPressed(Keys.SHIFT_LEFT)) camMoveSpeed *= camMoveSpeedAccelerationFactor; if (Gdx.input.isKeyPressed(Keys.LEFT)) moveCamera(-camMoveSpeed, 0); if (Gdx.input.isKeyPressed(Keys.RIGHT)) moveCamera(camMoveSpeed, 0); if (Gdx.input.isKeyPressed(Keys.UP)) moveCamera(0, camMoveSpeed); if (Gdx.input.isKeyPressed(Keys.DOWN)) moveCamera(0, -camMoveSpeed); if (Gdx.input.isKeyPressed(Keys.BACKSPACE)) cameraHelper.setPosition(0, 0); } // Camera Controls (zoom) float camZoomSpeed = 1 * deltaTime; float camZoomSpeedAccelerationFactor = 5; if (Gdx.input.isKeyPressed(Keys.SHIFT_LEFT)) camZoomSpeed *= camZoomSpeedAccelerationFactor; if (Gdx.input.isKeyPressed(Keys.COMMA)) cameraHelper.addZoom(camZoomSpeed); if (Gdx.input.isKeyPressed(Keys.PERIOD)) cameraHelper.addZoom(-camZoomSpeed); if (Gdx.input.isKeyPressed(Keys.SLASH)) cameraHelper.setZoom(1); } private void handleInputGame(float deltaTime) { if (cameraHelper.hasTarget(level.bunnyHead)) { // Player Movement if (Gdx.input.isKeyPressed(Keys.LEFT)) { level.bunnyHead.velocity.x = -level.bunnyHead.terminalVelocity.x; } else if (Gdx.input.isKeyPressed(Keys.RIGHT)) { level.bunnyHead.velocity.x = level.bunnyHead.terminalVelocity.x; } else { // Execute auto-forward movement on non-desktop platform if (Gdx.app.getType() != ApplicationType.Desktop) { level.bunnyHead.velocity.x = level.bunnyHead.terminalVelocity.x; } } // Bunny Jump if (Gdx.input.isTouched() || Gdx.input.isKeyPressed(Keys.SPACE)) level.bunnyHead.setJumping(true); else level.bunnyHead.setJumping(false); } } private void moveCamera(float x, float y) { x += cameraHelper.getPosition().x; y += cameraHelper.getPosition().y; cameraHelper.setPosition(x, y); } @Override public boolean keyUp(int keycode) { // Reset game world if (keycode == Keys.R) { init(); Gdx.app.debug(TAG, "Game world resetted"); } // Toggle camera follow else if (keycode == Keys.ENTER) { cameraHelper.setTarget(cameraHelper.hasTarget() ? null : level.bunnyHead); Gdx.app.debug(TAG, "Camera follow enabled: " + cameraHelper.hasTarget()); } // Back to Menu else if (keycode == Keys.ESCAPE || keycode == Keys.BACK) { backToMenu(); } return false; } private void backToMenu() { // switch to menu screen game.setScreen(new MenuScreen(game)); } }