LibGDX visibility - java

Is there a way to check if my sprite is visible? For instance I have a specific sprite I want to appear only IF this other sprite isn't visible. Example "You Win" will only appear if you win the game and the "You Lose" sprite isn't already on the screen. Thanks!

Visibility of sprite can be maintained by extending Sprite class. Add data member in your extended Sprite Class and at run-time check your sprite is visible of not.
you can also fulfill your requirement by this :
private Sprite win,loose;
private SpriteBatch spriteBatch;
private DialogType dialogType;
#Override
public void create () {
dialogType=DialogType.NONE;
spriteBatch=new SpriteBatch();
win=new Sprite(...);
loose=new Sprite(...);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
spriteBatch.begin();
...
...
if(dialogType==WIN){
win.draw(spriteBatch);
}else if(dialogType==LOOSE){
loose.draw(spriteBatch);
}
spriteBatch.end();
}
public enum DialogType {
NONE,WIN,LOOSE
}

Seems like an overwhelm to do what you are trying to do, like I said in the comment with a simple boolean win,loose; you pretty much cover your example, or like other comment said you should not track the game state according with some sprite visibility make a enum and track the game state instead, like the other answer, BUT ima give you a solution
Use Image instead...
Image image = new Image(texture);
image.setBounds(0,0,100,100); // set x,y,width,height
stage.add(image); //add to stage
image.setVisible(false); //make it invisible
image.setVisible(true); //make it visible
image.isVisible(); //check if is visible

Related

How to create very simple pause/resume game in libgdx

