package com.amaya.game;
import com.amaya.game.entities.Fish;
import com.amaya.game.entities.Level;
import com.amaya.game.screens.BaseScreen;
import com.amaya.game.screens.GameOverScreen;
import com.amaya.game.screens.InfoScreen;
import com.amaya.game.screens.LevelScreen;
import com.amaya.game.screens.MenuScreen;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Rectangle;
import java.util.LinkedList;
import java.util.Random;
/**
* Class responsible for persistence of the current game state.
*
* @see <a href="https://github.com/libgdx/libgdx-demo-superjumper">Sample</a>
*/
public class Spacefish extends Game {
/* [ CONSTANTS ] ========================================================================================================================================= */
/** Logs Tag. */
public static final String LOG_TAG = "spacefish";
/* [ STATIC MEMBERS ] ==================================================================================================================================== */
/** Random numbers generator. */
private final static Random sRandom = new Random(System.currentTimeMillis());
/* [ MEMBERS ] =========================================================================================================================================== */
/** Reference on shape renderer that we using for debugging bounds. */
private ShapeRenderer mDebugShapes;
/** Drawing batching. */
private SpriteBatch mBatch;
/** Create entity of the Fish/user. */
private final Fish mFish = new Fish();
/** UI navigation backstack. */
private final LinkedList<BaseScreen> mUiStack = new LinkedList<BaseScreen>();
/* [ STATIC METHODS ] ==================================================================================================================================== */
public static int randomInt(final int max) {
return sRandom.nextInt(max);
}
public static float randomFloat(final float max) {
return sRandom.nextFloat() * max;
}
/* [ GETTER / SETTER METHODS ] =========================================================================================================================== */
public SpriteBatch getBatch() {
return mBatch;
}
public ShapeRenderer getDebugShapes() {
return mDebugShapes;
}
public Fish getFish() {
return mFish;
}
protected InfoScreen getInfo() {
return new InfoScreen(this);
}
protected LevelScreen getLevel() {
// use builder pattern for level configuration building.
final Level level = new Level.Builder()
.setTotalTime(45)
.randomize()
.build();
return new LevelScreen(this, level);
}
protected MenuScreen getMenu() {
return new MenuScreen(this);
}
protected GameOverScreen getGameOver() {
return new GameOverScreen(this);
}
/* [ Interface ApplicationListener ] ===================================================================================================================== */
@Override
public void create() {
mBatch = LibGdxFactory.getInstance().newSpriteBatch();
mDebugShapes = LibGdxFactory.getInstance().newShapeRenderer();
GameResources.getInstance().load();
navigateToMenu();
}
@Override
public void dispose() {
GameResources.getInstance().dispose();
}
/* [ IMPLEMENTATION & HELPERS ] ========================================================================================================================== */
public LinkedList<BaseScreen> getNavigationStack() {
return mUiStack;
}
public void navigateBack() {
if (Debug.UI_NAVIGATION)
Gdx.app.log(LOG_TAG, "[navigate] to previous screen");
// in back stack should stay at least one Screen
if (mUiStack.size() > 1) {
mUiStack.removeLast();
setScreen(mUiStack.getLast());
if (Debug.UI_NAVIGATION)
Gdx.app.log(LOG_TAG, "[navigate] to previous screen: " + mUiStack.getLast().getClass().getSimpleName());
}
}
public void navigateToInfo() {
if (Debug.UI_NAVIGATION)
Gdx.app.log(LOG_TAG, "[navigate] to 'Info'");
mUiStack.add(getInfo());
setScreen(mUiStack.getLast());
}
public void navigateToLevel() {
if (Debug.UI_NAVIGATION)
Gdx.app.log(LOG_TAG, "[navigate] to 'Game Level'");
mUiStack.add(getLevel());
setScreen(mUiStack.getLast());
}
public void navigateToMenu() {
if (Debug.UI_NAVIGATION)
Gdx.app.log(LOG_TAG, "[navigate] to 'Main Menu'");
mUiStack.add(getMenu());
setScreen(mUiStack.getLast());
}
public void navigateToGameOver() {
if (Debug.UI_NAVIGATION)
Gdx.app.log(LOG_TAG, "[navigate] to 'Game Over'");
// recreate navigation stack. From Game over screen we can return only to 'main menu'
mUiStack.clear();
mUiStack.add(getMenu());
mUiStack.add(getGameOver());
setScreen(mUiStack.getLast());
}
/* [ NESTED DECLARATIONS ] =============================================================================================================================== */
/** Dimensions used for game design. */
public interface Dimensions {
/** Width. Portrait game in virtual resolution: 320x480. */
int VIRTUAL_SCREEN_WIDTH = 320;
/** Height. Portrait game in virtual resolution: 320x480. */
int VIRTUAL_SCREEN_HEIGHT = 480;
/** Aspect ration: <code>0.6666f</code>. Portrait game in virtual resolution: 320x480. */
float VIRTUAL_ASPECT_RATIO = (float) VIRTUAL_SCREEN_WIDTH / (float) VIRTUAL_SCREEN_HEIGHT;
/** white space between several Menu Items. */
float DELIMITER = 20.0f;
/** smallest whitespace. */
float SPACE = 4.0f;
/** Width of the icon used for image buttons. */
float ICON_WIDTH = 32.0f;
/** Height of the icon used for image buttons. */
float ICON_HEIGHT = 32.0f;
/** Button Controls minimal padding. */
float ICON_PADDING = 16.0f;
/** fish entity width. */
float FISH_WIDTH = 64.0f;
/** fish entity height. */
float FISH_HEIGHT = 32.0f;
/** Calculations accuracy. */
float ACCURACY = 0.55f;
}
/** Debug switches, allow to disable or enable logs in specific module. */
public interface Debug {
/** dump strategy calculations. */
boolean STRATEGY_MOMENTUM = false;
/** dump strategy calculations. */
boolean STRATEGY_LINEAR = false;
/** dump strategy calculations. */
boolean STRATEGY_GRAVITY = false;
/** dump fish trajectory. */
boolean FISH_BEHAVIOR = false;
/** dump alien trajectory. */
boolean ALIEN_BEHAVIOR = false;
/** dump asteroid trajectory. */
boolean ASTEROID_BEHAVIOR = false;
/** dump level randomized numbers. */
boolean LEVEL_NUMBERS = false;
/** dump ui bounds. */
boolean UI_BOUNDS = false;
/** dump ui screens navigation. */
boolean UI_NAVIGATION = false;
/** dump level update strategy results. */
boolean LEVEL_DROPS = false;
/** dump ui clicks. */
boolean UI_CLICKS = false;
/** dump MoveToCommands creation. */
boolean MOVE_COMMANDS = false;
/** dump Move trajectory creation. */
boolean MOVE_TRAJECTORY = false;
/** dump run environment */
boolean ENVIRONMENT = false;
/** dump level state changes. */
boolean LEVEL_STATE = false;
/** dump any fish collisions. */
boolean FISH_COLLISIONS = false;
/** dump all expired commands processing. */
boolean EXPIRED_COMMANDS = true;
}
}