com.group6.penguinsgame.DemoMap.java Source code

Java tutorial

Introduction

Here is the source code for com.group6.penguinsgame.DemoMap.java

Source

package com.group6.penguinsgame;

/**
 *   Copyright 2013 Aaron Horn aaron@cs.txstate.edu
 *
 *   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.
 * 
 * Source:
 * 
 */

//import aurelienribon.bodyeditor.BodyEditorLoader;

import aurelienribon.bodyeditor.BodyEditorLoader;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.me.mypenguins.screens.TiledMapHelper;

public class DemoMap implements ApplicationListener {
    /**
     * The time the last frame was rendered, used for throttling framerate
     */
    private long lastRender;
    private static final float JUMPER_WIDTH = 8;
    private TiledMapHelper tiledMapHelper;
    private Vector2 jumperModelOrigin;

    /**
     * Holder of the texture for the various non-map sprites the game will have.
     */
    private Texture overallTexture;

    /**
     * As the name implies, this is the sprite for the jumper character. The
     * boolean is just to track which direction the jumper is facing. There are
     * better ways to handle this, but in a real game you would handle the
     * character sprite a lot differently (with animations and all that) so
     * let's call that outside the scope of this example.
     */
    private Sprite jumperSprite;
    private boolean jumperFacingRight;

    /**
     * The libgdx SpriteBatch -- used to optimize sprite drawing.
     */
    private SpriteBatch spriteBatch;

    /**
     * This is the main box2d "container" object. All bodies will be loaded in
     * this object and will be simulated through calls to this object.
     */
    private World world;
    private Body jumperModel;

    /**
     * This is the player character. It will be created as a dynamic object.
     */
    private Body jumper;

    /**
     * This box2d debug renderer comes from libgdx test code. It draws lines
     * over all collision boundaries, so it is immensely useful for verifying
     * that the world collisions are as you expect them to be. It is, however,
     * slow, so only use it for testing.
     */
    private Box2DDebugRenderer debugRenderer;

    /**
     * Box2d works best with small values. If you use pixels directly you will
     * get weird results -- speeds and accelerations not feeling quite right.
     * Common practice is to use a constant to convert pixels to and from
     * "meters".
     */
    public static final float PIXELS_PER_METER = 60.0f;

    /**
     * The screen's width and height. This may not match that computed by
     * libgdx's gdx.graphics.getWidth() / getHeight() on devices that make use
     * of on-screen menu buttons.
     */
    private int screenWidth;
    private int screenHeight;

    public DemoMap() {
        super();

        // Defer until create() when Gdx is initialized.
        screenWidth = -1;
        screenHeight = -1;
    }

    public DemoMap(int width, int height) {
        super();

        screenWidth = width;
        screenHeight = height;
    }

    @Override
    public void create() {
        /**
         * If the viewport's size is not yet known, determine it here.
         */
        if (screenWidth == -1) {
            screenWidth = Gdx.graphics.getWidth();
            screenHeight = Gdx.graphics.getHeight();
        }

        tiledMapHelper = new TiledMapHelper();

        tiledMapHelper = new TiledMapHelper();

        tiledMapHelper.setPackerDirectory("data/packer");

        tiledMapHelper.loadMap("data/world/level1/level.tmx");

        tiledMapHelper.prepareCamera(screenWidth, screenHeight);

        /**
         * Load up the overall texture and chop it in to pieces. In this case,
         * piece.
         */
        overallTexture = new Texture(Gdx.files.internal("data/sprite.png"));
        overallTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);

        jumperSprite = new Sprite(overallTexture, 0, 0, 31, 37);

        spriteBatch = new SpriteBatch();

        /**
         * You can set the world's gravity in its constructor. Here, the gravity
         * is negative in the y direction (as in, pulling things down).
         */
        // 0. Create a loader for the file saved from the editor.
        // needs work
        BodyEditorLoader loader = new BodyEditorLoader("data/penFig.json");

        world = new World(new Vector2(0.0f, -10.0f), true);

