com.gamejolt.mikykr5.ceidecpong.GameCore.java Source code

Java tutorial

Introduction

Here is the source code for com.gamejolt.mikykr5.ceidecpong.GameCore.java

Source

/*
 * Copyright (c) 2014, Miguel Angel Astor Romero
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer. 
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * Read the LICENSE file for more details.
 */
package com.gamejolt.mikykr5.ceidecpong;

import aurelienribon.tweenengine.Tween;
import aurelienribon.tweenengine.TweenEquations;
import aurelienribon.tweenengine.primitives.MutableFloat;

import com.badlogic.gdx.Application;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.gamejolt.mikykr5.ceidecpong.interfaces.AssetsLoadedListener;
import com.gamejolt.mikykr5.ceidecpong.states.BaseState;
import com.gamejolt.mikykr5.ceidecpong.states.InGameState;
import com.gamejolt.mikykr5.ceidecpong.states.LoadingState;
import com.gamejolt.mikykr5.ceidecpong.states.LogoScreenState;
import com.gamejolt.mikykr5.ceidecpong.states.MainMenuState;
import com.gamejolt.mikykr5.ceidecpong.utils.AsyncAssetLoader;

/**
 * This is the central class of the Game. It is in charge of maintaining the game's
 * life cycle and switching between the different application states. It also renders
 * the fade effects when switching states.
 * 
 * @author Miguel Astor
 */
public class GameCore extends Game {
    /**
     * Tag used for logging.
     */
    private static final String TAG = "GAME_CORE";

    /**
     * Class name used for logging.
     */
    private static final String CLASS_NAME = GameCore.class.getSimpleName();

    /**
     * An enumerated type used for state switching.
     */
    public enum game_states_t {
        LOGO_SCREEN(0), MAIN_MENU(1), IN_GAME(2), QUIT(3), LOADING(4);

        private int value;

        private game_states_t(int value) {
            this.value = value;
        }

        public int getValue() {
            return this.value;
        }

        public static int getNumStates() {
            return 5;
        }
    };

    /**
     * A pointer to the currently active state.
     */
    private game_states_t currState;

    /**
     * A pointer to the state to switch to. Usually null.
     */
    public game_states_t nextState;

    /**
     * An array to hold all application states.
     */
    private BaseState[] states;

    /**
     * The {@link SpriteBatch} used to render all 2D graphics in the game.
     */
    public SpriteBatch batch;

    /**
     * A pixel perfect camera used to render the fade effects.
     */
    private OrthographicCamera pixelPerfectCamera;

    // Fade in/out effect fields.
    /**
     * The fade graphic.
     */
    private Texture fadeTexture;

    /**
     * A {@link MutableFloat} used to interpolate the transparency of {@link GameCore#fadeTexture}.
     */
    private MutableFloat alpha;

    /**
     * A {@link Tween} instance used to interpolate between full transparency to no transparency.
     */
    private Tween fadeOut;

    /**
     * A {@link Tween} instance used to interpolate between no transparency to full transparency.
     */
    private Tween fadeIn;

    /**
     * A flag to indicate that a fade effect is in progress.
     */
    private boolean fading;

    @Override
    public void create() {
        AsyncAssetLoader loader = AsyncAssetLoader.getInstance();

        // Set up rendering fields and settings.
        ShaderProgram.pedantic = false; // Not passing all variables to a shader will not close the game.
        batch = new SpriteBatch();
        batch.enableBlending();
        batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
        pixelPerfectCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

        // Prepare the fading effect.
        Pixmap pixmap = new Pixmap(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), Format.RGBA4444);
        pixmap.setColor(0, 0, 0, 1);
        pixmap.fill();
        fadeTexture = new Texture(pixmap);
        pixmap.dispose();

        // Create the initial interpolators and start with a fade in effect.
        alpha = new MutableFloat(1.0f);
        fadeOut = Tween.to(alpha, 0, 0.5f).target(1.0f).ease(TweenEquations.easeInQuint);
        fadeIn = Tween.to(alpha, 0, 2.5f).target(0.0f).ease(TweenEquations.easeInQuint);
        fadeIn.start();
        fading = true;