i am newbie for libgdx,
How to create very simple pause/resume game in libgdx??
I'm trying to implement simple game using libgdx. I have want to create pause the game but don't know how to pause and resume game based on user input.Kindly suggest idea as well as some practical code to implement the same.I am using simple game code demonstrated in libgdx library. Thank you.
public class MyGdxGame extends ApplicationAdapter {
SpriteBatch batch;
Texture img;
float x;
float y;
#Override
public void create () {
batch = new SpriteBatch();
img = new Texture("badlogic.jpg");
}
#Override
public void render () {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
x= x+4;
if(Gdx.input.isKeyPressed(Input.Keys.P)){
// pause
}
batch.begin();
batch.draw(img, x, y);
batch.end();
}
#Override
public void dispose () {
batch.dispose();
img.dispose();
}
}
Press P key to press the game
if(Gdx.input.isKeyPressed(Input.Keys.P)){
// if(game.pause()){
game.resume();
}else{
game.pause();
}
}
any idea??? thanks
Your render method is called repeatable and what "paused" means is up to you. You have to implement your logic that handles "paused" state because that doesn't mean anything to libGDX.
If you want everything to freeze when game is paused but still to be drawn best way is (IMHO) to fully separate drawing from calculating (movements and stuff). So i.e. when your render method is called you will call your drawing method once (to draw the graphics) but you will also calculate how many times your calculation method should be call (to have same game speed independently on frame rate) and call it that many times.
Then when your game is paused you will just skip calling your calculation method and call only drawing method. So nothing will move and until you end your pause the same graphics will be drawn.
And to keep paused state you can have some boolean variable. Every time p key is pressed you should invert it, like:
if(Gdx.input.isKeyPressed(Input.Keys.P)){
paused = !paused;
}
or something (as #Tenfour04 suggested).

LibGDX Game Pause State: Animation flicker/bug

Im trying to implement a pause option for my following game. By pressing the back button my game should go to the updatePause() method. But instead it renders the latest 2-3 frames repeatedly. Making it look like it's "flickering".
By trying to prevent this I've added (in the comments) non-continously rendering which prevented the flickering. But then Im facing the problem that pressing the back-button more than once will render another frame. (one of those flickering frames). This is my code structure in short:
public class GameScreen implements Screen {
private static final int GAME_RUNNING = 0;
private static final int GAME_PAUSED = 1;
private static final int GAME_OVER = 2;
private static final int GAME_LEVEL_END = 3;
private int gameState;
private GdxGame game;
//create()
public GameScreen(final GdxGame game) {
//create all the stuff
}
#Override
public void render(float deltaTime) {
switch (gameState) {
case GAME_RUNNING:
updateRunning(deltaTime);
break;
case GAME_PAUSED:
updatePause(deltaTime);
break;
case GAME_OVER:
updateGameOver();
break;
}
}
public void updateRunning(float deltaTime) {
//draw section
if (gameState == GAME_RUNNING) {
game.batch.begin();
//Draw some stuff
game.batch.end();
//move section
handleInput();
}
}
public void updatePause(float deltaTime) {
//Gdx.graphics.setContinuousRendering(false);
//resume
if (Gdx.input.isTouched()) {
gameState = GAME_RUNNING;
//Gdx.graphics.setContinuousRendering(true);
return;
}
}
private void handleInput() {
//catch back button
Gdx.input.setCatchBackKey(true);
if (Gdx.input.isKeyJustPressed(Input.Keys.BACK)) {
gameState = GAME_PAUSED;
return;
}
}
}
Any tips to prevent the flickering?
The render() method is supposed to draw something to the screen. If it doesn't, then the contents of the back buffer will be undefined (so may contain a previous frame) and you get this flicker.
Disabling continuous rendering sounds like a good approach. Alternatively, continue drawing even if the game is paused.
As Thomas points out in his answer. It should be drawing every frame.
I haven't see you draw anything on screen yet, so backbuffer might just contain junk information. One way to solve this is to always clear the screen at the top of render(). This means when you switch immediately to another game state, it will make sure that screen is clear and no flickering result as you experienced.
public void render(float deltaTime) {
// clear screen
Gdx.gl.glClearColor(0f, 0f, 0f, 1.0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
...
}
As Thomas said: continue drawing is a way to fix it. So I drew the latest frame and disabled continous rendering after that. The result is having no bug at all and giving the CPU a rest.

How to manage screens

i'm making a game in libgdx but i'm new and i donĀ“t know if my code is the correct form or the best way to do it.
i'm trying to make the basis of the game:
a screen manager to implement a Menu,
an option screen
a loading screen
a game screen
a pause Screem
a game over screen
In the loading screen I like to do something like Dragon Ball when the loading screen allow us to make goku eat rice, the pause screen needs to draw some statistics and options something like Megaman or Castlevania, the menu do something when the player touch a button something like move the camera or open a door, or move to another "scenario" showing another options, and the game over screen needs to previously gives the player the opportunity to win some life to not lose the game.
I try to make this in this form:
I have the main class of the game with the constructor, and the overriden metods create(), render(), resize() and dispose(), the variables for a camera, a viewport, a Spritebatch, a int to store the current screen, and a manager for the screens.
public class BOS_Project extends Game {
OrthographicCamera camera;
Viewport viewport;
SpriteBatch batch;
AssetManager manager = new AssetManager();
int actualScreen = 0;
public BOS_Project(){
camera = new OrthographicCamera();
camera.setToOrtho(false, screenWidth, screenHeight);
viewport = new FitViewport(screenWidth, screenHeight);
}
#Override
public void create(){
batch = new SpriteBatch();
}
#Override
public void render(){
actualScreen = 1;
ScreenManager.getInstance().showScreen(1, this);
super.render();
}
#Override
public void resize(int width, int height){
viewport.update(width, height);
}
#Override
public void dispose(){
batch.dispose();
}
}
Also the class ScreenManager is singleton, and
public class ScreenManager{
private static ScreenManager instance;
private Game game;
Screen screen;
private ScreenManager(){
super();
}
public static ScreenManager getInstance(){
if(instance == null){
instance = new ScreenManager();
}
return instance;
}
public void initialize(Game game){
this.game = game;
}
public void showScreen(int currentscreen, BOS_Project game){
if(currentscreen == 1){
if(screen!=null)
screen.dispose();
screen = new LoadingScreen(game, game.actualScreen);
game.setScreen(screen);
}else if(currentscreen == 2){
if(screen!=null)
screen.dispose();
screen = new GameScreen(game);
game.setScreen(screen);
}else{
if(screen!=null)
screen.dispose();
screen = new MenuScreen(game);
game.setScreen(screen);
}
}
The other classes are the MenuScreen, GameScreen and Loading Screen.
Loading Screen:
public LoadingScreen(BOS_Project game2, int screen2){
game = game2;
screen = screen2;
game.manager.load("button.png", Texture.class);
game.manager.finishLoadingAsset("button.png");
sprite1 = new Sprite(game.manager.get("button.png", Texture.class));
sprite1.setPosition(0, 0);
//This is a method to load the assets for the especific screen
game.load(screen);
}
#Override
public void render(float delta){
if(game.manager.getProgress()==1) {
if (time < 3) {
Gdx.app.log("Loading: ", "90.0");
}
}else {
Gdx.app.log("Loading: ", String.valueOf(game.manager.getProgress() * 100));
}
game.manager.update();
batch = game.batch;
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
sprite1.draw(batch);
if(game.manager.getProgress()==1 && time > 3){
if(screen==1) {
ScreenManager.getInstance().showScreen(2, game);
}else{
ScreenManager.getInstance().showScreen(3, game);
}
}else{
time += delta;
}
batch.end();
super.render(delta);
}
The Menu and Game classes are similar to loading, only call the assets and draw some sprite on the render method.
This code function well to change screens but I don't know if is the correct form, and another big question is how to manage the pause screen, because I manage this only storing a variable if the variable is pause the render method draw something, if not draw the normal game, but if I want to change the options and images of the pause I need to check variables to know what the pause needs to draw.
if(pause){
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
spritePause.draw(batch);
batch.end();
}else if(game){
batch.begin();
spriteGame.draw(batch);
batch.end();
}
So, am i doing it right? or what would you recommend me? Some examples or maybe specific tutorials to achieve this would be great.
There is not only one correct way of managing screens. Libido gives you the freedom to do it exactly how you please. You can extend the Screen class to make screens for the different needs of your project. You can manage your screens as states and manage them with a state manager.
Regarding the Pause and Game Over screen, you can do that in different ways too.
You can have a dedicated screen to switch to or you can have a Pause and GameOver state in your Game state/screen and show the Pause/GameOver elements on top of your gamescreen while the game is still in the background.
So there is not a single correct way of doing it. The correct way is what works for your game.
For some inspiration:
pixnbgames.com : How to manage screens
Brent Aureli : Game State Manager
As #IronMonkey has answered, there is no "correct" way.
I do it with one GameScreen class only, and have a lot of different states inside the GameScreen class. The GameScreen class is very simple and short (100-200 LOC), and is responsible for switching between states. States are similar to the GameScreen class, but they can be entered and exited without the need to instantiate new objecs.
class GameScreen extends ScreenAdapter implements Disposable {
GameState menuState;
GameState playState;
GameState currentState;
public GameScreen(final MyGame game) {
menuState = new MenuState(this);
playState = new PlayState(this);
}
public void setState(GameState state) {
if(currentState == state) return;
// states have a method 'exit' where you can pause them or finalize something
if(currentState != null)
currentState.exit();
currentState = state;
// also states have 'enter' where you can unpause or init something when entering
currentState.enter();
}
public void render(float delta) {
currentState.render(delta);
}
}
First, this is very resource efficient, because the needed states are created only once when the game is started. Second, because you never destroy the states, but just change them and call enter/exit, they always retain perfectly their current state, i.e. variables, objects and everything and when you go back to a state, it is exactly as it was before you left it.
GameState is interface and you are free to implement it as you wish.
public interface GameState
{
public void enter();
public void exit();
public void update(float delta);
public void render(SpriteBatch batch, float delta);
public String toString();
public void dispose();
}

How to Make a button that directly Extends Actor? Libgdx

I want to make a button that directly extends Actor. The reason I want to do this is because I don't want to go through the trouble of making a text button that has skins and such. I just want to be able to load my png file on the screen and make it clickable. Anyone have ideas or should I just stick to the Textbutton?
How about an ImageTextButton?
Or you use a Button, and add a Stack (which holds multiple items, that you can place on them self)
I don't recommend you, to do your own button. You'll reinvent the wheel.
I suggest: try ImageTextButton.
If that does not help --> Button + Stack
public class TextureActor extends Actor {
private Texture texture;
public TextureActor(Texture texture) {
this.texture = texture;
}
#Override
public void draw(Batch batch, float parentAlpha) {
batch.draw(texture, getX(), getY(), getWidth(), getHeight());
}
}
You can certainly replace Texture with anything else which can be drawn by the batch. Or use another draw method with more detailed parameters.
Buttons don't actually need a skin, so it would be far easier to just make a factory method to simplify it, rather than code all the logic of a proper button:
public static Button makeButton (TextureRegion upImage, TextureRegion downImage, Actor contentActor) {
Button.ButtonStyle style = new Button.ButtonStyle();
style.up = new TextureRegionDrawable(upImage);
style.down = new TextureRegionDrawable(downImage);
return contentActor == null ? new Button(style) : new Button(contentActor, style);
}

libGDX SpriteCache: transparency on images not displayed properly

I'm developing a Tower Defense game using libGDX. I've just started and I am able to display the path, the "environment" and the enemies walking along the path.
I displayed the environment using a SpriteBatch-Object, like this:
public LevelController(Level level) {
spriteBach = new SpriteBach();
atlas = new TextureAtlas(Gdx.files.internal("images/textures/textures.pack"));
}
public void setSize() {
spriteBatch.setProjectionMatrix(this.cam.combined);
}
public void render() {
spriteBatch.begin();
drawTowerBases();
spriteBatch.end();
}
private void drawTowerBases() {
// for each tower base (=environment square)
TextureRegion towerBaseTexture = atlas.findRegion("TowerBase");
if(towerBaseTexture != null) {
spriteBatch.draw(towerBaseTexture, x, y, 1f, 1f);
}
}
This is working properly and the textures are displayed well: Tower Defense using spriteBatch
Now, I was wondering if it is possible to cache the background. Because it stays the same, there is no need to calculate it every time. I've found the SpriteCache through Google-Search. So I changed the code as follows:
public LevelController(Level Level) {
spriteCache= new SpriteCache();
atlas = new TextureAtlas(Gdx.files.internal("images/textures/textures.pack"));
spriteCache.beginCache();
this.drawTowerBases();
this.spriteCacheEnvironmentId = spriteCache.endCache();
}
public void setSize() {
this.cam.update();
spriteCache.setProjectionMatrix(this.cam.combined);
}
public void render() {
spriteCache.begin();
spriteCache.draw(this.spriteCacheEnvironmentId);
spriteCache.end();
}
private void drawTowerBases() {
// for each tower base (=environment square)
TextureRegion towerBaseTexture = atlas.findRegion("TowerBase");
if(towerBaseTexture != null) {
spriteCache.add(towerBaseTexture, x, y, 1f, 1f);
}
}
And now the game looks like this: Tower Defense using spriteCache
For me it seems as if the transparency is not rendered properly. If I take images without transparency, everything works fine. Does anyone have an idea, why this happens and how I can fix this?
Thank you in advance.
Taken from the SpriteCache documentation:
Note that SpriteCache does not manage blending. You will need to enable blending (Gdx.gl.glEnable(GL10.GL_BLEND);) and set the blend func as needed before or between calls to draw(int).
I guess there is not much more to say.

Categories

Resources