        // 1. Create a BodyDef, as usual.
        BodyDef jumperBodyDef = new BodyDef();//BodyDef bd = new BodyDef();
        jumperBodyDef.type = BodyDef.BodyType.DynamicBody;//bd.type = BodyType.DynamicBody;
        jumperBodyDef.position.set(5.0f, 5.0f);//bd.position.set(0, 0);

        jumper = world.createBody(jumperBodyDef);

        /**
         * Boxes are defined by their "half width" and "half height", hence the
         * 2 multiplier.
         */
        PolygonShape jumperShape = new PolygonShape();
        jumperShape.setAsBox(jumperSprite.getWidth() / (2 * PIXELS_PER_METER),
                jumperSprite.getHeight() / (2 * PIXELS_PER_METER));

        /**
         * The character should not ever spin around on impact.
         */
        jumper.setFixedRotation(true);

        /**
         * The density and friction of the jumper were found experimentally.
         * Play with the numbers and watch how the character moves faster or
         * slower.
         */

        // 2. Create a FixtureDef, as usual.
        FixtureDef jumperFixtureDef = new FixtureDef();//FixtureDef fd = new FixtureDef();
        jumperFixtureDef.shape = jumperShape;
        jumperFixtureDef.density = 0.1f;//fd.density = 1;
        jumperFixtureDef.friction = 2.0f;//fd.friction = 0.5f;
        //fd.restitution = 0.3f;

        // 3. Create a Body, as usual.
        //jumperModel = world.createBody(jumperBodyDef);
        jumper.createFixture(jumperFixtureDef);
        jumperShape.dispose();

        tiledMapHelper.loadCollisions("data/collisions.txt", world, PIXELS_PER_METER);

        // 4. Create the body fixture automatically by using the loader.
        //needs work
        //loader.attachFixture(jumperModel, "test01", jumperFixtureDef, JUMPER_WIDTH);
        //jumperModelOrigin = loader.getOrigin("test01", JUMPER_WIDTH).cpy();

        debugRenderer = new Box2DDebugRenderer();

