Java tutorial
/******************************************************************************* * Copyright 2014 Maciej 'dagon' Szewczyk www.dagondev.com * * 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.dagondev.drop; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; import com.badlogic.gdx.InputProcessor; import com.badlogic.gdx.Screen; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.g2d.Animation; import com.holidaystudios.tools.GifDecoder; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; public class MainMenuScreen implements Screen, InputProcessor { final DropGame game; OrthographicCamera camera; ArrayList<String> baseTextArray; ArrayList<String> rulesTextArray; ArrayList<String> creditsTextArray; ArrayList<Animation> animations; int baseWidth; int baseHeight; float stateTime; boolean moveToGame = false; boolean credits = false; static final String ANIM_PATH = ""; static final String FALL_OF_ARENA_NAME = ANIM_PATH + "test.gif"; static final String DEATH_FROM_ABOVE_NAME = ANIM_PATH + "test2.gif"; static final String RING_THE_SUN_NAME = ANIM_PATH + "test3.gif"; static final String MOVING_AND_DEATH_NAME = ANIM_PATH + "test4.gif"; static final int LINE_HEIGHT = 20; static final int LINE_WIDTH_START = 20; public MainMenuScreen(final DropGame gam, int baseWidth, int baseHeight) { game = gam; camera = new OrthographicCamera(); camera.setToOrtho(false, baseWidth, baseHeight); this.baseWidth = baseWidth; this.baseHeight = baseHeight; moveToGame = false; credits = false; Gdx.input.setInputProcessor(this); initializeText(); initializeAnimations(); } /** * Load all gifs from resources to convenient format for libgdx. */ private void initializeAnimations() { animations = new ArrayList<Animation>(); String[] anims = new String[] { FALL_OF_ARENA_NAME, DEATH_FROM_ABOVE_NAME, RING_THE_SUN_NAME, MOVING_AND_DEATH_NAME }; try { for (int i = 0; i < anims.length; i++) { InputStream inputStream = Gdx.files.internal(anims[i]).read(); GifDecoder gifDecoder = new GifDecoder(); if (gifDecoder.read(inputStream) == GifDecoder.STATUS_OK) { animations.add(gifDecoder.getAnimation(Animation.PlayMode.LOOP)); } inputStream.close(); } } catch (IOException e) { Gdx.app.error("initializeAnimations", e.getMessage()); } } /** * static creation of text. */ private void initializeText() { baseTextArray = new ArrayList<String>(); baseTextArray.add("Welcome to Drop!"); baseTextArray.add(""); baseTextArray.add( "Press Escape to exit game, F1 for credits and any other keyboard/mouse key to start the game."); baseTextArray.add(""); baseTextArray.add("Red player's movement controls: W (up), A (left), D (right)."); baseTextArray.add("Blue player's movement controls: Up, Left and Right Arrow keys."); baseTextArray.add(""); baseTextArray.add("There are three ways to win:"); rulesTextArray = new ArrayList<String>(); rulesTextArray.add("1. Push enemy off the arena"); rulesTextArray.add("2. Drop an object on top of the enemy"); rulesTextArray.add("3. Hit the ring on top of the arena"); creditsTextArray = new ArrayList<String>(); creditsTextArray.add("Credits:"); creditsTextArray.add(""); creditsTextArray.add("Drop:"); creditsTextArray .add("Drop is licensed under the Apache 2 License, meaning you can use it free of charge, "); creditsTextArray.add("without strings attached in commercial and non-commercial projects."); creditsTextArray.add(""); creditsTextArray.add("Copyright 2014 Maciej 'dagon' Szewczyk www.dagondev.com"); creditsTextArray.add(""); creditsTextArray.add("Used libraries:"); creditsTextArray.add("LibGDX, LWJGL, JBox2D, Box2DLights, RubeLoader, GifDecoder"); creditsTextArray.add(""); creditsTextArray.add( "Press Escape to exit game, F1 for credits and any other keyboard/mouse key to start the game."); } @Override public void render(float delta) { preRenderUpdate(delta); Gdx.gl.glClearColor(0, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); stateTime += Gdx.graphics.getDeltaTime(); //instead drawing this way like dirty peasant, make use of https://github.com/libgdx/libgdx/wiki/Scene2d if (credits) drawCredits(); else drawMainScreen(); postRenderUpdate(delta); } /** * handles rendering of credits text, shoudn`t be called with {@link #drawMainScreen()} at same time */ private void drawCredits() { int y = LINE_HEIGHT; int x = LINE_WIDTH_START; game.batch.begin(); for (String text : creditsTextArray) { game.font.draw(game.batch, text, x, baseHeight - y); y += LINE_HEIGHT; } game.batch.end(); } /** * handles rendering of main screen text and gifs, shoudn`t be called with {@link #drawCredits()} at same time */ private void drawMainScreen() { int y = LINE_HEIGHT; int x = LINE_WIDTH_START; game.batch.begin(); for (String text : baseTextArray) { game.font.draw(game.batch, text, x, baseHeight - y); y += LINE_HEIGHT; } y += LINE_HEIGHT; int i = 0; int oldX = x; for (String rule : rulesTextArray) { if (animations.size() <= i) { game.batch.end(); return; } Animation animation = animations.get(i); game.font.draw(game.batch, rule, x, baseHeight - y); game.batch.draw(animation.getKeyFrame(stateTime), x, baseHeight - (y + LINE_HEIGHT + animation.getKeyFrame(0).getRegionHeight())); x += baseWidth / 3; i++; } //draw last animation with text x = oldX; Animation lastAnimation = animations.get(animations.size() - 1); y += LINE_HEIGHT; y += animations.get(0).getKeyFrame(0).getRegionHeight() * 1.5; game.font.draw(game.batch, "Use slopes to get in the air or on the higher ledges.", x, baseHeight - y); y += LINE_HEIGHT * 2; game.font.draw(game.batch, "Watch out for other obstacles, they can stomp on you as well as you on them!", x, baseHeight - y); y -= LINE_HEIGHT * 2; y -= animations.get(0).getKeyFrame(0).getRegionHeight() * 0.5; x = LINE_WIDTH_START + baseWidth - baseWidth / 3; game.batch.draw(lastAnimation.getKeyFrame(stateTime), x, baseHeight - (y + LINE_HEIGHT + lastAnimation.getKeyFrame(0).getRegionHeight())); game.batch.end(); } /** * Handles logic that should be handled before any rendering stuff happens * @param delta */ private void preRenderUpdate(float delta) { camera.update(); } /** * Handles logic that should be handled after any rendering stuff happens. * In this scenario that means after any other game logic. * @param delta */ private void postRenderUpdate(float delta) { //this must be on the end of game loop because dispose can only be called when nothing is in use. if (!moveToGame) return; game.setScreen(new GameScreen(game, baseWidth, baseHeight)); dispose(); } @Override public void resize(int width, int height) { //stage.getViewport().update(width, height, true); } @Override public void show() { } @Override public void hide() { } @Override public void pause() { } @Override public void resume() { } @Override public void dispose() { } @Override public boolean keyDown(int keycode) { return false; } @Override public boolean keyUp(int keycode) { if (keycode == Input.Keys.F1) credits = !credits; else if (keycode != Input.Keys.ESCAPE) moveToGame = true; else Gdx.app.exit(); return false; } @Override public boolean keyTyped(char character) { return false; } @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { return false; } @Override public boolean touchUp(int screenX, int screenY, int pointer, int button) { moveToGame = true; return false; } @Override public boolean touchDragged(int screenX, int screenY, int pointer) { return false; } @Override public boolean mouseMoved(int screenX, int screenY) { return false; } @Override public boolean scrolled(int amount) { return false; } }