I have been making a simple game using LibGDX and now I am trying to add a health bar in my game.
I have successfully added the health bar in the game and it is working fine at this moment.
The problem , however, is how to further modify this code like professionals do.
I am still in learning process so I have been trying to figure how to further make it look
better, succinct, and professional but wan't able to furnish it further.
I have pasted my HealthBar class code below. I will appreciate any suggestion so that I can think better and efficient when writing any codes in future.
public class HealthBar extends Actor{
protected float MaxHealthX;
protected static float HealthBarY= 36;
float decreaseRate = 0;
float addHealth = 0;
float deductHealth = 0;
ShapeRenderer sr;
static private boolean projectionMatrixSet;
private boolean isHitE = false;
private boolean isHitI = false;
float totalSubractedHP = 0;
float totalAddedHP = 0;
public HealthBar(){
sr = new ShapeRenderer();
projectionMatrixSet = false;
}
#Override
public void draw(Batch batch, float parentAlpha){
//if a main character is hit by enemy
if(isHitE==true){
//subtractHP();
totalSubractedHP += 1;
isHitE = false;
}
if(isHitI==true){
totalAddedHP += 10;
isHitI = false;
}
MaxHealthX=296-decreaseRate+totalAddedHP-totalSubractedHP;
batch.end();
if(!projectionMatrixSet){
sr.setProjectionMatrix(batch.getProjectionMatrix());
}
sr.begin(ShapeType.Filled);
sr.setColor(Color.BLACK);
sr.rect(40,650,300,40);
if(isOutOfHealth() == false){
sr.setColor(Color.RED);
sr.rect(42, 652, MaxHealthX, HealthBarY);
}
sr.end();
batch.begin();
}
//updating health decrease rate as time passes by
public void updateHealthBar(float delta) {
decreaseRate += 10*delta;
}
//checks whether health is greater than zero
public boolean isOutOfHealth(){
if(MaxHealthX > 0){
return false;
}else{
return true;
}
}
//checking if hit by enemy
public boolean isHitByEnemy(){
isHitE = true;
return isHitE;
}
public boolean isHitByItem(){
isHitI = true;
return isHitI;
}
ShapeRenderer is normaly only used for debuging. In the endgame most times only SpriteBatch is used.
In the draw method you call batch.end() which calls flush(). This method is a bit "heavy" and should only be called, if it is really neccessary. So in your case it would be better to use batch instead of ShapeRenderer to draw the whole HealthBar.
Even better:
Use the Scene2D Progressbar, which should be exactly what you are looking for.
This ProgressBar need a range (for example min = 0, max = 100), a stepSize (for example 1.0) a boolean vertical, and a ProgressBarStyle.
The ProgressBarStyle in your case just needs 2 Drawables:
backgroung
disabledBackground
You can then use setValue(maxHealthX), which will set the background from 0-maxHealthX (rounded to the nearest stepSize) and disabledBackground from maxHealthX-end of progressbar.
This is how you can do it ,implement logic your self
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class MyGdxGame extends ApplicationAdapter {
SpriteBatch batch;
int i=0;
Texture texture,texture2;
#Override
public void create () {
batch = new SpriteBatch();
initTestObjects() ;
}
#Override
public void render () {
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(texture2,100,100,300,20);
batch.draw(texture,100,100,i,20);
if(i>300)
{
i=0;
}
i++;
batch.end();
}
private void initTestObjects() {
int width =1 ;
int height = 1;
Pixmap pixmap = createProceduralPixmap(width, height,0,1,0);
Pixmap pixmap2 = createProceduralPixmap(width, height,1,0,0);
texture = new Texture(pixmap);
texture2 = new Texture(pixmap2);
}
private Pixmap createProceduralPixmap (int width, int height,int r,int g,int b) {
Pixmap pixmap = new Pixmap(width, height, Format.RGBA8888);
pixmap.setColor(r, g, b, 1);
pixmap.fill();
return pixmap;
}
}
Related
I'm trying to develop a small tower defense game with libGDX and am getting the following exception:
Exception in thread "LWJGL Application" java.lang.NullPointerException
at com.badlogic.gdx.graphics.g2d.SpriteBatch.switchTexture(SpriteBatch.java:1067)
at com.badlogic.gdx.graphics.g2d.SpriteBatch.draw(SpriteBatch.java:558)
at com.badlogic.gdx.graphics.g2d.Sprite.draw(Sprite.java:517)
at levels.AISprite.draw(AISprite.java:33)
at levels.levelGenerator.render(levelGenerator.java:44)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:232)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:127)
I understand that there is something that is not initialized, but what? Would be really happy if you could help me and explain whats the issue.
I would also be glad if you could improve my code! Thanks in advance
Code (only where the magic happens):
levelGenerator Class
public class levelGenerator extends ApplicationAdapter {
private final String level;
SpriteBatch batch;
Texture img;
Scorpion scorpion;
private Array<AISprite> aiSprites;
public levelGenerator(String level){
this.level = level;
}
#Override
public void create () {
Gdx.graphics.setTitle("Tower Defense Game");
scorpion = new Scorpion();
img = new Texture(level);
scorpion.createImage();
aiSprites = new Array<AISprite>();
aiSprites.add(new AISprite(scorpion, LevelOne.levelOnePath()));
}
public void render () {
batch = new SpriteBatch();
batch.begin();
//just the level image background
batch.draw(img, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
scorpion.renderImage();
for(AISprite aiSprite: aiSprites){
aiSprite.draw(batch);
}
for(AISprite aiSprite: aiSprites){
Vector2 previous = aiSprite.getPath().first();
for(Vector2 waypoint: aiSprite.getPath()){
previous = waypoint;
}
}
}
#Override
public void dispose () {
batch.dispose();
img.dispose();
scorpion.disposeImage();
}
}
Entity Class:
public class Entity extends Sprite {
String atlasPath;
private Animation<TextureRegion> animation;
private TextureAtlas entityAtlas;
private float timePassed = 0;
SpriteBatch batch;
public Entity(String atlasPath){
this.atlasPath = atlasPath;
}
public void createImage(){
// path for scorpion atlas file: "assetsPack/scorpions/scorpionRunning/scorpionPack.atlas"
entityAtlas = new TextureAtlas(Gdx.files.internal(atlasPath));
animation = new Animation<TextureRegion>(1/40f, entityAtlas.getRegions());
}
public void renderImage(){
batch = new SpriteBatch();
batch.begin();
timePassed += Gdx.graphics.getDeltaTime();
batch.draw(animation.getKeyFrame(timePassed, true), 0, 0);
batch.end();
}
public void disposeImage(){
entityAtlas.dispose();
}
}
Scorpion (Entity) Class:
public class Scorpion extends Entity {
public Scorpion(){
super("assetsPack/scorpions/scorpionRunning/scorpionPack.atlas");
}
Next class is the one for the pathfinding of the entities
public class AISprite extends Sprite {
private Vector2 velocity = new Vector2();
private float speed = 100, tolerance = 3;
public Array<Vector2> getPath() {
return path;
}
private Array<Vector2> path;
private int waypoint = 0;
public AISprite(Entity entity, Array<Vector2> path){
super(entity);
this.path = path;
}
public void draw(SpriteBatch spriteBatch){
update(Gdx.graphics.getDeltaTime());
super.draw(spriteBatch);
}
public void update(float delta){
float angle = (float) Math.atan2(path.get(waypoint).y - getY(), path.get(waypoint).x - getX());
velocity.set((float) Math.cos(angle) * speed, (float) Math.sin(angle) * speed);
setPosition(getX() + velocity.x * delta, getY() + velocity.y * delta);
if(isWaypointReached()){
setPosition(path.get(waypoint).x, path.get(waypoint).y);
if(waypoint + 1 >= path.size){
waypoint = 0;
}
else{
waypoint++;
}
}
}
public boolean isWaypointReached(){
return path.get(waypoint).x - getX() <= speed / tolerance * Gdx.graphics.getDeltaTime() && path.get(waypoint).y - getY() <= speed / tolerance * Gdx.graphics.getDeltaTime() ;
}
}
use a debugger, set a breakpoint on levels.levelGenerator.render(levelGenerator.java:44), and check what causes the erro .... if you never used a debugger, I strongly(!!!) recommend you learn how to use one before you continue with libgdx
Make sure that all your Gdx calls are made after the create() method is called. All gdx objects are null before that point, so calls such as Gdx.graphics.(...) or Gdx.app.(...) or Gdx.audio.(...) etc. will throw a NPE
I want to make a game wherein when the main character sprite's X coordinate is less than the middle of the screen, he moves to the right and when it's more than the middle of the screen, he moves to the left. The sprite's animation changes when he is moving and when he is still (after reaching its destination). What I want to know is how can I do this when the sprite and its code for animation is in one class and the code for changing its X coordinate is in another class? Is it best to draw the same sprite in every class? How can I change the sprite when it is moving horizontally and when it is still? I plan to separate the code for what the sprite's actions will be in different classes because i want to call them randomly. Here is my code for the sprite's animation and i have no class for changing the x coordinate yet :
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.jpfalmazan.ninjaassault.NinjaAssault;
public class MainScreen implements Screen {
private static final int FRAME_COLS = 3;
private static final int FRAME_ROWS = 2;
Animation walkAnimation;
Texture walkSheet = new Texture ("ninjaWalk.png");
TextureRegion[] walkFrames;
TextureRegion currentFrame;
Texture holdStart;
float stateTime;
public Texture background;
private NinjaAssault game;
private Music BackgroundSFX;
public float screenWidth = Gdx.graphics.getWidth();
public float screenHeight = Gdx.graphics.getHeight();
float x = screenWidth/2;
float y = screenHeight/2;
public float walkSheetWidth = walkSheet.getWidth();
public float walkSheetHeight = walkSheet.getHeight();
public MainScreen (NinjaAssault game){
this.game = game;
}
#Override
public void show(){
background = new Texture("BGBlue.png");
holdStart = new Texture ("HoldStart.png");
BackgroundSFX = Gdx.audio.newMusic(Gdx.files.internal("data/RADWIMPS-iindesuka.mp3"));
TextureRegion[][] tmp = TextureRegion.split(walkSheet, (int )walkSheetWidth/FRAME_COLS, (int) walkSheetHeight/FRAME_ROWS);
walkFrames = new TextureRegion[FRAME_COLS*FRAME_ROWS];
int index = 0;
for (int i = 0; i < FRAME_ROWS; i++){
for (int j = 0; j < FRAME_COLS; j++) {
walkFrames[index++] = tmp[i][j];
}
}
walkAnimation = new Animation(0.0887f, walkFrames);
stateTime = 0f;
}
#Override
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stateTime += Gdx.graphics.getDeltaTime();
currentFrame = walkAnimation.getKeyFrame(stateTime, true);
float hsWidth = holdStart.getWidth();
float hsHeight = holdStart.getHeight();
float currentFrameWidth = (float)(screenHeight*0.15);
float currentFrameHeight = (float)(screenHeight*0.15);
float holdStartWidth = (float)(screenWidth * 0.75);
game.batch.begin();
game.batch.draw(background,0,0, screenWidth,screenHeight);
BackgroundSFX.play();
game.batch.draw(currentFrame, x -currentFrameWidth/2, 0,currentFrameWidth,currentFrameHeight);
game.batch.draw(holdStart, (screenWidth / 2 - (holdStartWidth / 2)), (float) (screenHeight * 0.5), holdStartWidth, holdStartWidth * (hsHeight / hsWidth));
game.batch.end();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
BackgroundSFX.dispose();
background.dispose();
walkSheet.dispose();
holdStart.dispose();
}
}
I tried to research on how to do this but the answers I get wasn't that helpful.
Simplest way is to create a Player class and put all the code for the animation and frames in there. Then give it a way to save its position. Like a vector or just a float for the x coordinate. Or even better, use a Rectangle. A rectangle will make moving and collision detection much easier.
Something like this:
public class Player{
private Animation walkAnimation;
private Texture walkSheet;
private TextureRegion[] walkFrames;
private TextureRegion currentFrame;
private float stateTime;
private Rectangle bound; //used for positioning and collision detection
public Player(float x, float y, float width, float height){
bound = new Rectangle();
bound.x = x;
bound.y = y;
bound.width = width;
bound.height = height;
walkSheet = new Texture ("ninjaWalk.png");
TextureRegion[][] tmp = TextureRegion.split(walkSheet,(int)walkSheetWidth/FRAME_COLS, (int) walkSheetHeight/FRAME_ROWS);
walkFrames = new TextureRegion[FRAME_COLS*FRAME_ROWS];
int index = 0;
for (int i = 0; i < FRAME_ROWS; i++){
for (int j = 0; j < FRAME_COLS; j++) {
walkFrames[index++] = tmp[i][j];
}
}
walkAnimation = new Animation(0.0887f, walkFrames);
stateTime = 0f;
}
public rectangle getBound(){
return bound;
}
public void update(float delta){
statetime += delta;
currentFrame = walkAnimation.getKeyFrame(stateTime, true);
}
public TextureRegion getCurrentFrame(){
return currentFrame;
}
}
This is just a quick untested example.
You say you want to move the player from another class. I don't know how you plan to do that, but all you need to do to move the player is to manipulate the x and y of the bound.
Just some other comments on you code:
#Override
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
player.update(delta); // to update the player
/***
* This does not have to be set every single frame. Move it to show()
*
float hsWidth = holdStart.getWidth();
float hsHeight = holdStart.getHeight();
float currentFrameWidth = (float)(screenHeight*0.15);
float currentFrameHeight = (float)(screenHeight*0.15);
float holdStartWidth = (float)(screenWidth * 0.75);
****************************************************/
BackgroundSFX.play(); // I am sure you don't need to start playing this every single frame? 60 times a second.
game.batch.begin();
game.batch.draw(background,0,0, screenWidth,screenHeight);
game.batch.draw(player.getCurrentFrame(), player.getBound().x, player.getbound().y, player.getBound().width, player.getBound().height)
game.batch.draw(holdStart, (screenWidth / 2 - (holdStartWidth / 2)), (float) (screenHeight * 0.5), holdStartWidth, holdStartWidth * (hsHeight / hsWidth));
game.batch.end();
}
Here is my Core project :
public class GameClass extends Game {
public static int screenWidth, screenHeight;
public static CustomScreen currentScreen;
public static PlayScreen playScreen;
#Override
public void create () {
screenWidth = Gdx.graphics.getWidth();
screenHeight = Gdx.graphics.getHeight();
CustomScreen.initialize();
playScreen = new PlayScreen(this);
SetScreen(playScreen);
}
public void SetScreen(CustomScreen screen) {
currentScreen = screen;
setScreen(currentScreen);
}
}
public abstract class CustomScreen implements Screen {
GameClass game;
static BitmapFont font;
static SpriteBatch batcher;
static OrthographicCamera cam;
public CustomScreen(GameClass game) {
this.game = game;
}
public static void initialize() {
cam = new OrthographicCamera();
cam.setToOrtho(true, GameClass.screenWidth, GameClass.screenHeight);
batcher = new SpriteBatch();
batcher.setProjectionMatrix(cam.combined);
font = new BitmapFont();
font.setScale(4f, -4f);
}
public void Clear() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
}
#Override
public abstract void render(float delta);
}
public class PlayScreen extends CustomScreen {
public static final int speed = 300;
public ArrayList<Entity> entityList;
Random rand = new Random();
float timer = rand.nextInt(2) + rand.nextFloat();
public PlayScreen(GameClass game) {
super(game);
entityList = new ArrayList<Entity>();
}
void update(float delta) {
timer -= delta;
if (timer <= 0) {
entityList.add(new Enemy(GameClass.screenWidth, rand.nextInt(GameClass.screenHeight - Enemy.Height)));
timer += rand.nextInt(2) + rand.nextFloat() + 1/2;
}
for (int i = entityList.size(); i > 0; --i)
entityList.get(i-1).update(delta);
}
#Override
public void render(float delta) {
Clear();
update(delta);
batcher.begin();
for (int i = 0; i < entityList.size(); ++i) {
entityList.get(i).Display(batcher);
}
if (entityList.size() > 1)
System.out.println(entityList.get(1).posX - entityList.get(0).posX);
batcher.end();
}
}
public abstract class Entity {
protected Sprite sprite;
public int posX, posY, width, height;
public Entity(int posX, int posY, int width, int height) {
this.posX = posX;
this.posY = posY;
this.width = width;
this.height = height;
}
public abstract void update(float delta);
public void Display(SpriteBatch batcher) {
batcher.draw(sprite, posX, posY, width, height);
}
}
public class Enemy extends Entity {
static Sprite texture = new Sprite(new Texture(Gdx.files.internal("enemy.png")));
public static int Width = 300, Height = 200;
public Enemy(int posX, int posY) {
super(posX, posY, Width, Height);
this.sprite = Enemy.texture;
}
#Override
public void update(float delta, int i) {
posX -= delta * PlayScreen.speed;
if (posX + width < 0) {
GameClass.playScreen.entityList.remove(this);
}
}
}
In PlayScreen, enemies keep spawning randomly, and they move from the right of the screen to the left, at a constant speed (final int 300). But when they reach the left edge of the screen (when posX <= 0), they slow down, for an unknown reason. The thing is, I didn't program anything to happen when an enemy reaches the edge of the screen. (I programmed them to disappear when they are completely outside of the screen, when posX + width <= 0, but it has nothing to do with my problem, since even when I remove this, they keep slowing down when reaching the edge of the screen).
It happends with both the desktop and the android projects, so this definitely comes from the Core project.
I have no idea why this happens, this is really, really awkward.
Here is a couple picture to show you what happens.
http://i.stack.imgur.com/DrOSH.png
http://i.stack.imgur.com/Zjtju.png
We can see that the two enemies are closer to each other on the second picture than on the first one.
You can set PlayScreen.speed to 100 instead of 300, it will be even more noticeable.
And if you set it to a low enough value, like 20, enemies will not just slow down, they will basically stop moving.
I'm lost and have no idea how to fix this problem. If you have any, please feel free to share it.
I fixed it. The problem was that Enemy.posX was an int instead of a float.
I'm not quite certain but I'd guess that your calculations in the Enemy class involving delta get rounded (since PlayScreen.Speed is an integer).
Having a low enough PlayScreen.Speed or a low enough delta will result in delta * PlayScreen.Speed being 0.something which will get cut off to 0 when converting to an integer, resulting in posX never changing.
I usually use floats for all calculations involving positions (e.g. posX and posY and so on...) so that this cutting off doesn't happen until something gets drawn on the screen (since pixels are always integers). This produces more accurate results and solves a lot of problems around movement on the screen.
I have made a class for the level generation and have got so far with it:
public class LevelGenerator {
private Sprite environment;
private float leftEdge, rightEdge, minGap, maxGap, y;
public Enemy enemy;
public LevelGenerator(Sprite environment, float leftEdge, float rightEdge,
float minGap, float maxGap) {
this.environment = environment;
this.leftEdge = leftEdge;
this.rightEdge = rightEdge;
this.minGap = minGap;
this.maxGap = maxGap;
}
public void generate(float topEdge){
if(y + MathUtils.random(minGap, maxGap) < topEdge)
return;
y = topEdge;
float x = MathUtils.random(leftEdge, rightEdge);
}
Basically, what I want to happen is for the enemy block to randomly generate on the sides of the screen. Here is the enemy block class (very simple):
public class Enemy extends Sprite{
public Enemy(Sprite sprite) {
super(sprite);
}
#Override
public void draw(Batch spriteBatch){
super.draw(spriteBatch);
}
}
This is what the game looks like at the moment when the block is just simply drawn on the game screen in a static position: http://i.imgur.com/SIt18Qn.png. What I am trying to achieve is for these "enemy" blocks to spawn randomly on either side of the screen but I can't seem to figure out a way to do it with the code I have so far.
Thank you!
I could not test but I think it will be fine, you have a rectangle if you want to see if it collides with another actor, if so updates its position in the update and draw method, and ramdon method start customizing to see if the coordinates, which colicionan be assigned to another actor rectagulo enemy or bye.
public class overFlowEnemy extends Sprite {
private final float maxH = Gdx.graphics.getHeight();
private final float maxW = Gdx.graphics.getWidth();
private Rectangle rectangle;
private Random random = new Random();
private float inttt = 0;
private float randomN = 0;
private boolean hasCollided = false;
public overFlowEnemy(Sprite sprite) {
super(sprite);
crearEnemigo();
rectangle = new Rectangle(getX(), getY(), getWidth(), getHeight());
}
#Override
public void draw(Batch spriteBatch) {
super.draw(spriteBatch);
}
private void crearEnemigo(){
setX(RandomNumber((int)maxW));
setY(RandomNumber((int)maxH));
}
private int RandomNumber(int pos) {
random.setSeed(System.nanoTime() * (long) inttt);
this.randomN = random.nextInt(pos);
inttt += randomN;
return (int)randomN;
}
public Rectangle getColliderActor(){
return this.rectangle;
}
}
the class as this should create a random enemy.
Edit: rereading your question, is that my English is not very good, and I think you wanted to be drawn only on the sides of the screen if so, tell me or adapts the class because when you create thought, which was across the screen.
I just added another class, if you can and want to work as you tell me which is correct, and delete the other.
public class overFlow extends Sprite {
private final float maxH = Gdx.graphics.getHeight();
private final float maxW = Gdx.graphics.getWidth();
private Rectangle rectangle;
private Random random = new Random();
private float inttt = 0;
private float randomN = 0;
private boolean hasCollided = false;
public overFlow(Sprite sprite) {
super(sprite);
crearEnemigo();
rectangle = new Rectangle(getX(), getY(), getWidth(), getHeight());
}
#Override
public void draw(Batch spriteBatch) {
super.draw(spriteBatch);
}
private void crearEnemigo(){
setX(RandomNumber((int)maxW, true));
setY(RandomNumber((int)maxH, false));
}
private int RandomNumber(int pos, boolean w) {
random.setSeed(System.nanoTime() * (long) inttt);
if (w = true){
this.randomN = random.nextInt((pos));
if(randomN % 2 == 0){
randomN = (pos - getWidth());
}else{
randomN = 0; //left screen
}
}else{
this.randomN = random.nextInt(pos - (int)getHeight());
}
inttt += randomN;
return (int)randomN;
}
public Rectangle getColliderActor(){
return this.rectangle;
}
}
In my libgdx game it functions how i want it to but when i exit the game it starts of from where i was before, i want it to restart. The code is as follows.
package com.me.fixGame;
import java.util.Random;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
//import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.utils.Scaling;
import com.sun.jmx.snmp.tasks.Task;
public class fixGame implements ApplicationListener {
SpriteBatch batch;
SpriteBatch spriteBatch;
Texture trash;
Texture paper;
SpriteBatch spritebatch;
Vector2 position;
Vector2 pas;
boolean collide;
boolean countMe=false;
Vector2 size;
Vector2 size2;
Vector2 pos;
Rectangle bounds;
float posSpeed=30;
Rectangle bounds2;
float delay = 1; // seconds
boolean counted= false;
int score = 3;
//Texture Gogreen;
String myScore;
Texture background;
CharSequence str = "Lives left: 3"; // = myScore;
CharSequence line = "Score: 0"; // = myScore;
String myLife;
int life=0;
BitmapFont font;
float x;
float y;
boolean collision = false;
#Override
public void create() {
//Gogreen = new Texture(Gdx.files.internal("data/gogreenNow.jpg"));
background = new Texture(Gdx.files.internal("data/trash.png"));
x= background.getWidth();
y=background.getHeight();
//float delaySeconds = 1;
spriteBatch = new SpriteBatch();
trash = new Texture(Gdx.files.internal("data/trash.png"));
paper = new Texture(Gdx.files.internal("data/paper1.jpg"));
position = new Vector2(100, 50);
pos = new Vector2(54, 14);
batch = new SpriteBatch();
BitmapFont font = new BitmapFont();
size2 = new Vector2(trash.getWidth() ,trash.getHeight() );
//size2.y = trash.getHeight();
//size2.x = trash.getWidth();
size = new Vector2(paper.getWidth() ,paper.getHeight());
bounds= new Rectangle(pos.x, pos.y, size.x, size.y);
bounds2= new Rectangle(position.x, position.y, size2.x, size2.y);
}
#Override
public void dispose() {
}
public void update(){
bounds.set(pos.x, pos.y, size.x, size.y);
bounds2.set(position.x, position.y, size2.x, size2.y);
float pos1=Gdx.input.getAccelerometerX();
//if(pos1<0)
// pos1=(-1)*pos1;
position.x = position.x - 5*pos1;
}
#Override
public void render() {
if(bounds.overlaps(bounds2)){
collision=true;
counted=true;
}else{
collision=false;
}
if(collision==true){
}
if(pos.y<640){
counted=false;
} else if(pos.y > 640 && collision==false && counted==false){
counted=true;
score= score-1;
myScore = "Lives left: " + score;
str = myScore;
}
if(bounds.overlaps(bounds2)){
countMe=true;
life= life+50;
myLife = "Score: " + life;
line = myLife;
}
if(position.x<0){
position.x= position.x+11;
}
if(position.x>425){
position.x= position.x-11;
}
update();
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
pos.y=pos.y-posSpeed;
//posSpeed = posSpeed+(2/3);
if(pos.y<0){
pos.y = 700;
Random randomGenerator = new Random();
pos.x = randomGenerator.nextInt(500);
}
BitmapFont font = new BitmapFont();
batch.begin();
batch.draw(background, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
if (!collision) {
batch.draw(paper, pos.x, pos.y);
}
//batch.draw(paper, pos.x, pos.y);
batch.draw(trash, position.x, position.y);
font.setScale(3);
font.setColor(0.0f, 0.0f, 1.0f,1.0f);
font.draw(batch, str, 300,900);
font.draw(batch, line, 300, 950);
batch.end();
font.dispose();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
I searched through out the web and I could not find anything. Does anybody have any answers?
Any help would be appreciated thanks in advance.
Are you talking about desktop or Android?
Assuming you're talking about Android, when the user exits the game, the pause() function is called. When the user goes back to the game, the resume() function is called.
I would bet that your game would "reset" if you ran some other apps between exiting and resuming the game. Normally people save the state of the game in pause() and then load it in resume(), but for your case, it sounds like you just want to reset it each time.
If all of the above is actually true for you, just reset the game state in the resume() function.
For Android: If the user presses the "Home" button or a call is incoming the games pause() method is called. If the user returns after the call or after some time normally resume() is called. But if the Android OS decided to close your app, create() will be called, and if you do not store savegames i am sure it would reset the game.
In your case the user did not exit the game but "pause" it by pressing "Home" button. To reset the game then, you could call dispose() in your pause() method, and in dispose you simply close your app. On Desktop pause() is called if you switch window or minimize the app, as far as i know. If you do not want to close the app in this case you have to controll, if it is desktop or android.