1. Cấu trúc game
A. Khởi tạo dự án và cấu hình ban đầu
- Tạo dự án Libgdx: Sử dụng công cụ setup của Libgdx để tạo một dự án mới với các module cần thiết cho desktop, Android, iOS và HTML5.
- Cấu hình dự án: Thiết lập các thông số cơ bản như tên dự án, package, các module tích hợp và các thư viện phụ trợ.
B. Cấu trúc thư mục
core/main: Tôi chia thành các thư mục sau:
- Assets.java: Quản lý tài nguyên của trò chơi.
- MainSuperJumper.java: Lớp khởi động trò chơi chính.
- Settings.java: Quản lý cài đặt trò chơi.
- game: Chứa các lớp quản lý logic và render của trò chơi.
- GameScreen.java: Màn hình chính của trò chơi.
- WorldGame.java: Quản lý logic của thế giới game.
- WorldGameRender.java: Chịu trách nhiệm vẽ các đối tượng trong thế giới game lên màn hình.
- objetos: Chứa các lớp đại diện cho các đối tượng trong trò chơi.
- Bullet.java
- Enemigo.java
- Item.java
- Moneda.java
- Nube.java
- Personaje.java
- PiezaPlataformas.java
- Plataformas.java
- Rayo.java
- scene2d: Chứa các lớp liên quan đến Scene2D.
- AnimatedSpriteActor.java
- Ventana.java
- VentanaGameOver.java
- VentanaPause.java
- screens: Chứa các màn hình khác của trò chơi.
- MainMenuScreen.java
- Screens.java
C.Các phần chính của game
MainSuperJumper.java
public class MainSuperJumper extends Game { // Các biến dịch vụ và xử lý yêu cầu cần thiết cho trò chơi public final GameServicesHandler gameServiceHandler; public final RequestHandler reqHandler; public final FacebookHandler facebookHandler; public I18NBundle idiomas; // Đối tượng cho việc đa ngôn ngữ // Constructor nhận các xử lý yêu cầu và dịch vụ trò chơi làm tham số public MainSuperJumper(RequestHandler reqHandler, GameServicesHandler gameServiceHandler, FacebookHandler facebookHandler) { this.reqHandler = reqHandler; this.gameServiceHandler = gameServiceHandler; this.facebookHandler = facebookHandler; } // Các biến thể hiện Stage và SpriteBatch public Stage stage; public SpriteBatch batcher; @Override public void create() { // idiomas = I18NBundle.createBundle(Gdx.files.internal("strings/strings")); // Khởi tạo Stage với kích thước tương thích với màn hình stage = new Stage(new StretchViewport(Screens.SCREEN_WIDTH, Screens.SCREEN_HEIGHT)); // Khởi tạo SpriteBatch để vẽ đồ họa batcher = new SpriteBatch(); // Tải cài đặt trò chơi Settings.load(); // Tải tài nguyên của trò chơi Assets.load(); // Achievements.init(this); // Đặt màn hình chính của trò chơi là MainMenuScreen setScreen(new MainMenuScreen(this)); } }
Quản lý tài nguyên (Assets)
public class Assets { public static BitmapFont fontChico; public static BitmapFont fontGrande; public static AtlasRegion fondo; public static TextureRegionDrawable titulo; /** * Personaje */ public static AtlasRegion personajeJump; public static AtlasRegion personajeStand; public static Animation<TextureRegion> personajeWalk; public static AtlasRegion coin; public static AtlasRegion gun; public static AtlasRegion bullet; public static AtlasRegion spring; public static AtlasRegion bubbleSmall; public static AtlasRegion jetpackSmall; public static AtlasRegion bubble; public static AtlasRegion jetpack; public static Animation<TextureRegion> jetpackFire; public static Animation<TextureRegion> enemigo; public static AtlasRegion nubeHappy; public static AtlasRegion nubeAngry; public static Animation<TextureRegion> rayo; public static AtlasRegion nubeViento; /** * Plataformas */ public static AtlasRegion plataformaBeige; public static AtlasRegion plataformaBeigeLight; public static AtlasRegion plataformaBeigeBroken; public static AtlasRegion plataformaBeigeLeft; public static AtlasRegion plataformaBeigeRight; public static AtlasRegion plataformaBlue; public static AtlasRegion plataformaBlueLight; public static AtlasRegion plataformaBlueBroken; public static AtlasRegion plataformaBlueLeft; public static AtlasRegion plataformaBlueRight; public static AtlasRegion plataformaGray; public static AtlasRegion plataformaGrayLight; public static AtlasRegion plataformaGrayBroken; public static AtlasRegion plataformaGrayLeft; public static AtlasRegion plataformaGrayRight; public static AtlasRegion plataformaGreen; public static AtlasRegion plataformaGreenLight; public static AtlasRegion plataformaGreenBroken; public static AtlasRegion plataformaGreenLeft; public static AtlasRegion plataformaGreenRight; public static AtlasRegion plataformaMulticolor; public static AtlasRegion plataformaMulticolorLight; public static AtlasRegion plataformaMulticolorBroken; public static AtlasRegion plataformaMulticolorLeft; public static AtlasRegion plataformaMulticolorRight; public static AtlasRegion plataformaPink; public static AtlasRegion plataformaPinkLight; public static AtlasRegion plataformaPinkBroken; public static AtlasRegion plataformaPinkLeft; public static AtlasRegion plataformaPinkRight; public static TextureRegionDrawable btPause; public static LabelStyle labelStyleChico; public static LabelStyle labelStyleGrande; public static TextButtonStyle textButtonStyleGrande; public static NinePatchDrawable pixelNegro; public static void loadStyles(TextureAtlas atlas) { // Label Style labelStyleChico = new LabelStyle(fontChico, Color.WHITE); labelStyleGrande = new LabelStyle(fontGrande, Color.WHITE); TextureRegionDrawable button = new TextureRegionDrawable(atlas.findRegion("button")); textButtonStyleGrande = new TextButtonStyle(button, button, null, fontGrande); pixelNegro = new NinePatchDrawable(new NinePatch(atlas.findRegion("pixelNegro"), 1, 1, 0, 0)); } public static void load() { TextureAtlas atlas = new TextureAtlas(Gdx.files.internal("data/atlasMap.txt")); // fontChico = new BitmapFont(Gdx.files.internal("data/fontChico.fnt"), atlas.findRegion("fontChico")); fontChico = new BitmapFont(Gdx.files.internal("data/fontGrande.fnt"), atlas.findRegion("fontGrande")); fontGrande = new BitmapFont(Gdx.files.internal("data/fontGrande.fnt"), atlas.findRegion("fontGrande")); loadStyles(atlas); btPause = new TextureRegionDrawable(atlas.findRegion("btPause")); fondo = atlas.findRegion("Background"); titulo = new TextureRegionDrawable(atlas.findRegion("titulo")); /** * Personaje */ personajeJump = atlas.findRegion("personajeJump"); personajeStand = atlas.findRegion("personajeStand"); AtlasRegion walk1 = atlas.findRegion("personajeWalk1"); AtlasRegion walk2 = atlas.findRegion("personajeWalk2"); personajeWalk = new Animation(.5f, walk1, walk2); coin = atlas.findRegion("Coin"); gun = atlas.findRegion("Pistol"); bullet = atlas.findRegion("Bullet"); spring = atlas.findRegion("Spring"); bubbleSmall = atlas.findRegion("Bubble_Small"); jetpackSmall = atlas.findRegion("Jetpack_Small"); bubble = atlas.findRegion("Bubble_Big"); jetpack = atlas.findRegion("Jetpack_Big"); AtlasRegion jetpackFire1 = atlas.findRegion("JetFire1"); AtlasRegion jetpackFire2 = atlas.findRegion("JetFire2"); jetpackFire = new Animation(.085f, jetpackFire1, jetpackFire2); AtlasRegion enemigo1 = atlas.findRegion("HearthEnemy1"); AtlasRegion enemigo2 = atlas.findRegion("HearthEnemy2"); enemigo = new Animation(.2f, enemigo1, enemigo2); nubeHappy = atlas.findRegion("HappyCloud"); nubeAngry = atlas.findRegion("AngryCloud"); nubeViento = atlas.findRegion("CloudWind"); AtlasRegion lightning1 = atlas.findRegion("Lightning1"); AtlasRegion lightning2 = atlas.findRegion("Lightning2"); rayo = new Animation(.08f, lightning1, lightning2); /** * Plataformas */ plataformaBeige = atlas.findRegion("LandPiece_DarkBeige"); plataformaBeigeLight = atlas.findRegion("LandPiece_LightBeige"); plataformaBeigeBroken = atlas.findRegion("BrokenLandPiece_Beige"); plataformaBeigeLeft = atlas.findRegion("HalfLandPiece_Left_Beige"); plataformaBeigeRight = atlas.findRegion("HalfLandPiece_Right_Beige"); plataformaBlue = atlas.findRegion("LandPiece_DarkBlue"); plataformaBlueLight = atlas.findRegion("LandPiece_LightBlue"); plataformaBlueBroken = atlas.findRegion("BrokenLandPiece_Blue"); plataformaBlueLeft = atlas.findRegion("HalfLandPiece_Left_Blue"); plataformaBlueRight = atlas.findRegion("HalfLandPiece_Right_Blue"); plataformaGray = atlas.findRegion("LandPiece_DarkGray"); plataformaGrayLight = atlas.findRegion("LandPiece_LightGray"); plataformaGrayBroken = atlas.findRegion("BrokenLandPiece_Gray"); plataformaGrayLeft = atlas.findRegion("HalfLandPiece_Left_Gray"); plataformaGrayRight = atlas.findRegion("HalfLandPiece_Right_Gray"); plataformaGreen = atlas.findRegion("LandPiece_DarkGreen"); plataformaGreenLight = atlas.findRegion("LandPiece_LightGreen"); plataformaGreenBroken = atlas.findRegion("BrokenLandPiece_Green"); plataformaGreenLeft = atlas.findRegion("HalfLandPiece_Left_Green"); plataformaGreenRight = atlas.findRegion("HalfLandPiece_Right_Green"); plataformaMulticolor = atlas.findRegion("LandPiece_DarkMulticolored"); plataformaMulticolorLight = atlas.findRegion("LandPiece_LightMulticolored"); plataformaMulticolorBroken = atlas.findRegion("BrokenLandPiece_Multicolored"); plataformaMulticolorLeft = atlas.findRegion("HalfLandPiece_Left_Multicolored"); plataformaMulticolorRight = atlas.findRegion("HalfLandPiece_Right_Multicolored"); plataformaPink = atlas.findRegion("LandPiece_DarkPink"); plataformaPinkLight = atlas.findRegion("LandPiece_LightPink"); plataformaPinkBroken = atlas.findRegion("BrokenLandPiece_Pink"); plataformaPinkLeft = atlas.findRegion("HalfLandPiece_Left_Pink"); plataformaPinkRight = atlas.findRegion("HalfLandPiece_Right_Pink"); } }
Settings.java
public class Settings { public final static int NUM_GEMS_SHARE_FACEBOOK = 250; public final static int NUM_GEMS_INVITE_FACEBOOK = 50; public static boolean isMusicOn; public static boolean isSoundOn; public static boolean didBuyNoAds; public static boolean didLikeFacebook; public static boolean didRate; public static int numeroVecesJugadas; public static int coinsTotal; public static int numBullets; public static int bestScore; public static int LEVEL_LIFE; public static int LEVEL_SHIELD; public static int LEVEL_SECOND_JUMP; public static int LEVEL_WEAPON; private final static Preferences pref = Gdx.app.getPreferences("com.nopalsoft.superjumper"); public static void save() { pref.putBoolean("isMusicOn", isMusicOn); pref.putBoolean("isSoundOn", isSoundOn); pref.putBoolean("didBuyNoAds", didBuyNoAds); pref.putBoolean("didLikeFacebook", didLikeFacebook); pref.putBoolean("didRate", didRate); pref.putInteger("numeroVecesJugadas", numeroVecesJugadas); pref.putInteger("coinsTotal", coinsTotal); pref.putInteger("numBullets", numBullets); pref.putInteger("bestScore", bestScore); pref.putInteger("LEVEL_WEAPON", LEVEL_WEAPON); pref.putInteger("LEVEL_SECOND_JUMP", LEVEL_SECOND_JUMP); pref.putInteger("LEVEL_LIFE", LEVEL_LIFE); pref.putInteger("LEVEL_SHIELD", LEVEL_SHIELD); pref.flush(); } public static void load() { isMusicOn = pref.getBoolean("isMusicOn", true); isSoundOn = pref.getBoolean("isSoundOn", true); didBuyNoAds = pref.getBoolean("didBuyNoAds", false); didLikeFacebook = pref.getBoolean("didLikeFacebook", false); didRate = pref.getBoolean("didRate", false); numeroVecesJugadas = pref.getInteger("numeroVecesJugadas", 0); coinsTotal = pref.getInteger("coinsTotal", 0); numBullets = pref.getInteger("numBullets", 30); bestScore = pref.getInteger("bestScore", 0); LEVEL_WEAPON = pref.getInteger("LEVEL_WEAPON", 0); LEVEL_SECOND_JUMP = pref.getInteger("LEVEL_SECOND_JUMP", 0); LEVEL_LIFE = pref.getInteger("LEVEL_LIFE", 0); LEVEL_SHIELD = pref.getInteger("LEVEL_SHIELD", 0); } public static void setBestScore(int distance) { if (bestScore < distance) { bestScore = distance; save(); } } }
GameScreen.java
public class GameScreen extends Screens { // Các trạng thái của màn hình game static final int STATE_RUNNING = 2; static final int STATE_PAUSED = 3; static final int STATE_GAME_OVER = 4; static int state; public WorldGame oWorld; WorldGameRender renderer; Vector3 touchPositionWorldCoords; boolean didFire; Label lbDistancia, lbMonedas, lbBullets; Button btPause; VentanaPause ventanPause; public GameScreen(MainSuperJumper game) { super(game); // Khởi tạo các thành phần UI và thực thể trong màn hình chơi game ventanPause = new VentanaPause(this); oWorld = new WorldGame(); renderer = new WorldGameRender(batcher, oWorld); touchPositionWorldCoords = new Vector3(); // Thiết lập trạng thái ban đầu của màn hình game state = STATE_RUNNING; Settings.numeroVecesJugadas++; // Tạo bảng điều khiển hiển thị điểm và thông tin khác Table menuMarcador = new Table(); menuMarcador.setSize(SCREEN_WIDTH, 40); menuMarcador.setY(SCREEN_HEIGHT - menuMarcador.getHeight()); lbMonedas = new Label("", Assets.labelStyleGrande); lbDistancia = new Label("", Assets.labelStyleGrande); lbBullets = new Label("", Assets.labelStyleGrande); menuMarcador.add(new Image(new TextureRegionDrawable(Assets.coin))).left().padLeft(5); menuMarcador.add(lbMonedas).left(); menuMarcador.add(lbDistancia).center().expandX(); menuMarcador.add(new Image(new TextureRegionDrawable(Assets.gun))).height(45).width(30).left(); menuMarcador.add(lbBullets).left().padRight(5); // Tạo nút pause btPause = new Button(Assets.btPause); btPause.setSize(35, 35); btPause.setPosition(SCREEN_WIDTH - 40, SCREEN_HEIGHT - 80); addEfectoPress(btPause); // Thêm hiệu ứng khi nút được nhấn btPause.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { setPaused(); // Gọi hàm tạm dừng khi nút được nhấn } }); // Thêm các thành phần UI vào Stage stage.addActor(menuMarcador); stage.addActor(btPause); } // Cập nhật logic game @Override public void update(float delta) { switch (state) { case STATE_RUNNING: updateRunning(delta); break; case STATE_GAME_OVER: updateGameOver(delta); break; } } private void updateRunning(float delta) { // Cập nhật các thông số trong trạng thái chạy game float acelX = 0; acelX = -(Gdx.input.getAccelerometerX() / 3f); if (Gdx.input.isKeyPressed(Keys.A)) acelX = -1; else if (Gdx.input.isKeyPressed(Keys.D)) acelX = 1; oWorld.update(delta, acelX, didFire, touchPositionWorldCoords); lbMonedas.setText("x" + oWorld.coins); lbDistancia.setText("Score " + oWorld.distanciaMax); lbBullets.setText("x" + Settings.numBullets); if (oWorld.state == WorldGame.STATE_GAMEOVER) { setGameover(); } didFire = false; } private void updateGameOver(float delta) { oWorld.update(delta, 0, false, touchPositionWorldCoords); } // Vẽ đồ họa @Override public void draw(float delta) { // Vẽ nền và các thành phần game batcher.begin(); batcher.draw(Assets.fondo, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); batcher.end(); // Nếu không trong trạng thái tạm dừng, vẽ các đối tượng game if (state != STATE_PAUSED) { renderer.render(delta); } } // Hàm tạm dừng game private void setPaused() { if (state == STATE_RUNNING) { state = STATE_PAUSED; ventanPause.show(stage); } } // Hàm khi game đang chạy public void setRunning() { state = STATE_RUNNING; } // Hàm khi game kết thúc private void setGameover() { state = STATE_GAME_OVER; Settings.setBestScore(oWorld.distanciaMax); game.gameServiceHandler.submitScore(oWorld.distanciaMax); new VentanaGameover(this).show(stage); } // Ẩn màn hình game @Override public void hide() { if (Settings.numeroVecesJugadas % 7 == 0) game.reqHandler.showInterstitial(); super.hide(); } // Xử lý sự kiện khi người chơi chạm vào màn hình @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { touchPositionWorldCoords.set(screenX, 0, 0); renderer.unprojectToWorldCoords(touchPositionWorldCoords); didFire = true; return false; } // Xử lý sự kiện khi người chơi nhấn phím @Override public boolean keyDown(int keycode) { if (keycode == Keys.ESCAPE || keycode == Keys.BACK) { if (ventanPause.isVisible()) ventanPause.hide(); else setPaused(); return true; } return super.keyDown(keycode); } }
WorldGame.java
public class WorldGame { final float WIDTH = Screens.WORLD_WIDTH; final float HEIGHT = Screens.WORLD_HEIGHT; final public static int STATE_RUNNING = 0; final public static int STATE_GAMEOVER = 1; int state; float TIME_TO_CREATE_NUBE = 15; float timeToCreateNube; public World oWorldBox; Personaje oPer; private Array<Body> arrBodies; Array<Plataformas> arrPlataformas; Array<PiezaPlataformas> arrPiezasPlataformas; Array<Moneda> arrMonedas; Array<Enemigo> arrEnemigo; Array<Item> arrItem; Array<Nube> arrNubes; Array<Rayo> arrRayos; Array<Bullet> arrBullets; public int coins; public int distanciaMax; float mundoCreadoHastaY; public WorldGame() { oWorldBox = new World(new Vector2(0, -9.8f), true); oWorldBox.setContactListener(new Colisiones()); arrBodies = new Array<Body>(); arrPlataformas = new Array<Plataformas>(); arrPiezasPlataformas = new Array<PiezaPlataformas>(); arrMonedas = new Array<Moneda>(); arrEnemigo = new Array<Enemigo>(); arrItem = new Array<Item>(); arrNubes = new Array<Nube>(); arrRayos = new Array<Rayo>(); arrBullets = new Array<Bullet>(); timeToCreateNube = 0; state = STATE_RUNNING; crearPiso(); crearPersonaje(); mundoCreadoHastaY = oPer.position.y; crearSiguienteParte(); } private void crearSiguienteParte() { float y = mundoCreadoHastaY + 2; for (int i = 0; mundoCreadoHastaY < (y + 10); i++) { mundoCreadoHastaY = y + (i * 2); crearPlataforma(mundoCreadoHastaY); crearPlataforma(mundoCreadoHastaY); if (MathUtils.random(100) < 5) Moneda.createMoneda(oWorldBox, arrMonedas, mundoCreadoHastaY); if (MathUtils.random(20) < 5) Moneda.createUnaMoneda(oWorldBox, arrMonedas, mundoCreadoHastaY + .5f); if (MathUtils.random(20) < 5) crearEnemigo(mundoCreadoHastaY + .5f); if (timeToCreateNube >= TIME_TO_CREATE_NUBE) { crearNubes(mundoCreadoHastaY + .7f); timeToCreateNube = 0; } if (MathUtils.random(50) < 5) createItem(mundoCreadoHastaY + .5f); } } /** * El piso solo aparece 1 vez, al principio del juego */ private void crearPiso() { BodyDef bd = new BodyDef(); bd.type = BodyType.StaticBody; Body body = oWorldBox.createBody(bd); EdgeShape shape = new EdgeShape(); shape.set(0, 0, Screens.WORLD_WIDTH, 0); FixtureDef fixutre = new FixtureDef(); fixutre.shape = shape; body.createFixture(fixutre); body.setUserData("piso"); shape.dispose(); } private void crearPersonaje() { oPer = new Personaje(2.4f, .5f); BodyDef bd = new BodyDef(); bd.position.set(oPer.position.x, oPer.position.y); bd.type = BodyType.DynamicBody; Body body = oWorldBox.createBody(bd); PolygonShape shape = new PolygonShape(); shape.setAsBox(Personaje.WIDTH / 2f, Personaje.HEIGTH / 2f); FixtureDef fixutre = new FixtureDef(); fixutre.shape = shape; fixutre.density = 10; fixutre.friction = 0; fixutre.restitution = 0; body.createFixture(fixutre); body.setUserData(oPer); body.setFixedRotation(true); shape.dispose(); } private void crearPlataforma(float y) { Plataformas oPlat = Pools.obtain(Plataformas.class); oPlat.init(MathUtils.random(Screens.WORLD_WIDTH), y, MathUtils.random(1)); BodyDef bd = new BodyDef(); bd.position.set(oPlat.position.x, oPlat.position.y); bd.type = BodyType.KinematicBody; Body body = oWorldBox.createBody(bd); PolygonShape shape = new PolygonShape(); shape.setAsBox(Plataformas.WIDTH_NORMAL / 2f, Plataformas.HEIGTH_NORMAL / 2f); FixtureDef fixutre = new FixtureDef(); fixutre.shape = shape; body.createFixture(fixutre); body.setUserData(oPlat); arrPlataformas.add(oPlat); shape.dispose(); } /** * La plataforma rompible son 2 cuadros * * @param i */ private void crearPiezasPlataforma(Plataformas oPlat) { crearPiezasPlataforma(oPlat, PiezaPlataformas.TIPO_LEFT); crearPiezasPlataforma(oPlat, PiezaPlataformas.TIPO_RIGHT); } private void crearPiezasPlataforma(Plataformas oPla, int tipo) { PiezaPlataformas oPieza; float x; float angularVelocity = 100; if (tipo == PiezaPlataformas.TIPO_LEFT) { x = oPla.position.x - PiezaPlataformas.WIDTH_NORMAL / 2f; angularVelocity *= -1; } else { x = oPla.position.x + PiezaPlataformas.WIDTH_NORMAL / 2f; } oPieza = Pools.obtain(PiezaPlataformas.class); oPieza.init(x, oPla.position.y, tipo, oPla.color); BodyDef bd = new BodyDef(); bd.position.set(oPieza.position.x, oPieza.position.y); bd.type = BodyType.DynamicBody; Body body = oWorldBox.createBody(bd); PolygonShape shape = new PolygonShape(); shape.setAsBox(PiezaPlataformas.WIDTH_NORMAL / 2f, PiezaPlataformas.HEIGTH_NORMAL / 2f); FixtureDef fixutre = new FixtureDef(); fixutre.shape = shape; fixutre.isSensor = true; body.createFixture(fixutre); body.setUserData(oPieza); body.setAngularVelocity(MathUtils.degRad * angularVelocity); arrPiezasPlataformas.add(oPieza); shape.dispose(); } private void crearEnemigo(float y) { Enemigo oEn = Pools.obtain(Enemigo.class); oEn.init(MathUtils.random(Screens.WORLD_WIDTH), y); BodyDef bd = new BodyDef(); bd.position.set(oEn.position.x, oEn.position.y); bd.type = BodyType.DynamicBody; Body body = oWorldBox.createBody(bd); PolygonShape shape = new PolygonShape(); shape.setAsBox(Enemigo.WIDTH / 2f, Enemigo.HEIGHT / 2f); FixtureDef fixutre = new FixtureDef(); fixutre.shape = shape; fixutre.isSensor = true; body.createFixture(fixutre); body.setUserData(oEn); body.setGravityScale(0); float velocidad = MathUtils.random(1f, Enemigo.VELOCIDAD_X); if (MathUtils.randomBoolean()) body.setLinearVelocity(velocidad, 0); else body.setLinearVelocity(-velocidad, 0); arrEnemigo.add(oEn); shape.dispose(); } private void createItem(float y) { Item oItem = Pools.obtain(Item.class); oItem.init(MathUtils.random(Screens.WORLD_WIDTH), y); BodyDef bd = new BodyDef(); bd.position.set(oItem.position.x, oItem.position.y); bd.type = BodyType.StaticBody; Body oBody = oWorldBox.createBody(bd); PolygonShape shape = new PolygonShape(); shape.setAsBox(Item.WIDTH / 2f, Item.HEIGHT / 2f); FixtureDef fixture = new FixtureDef(); fixture.shape = shape; fixture.isSensor = true; oBody.createFixture(fixture); oBody.setUserData(oItem); shape.dispose(); arrItem.add(oItem); } private void crearNubes(float y) { Nube oNube = Pools.obtain(Nube.class); oNube.init(MathUtils.random(Screens.WORLD_WIDTH), y); BodyDef bd = new BodyDef(); bd.position.set(oNube.position.x, oNube.position.y); bd.type = BodyType.DynamicBody; Body body = oWorldBox.createBody(bd); PolygonShape shape = new PolygonShape(); shape.setAsBox(Nube.WIDTH / 2f, Nube.HEIGHT / 2f); FixtureDef fixutre = new FixtureDef(); fixutre.shape = shape; fixutre.isSensor = true; body.createFixture(fixutre); body.setUserData(oNube); body.setGravityScale(0); float velocidad = MathUtils.random(1f, Nube.VELOCIDAD_X); if (MathUtils.randomBoolean()) body.setLinearVelocity(velocidad, 0); else body.setLinearVelocity(-velocidad, 0); arrNubes.add(oNube); shape.dispose(); } private void crearRayo(float x, float y) { Rayo oRayo = Pools.obtain(Rayo.class); oRayo.init(x, y); BodyDef bd = new BodyDef(); bd.position.set(oRayo.position.x, oRayo.position.y); bd.type = BodyType.KinematicBody; Body body = oWorldBox.createBody(bd); PolygonShape shape = new PolygonShape(); shape.setAsBox(Rayo.WIDTH / 2f, Rayo.HEIGHT / 2f); FixtureDef fixutre = new FixtureDef(); fixutre.shape = shape; fixutre.isSensor = true; body.createFixture(fixutre); body.setUserData(oRayo); body.setLinearVelocity(0, Rayo.VELOCIDAD_Y); arrRayos.add(oRayo); shape.dispose(); } private void crearBullet(float origenX, float origenY, float destinoX, float destinoY) { Bullet oBullet = Pools.obtain(Bullet.class); oBullet.init(origenX, origenY); BodyDef bd = new BodyDef(); bd.position.set(oBullet.position.x, oBullet.position.y); bd.type = BodyType.KinematicBody; Body body = oWorldBox.createBody(bd); PolygonShape shape = new PolygonShape(); shape.setAsBox(Bullet.SIZE / 2f, Bullet.SIZE / 2f); FixtureDef fixutre = new FixtureDef(); fixutre.shape = shape; fixutre.isSensor = true; body.createFixture(fixutre); body.setUserData(oBullet); body.setBullet(true); Vector2 destino = new Vector2(destinoX, destinoY); destino.sub(oBullet.position).nor().scl(Bullet.VELOCIDAD_XY); body.setLinearVelocity(destino.x, destino.y); arrBullets.add(oBullet); shape.dispose(); } public void update(float delta, float acelX, boolean fire, Vector3 touchPositionWorldCoords) { oWorldBox.step(delta, 8, 4); eliminarObjetos(); /** * REviso si es necesario generar la siquiete parte del mundo */ if (oPer.position.y + 10 > mundoCreadoHastaY) { crearSiguienteParte(); } timeToCreateNube += delta;// Actualizo el tiempo para crear una nube oWorldBox.getBodies(arrBodies); Iterator<Body> i = arrBodies.iterator(); while (i.hasNext()) { Body body = i.next(); if (body.getUserData() instanceof Personaje) { updatePersonaje(body, delta, acelX, fire, touchPositionWorldCoords); } else if (body.getUserData() instanceof Plataformas) { updatePlataforma(body, delta); } else if (body.getUserData() instanceof PiezaPlataformas) { updatePiezaPlataforma(body, delta); } else if (body.getUserData() instanceof Moneda) { updateMoneda(body, delta); } else if (body.getUserData() instanceof Enemigo) { updateEnemigo(body, delta); } else if (body.getUserData() instanceof Item) { updateItem(body, delta); } else if (body.getUserData() instanceof Nube) { updateNube(body, delta); } else if (body.getUserData() instanceof Rayo) { updateRayo(body, delta); } else if (body.getUserData() instanceof Bullet) { updateBullet(body, delta); } } if (distanciaMax < (oPer.position.y * 10)) { distanciaMax = (int) (oPer.position.y * 10); } // Si el personaje esta 5.5f mas abajo de la altura maxima se muere (Se multiplica por 10 porque la distancia se multiplica por 10 ) if (oPer.state == Personaje.STATE_NORMAL && distanciaMax - (5.5f * 10) > (oPer.position.y * 10)) { oPer.die(); } if (oPer.state == Personaje.STATE_DEAD && distanciaMax - (25 * 10) > (oPer.position.y * 10)) { state = STATE_GAMEOVER; } } private void eliminarObjetos() { oWorldBox.getBodies(arrBodies); Iterator<Body> i = arrBodies.iterator(); while (i.hasNext()) { Body body = i.next(); if (!oWorldBox.isLocked()) { if (body.getUserData() instanceof Plataformas) { Plataformas oPlat = (Plataformas) body.getUserData(); if (oPlat.state == Plataformas.STATE_DESTROY) { arrPlataformas.removeValue(oPlat, true); oWorldBox.destroyBody(body); if (oPlat.tipo == Plataformas.TIPO_ROMPIBLE) crearPiezasPlataforma(oPlat); Pools.free(oPlat); } } else if (body.getUserData() instanceof Moneda) { Moneda oMon = (Moneda) body.getUserData(); if (oMon.state == Moneda.STATE_TAKEN) { arrMonedas.removeValue(oMon, true); oWorldBox.destroyBody(body); Pools.free(oMon); } } else if (body.getUserData() instanceof PiezaPlataformas) { PiezaPlataformas oPiez = (PiezaPlataformas) body.getUserData(); if (oPiez.state == PiezaPlataformas.STATE_DESTROY) { arrPiezasPlataformas.removeValue(oPiez, true); oWorldBox.destroyBody(body); Pools.free(oPiez); } } else if (body.getUserData() instanceof Enemigo) { Enemigo oEnemy = (Enemigo) body.getUserData(); if (oEnemy.state == Enemigo.STATE_DEAD) { arrEnemigo.removeValue(oEnemy, true); oWorldBox.destroyBody(body); Pools.free(oEnemy); } } else if (body.getUserData() instanceof Item) { Item oItem = (Item) body.getUserData(); if (oItem.state == Item.STATE_TAKEN) { arrItem.removeValue(oItem, true); oWorldBox.destroyBody(body); Pools.free(oItem); } } else if (body.getUserData() instanceof Nube) { Nube oNube = (Nube) body.getUserData(); if (oNube.state == Nube.STATE_DEAD) { arrNubes.removeValue(oNube, true); oWorldBox.destroyBody(body); Pools.free(oNube); } } else if (body.getUserData() instanceof Rayo) { Rayo oRayo = (Rayo) body.getUserData(); if (oRayo.state == Rayo.STATE_DESTROY) { arrRayos.removeValue(oRayo, true); oWorldBox.destroyBody(body); Pools.free(oRayo); } } else if (body.getUserData() instanceof Bullet) { Bullet oBullet = (Bullet) body.getUserData(); if (oBullet.state == Bullet.STATE_DESTROY) { arrBullets.removeValue(oBullet, true); oWorldBox.destroyBody(body); Pools.free(oBullet); } } else if (body.getUserData().equals("piso")) { if (oPer.position.y - 5.5f > body.getPosition().y || oPer.state == Personaje.STATE_DEAD) { oWorldBox.destroyBody(body); } } } } } private void updatePersonaje(Body body, float delta, float acelX, boolean fire, Vector3 touchPositionWorldCoords) { oPer.update(body, delta, acelX); if (Settings.numBullets > 0 && fire) { crearBullet(oPer.position.x, oPer.position.y, touchPositionWorldCoords.x, touchPositionWorldCoords.y); Settings.numBullets--; } } private void updatePlataforma(Body body, float delta) { Plataformas obj = (Plataformas) body.getUserData(); obj.update(delta); if (oPer.position.y - 5.5f > obj.position.y) { obj.setDestroy(); } } private void updatePiezaPlataforma(Body body, float delta) { PiezaPlataformas obj = (PiezaPlataformas) body.getUserData(); obj.update(delta, body); if (oPer.position.y - 5.5f > obj.position.y) { obj.setDestroy(); } } private void updateMoneda(Body body, float delta) { Moneda obj = (Moneda) body.getUserData(); obj.update(delta); if (oPer.position.y - 5.5f > obj.position.y) { obj.take(); } } private void updateEnemigo(Body body, float delta) { Enemigo obj = (Enemigo) body.getUserData(); obj.update(body, delta); if (oPer.position.y - 5.5f > obj.position.y) { obj.hit(); } } private void updateItem(Body body, float delta) { Item obj = (Item) body.getUserData(); obj.update(delta); if (oPer.position.y - 5.5f > obj.position.y) { obj.take(); } } private void updateNube(Body body, float delta) { Nube obj = (Nube) body.getUserData(); obj.update(body, delta); if (obj.isLighthing) { crearRayo(obj.position.x, obj.position.y - .65f); obj.fireLighting(); } if (oPer.position.y - 5.5f > obj.position.y) { obj.destroy(); } } private void updateRayo(Body body, float delta) { Rayo obj = (Rayo) body.getUserData(); obj.update(body, delta); if (oPer.position.y - 5.5f > obj.position.y) { obj.destroy(); } } private void updateBullet(Body body, float delta) { Bullet obj = (Bullet) body.getUserData(); obj.update(body, delta); if (oPer.position.y - 5.5f > obj.position.y) { obj.destroy(); } } class Colisiones implements ContactListener { @Override public void beginContact(Contact contact) { Fixture a = contact.getFixtureA(); Fixture b = contact.getFixtureB(); if (a.getBody().getUserData() instanceof Personaje) beginContactPersonaje(a, b); else if (b.getBody().getUserData() instanceof Personaje) beginContactPersonaje(b, a); if (a.getBody().getUserData() instanceof Bullet) beginContactBullet(a, b); else if (b.getBody().getUserData() instanceof Bullet) beginContactBullet(b, a); } private void beginContactPersonaje(Fixture fixPersonaje, Fixture fixOtraCosa) { Object otraCosa = fixOtraCosa.getBody().getUserData(); if (otraCosa.equals("piso")) { oPer.jump(); if (oPer.state == Personaje.STATE_DEAD) { state = STATE_GAMEOVER; } } else if (otraCosa instanceof Plataformas) { Plataformas obj = (Plataformas) otraCosa; if (oPer.velocidad.y <= 0) { oPer.jump(); if (obj.tipo == Plataformas.TIPO_ROMPIBLE) { obj.setDestroy(); } } } else if (otraCosa instanceof Moneda) { Moneda obj = (Moneda) otraCosa; obj.take(); coins++; oPer.jump(); } else if (otraCosa instanceof Enemigo) { oPer.hit(); } else if (otraCosa instanceof Rayo) { oPer.hit(); } else if (otraCosa instanceof Item) { Item obj = (Item) otraCosa; obj.take(); switch (obj.tipo) { case Item.TIPO_BUBBLE: oPer.setBubble(); break; case Item.TIPO_JETPACK: oPer.setJetPack(); break; case Item.TIPO_GUN: Settings.numBullets += 10; break; } } } private void beginContactBullet(Fixture fixBullet, Fixture fixOtraCosa) { Object otraCosa = fixOtraCosa.getBody().getUserData(); Bullet oBullet = (Bullet) fixBullet.getBody().getUserData(); if (otraCosa instanceof Enemigo) { Enemigo obj = (Enemigo) otraCosa; obj.hit(); oBullet.destroy(); } else if (otraCosa instanceof Nube) { Nube obj = (Nube) otraCosa; obj.hit(); oBullet.destroy(); } } @Override public void endContact(Contact contact) { } @Override public void preSolve(Contact contact, Manifold oldManifold) { Fixture a = contact.getFixtureA(); Fixture b = contact.getFixtureB(); if (a.getBody().getUserData() instanceof Personaje) preSolveHero(a, b, contact); else if (b.getBody().getUserData() instanceof Personaje) preSolveHero(b, a, contact); } private void preSolveHero(Fixture fixPersonaje, Fixture otraCosa, Contact contact) { Object oOtraCosa = otraCosa.getBody().getUserData(); if (oOtraCosa instanceof Plataformas) { // Si va para arriba atraviesa la plataforma Plataformas obj = (Plataformas) oOtraCosa; float ponyY = fixPersonaje.getBody().getPosition().y - .30f; float pisY = obj.position.y + Plataformas.HEIGTH_NORMAL / 2f; if (ponyY < pisY) contact.setEnabled(false); if (obj.tipo == Plataformas.TIPO_NORMAL && oPer.state == Personaje.STATE_DEAD) { contact.setEnabled(false); } } } @Override public void postSolve(Contact contact, ContactImpulse impulse) { // TODO Auto-generated method stub } } }
WorldGameRender.java
public class WorldGameRender { final float WIDTH = Screens.WORLD_WIDTH; final float HEIGHT = Screens.WORLD_HEIGHT; WorldGame oWorld; SpriteBatch batcher; OrthographicCamera oCam; Box2DDebugRenderer boxRender; public WorldGameRender(SpriteBatch batcher, WorldGame oWorld) { this.oWorld = oWorld; this.batcher = batcher; oCam = new OrthographicCamera(WIDTH, HEIGHT); oCam.position.set(WIDTH / 2f, HEIGHT / 2f, 0); boxRender = new Box2DDebugRenderer(); } public void unprojectToWorldCoords(Vector3 touchPoint) { oCam.unproject(touchPoint); } public void render(float delta) { if (oWorld.state == WorldGame.STATE_RUNNING) oCam.position.y = oWorld.oPer.position.y; if (oCam.position.y < Screens.WORLD_HEIGHT / 2f) { oCam.position.y = Screens.WORLD_HEIGHT / 2f; } oCam.update(); batcher.setProjectionMatrix(oCam.combined); batcher.begin(); renderPersonaje(); renderPlataformas(); renderPiezasPlataformas(); renderCoins(); renderItems(); renderEnemigo(); renderNube(); renderRayo(); renderBullet(); batcher.end(); // boxRender.render(oWorld.oWorldBox, oCam.combined); } private void renderPersonaje() { AtlasRegion keyframe = null; Personaje obj = oWorld.oPer; if (obj.velocidad.y > 0) keyframe = Assets.personajeJump; else keyframe = Assets.personajeStand; if (obj.velocidad.x > 0) batcher.draw(keyframe, obj.position.x + Personaje.DRAW_WIDTH / 2f, obj.position.y - Personaje.DRAW_HEIGTH / 2f, -Personaje.DRAW_WIDTH / 2f, Personaje.DRAW_HEIGTH / 2f, -Personaje.DRAW_WIDTH, Personaje.DRAW_HEIGTH, 1, 1, obj.angleDeg); else batcher.draw(keyframe, obj.position.x - Personaje.DRAW_WIDTH / 2f, obj.position.y - Personaje.DRAW_HEIGTH / 2f, Personaje.DRAW_WIDTH / 2f, Personaje.DRAW_HEIGTH / 2f, Personaje.DRAW_WIDTH, Personaje.DRAW_HEIGTH, 1, 1, obj.angleDeg); if (obj.isJetPack) { batcher.draw(Assets.jetpack, obj.position.x - .45f / 2f, obj.position.y - .7f / 2f, .45f, .7f); TextureRegion fireFrame = Assets.jetpackFire.getKeyFrame(obj.durationJetPack, true); batcher.draw(fireFrame, obj.position.x - .35f / 2f, obj.position.y - .95f, .35f, .6f); } if (obj.isBubble) { batcher.draw(Assets.bubble, obj.position.x - .5f, obj.position.y - .5f, 1, 1); } } private void renderPlataformas() { Iterator<Plataformas> i = oWorld.arrPlataformas.iterator(); while (i.hasNext()) { Plataformas obj = i.next(); AtlasRegion keyframe = null; if (obj.tipo == Plataformas.TIPO_ROMPIBLE) { switch (obj.color) { case Plataformas.COLOR_BEIGE: keyframe = Assets.plataformaBeigeBroken; break; case Plataformas.COLOR_BLUE: keyframe = Assets.plataformaBlueBroken; break; case Plataformas.COLOR_GRAY: keyframe = Assets.plataformaGrayBroken; break; case Plataformas.COLOR_GREEN: keyframe = Assets.plataformaGreenBroken; break; case Plataformas.COLOR_MULTICOLOR: keyframe = Assets.plataformaMulticolorBroken; break; case Plataformas.COLOR_PINK: keyframe = Assets.plataformaPinkBroken; break; } } else { switch (obj.color) { case Plataformas.COLOR_BEIGE: keyframe = Assets.plataformaBeige; break; case Plataformas.COLOR_BLUE: keyframe = Assets.plataformaBlue; break; case Plataformas.COLOR_GRAY: keyframe = Assets.plataformaGray; break; case Plataformas.COLOR_GREEN: keyframe = Assets.plataformaGreen; break; case Plataformas.COLOR_MULTICOLOR: keyframe = Assets.plataformaMulticolor; break; case Plataformas.COLOR_PINK: keyframe = Assets.plataformaPink; break; case Plataformas.COLOR_BEIGE_LIGHT: keyframe = Assets.plataformaBeigeLight; break; case Plataformas.COLOR_BLUE_LIGHT: keyframe = Assets.plataformaBlueLight; break; case Plataformas.COLOR_GRAY_LIGHT: keyframe = Assets.plataformaGrayLight; break; case Plataformas.COLOR_GREEN_LIGHT: keyframe = Assets.plataformaGreenLight; break; case Plataformas.COLOR_MULTICOLOR_LIGHT: keyframe = Assets.plataformaMulticolorLight; break; case Plataformas.COLOR_PINK_LIGHT: keyframe = Assets.plataformaPinkLight; break; } } batcher.draw(keyframe, obj.position.x - Plataformas.DRAW_WIDTH_NORMAL / 2f, obj.position.y - Plataformas.DRAW_HEIGTH_NORMAL / 2f, Plataformas.DRAW_WIDTH_NORMAL, Plataformas.DRAW_HEIGTH_NORMAL); } } private void renderPiezasPlataformas() { Iterator<PiezaPlataformas> i = oWorld.arrPiezasPlataformas.iterator(); while (i.hasNext()) { PiezaPlataformas obj = i.next(); AtlasRegion keyframe = null; if (obj.tipo == PiezaPlataformas.TIPO_LEFT) { switch (obj.color) { case Plataformas.COLOR_BEIGE: keyframe = Assets.plataformaBeigeLeft; break; case Plataformas.COLOR_BLUE: keyframe = Assets.plataformaBlueLeft; break; case Plataformas.COLOR_GRAY: keyframe = Assets.plataformaGrayLeft; break; case Plataformas.COLOR_GREEN: keyframe = Assets.plataformaGreenLeft; break; case Plataformas.COLOR_MULTICOLOR: keyframe = Assets.plataformaMulticolorLeft; break; case Plataformas.COLOR_PINK: keyframe = Assets.plataformaPinkLeft; break; } } else { switch (obj.color) { case Plataformas.COLOR_BEIGE: keyframe = Assets.plataformaBeigeRight; break; case Plataformas.COLOR_BLUE: keyframe = Assets.plataformaBlueRight; break; case Plataformas.COLOR_GRAY: keyframe = Assets.plataformaGrayRight; break; case Plataformas.COLOR_GREEN: keyframe = Assets.plataformaGreenRight; break; case Plataformas.COLOR_MULTICOLOR: keyframe = Assets.plataformaMulticolorRight; break; case Plataformas.COLOR_PINK: keyframe = Assets.plataformaPinkRight; break; } } batcher.draw(keyframe, obj.position.x - PiezaPlataformas.DRAW_WIDTH_NORMAL / 2f, obj.position.y - PiezaPlataformas.DRAW_HEIGTH_NORMAL / 2f, PiezaPlataformas.DRAW_WIDTH_NORMAL / 2f, PiezaPlataformas.DRAW_HEIGTH_NORMAL / 2f, PiezaPlataformas.DRAW_WIDTH_NORMAL, PiezaPlataformas.DRAW_HEIGTH_NORMAL, 1, 1, obj.angleDeg); } } private void renderCoins() { Iterator<Moneda> i = oWorld.arrMonedas.iterator(); while (i.hasNext()) { Moneda obj = i.next(); batcher.draw(Assets.coin, obj.position.x - Moneda.DRAW_WIDTH / 2f, obj.position.y - Moneda.DRAW_HEIGHT / 2f, Moneda.DRAW_WIDTH, Moneda.DRAW_HEIGHT); } } private void renderItems() { Iterator<Item> i = oWorld.arrItem.iterator(); while (i.hasNext()) { Item obj = i.next(); TextureRegion keyframe = null; switch (obj.tipo) { case Item.TIPO_BUBBLE: keyframe = Assets.bubbleSmall; break; case Item.TIPO_JETPACK: keyframe = Assets.jetpackSmall; break; case Item.TIPO_GUN: keyframe = Assets.gun; break; } batcher.draw(keyframe, obj.position.x - Item.DRAW_WIDTH / 2f, obj.position.y - Item.DRAW_HEIGHT / 2f, Item.DRAW_WIDTH, Item.DRAW_HEIGHT); } } private void renderEnemigo() { Iterator<Enemigo> i = oWorld.arrEnemigo.iterator(); while (i.hasNext()) { Enemigo obj = i.next(); TextureRegion keyframe = Assets.enemigo.getKeyFrame(obj.stateTime, true); batcher.draw(keyframe, obj.position.x - Enemigo.DRAW_WIDTH / 2f, obj.position.y - Enemigo.DRAW_HEIGHT / 2f, Enemigo.DRAW_WIDTH, Enemigo.DRAW_HEIGHT); } } private void renderNube() { Iterator<Nube> i = oWorld.arrNubes.iterator(); while (i.hasNext()) { Nube obj = i.next(); TextureRegion keyframe = null; switch (obj.tipo) { case Nube.TIPO_ANGRY: keyframe = Assets.nubeAngry; break; case Nube.TIPO_HAPPY: keyframe = Assets.nubeHappy; break; } batcher.draw(keyframe, obj.position.x - Nube.DRAW_WIDTH / 2f, obj.position.y - Nube.DRAW_HEIGHT / 2f, Nube.DRAW_WIDTH, Nube.DRAW_HEIGHT); if (obj.isBlowing) { batcher.draw(Assets.nubeViento, obj.position.x - .35f, obj.position.y - .85f, .6f, .8f); } } } private void renderRayo() { Iterator<Rayo> i = oWorld.arrRayos.iterator(); while (i.hasNext()) { Rayo obj = i.next(); TextureRegion keyframe = Assets.rayo.getKeyFrame(obj.stateTime, true); batcher.draw(keyframe, obj.position.x - Rayo.DRAW_WIDTH / 2f, obj.position.y - Rayo.DRAW_HEIGHT / 2f, Rayo.DRAW_WIDTH, Rayo.DRAW_HEIGHT); } } private void renderBullet() { Iterator<Bullet> i = oWorld.arrBullets.iterator(); while (i.hasNext()) { Bullet obj = i.next(); batcher.draw(Assets.bullet, obj.position.x - Bullet.SIZE / 2f, obj.position.y - Bullet.SIZE / 2f, Bullet.SIZE, Bullet.SIZE); } } }
Personaje.java
public class Personaje { public final static int STATE_NORMAL = 0; public final static int STATE_DEAD = 1; public int state; public final static float DRAW_WIDTH = .75f; public final static float DRAW_HEIGTH = .8f; public final static float WIDTH = .4f; public final static float HEIGTH = .6f; final float VELOCIDAD_JUMP = 7.5f; final float VELOCIDAD_X = 5; public final float DURATION_BUBBLE = 3; public float durationBubble; public final float DURATION_JETPACK = 3; public float durationJetPack; final public Vector2 position; public Vector2 velocidad; public float angleDeg; public float stateTime; boolean didJump; public boolean isBubble; public boolean isJetPack; public Personaje(float x, float y) { position = new Vector2(x, y); velocidad = new Vector2(); stateTime = 0; state = STATE_NORMAL; } public void update(Body body, float delta, float acelX) { position.x = body.getPosition().x; position.y = body.getPosition().y; velocidad = body.getLinearVelocity(); if (state == STATE_NORMAL) { if (didJump) { didJump = false; stateTime = 0; velocidad.y = VELOCIDAD_JUMP; } velocidad.x = acelX * VELOCIDAD_X; if (isBubble) { durationBubble += delta; if (durationBubble >= DURATION_BUBBLE) { durationBubble = 0; isBubble = false; } } if (isJetPack) { durationJetPack += delta; if (durationJetPack >= DURATION_JETPACK) { durationJetPack = 0; isJetPack = false; } velocidad.y = VELOCIDAD_JUMP; } } else { body.setAngularVelocity(MathUtils.degRad * 360); velocidad.x = 0; } body.setLinearVelocity(velocidad); if (position.x >= Screens.WORLD_WIDTH) { position.x = 0; body.setTransform(position, 0); } else if (position.x <= 0) { position.x = Screens.WORLD_WIDTH; body.setTransform(position, 0); } angleDeg = body.getAngle() * MathUtils.radDeg; velocidad = body.getLinearVelocity(); stateTime += delta; } public void jump() { didJump = true; } public void hit() { if (state == STATE_NORMAL && !isBubble && !isJetPack) { state = STATE_DEAD; stateTime = 0; } } public void die() { if (state == STATE_NORMAL) { state = STATE_DEAD; stateTime = 0; } } public void setBubble() { if (state == STATE_NORMAL) { isBubble = true; durationBubble = 0; } } public void setJetPack() { if (state == STATE_NORMAL) { isJetPack = true; durationJetPack = 0; } } }
MainMenuScreen.java
public class MainMenuScreen extends Screens { Image titulo; TextButton btShop, btPlay, btLeaderboard, btRate; Button btMusica; Label lbBestScore; public MainMenuScreen(final MainSuperJumper game) { super(game); titulo = new Image(Assets.titulo); titulo.setPosition(SCREEN_WIDTH / 2f - titulo.getWidth() / 2f, 800); titulo.addAction(Actions.sequence(Actions.moveTo(titulo.getX(), 600, 1, Interpolation.bounceOut), Actions.run(new Runnable() { @Override public void run() { stage.addActor(lbBestScore); } }))); lbBestScore = new Label("Best score " + Settings.bestScore, Assets.labelStyleChico); lbBestScore.setPosition(SCREEN_WIDTH / 2f - lbBestScore.getWidth() / 2f, 570); lbBestScore.getColor().a = 0; lbBestScore.addAction(Actions.alpha(1, .25f)); btPlay = new TextButton("Play", Assets.textButtonStyleGrande); btPlay.setPosition(SCREEN_WIDTH / 2f - btPlay.getWidth() / 2f, 440); btPlay.pad(10); btPlay.pack(); addEfectoPress(btPlay); btPlay.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { changeScreenWithFadeOut(GameScreen.class, game); } }); btShop = new TextButton("Shop", Assets.textButtonStyleGrande); btShop.setPosition(SCREEN_WIDTH / 2f - btShop.getWidth() / 2f, 340); btShop.pad(10); btShop.pack(); addEfectoPress(btShop); btShop.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { } }); btRate = new TextButton("Rate", Assets.textButtonStyleGrande); btRate.setPosition(SCREEN_WIDTH / 2f - btRate.getWidth() / 2f, 340); btRate.pad(10); btRate.pack(); addEfectoPress(btRate); btRate.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { game.reqHandler.showRater(); } }); btLeaderboard = new TextButton("Leaderboard", Assets.textButtonStyleGrande); btLeaderboard.pad(10); btLeaderboard.pack(); btLeaderboard.setPosition(SCREEN_WIDTH / 2f - btLeaderboard.getWidth() / 2f, 240); addEfectoPress(btLeaderboard); btLeaderboard.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { if (game.gameServiceHandler.isSignedIn()) game.gameServiceHandler.getLeaderboard(); else game.gameServiceHandler.signIn(); } }); stage.addActor(titulo); stage.addActor(btPlay); stage.addActor(btRate); // stage.addActor(btShop); stage.addActor(btLeaderboard); } @Override public void update(float delta) { } @Override public void draw(float delta) { batcher.begin(); batcher.draw(Assets.fondo, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); batcher.draw(Assets.plataformaBeigeBroken, 100, 100, 125, 45); batcher.draw(Assets.plataformaBlue, 350, 280, 125, 45); batcher.draw(Assets.plataformaMulticolor, 25, 430, 125, 45); batcher.draw(Assets.personajeJump, 25, 270, 75, 80); batcher.draw(Assets.nubeHappy, 350, 500, 95, 60); batcher.end(); } @Override public boolean keyDown(int keycode) { if (keycode == Keys.ESCAPE || keycode == Keys.BACK) { Gdx.app.exit(); } return super.keyDown(keycode); } }
Screens.java
public abstract class Screens extends InputAdapter implements Screen { public static final int SCREEN_WIDTH = 480; public static final int SCREEN_HEIGHT = 800; public static final float WORLD_WIDTH = 4.8f; public static final float WORLD_HEIGHT = 8f; public MainSuperJumper game; public OrthographicCamera oCam; public SpriteBatch batcher; public Stage stage; protected Music music; public Screens(MainSuperJumper game) { this.stage = game.stage; this.stage.clear(); this.batcher = game.batcher; this.game = game; oCam = new OrthographicCamera(SCREEN_WIDTH, SCREEN_HEIGHT); oCam.position.set(SCREEN_WIDTH / 2f, SCREEN_HEIGHT / 2f, 0); InputMultiplexer input = new InputMultiplexer(this, stage); Gdx.input.setInputProcessor(input); } @Override public void render(float delta) { if (delta > .1f) delta = .1f; update(delta); stage.act(delta); oCam.update(); batcher.setProjectionMatrix(oCam.combined); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); draw(delta); stage.draw(); } public void addEfectoPress(final Actor actor) { actor.addListener(new InputListener() { @Override public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { actor.setPosition(actor.getX(), actor.getY() - 5); event.stop(); return true; } @Override public void touchUp(InputEvent event, float x, float y, int pointer, int button) { actor.setPosition(actor.getX(), actor.getY() + 5); } }); } Image blackFadeOut; public void changeScreenWithFadeOut(final Class<?> newScreen, final MainSuperJumper game) { blackFadeOut = new Image(Assets.pixelNegro); blackFadeOut.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); blackFadeOut.getColor().a = 0; blackFadeOut.addAction(Actions.sequence(Actions.fadeIn(.5f), Actions.run(new Runnable() { @Override public void run() { if (newScreen == GameScreen.class) { game.setScreen(new GameScreen(game)); } else if (newScreen == MainMenuScreen.class) { game.setScreen(new MainMenuScreen(game)); } // else if (newScreen == ShopScreen.class) // game.setScreen(new ShopScreen(game)); // El blackFadeOut se remueve del stage cuando se le da new Screens(game) "Revisar el constructor de la clase Screens" por lo que no hay necesidad de hacer // blackFadeout.remove(); } }))); Label lbl = new Label("Loading..", Assets.labelStyleGrande); lbl.setPosition(SCREEN_WIDTH / 2f - lbl.getWidth() / 2f, SCREEN_HEIGHT / 2f - lbl.getHeight() / 2f); lbl.getColor().a = 0; lbl.addAction(Actions.fadeIn(.6f)); stage.addActor(blackFadeOut); stage.addActor(lbl); } public abstract void update(float delta); public abstract void draw(float delta); @Override public void resize(int width, int height) { stage.getViewport().update(width, height, true); } @Override public void show() { } @Override public void hide() { if (music != null) { music.stop(); music.dispose(); music = null; } Settings.save(); } @Override public void pause() { } @Override public void resume() { } @Override public void dispose() { batcher.dispose(); } }
2.Thành viên và source code
Thành viên : Ngô Mạnh Thông , Trịnh Ngọc Quang
Lớp : 22CDTH11
source code :