diff --git a/core/src/com/gamejolt/mikykr5/ceidecpong/states/LoadingState.java b/core/src/com/gamejolt/mikykr5/ceidecpong/states/LoadingState.java index 2cf134e..db47791 100644 --- a/core/src/com/gamejolt/mikykr5/ceidecpong/states/LoadingState.java +++ b/core/src/com/gamejolt/mikykr5/ceidecpong/states/LoadingState.java @@ -26,20 +26,52 @@ import com.gamejolt.mikykr5.ceidecpong.effects.ScrollingBackground; import com.gamejolt.mikykr5.ceidecpong.utils.AsyncAssetLoader; import com.gamejolt.mikykr5.ceidecpong.utils.managers.CachedFontManager; +/** + * A state that shows a loading screen and updates the {@link AsyncAssetLoader}. + * + * @author Miguel Astor + */ public class LoadingState extends BaseState{ - // Helper fields. + /** + * The {@link AsyncAssetLoader} instance that must be updated. + */ private AsyncAssetLoader loader; + + /** + * An instance of the {@link CachedFontManager} used to render the loading screen. + */ private CachedFontManager fontManager; + + /** + * A time counter to avoid changing this state too quickly. + */ private float timeSinceShown; + + /** + * A flag to indicate that this state is finished. + */ private boolean loadingDone; - // Graphic data. + /** + * The {@link BitmapFont} used to render the loading screen. + */ private BitmapFont font; + + /** + * A {@link ScrollingBackground} effect to make things livelier. + */ private ScrollingBackground scrollingBckg; + /** + * Creates the loading screen. + * + * @param core A game core. See {@link BaseState#BaseState(GameCore)} for details. + * @throws IllegalArgumentException If core is null. + */ public LoadingState(final GameCore core) throws IllegalArgumentException{ super(core); + // Get the singleton instances. loader = AsyncAssetLoader.getInstance(); fontManager = CachedFontManager.getInstance(); @@ -49,6 +81,7 @@ public class LoadingState extends BaseState{ // Set up the background. scrollingBckg = new ScrollingBackground("data/gfx/textures/floortiles.png", false); + // Set the flags. stateEnabled = false; loadingDone = false; } @@ -67,20 +100,25 @@ public class LoadingState extends BaseState{ core.batch.setProjectionMatrix(pixelPerfectCamera.combined); core.batch.begin();{ - // Render background. + // Render the background. scrollingBckg.render(core.batch); font.setColor(Color.BLACK); font.draw(core.batch, "Loading", -(bounds.width / 2), -(bounds.height / 2)); - }core.batch.end(); + // If the loader has not finished loading then update it. if(!loadingDone && loader != null){ + // Update the loader and check if it finished. if(loader.loadAssets()){ loadingDone = true; } } + // If it has been at least 3 seconds since this state got enabled then + // change to the next state if the loader is finished. This is to avoid + // a graphics bug that happens in the core if a state transition is scheduled + // while another effect is already in place. timeSinceShown += delta; if(loadingDone && timeSinceShown >= 3.0f) core.nextState = game_states_t.MAIN_MENU; diff --git a/core/src/com/gamejolt/mikykr5/ceidecpong/states/LogoScreenState.java b/core/src/com/gamejolt/mikykr5/ceidecpong/states/LogoScreenState.java index c43d5eb..b5024b6 100644 --- a/core/src/com/gamejolt/mikykr5/ceidecpong/states/LogoScreenState.java +++ b/core/src/com/gamejolt/mikykr5/ceidecpong/states/LogoScreenState.java @@ -21,10 +21,33 @@ import com.badlogic.gdx.graphics.Texture; import com.gamejolt.mikykr5.ceidecpong.GameCore; import com.gamejolt.mikykr5.ceidecpong.GameCore.game_states_t; +/** + * A simple state that just shows a logo. + * + * @author Miguel Astor + */ public class LogoScreenState extends BaseState{ + /** + * The maximum amount of time to show the logo. + */ + private static final long MAX_TIME = 8000L; + + /** + * The logo to show. + */ private Texture logo; + + /** + * A time counter. + */ private long then; + /** + * Create the logo. + * + * @param core A game core. See {@link BaseState#BaseState(GameCore)} for details. + * @throws IllegalArgumentException If core is null. + */ public LogoScreenState(final GameCore core) throws IllegalArgumentException{ super(core); then = System.currentTimeMillis(); @@ -38,14 +61,16 @@ public class LogoScreenState extends BaseState{ Gdx.gl.glClearColor(0, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + // Render the logo. core.batch.setProjectionMatrix(this.pixelPerfectCamera.combined); core.batch.begin();{ core.batch.draw(logo, -logo.getWidth() / 2, -logo.getHeight() / 2); }core.batch.end(); + // Check if the time expired, then change to the next state if needed. now = System.currentTimeMillis(); delta = now - then; - if(delta > 8000L){ + if(delta > MAX_TIME){ core.nextState = game_states_t.LOADING; then = now; } @@ -58,15 +83,15 @@ public class LogoScreenState extends BaseState{ @Override public boolean touchDown(int screenX, int screenY, int pointer, int button){ + // Set the time counter to 0 so that a state change will be scheduled on the next frame. then = 0L; - return true; }; @Override public boolean keyDown(int keycode){ + // Set the time counter to 0 so that a state change will be scheduled on the next frame. then = 0L; - return true; }; } diff --git a/core/src/com/gamejolt/mikykr5/ceidecpong/states/MainMenuState.java b/core/src/com/gamejolt/mikykr5/ceidecpong/states/MainMenuState.java index a4db005..39f7d3f 100644 --- a/core/src/com/gamejolt/mikykr5/ceidecpong/states/MainMenuState.java +++ b/core/src/com/gamejolt/mikykr5/ceidecpong/states/MainMenuState.java @@ -34,10 +34,25 @@ import com.gamejolt.mikykr5.ceidecpong.interfaces.AssetsLoadedListener; import com.gamejolt.mikykr5.ceidecpong.utils.AsyncAssetLoader; import com.gamejolt.mikykr5.ceidecpong.utils.managers.CachedFontManager; +/** + * A state in charge of rendering and handling the main menu of the game. + * + * @author Miguel Astor + */ public class MainMenuState extends BaseState implements AssetsLoadedListener{ - // Helper fields. + /** + * An {@link AsyncAssetLoader} instance. + */ private AsyncAssetLoader loader; + + /** + * An instance of the {@link CachedFontManager} used to render the buttons. + */ private CachedFontManager fontManager; + + /** + * A flag to indicate that all assets have been loaded. + */ private boolean assetsLoaded; // Buttons and other GUI components. @@ -51,15 +66,39 @@ public class MainMenuState extends BaseState implements AssetsLoadedListener{ private NinePatch menuButtonEnabled9p; private NinePatch menuButtonDisabled9p; private NinePatch menuButtonPressed9p; - private BitmapFont font; + private BitmapFont buttonFont; + + /** + * A {@link ScrollingBackground} effect to make things livelier. + */ private ScrollingBackground scrollingBckg; - // Button touch helper fields. + /** + * A flag to indicate that the start button is pressed. + */ private boolean startButtonTouched; + + /** + * A holder to identify the finger that is touching the start button in multitouch screens. + */ private int startButtonTouchPointer; + + /** + * A flag to indicate that the quit button is pressed. + */ private boolean quitButtonTouched; + + /** + * A holder to identify the finger that is touching the quit button in multitouch screens. + */ private int quitButtonTouchPointer; + /** + * Creates the menu and loads all related assets. + * + * @param core A game core. See {@link BaseState#BaseState(GameCore)} for details. + * @throws IllegalArgumentException If core is null. + */ public MainMenuState(final GameCore core) throws IllegalArgumentException{ super(core); @@ -71,7 +110,7 @@ public class MainMenuState extends BaseState implements AssetsLoadedListener{ loader.addAssetToLoad("data/gfx/gui/Anonymous_Pill_Button_Yellow.png", Texture.class); loader.addAssetToLoad("data/gfx/gui/Anonymous_Pill_Button_Cyan.png", Texture.class); loader.addAssetToLoad("data/gfx/gui/Anonymous_Pill_Button_Blue.png", Texture.class); - font = fontManager.loadFont("data/fonts/d-puntillas-B-to-tiptoe.ttf"); + buttonFont = fontManager.loadFont("data/fonts/d-puntillas-B-to-tiptoe.ttf"); // Set up the background. scrollingBckg = new ScrollingBackground("data/gfx/textures/grass.png"); @@ -94,10 +133,10 @@ public class MainMenuState extends BaseState implements AssetsLoadedListener{ core.batch.setProjectionMatrix(pixelPerfectCamera.combined); core.batch.begin();{ - + // Render the background. scrollingBckg.render(core.batch); - // Render buttons. + // Render the buttons. startButton.draw(core.batch, 1.0f); quitButton.draw(core.batch, 1.0f); @@ -121,6 +160,8 @@ public class MainMenuState extends BaseState implements AssetsLoadedListener{ public boolean touchDown(int screenX, int screenY, int pointer, int button){ unprojectTouch(screenX, screenY); + // If either button is enabled, has been touched and the opposite button is not touched then mark it as + // activated and save the id of the pointer that touched it. if(!startButton.isDisabled() && startButtonBBox.contains(touchPointWorldCoords) && !quitButtonTouched){ startButton.setChecked(true); startButtonTouched = true; @@ -138,6 +179,8 @@ public class MainMenuState extends BaseState implements AssetsLoadedListener{ public boolean touchUp(int screenX, int screenY, int pointer, int button){ unprojectTouch(screenX, screenY); + // If either button was activated and touched but has been released by the user then mark it as inactive + // and execute it's respective state change. if(!startButton.isDisabled() && startButtonBBox.contains(touchPointWorldCoords) && startButtonTouched){ startButton.setChecked(false); startButtonTouched = false; @@ -157,6 +200,8 @@ public class MainMenuState extends BaseState implements AssetsLoadedListener{ public boolean touchDragged(int screenX, int screenY, int pointer){ unprojectTouch(screenX, screenY); + // If either button was touched but the user dragged the pointer away from the button without releasing it then + // mark the button as inactive. if(!startButton.isDisabled() && startButtonTouched && pointer == startButtonTouchPointer && !startButtonBBox.contains(touchPointWorldCoords)){ startButtonTouchPointer = -1; startButtonTouched = false; @@ -172,7 +217,8 @@ public class MainMenuState extends BaseState implements AssetsLoadedListener{ @Override public boolean keyDown(int keycode){ - if(keycode == Input.Keys.BACK){ + // If the user pressed the escape key or the back button in Android then quit. + if(keycode == Input.Keys.BACK || keycode == Input.Keys.ESCAPE){ Gdx.app.exit(); return true; } @@ -194,7 +240,7 @@ public class MainMenuState extends BaseState implements AssetsLoadedListener{ // Create the buttons. textButtonStyle = new TextButtonStyle(); - textButtonStyle.font = font; + textButtonStyle.font = buttonFont; textButtonStyle.up = new NinePatchDrawable(menuButtonEnabled9p); textButtonStyle.checked = new NinePatchDrawable(menuButtonPressed9p); textButtonStyle.disabled = new NinePatchDrawable(menuButtonDisabled9p);