Back to project page RollOverSphere---a-simple-libgdx-game.
The source code is released under:
MIT License
If you think the Android project RollOverSphere---a-simple-libgdx-game listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.igorcrevar.rolloverchuck.scenes; /*from w ww . j a va 2s . c om*/ import java.util.Random; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.InputProcessor; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.glutils.ShaderProgram; import com.badlogic.gdx.math.Matrix4; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.math.collision.Sphere; import com.igorcrevar.rolloverchuck.GameConsts; import com.igorcrevar.rolloverchuck.GameData; import com.igorcrevar.rolloverchuck.GameManager; import com.igorcrevar.rolloverchuck.IActivityRequestHandler; import com.igorcrevar.rolloverchuck.IScene; import com.igorcrevar.rolloverchuck.ISceneManager; import com.igorcrevar.rolloverchuck.ISceneManager.GameState; import com.igorcrevar.rolloverchuck.ISceneManager.Type; import com.igorcrevar.rolloverchuck.objects.ChuckObject; import com.igorcrevar.rolloverchuck.objects.BoxObject; import com.igorcrevar.rolloverchuck.objects.FieldObject; import com.igorcrevar.rolloverchuck.objects.boxes.BoxManager; import com.igorcrevar.rolloverchuck.objects.boxes.BoxRegionManager; import com.igorcrevar.rolloverchuck.objects.boxes.BoxTypeFactory; import com.igorcrevar.rolloverchuck.objects.boxes.IBoxRegion; import com.igorcrevar.rolloverchuck.physics.CollisionSolver; import com.igorcrevar.rolloverchuck.physics.ICollisionIterationHandler; import com.igorcrevar.rolloverchuck.points.PointsManager; import com.igorcrevar.rolloverchuck.scenes.GameMode.IGameMode; import com.igorcrevar.rolloverchuck.utils.GameHelper; import com.igorcrevar.rolloverchuck.utils.Mathf; public class GameScene implements IScene, InputProcessor, ICollisionIterationHandler, IActivityRequestHandler.IConfirmDialogCallback { private Matrix4 projViewMatrix; private Matrix4 viewMatrix; private Vector3 lightPos; private Matrix4 tmpProjViewMatrix = new Matrix4(); private Matrix4 tmpViewMatrix = new Matrix4(); private Vector3 tmpVertex = new Vector3(); private GameManager gameManager; private ISceneManager sceneManager; private FieldObject field; private ChuckObject chuckObject; // (X, Y, pointer) private Vector3 lastTouchPointer = new Vector3(); // we want to prevent moving to mouch with one touch private float touchMovingDistance; // collision solver private CollisionSolver collisionSolver = new CollisionSolver(); private SpriteBatch spriteBatch = new SpriteBatch(); private PointsManager pointsManager = new PointsManager(); private BoxManager boxManager; private BoxRegionManager boxRegionManager; private Sphere boundingSphere1 = new Sphere(Vector3.X, 0.0f); private Sphere boundingSphere2 = new Sphere(Vector3.X, 0.0f); private Random random = new Random(); private float timer = 0; private float lastTimeBoxPickUp; private int pointsMulti; private float timeBoxGenerated; private float timeBonusBoxGenerated; private float timeNegativeBoxGenerated; private boolean shouldReturnToPrevScene; private IGameMode gameMode; private Sprite pointImage = new Sprite(); public GameScene(ISceneManager sceneManager) { this.sceneManager = sceneManager; this.gameManager = sceneManager.getGameManager(); float projAspect = (float)Gdx.graphics.getWidth() / Gdx.graphics.getHeight(); projViewMatrix = new Matrix4().setToProjection(0.1f, 1000.0f, 35.0f, projAspect); viewMatrix = new Matrix4().setToLookAt(new Vector3(0.0f, 34.0f, 30.0f), new Vector3(0.0f, 29.0f, 24.0f), Vector3.Y); projViewMatrix.mul(viewMatrix); lightPos = new Vector3(20.0f, 40.0f, 36.0f); field = new FieldObject(gameManager); chuckObject = new ChuckObject(gameManager); boxManager = new BoxManager(gameManager); boxRegionManager = new BoxRegionManager(gameManager.getGameData()); pointImage.setRegion(gameManager.getTextureAtlas("base").findRegion("point")); pointImage.setSize(60, 60); pointImage.setPosition(40, 850); } @Override public void init(ISceneManager sceneManager) { Gdx.input.setInputProcessor(this); // Use culling to remove back faces. Gdx.gl.glDisable(GL20.GL_CULL_FACE); Gdx.gl.glCullFace(GL20.GL_BACK); // Enable depth testing Gdx.gl.glEnable(GL20.GL_DEPTH_TEST); Gdx.gl.glDepthFunc(GL20.GL_LEQUAL); pointsManager.init(); chuckObject.init(); boxManager.init(); boxRegionManager.init(); timer = 0; lastTimeBoxPickUp = 0.0f; pointsMulti = 1; shouldReturnToPrevScene = false; sceneManager.getGameManager().getStars().init(sceneManager.getGameManager().getTextureAtlas("base").findRegion("star")); // box generator timeBoxGenerated = -10000f; // Immediately normal box should be generated timeNegativeBoxGenerated = 0.0f; timeBonusBoxGenerated = 0.0f; } @Override public void update(ISceneManager sceneManager, float deltaTime) { if (gameMode == null) { throw new IllegalArgumentException("Game mode not set!"); } if (sceneManager.isGamePaused()) { return; } if (shouldReturnToPrevScene) { // score/etc will be saved only if player played game at least for nnn long sceneManager.finishGame(timer > sceneManager.getGameManager().getGameData().MinTimeCountAsOnePlay); sceneManager.setScene(Type.IntroScene); return; } if (sceneManager.getGameState() == GameState.COUNTING) { updateCounting(deltaTime); } else { updateWorld(deltaTime); } // draw GameHelper.clearScreen(); GameHelper.setProjectionFor2D(spriteBatch, 1920, 1080); spriteBatch.begin(); sceneManager.getGameManager().getStars().update(deltaTime); sceneManager.getGameManager().getStars().draw(spriteBatch); spriteBatch.end(); Gdx.gl.glEnable(GL20.GL_BLEND); Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); // draw field Gdx.gl.glEnable(GL20.GL_TEXTURE_2D); Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0); tmpProjViewMatrix.set(projViewMatrix); field.draw(tmpProjViewMatrix); // draw shadows Gdx.gl.glDisable(GL20.GL_DEPTH_TEST); tmpProjViewMatrix.set(projViewMatrix); ShaderProgram sp = gameManager.getShader("shadow"); sp.begin(); sp.setUniformf(GameConsts.LightPosName, lightPos); sp.setUniformf("u_planeY", 0.0f + GameData.ObjectZero.y); chuckObject.drawShadow(sp, tmpProjViewMatrix); sp.end(); Gdx.gl.glEnable(GL20.GL_DEPTH_TEST); // chuck Gdx.gl.glEnable(GL20.GL_CULL_FACE); tmpProjViewMatrix.set(projViewMatrix); tmpViewMatrix.set(viewMatrix); chuckObject.draw(tmpProjViewMatrix, tmpViewMatrix, lightPos); // boxes Gdx.gl.glDisable(GL20.GL_CULL_FACE); tmpProjViewMatrix.set(projViewMatrix); tmpViewMatrix.set(viewMatrix); boxManager.draw(tmpProjViewMatrix, tmpViewMatrix, lightPos); // draw points GameHelper.setProjectionFor2D(spriteBatch, 1920, 1080); spriteBatch.begin(); pointImage.draw(spriteBatch); BitmapFont font = gameManager.getBitmapFont(); font.setScale(0.8f); pointsManager.draw(spriteBatch, font); font.setColor(Color.WHITE); font.draw(spriteBatch, GameHelper.getStringPoints(sceneManager.getCurrentScore()), 120, 900); if (sceneManager.getGameState() == GameState.COUNTING) { int valInt = (int)(4 - timer * 2); font.draw(spriteBatch, valInt > 0 ? String.valueOf(valInt) : "Go!", valInt > 0 ? 940 : 920, 940); font.setColor(Color.BLACK); String txt = "Slide to move ball!"; font.draw(spriteBatch, txt, GameHelper.getAlignedPosX(font, txt, 1920f) - 20f, 805f); font.setColor(Color.WHITE); font.draw(spriteBatch, txt, GameHelper.getAlignedPosX(font, txt, 1920f), 800f); } gameMode.drawSprites(font, spriteBatch); spriteBatch.end(); gameMode.postUpdate(spriteBatch); } @Override public void dispose(ISceneManager sceneManager) { spriteBatch.dispose(); gameMode.dispose(); } @Override public void leave(ISceneManager sceneManager) { } @Override public boolean keyDown(int keycode) { if(keycode == Keys.HOME) { Gdx.app.log("chuck", "GameScene home pressed"); } return true; } @Override public boolean keyUp(int keycode) { if (keycode == Keys.BACK || keycode == Keys.ESCAPE) { if (sceneManager.isGameActive()) { sceneManager.setGameState(GameState.PAUSED); sceneManager.getRequestHandler().confirmDialog("Quit current game?", this); } else { shouldReturnToPrevScene = true; } } return true; } @Override public boolean keyTyped(char character) { return false; } @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { lastTouchPointer.set(screenX, screenY, pointer); touchMovingDistance = 0f; return true; } @Override public boolean touchUp(int screenX, int screenY, int pointer, int button) { if (sceneManager.isGameOver()) { gameMode.touchUp(screenX, screenY, pointer, button); return true; } return true; } @Override public boolean touchDragged(int screenX, int screenY, int pointer) { if (sceneManager.isGameActive() && touchMovingDistance < gameManager.getGameData().ChuckAcc) { float dx = screenX - lastTouchPointer.x; float dz = screenY - lastTouchPointer.y; float incX = dx / Gdx.graphics.getWidth() * gameManager.getGameData().ChuckAcc; float incZ = dz / Gdx.graphics.getHeight() * gameManager.getGameData().ChuckAcc; touchMovingDistance += Math.sqrt(incX * incX + incZ * incZ); chuckObject.addMoving(incX, incZ); lastTouchPointer.set(screenX, screenY, pointer); } return true; } @Override public boolean mouseMoved(int screenX, int screenY) { return false; } @Override public boolean scrolled(int amount) { return false; } @Override public void confirmDialogResult(boolean result) { sceneManager.setGameState(GameState.Active); shouldReturnToPrevScene = result; } // called after every step of "physics" engine @Override public boolean iterationHandler(Vector3 position, float time, Object tag) { // set chuck bounding box and radius boundingSphere1.center.set(position); boundingSphere1.radius = Mathf.lerp(chuckObject.getPrevFrameRadius(), chuckObject.getCurrentRadius(), time); int boxIndex = boxManager.getAvailableCount() - 1; BoxObject boxObject; while ((boxObject = boxManager.getBoxObject(boxIndex)) != null) { // populate bounding sphere for box boundingSphere2.center.set(boxObject.GetPosition()); boundingSphere2.radius = boxObject.getScale() * 0.5f; // check collision between two spheres if (boundingSphere1.overlaps(boundingSphere2)) { // add points or power ups int points = boxObject.getPoints(); if (points > 0) { // point multiplicator! // if player pick up points really fast than points are multiplicated every time if (timer - lastTimeBoxPickUp < gameManager.getGameData().PointMultiplicatorTime) { pointsMulti = Math.min(pointsMulti * 2, gameManager.getGameData().PointMaxMultiplicator); } else { // not picked fast enough - reset multiplicator pointsMulti = 1; } // add score and update point manager addScore(points > 1 ? pointsMulti + points - 1 : pointsMulti, boxObject); // update time for multi bonus lastTimeBoxPickUp = timer; // remove collided box from available boxes list boxManager.remove(boxIndex); // generate new box immediately after picking up positive generateBox(0); } else if (points < 0) { // reset multi pointsMulti = 1; // add score addScore(points, boxObject); // remove collided box from available boxes list boxManager.remove(boxIndex); } else { boxObject.applyUpgrade(chuckObject); // remove collided box from available boxes list boxManager.remove(boxIndex); } } --boxIndex; } return false; } private void generateBox(int type) { IBoxRegion br = boxRegionManager.getOne(chuckObject.getCurrentPosition(), gameManager.getGameData().BoxDistanceSquared); if (br != null) { boxManager.add(br, gameManager.getGameData().BoxTimeToLive, BoxTypeFactory.create(type)); } } private void updateWorld(float deltaTime) { // generation of new boxes - only if game is active if (sceneManager.isGameActive()) { // standard box if (timer - timeBoxGenerated >= gameManager.getGameData().BoxGenerationTime) { timeBoxGenerated = timer; generateBox(0); // power ups (grow up/shrink) are (almost) completely random! // They can only be generated when new box is generated int val = random.nextInt(40); if (val == 5) { generateBox(1); } else if (val == 10) { generateBox(2); } } // bonus box if (timer - timeBonusBoxGenerated >= gameManager.getGameData().BoxBonusBoxGenerationTime) { timeBonusBoxGenerated = timer; generateBox(3); } // negative box if (timer - timeNegativeBoxGenerated >= gameManager.getGameData().BoxNegativeBoxGenerationTime) { timeNegativeBoxGenerated = timer; generateBox(4); } } // chuck update chuckObject.update(deltaTime); // boxes update boxManager.update(deltaTime); if (sceneManager.isGameActive()) { // detect collisions only if game is active ! collisionSolver.iterateOver(this, chuckObject.getPrevFramePosition(), chuckObject.getCurrentPosition(), null); } // update points pointsManager.update(deltaTime); // game mode update gameMode.update(timer, deltaTime); // icrement timer timer += deltaTime; } private void updateCounting(float deltaTime) { // chuck update chuckObject.update(deltaTime); Gdx.gl.glDisable(GL20.GL_CULL_FACE); timer += deltaTime; if (timer >= 2.0f) { timer = 0f; sceneManager.setGameState(GameState.Active); gameManager.playGameMusic(); } } private void addScore(int pointIncrement, BoxObject boxObject) { tmpVertex.set(boxObject.GetPosition()).add(GameData.ObjectZero).add(0f, 0.5f * boxObject.getScale(), 0.0f); tmpVertex.prj(projViewMatrix); // 1920 x 1080 is default virtual screen float x = 1920f * (tmpVertex.x + 1) / 2; float y = 1080f * (tmpVertex.y + 1) / 2; pointsManager.add(pointIncrement, x - 20.0f, y + 30.0f); // update points in scene manager sceneManager.addToScore(pointIncrement); } public void setGameMode(IGameMode gameMode) { this.gameMode = gameMode; field.setTexture(this.gameMode.getFieldTextureRegion()); } }