package com.digitalwolf.screens; import com.badlogic.gdx.Application.ApplicationType; import com.badlogic.gdx.Game; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.digitalwolf.assets.Assets; import com.digitalwolf.creatures.Pumma; import com.digitalwolf.gamedata.EggData; import com.digitalwolf.gamedata.GameData; import com.digitalwolf.gamedata.GemData; import com.digitalwolf.screenhelpers.GameScreenGameOverMenu; import com.digitalwolf.screenhelpers.GameScreenGamePauseMenu; import com.digitalwolf.screenhelpers.GameScreenGameReadyMenu; import com.digitalwolf.screenhelpers.GameScreenLevelEndMenu; import com.digitalwolf.world.World; import com.digitalwolf.world.World.WorldListener; import com.digitalwolf.world.WorldRenderer; import com.moribitotech.mtx.AbstractScreen; import com.moribitotech.mtx.IScreen; import com.moribitotech.mtx.models.base.EmptyAbstractActorLight; import com.moribitotech.mtx.settings.AppSettings; public class GameScreen extends AbstractScreen implements IScreen{ //THREE ACTORS ONLY FOR DEMONSTRATION private BitmapFont gameFont; public static int gameOverCounterForAds =0; //DEFINITION OF SCREEN HELPERS THAT HELP CREATE MENU FOR VARIOUS GAME STATES public GameScreenGameReadyMenu gameScreenGameReadyMenu; public GameScreenGamePauseMenu gameScreenGamePauseMenu; public GameScreenGameOverMenu gameScreenGameOverMenu; public GameScreenLevelEndMenu gameScreenLevelEndMenu; EmptyAbstractActorLight healthBar; private float buttonSize = 100*AppSettings.getWorldSizeRatio(); private OrthographicCamera camera; //DEFINING THE VARIOUS STATES OF THE GAME public static final int GAME_READY = 0; public static final int GAME_RUNNING = 1; public static final int GAME_PAUSED = 2; public static final int GAME_LEVEL_END = 3; public static final int GAME_OVER = 4; public static int state; public static int lastScore; public static String gameoverinfo; public static String scoreString; public static int currentlevel =1; //CREATE AN INSTANCE OF WORLD AND WORLD RENDERER World world; WorldListener worldListener; WorldRenderer renderer; // KEEP A MODE FOR TESTING public static boolean DEBUG_MODE = false; public static int creditsPoint; public GameScreen(Game game, String screenName) { super(game, screenName); setUpTheWorld(); gameFont = new BitmapFont(Gdx.files.internal("data/gameFont.fnt"), Gdx.files.internal("data/gameFont.png"), false); state = GAME_READY; setUpScreenElements(); setUpInfoPanel(); setUpMenu(); //CREATE AN ORTHOGRAPHIC CAMERA THAT SHOWS US 30X20 UNITS OF THE WORLD //IN THIS FRAMEWORK 1 WORLD UNIT = 16 SCREEN PIXELS worldListener = new WorldListener() { @Override public void fall () { Assets.playSound(Assets.fall); } @Override public void grabgem () { Assets.playSound(Assets.gemgrab); } @Override public void grabegg() { Assets.playSound(Assets.egggrab); } @Override public void cry () { Assets.playSound(Assets.cry); } @Override public void ow() { Assets.playSound(Assets.ow); } @Override public void success () { Assets.playSound(Assets.success); } }; camera = new OrthographicCamera(AppSettings.SCREEN_W,AppSettings.SCREEN_H); camera.setToOrtho(false, 30, 20); camera.update(); //Called once the player completes a Level resetGame(); } public void resetGame() { // The game is reset each time the game is over lastScore = World.score; //########################### if(!DEBUG_MODE){ if(state == GAME_READY) gameScreenGameReadyMenu.sendInMenu(GameScreen.this); } creditsPoint =0; } public void setUpTheWorld(){ world = new World(worldListener); renderer = new WorldRenderer(world); } @Override public void setUpScreenElements() { // TODO Auto-generated method stub setBackgroundTexture(Assets.bg); if(!DEBUG_MODE){ gameScreenGameReadyMenu = new GameScreenGameReadyMenu(); gameScreenGamePauseMenu = new GameScreenGamePauseMenu(); gameScreenGameOverMenu = new GameScreenGameOverMenu(); gameScreenLevelEndMenu = new GameScreenLevelEndMenu(); } healthBar = new EmptyAbstractActorLight(500*AppSettings.getWorldPositionXRatio(), 18, true); healthBar.setPosition(140*AppSettings.getWorldPositionXRatio(), AppSettings.SCREEN_H - 25*AppSettings.getWorldPositionYRatio()); healthBar.setTextureRegion(Assets.transparent, true); } @Override public void setUpInfoPanel() { } @Override public void setUpMenu() { // SET UP ALL THE SCREEN HELPERS HERE if(!DEBUG_MODE){ gameScreenGameReadyMenu.setUpMenu(this); gameScreenGameOverMenu.setUpMenu(this); gameScreenGamePauseMenu.setUpMenu(this); gameScreenLevelEndMenu.setUpMenu(this); } } @Override public void render(float delta) { super.render(delta); /*************VERY IMPORTANT ***********************************************************************/ //SET THE VIEW OF THE WORLD RENDERER AS PER MY CAMERA DEFINED HERE SO THAT IT CAN MAP TO WORLD UNITS renderer.renderer.setView(camera); //BASE THE HORIZONTAL MOVEMENT OF THE CAMERA ON THE PLAYER MOVEMENT camera.position.x = world.pumma.position.x; //DON'T LET THE CAMERA SHOW PLACES WHERE THERE IS NO MAP if(camera.position.x < World.WORLD_WIDTH/2) { camera.position.x= World.WORLD_WIDTH/2; }else if(camera.position.x> World.mapWidth - World.WORLD_WIDTH/2){ camera.position.x= World.mapWidth - World.WORLD_WIDTH/2; } //UPDATE THE CAMERA TO REFLECT ALL THE CHANGES camera.update(); //UPDATE THE GAMESCREEN ACCORDING TO THE CURRENT GAME STATE update(delta); //THE SEQUENCE MATTERS.. IF I DRAW ALL THESE AFTER SWITCH STATES , THE GAME SHALL BE VISIBLE ONLY WHEN THE GAME //IS RUNNING AND NOT IN STATES LIKE LEVEL COMPLETED, PAUSE , READY AND GAMEOVER //RENDER THE GAME SPRITES & THE LEVEL MAP LAYER BY LAYER int[] prevlayers = new int[] {0, 1}; renderer.render(prevlayers); renderer.renderKey(delta); renderer.renderDoor(delta); renderer.renderSprings(delta); renderer.renderGems(delta); renderer.renderEggs(delta); renderer.renderSnakes(delta); renderer.renderDragons(delta); renderer.renderPlayer(delta); renderer.render(new int[] {2}); //UPDATE THE GAMESCREEN ACCORDING TO THE CURRENT GAME STATE //THIS METHOD IS CALLED IN RENDER() LOOP SO THAT IT CAN CONTINUOSLY CHECK THE //GAME STATES AND CALL A PARTICULAR RENDERSTATE() TO DRAW THINGS ACCORDINGLY /******************************************************************************/ //IMPLEMENT DIFFERENT UPDATE AND PRESENT METHODS FOR VARIOUS GAME STATES getStage().getSpriteBatch().begin(); switch(state) { case GAME_READY: renderReady(); break; case GAME_RUNNING: renderRunning(); break; case GAME_PAUSED: renderPaused(); break; case GAME_LEVEL_END: renderLevelEnd(); break; case GAME_OVER: renderGameOver(); break; } if(DEBUG_MODE){ gameFont.draw(getStage().getSpriteBatch(), "DEBUGGING MODE: ON", 300, 50); } getStage().getSpriteBatch().end(); } private void update(float delta) { // TODO Auto-generated method stub switch(state) { case GAME_READY: updateReady(); break; case GAME_RUNNING: updateRunning(delta); break; case GAME_PAUSED: updatePaused(); break; case GAME_LEVEL_END: updateLevelEnd(); break; case GAME_OVER: updateGameOver(); break; } } private void updateGameOver() { // TODO Auto-generated method stub if(DEBUG_MODE){ if (Gdx.input.justTouched()) { Gdx.app.log("A HIT", "GAME WENT FROM GAMEOVER TO MAINMENU"); getGame().setScreen(new MainMenuScreen(getGame(),"MainMenuScreen")); } } } private void updateLevelEnd() { // TODO Auto-generated method stub if(DEBUG_MODE){ if (Gdx.input.justTouched()) { Gdx.app.log("A HIT", "GAME WENT FROM LEVEL TO LEVEL"); currentlevel++; GameData.addToUnLockedLevel(GameScreen.currentlevel); world = new World(worldListener); renderer = new WorldRenderer(world); World.score = lastScore; state = GAME_READY; resetGame(); } } } private void updatePaused() { // TODO Auto-generated method stub if(DEBUG_MODE){ if (Gdx.input.justTouched()) { Gdx.app.log("A HIT", "GAME WENT TO PAUSE STATE"); state = GAME_RUNNING; return; } } } private void updateRunning(float delta) { // TODO Auto-generated method stub lastScore = World.score; currentlevel = World.levelID; scoreString = "" + lastScore; if(world.state == World.WORLD_STATE_GAME_OVER) { saveGameStates(); lastScore = World.score =0; if(!DEBUG_MODE){ gameScreenGameOverMenu.sendInMenu(this); } state = GAME_OVER; } if(world.state == World.WORLD_STATE_NEXT_LEVEL) { saveGameStates(); try{ creditsPoint = ((world.eggsPummaHave*50)/EggData.getEggPosition(currentlevel).length + ((world.gemsPummaHave*50)/GemData.getGemPosition(currentlevel).length)); } catch(Exception e){ creditsPoint = 0; } if(!DEBUG_MODE){ gameScreenLevelEndMenu.sendInMenu(this); } state = GAME_LEVEL_END; world.listener.success(); } //UPDATE THE PLAYER FOR USER INPUT updatePlayerForUserInput(delta); //UPDATE THE WORLD world.update(delta); } private void updatePlayerForUserInput(float delta) { boolean left = false; boolean right = false; boolean jump = false; boolean pause = false; if (Gdx.app.getType() == ApplicationType.Android || Gdx.app.getType() == ApplicationType.iOS) { for (int i = 0; i < 2; i++) { int x = (int)(Gdx.input.getX(i) / (float)Gdx.graphics.getWidth() * AppSettings.SCREEN_W); int y = (int)(Gdx.input.getY(i) / (float)Gdx.graphics.getWidth() * AppSettings.SCREEN_W); if (!Gdx.input.isTouched(i)) continue; if(y<= AppSettings.SCREEN_H && y>= AppSettings.SCREEN_H -90){ if (x <=90) { left |= true; } if (x > 1.2f*buttonSize && x <= 2.2f*buttonSize) { right |= true; } if (x >= AppSettings.SCREEN_W - 90 && x < AppSettings.SCREEN_W) { jump |= true; } } if (x >= AppSettings.SCREEN_W -64 && y >= 0 && y <= 70) { pause |= true; } } } // CHECK USER INPUT AND APPLY TO VELOCITY AND STATES OF THE MAIN PLAYER if ((Gdx.input.isKeyPressed(Keys.SPACE) && world.pumma.grounded) || (jump && world.pumma.grounded)) { world.pumma.velocity.y += world.pumma.JUMP_VELOCITY; world.pumma.setState(Pumma.JUMP); world.pumma.grounded = false; } if (Gdx.input.isKeyPressed(Keys.LEFT) ||left) { world.pumma.velocity.x = -world.pumma.MAX_VELOCITY; if (world.pumma.grounded) world.pumma.setState(Pumma.WALK); world.pumma.facesRight = false; } if (Gdx.input.isKeyPressed(Keys.RIGHT) || right) { world.pumma.velocity.x = world.pumma.MAX_VELOCITY; if (world.pumma.grounded) world.pumma.setState(Pumma.WALK); world.pumma.facesRight = true; } if (Gdx.input.isKeyPressed(Keys.P) || pause) { state = GAME_PAUSED; if(!DEBUG_MODE){ gameScreenGamePauseMenu.sendInMenu(this); } } } private void updateReady() { // TODO Auto-generated method stub if(DEBUG_MODE){ if (Gdx.input.justTouched()) { Gdx.app.log("A HIT", "GAME WENT FROM READY TO RUNNING STATE"); state = GAME_RUNNING; return; } } } private void renderGameOver() { // TODO Auto-generated method stub if(DEBUG_MODE){ gameFont.draw(getStage().getSpriteBatch(), " "+gameoverinfo, AppSettings.SCREEN_W/3, AppSettings.SCREEN_H/2 +80); getStage().getSpriteBatch().draw(Assets.logo, AppSettings.SCREEN_W/3, AppSettings.SCREEN_H/2); } } private void renderLevelEnd() { // TODO Auto-generated method stub if(DEBUG_MODE){ gameFont.draw(getStage().getSpriteBatch(), "Level "+currentlevel+" Completed", AppSettings.SCREEN_W/3, AppSettings.SCREEN_H/2 +80); getStage().getSpriteBatch().draw(Assets.logo, AppSettings.SCREEN_W/3, AppSettings.SCREEN_H/2); } } private void renderPaused() { // TODO Auto-generated method stub if(DEBUG_MODE){ gameFont.draw(getStage().getSpriteBatch(), " TOUCH TO RESUME", AppSettings.SCREEN_W/3, AppSettings.SCREEN_H/2 +80); getStage().getSpriteBatch().draw(Assets.pummaIcon, AppSettings.SCREEN_W/3, AppSettings.SCREEN_H/2); } } private void renderRunning() { gameFont.setScale(0.6f); gameFont.draw(getStage().getSpriteBatch(), "Score :"+World.score, 140*AppSettings.getWorldPositionXRatio(), AppSettings.SCREEN_H - 30*AppSettings.getWorldPositionYRatio()); //GEM AND NUMBER OF GEMS COLLECTED getStage().getSpriteBatch().draw(Assets.snake_gem, 5, AppSettings.SCREEN_H - 30*AppSettings.getWorldPositionYRatio(), 73/2.5f*AppSettings.getWorldSizeRatio(), 68/2.5f*AppSettings.getWorldSizeRatio()); gameFont.draw(getStage().getSpriteBatch(), " X "+world.gemsPummaHave, 30*AppSettings.getWorldPositionXRatio(), AppSettings.SCREEN_H - 5); //EGGS AND NUMBER OF EGGS COLLECTED getStage().getSpriteBatch().draw(Assets.egg, 5, AppSettings.SCREEN_H - 60*AppSettings.getWorldPositionYRatio(), 300/10*AppSettings.getWorldSizeRatio(), 233/10*AppSettings.getWorldSizeRatio()); gameFont.draw(getStage().getSpriteBatch(), " X "+world.eggsPummaHave, 30*AppSettings.getWorldPositionXRatio(), AppSettings.SCREEN_H - 30); //Display the Health Bar here using Scene2D Actor healthBar.setWidth((Math.min(460, world.pumma.health/2.2f))*AppSettings.getWorldPositionXRatio()); healthBar.draw(getStage().getSpriteBatch(), 1.0f); gameFont.draw(getStage().getSpriteBatch(), Math.min(100, world.pumma.health/10)+" %", healthBar.getX()+1.05f*healthBar.getWidth(), AppSettings.SCREEN_H - 8*AppSettings.getWorldPositionYRatio()); //TO BE DRAWN ONLY AFTER ALL GAME ELEMENTS ARE DRAWN TO AVOID OVERRIDE //DRAW THE GAME CONTROL UI ONLY ON ANDROID DEVICES IF THE GAME STATE IS RUNNING //if ((Gdx.app.getType() == ApplicationType.Android) || (Gdx.app.getType() == ApplicationType.iOS)){ getStage().getSpriteBatch().draw(Assets.left_button, 0f, 0f, 0f, 0f, buttonSize, buttonSize, 1f, 1f, 0f); getStage().getSpriteBatch().draw(Assets.right_button, 1.2f*buttonSize, 0f, 0f, 0f, buttonSize, buttonSize, 1f, 1f, 0f); getStage().getSpriteBatch().draw(Assets.jump_button, AppSettings.SCREEN_W -buttonSize, 0f, 0, 0, buttonSize, buttonSize, 1, 1, 0); getStage().getSpriteBatch().draw(Assets.pause_button, AppSettings.SCREEN_W-64,AppSettings.SCREEN_H -64, 0, 0, 64, 64, 1, 1, 0); //} } private void renderReady() { // TODO Auto-generated method stub if(DEBUG_MODE){ gameFont.draw(getStage().getSpriteBatch(), " Touch to Begin Level "+currentlevel, AppSettings.SCREEN_W/3, AppSettings.SCREEN_H/2 +80); getStage().getSpriteBatch().draw(Assets.logo, AppSettings.SCREEN_W/3, AppSettings.SCREEN_H/2); } } private void saveGameStates() { // STATES ARE SAVED IN KEY AND VALUE PAIRS AS PREFERENCES //GET THE EXISTING HIGHSCORES FROM PREFERENCES int[] scoresfromdb = GameData.getHighScores(); //CHECK IF THE CURRENT SCORE IS GREATER THAN THE STORED ONE if(lastScore > scoresfromdb[4]) scoreString = "NEW RECORD : " + lastScore; else scoreString = "SCORE : " + lastScore; //ADD THE NEW SCORE TO THE PREFERENCES IN DECREASING ORDER GameData.addScore(lastScore); GameData.savePefs(); } }