        // Create application states.
        states = new BaseState[game_states_t.getNumStates()];

        try {
            states[game_states_t.LOGO_SCREEN.getValue()] = new LogoScreenState(this);
            states[game_states_t.MAIN_MENU.getValue()] = new MainMenuState(this);
            states[game_states_t.IN_GAME.getValue()] = new InGameState(this);
            states[game_states_t.LOADING.getValue()] = new LoadingState(this);
            states[game_states_t.QUIT.getValue()] = null;
        } catch (IllegalArgumentException e) {
            Gdx.app.error(TAG, CLASS_NAME + ".create(): Illegal argument caught creating states: ", e);
            System.exit(1);
            return;
        }

        // Register every state as an AssetsLoadedListener if the state implements the interface.
        for (BaseState state : states) {
            if (state != null && state instanceof AssetsLoadedListener)
                loader.addListener((AssetsLoadedListener) state);
        }
        AsyncAssetLoader.freeInstance();
        loader = null;

        // Set the initial current and next states.
        currState = game_states_t.LOGO_SCREEN;
        nextState = null;
        this.setScreen(states[currState.getValue()]);

        // Set log level
        if (ProjectConstants.DEBUG) {
            Gdx.app.setLogLevel(Application.LOG_DEBUG);
        } else {
            Gdx.app.setLogLevel(Application.LOG_NONE);
        }
    }

    @Override
    public void render() {
        super.render();

        // If the current state set a value for nextState then switch to that state.
        if (nextState != null) {
            // First disable the current state so that it will no longer catch user inputs.
            states[currState.getValue()].onStateDisabled();

            if (!fadeOut.isStarted()) {
                // Start the fade out effect.
                fadeOut.start();
                fading = true;
            } else {
                // Update the fade out effect.
                fadeOut.update(Gdx.graphics.getDeltaTime());

                // When the fade out effect finishes, change to the requested state and launch the fade in effect.
                if (fadeOut.isFinished()) {
                    // Change to the requested state.
                    if (nextState != game_states_t.QUIT) {
                        currState = nextState;
                        nextState = null;
                        //states[currState.getValue()].onStateEnabled();
                        setScreen(states[currState.getValue()]);
                    } else {
                        nextState = null;
                        Gdx.app.exit();
                    }

                    // Reset the fade out effect and launch the fade in.
                    fadeOut.free();
                    fadeOut = Tween.to(alpha, 0, 0.5f).target(1.0f).ease(TweenEquations.easeInQuint);
                    fadeIn.start();
                }
            }
        }

        // If there is a fade in effect in progress.
        if (fadeIn.isStarted()) {
            if (!fadeIn.isFinished()) {
                // Update it until finished.
                fadeIn.update(Gdx.graphics.getDeltaTime());
            } else {
                // Stop and reset it when done.
                fading = false;
                fadeIn.free();
                fadeIn = Tween.to(alpha, 0, 0.5f).target(0.0f).ease(TweenEquations.easeInQuint);
                states[currState.getValue()].onStateEnabled();
            }
        }

        // Render the fading sprite with alpha blending.
        if (fading) {
            batch.setProjectionMatrix(pixelPerfectCamera.combined);
            batch.begin();
            {
                batch.setColor(1, 1, 1, alpha.floatValue());
                batch.draw(fadeTexture, -(Gdx.graphics.getWidth() / 2), -(Gdx.graphics.getHeight() / 2));
                batch.setColor(1, 1, 1, 1);
            }
            batch.end();
        }
    }

    @Override
    public void dispose() {
        super.dispose();

        // Dispose all states.
        for (BaseState state : states) {
            if (state != null)
                state.dispose();
        }

        // Dispose other graphics.
        fadeTexture.dispose();
        batch.dispose();
    }
}