        lastRender = System.nanoTime();
    }

    @Override
    public void resume() {
    }

    @Override
    public void render() {
        long now = System.nanoTime();
        //Vector2 bottlePos = jumperModel.getPosition().sub(jumperModelOrigin);

        /**
         * Detect requested motion.
         */
        boolean moveLeft = false;
        boolean moveRight = false;
        boolean doJump = false;

        if (Gdx.input.isKeyPressed(Input.Keys.DPAD_RIGHT)) {
            moveRight = true;
        } else {
            for (int i = 0; i < 2; i++) {
                if (Gdx.input.isTouched(i) && Gdx.input.getX() > Gdx.graphics.getWidth() * 0.80f) {
                    moveRight = true;
                }
            }
        }

        if (Gdx.input.isKeyPressed(Input.Keys.DPAD_LEFT)) {
            moveLeft = true;
        } else {
            for (int i = 0; i < 2; i++) {
                if (Gdx.input.isTouched(i) && Gdx.input.getX() < Gdx.graphics.getWidth() * 0.20f) {
                    moveLeft = true;
                }
            }
        }

        if (Gdx.input.isKeyPressed(Input.Keys.DPAD_UP)) {
            doJump = true;
        } else {
            for (int i = 0; i < 2; i++) {
                if (Gdx.input.isTouched(i) && Gdx.input.getY() < Gdx.graphics.getHeight() * 0.20f) {
                    doJump = true;
                }
            }
        }

        /**
         * Act on that requested motion.
         * 
         * This code changes the jumper's direction. It's handled separately
         * from the jumping so that the player can jump and move simultaneously.
         * The horizontal figure was arrived at experimentally -- try other
         * values to experience different speeds.
         * 
         * The impulses are applied to the center of the jumper.
         */
        if (moveRight) {
            jumper.applyLinearImpulse(new Vector2(0.05f, 0.0f), jumper.getWorldCenter());
            if (jumperFacingRight == false) {
                jumperSprite.flip(true, false);
            }
            jumperFacingRight = true;
        } else if (moveLeft) {
            jumper.applyLinearImpulse(new Vector2(-0.05f, 0.0f), jumper.getWorldCenter());
            if (jumperFacingRight == true) {
                jumperSprite.flip(true, false);
            }
            jumperFacingRight = false;
        }

        /**
         * The jumper dude can only jump while on the ground. There are better
         * ways to detect ground contact, but for our purposes it is sufficient
         * to test that the vertical velocity is zero (or close to it). As in
         * the above code, the vertical figure here was found through
         * experimentation. It's enough to get the guy off the ground.
         * 
         * As before, impulse is applied to the center of the jumper.
         */
        if (doJump && Math.abs(jumper.getLinearVelocity().y) < 1e-9) {
            jumper.applyLinearImpulse(new Vector2(0.0f, 0.8f), jumper.getWorldCenter());
        }

        /**
         * Have box2d update the positions and velocities (and etc) of all
         * tracked objects. The second and third argument specify the number of
         * iterations of velocity and position tests to perform -- higher is
         * more accurate but is also slower.
         */
        world.step(Gdx.app.getGraphics().getDeltaTime(), 3, 3);

        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        /**
         * A nice(?), blue backdrop.
         */
        Gdx.gl.glClearColor(0, 0.5f, 0.9f, 0);

        /**
         * The camera is now controlled primarily by the position of the main
         * character, and secondarily by the map boundaries.
         */

        tiledMapHelper.getCamera().position.x = PIXELS_PER_METER * jumper.getPosition().x;

        /**
         * Ensure that the camera is only showing the map, nothing outside.
         */
        if (tiledMapHelper.getCamera().position.x < Gdx.graphics.getWidth() / 2) {
            tiledMapHelper.getCamera().position.x = Gdx.graphics.getWidth() / 2;
        }
        if (tiledMapHelper.getCamera().position.x >= tiledMapHelper.getWidth() - Gdx.graphics.getWidth() / 2) {
            tiledMapHelper.getCamera().position.x = tiledMapHelper.getWidth() - Gdx.graphics.getWidth() / 2;
        }

        if (tiledMapHelper.getCamera().position.y < Gdx.graphics.getHeight() / 2) {
            tiledMapHelper.getCamera().position.y = Gdx.graphics.getHeight() / 2;
        }
        if (tiledMapHelper.getCamera().position.y >= tiledMapHelper.getHeight() - Gdx.graphics.getHeight() / 2) {
            tiledMapHelper.getCamera().position.y = tiledMapHelper.getHeight() - Gdx.graphics.getHeight() / 2;
        }

        tiledMapHelper.getCamera().update();
        tiledMapHelper.render();

        /**
         * Prepare the SpriteBatch for drawing.
         */
        spriteBatch.setProjectionMatrix(tiledMapHelper.getCamera().combined);
        spriteBatch.begin();

        jumperSprite.setPosition(PIXELS_PER_METER * jumper.getPosition().x - jumperSprite.getWidth() / 2,
                PIXELS_PER_METER * jumper.getPosition().y - jumperSprite.getHeight() / 2);
        jumperSprite.draw(spriteBatch);

        /**
         * "Flush" the sprites to screen.
         */
        spriteBatch.end();

        /**
         * Draw this last, so we can see the collision boundaries on top of the
         * sprites and map.
         */
        debugRenderer.render(world, tiledMapHelper.getCamera().combined.scale(DemoMap.PIXELS_PER_METER,
                DemoMap.PIXELS_PER_METER, DemoMap.PIXELS_PER_METER));

        now = System.nanoTime();
        if (now - lastRender < 30000000) { // 30 ms, ~33FPS
            try {
                Thread.sleep(30 - (now - lastRender) / 1000000);
            } catch (InterruptedException e) {
            }
        }

        lastRender = now;
    }

    @Override
    public void resize(int width, int height) {
    }

    @Override
    public void pause() {
    }

    @Override
    public void dispose() {
    }
}