According to documentation the ExtendViewportshould extend the view and keep the aspect ratio, but whenever I try Implemented this viewPort Ive got two bars in the side of the phone screen. (this is sample background image,with some text and button on it to check how stretch will be).
Code:
public class Overlap2d extends Game {
public static float ASPECT_RATIO ;
public static final int GAME_SCREEN_WIDTH = 40;
public static final int GAME_SCREEN_HEIGHT = 80;
#Override
public void create () {
ASPECT_RATIO=(float)Gdx.graphics.getWidth()/(float)Gdx.graphics.getHeight() ;
ScreenManager.getScreenManager().init(this);
ScreenManager.getScreenManager().showScreen( ScreenName.MAIN_MENU );
}}
public abstract class AbstractScreen extends Stage implements Screen {
public AbstractScreen() {
super(new ExtendViewport(GAME_SCREEN_WIDTH,GAME_SCREEN_HEIGHT,new OrthographicCamera()));
}
public abstract void buildStage();
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 1, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
super.act(delta);
super.draw();
}
#Override
public void resize(int width, int height) {
getViewport().update(width,height);
}
#Override
public void show() {
Gdx.input.setInputProcessor(this);
}
#Override
public void resume() {}
#Override
public void pause() {}
#Override
public void hide() {}}
public class MenuScreen extends AbstractScreen{
private Texture txtrBg;
public MenuScreen() {
super();
txtrBg = new Texture( Gdx.files.internal("test.png") );
}
#Override
public void buildStage() {
getCamera().position.set(GAME_SCREEN_WIDTH / 2, GAME_SCREEN_HEIGHT / 2, 0);
Image bg = new Image(txtrBg);
bg.setSize(GAME_SCREEN_WIDTH,GAME_SCREEN_HEIGHT);
bg.setPosition(0,0);
addActor(bg);
}
#Override
public void dispose() {
super.dispose();
txtrBg.dispose();
}}
public static final int GAME_SCREEN_WIDTH = 40;
public static final int GAME_SCREEN_HEIGHT = 80;
you're using width and height ratio 1:2 but only very view device fits in this ratio so why don't you try 48 and 80 as viewport width and height.
Question is almost same so explanation can fit here also
https://stackoverflow.com/a/43398153/3445320
Related
I have added buttons to my code, but when I go to "resize", they get bigger or wider and it looks very bad. How can I resize the window and keep the button aspect ratio?
This is my code:
1)Main:
`package com.mygdx.game;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.mygdx.game.screen.MainMenuScreen;
public class gamename extends Game {
public static final int WIDTH = 760;
public static final int HEIGHT = 520;
public SpriteBatch batch;
#Override
public void create() {
batch = new SpriteBatch();
this.setScreen(new MainMenuScreen(this));
}
#Override
public void render(){
super.render();
}
}`
2)And this is the menu, here i use the image to view the buttons. MainMenu:
package com.mygdx.game.screen;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.mygdx.game.gamename;
public class MainMenuScreen implements Screen{
private static final int PLAY_BUTTON_WIDTH = 150;
private static final int PLAY_BUTTON_HEIGHT = 80;
private static final int OPTIONS_BUTTON_WIDTH = 150;
private static final int OPTIONS_BUTTON_HEIGHT = 80;
gamename game;
Texture playButtonActive;
Texture playButtonInactive;
Texture optionsButtonActive;
Texture optionsButtonInactive;
public MainMenuScreen (gamename game){
this.game = game;
playButtonActive = new Texture("play1.png");
playButtonInactive = new Texture("play2.png");
optionsButtonActive = new Texture("options1.png");
optionsButtonInactive = new Texture("options2.png");
}
#Override
public void show() {
}
#Override
public void render(float f) { //Colore e carica bottoni
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
game.batch.begin();
game.batch.draw(playButtonActive, 240, 150, PLAY_BUTTON_WIDTH, PLAY_BUTTON_HEIGHT);
game.batch.end();
}
#Override
public void resize(int i, int i1) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
}
I would like the button to be the same even if I manually increase the page size. Some say they use viewport but I have never used it and I don't know how to do it. Can someone help me?
Trying to create a simple loading Screen. The below code prints the correct progress, so I know that part works. But the rectangle is not being drawn. Not sure what is wrong.
Full LoadingScreen:
public class LoadingScreen implements Screen {
private static final float PROGRESS_BAR_WIDTH = MyGdxGame.WIDTH / 2f;
private static final float PROGRESS_BAR_HEIGHT = 50f;
GdxAssetManager assetManager;
Stage stage;
//Table mainTable;
private ShapeRenderer shapeRenderer;
private MyGdxGame game;
public LoadingScreen(MyGdxGame game){
this.game = game;
assetManager = game.getAssetManager();
shapeRenderer = new ShapeRenderer();
stage = new Stage(new StretchViewport(MyGdxGame.WIDTH, MyGdxGame.HEIGHT));
}
#Override
public void show() {
assetManager.loadGeneral();
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderProgressBar();
if (assetManager.getManager().update()) {
game.setScreen(new LoginScreen(game));
}
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
private void renderProgressBar() {
float progress = assetManager.getManager().getProgress();
System.out.println(PROGRESS_BAR_WIDTH * progress);
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
shapeRenderer.setColor(Color.RED);
shapeRenderer.rect(
(MyGdxGame.WIDTH - PROGRESS_BAR_WIDTH) / 2f,
(MyGdxGame.HEIGHT - PROGRESS_BAR_HEIGHT) / 2f,
PROGRESS_BAR_WIDTH * progress,
PROGRESS_BAR_HEIGHT
);
shapeRenderer.end();
}
#Override
public void resize(int width, int height) {
stage.getViewport().update(width, height);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
dispose();
}
#Override
public void dispose() {
stage.dispose();
shapeRenderer.dispose();
}
}
I guess methods of interest are render and renderProgressBar. Like I said, all I get is a white background until the loading is finished, but the print inside renderProgressBar prints the correct values.
Set projectionMatrix of ShapeRenderer using stage camera.
shapeRenderer.setProjectionMatrix(stage.getCamera().combined);
i'm new to libgdx and i can't figure out what i do wrong.
In my game I just want to switch between 2 screens (first is menuScreen, second is gameScreen). I have created these two screens and one game class, it all looks okay. But when i call my method setScreen(new GameScreen()) nothing happens. Also i should say, that i used screen and game classes in my previous project and all was ok, when i compare my current code to previous one i do not see any differences, so it is very curiously.
Here is my MenuScreen class:
MenuScreen implements Screen {
private SpriteBatch batch ;
private Texture texture;
private float timePassed;
public MenuScreen() {
timePassed = 0;
batch = new SpriteBatch();
texture = new Texture("texture.png");
#Override
public void render (float delta) {
timePassed += Gdx.graphics.getDeltaTime();
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (timePassed > 5) {GameClass.getInstance().setScreen(new GameScreen());} //it looks strange, but it's to check if all works properly
batch.begin();
batch.draw(texture, 0, 0);
batch.end();
}
#Override
public void dispose() {
batch.dispose();
texture.dispose();
}
#Override
public void hide() {
}
#Override
public void resume() {
}
#Override
public void pause() {
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
}}
Here is my GameScreen class:
GameScreen implements Screen {
private SpriteBatch batch2 ;
private Texture texture2;
public MenuScreen() {
batch2 = new SpriteBatch();
texture2 = new Texture("texture2.png");
}
#Override
public void render (float delta) {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch2.begin();
batch2.draw(texture2, 0, 0);
batch2.end();
}
#Override
public void dispose() {
batch2.dispose();
texture2.dispose();
}
#Override
public void hide() {
}
#Override
public void resume() {
}
#Override
public void pause() {
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
}}
And Game class:
public class ClassGame extends Game {
public static ClassGame getInstance(){
ClassGame instance = new ClassGame();
return instance;
}
#Override
public Screen getScreen() {
return super.getScreen();
}
#Override
public void setScreen(Screen screen) {
super.setScreen(screen);
}
#Override
public void resize(int width, int height) {
super.resize(width, height);
}
#Override
public void render() {
super.render();
}
#Override
public void resume() {
super.resume();
}
#Override
public void pause() {
super.pause();
}
#Override
public void dispose() {
super.dispose();
}
public ClassGame() {
super();
}
#Override
public void create() {
MenuScreen menuScreen = new MenuScreen();
setScreen(menuScreen);
}}
This is how I did for the same problem, i had three classes for two screen to switch between them. Here I am switching between second and third using a image actor as button.I also used two constructors in each class, one of them constructors with no arguments, below is my code hope you will get it.
My main class code:
public class First extends Game{
private Game game;
public Main(){ game=this; }
public void create() {
game.setScreen(new Second(game)); }}
Below is my first screen class code
public class Second implements Screen{
private Game second;
public Second(Game second){this.second=second;}
public Second(){}
// your code
Stage myStage=new Stage(new ScreenViewport());
Group myGroup=new Group();
Image secondButton=new Image(new Texture(Gdx.files.internal("image.png")));
public void show(){
myGroup.addActor(secondButton);
secondButton.addListener(new InputListener(){
second.setScreen(new Third(second)); });}
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
myStage.act(Gdx.graphics.getDeltaTime());
myStage.draw(); }
public void resize(int width, int height) {}
public void pause(){}
public void resume(){}
public void hide(){}
public void dispose(){}}}
And my next screen class code
public class Third implements Screen{
private Game third;
public Third(Game third){
this.third=third;}
public Third(){}
// your code
Stage myStage=new Stage(new ScreenViewport());
Group myGroup=new Group();
Image thirdButton=new Image(new Texture(Gdx.files.internal("image.png")));
public void show() {
myGroup.addActor(thirdButton);
thirdButton.addListener(new InputListener(){
third.setScreen(new Third(third));});}
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
myStage.act(Gdx.graphics.getDeltaTime());
myStage.draw();}
public void resize(int width, int height) { }
public void pause(){}
public void resume(){}
public void hide(){}
public void dispose(){}}}
I got it, guys. In my previous project i declared instance field outside of getInstance(). Like this :
public static GameClass instance = new GameClass();
public static GameClass getInstance(){
return instance;
}
But i still need your help. I don't know how this small thing wasn't letting me switch screens.
I am trying to override my Player class that extends Actor draw method but I am receiving an error saying
The method draw(SpriteBatch, float) of type Player must override or
implement a supertype method
Why can I not override the default draw method from the class Actor? Here is my code from the Player class.
public class Player extends Actor {
#Override
public void draw(SpriteBatch batch, float parentAlpha) {
Gdx.app.log(getName(), "Drawing player");
}
public Player() {
setName("mainPlayer");
playerBounds = new Rectangle(100, 100, 32, 32);
}
}
Here is my code from the class with the Stage that is being drawn.
public class Mainscreen implements Screen {
// Class TAG
private static final String TAG = "Main Screen";
// Screen Variable(s)
private Awakening g;
private SpriteBatch sprBatch;
private OrthographicCamera gameCamera;
private Player mainPlayer;
// Screen Stage(s)
private sMain sMain;
#Override
public void dispose() {
sprBatch.dispose();
sMain.dispose();
}
#Override
public void hide() {
g.inputController.removeProcessor(sMain);
dispose();
}
public Mainscreen(Awakening game){
g = game;
sMain = new sMain(g, g.configMgr.getWidth(), g.configMgr.getHeight(), true);
gameCamera = new OrthographicCamera();
gameCamera.setToOrtho(false, sMain.getWidth(), sMain.getHeight());
mainPlayer = new Player(g, gameCamera);
g.setPlayer(mainPlayer);
sprBatch = new SpriteBatch();
g.mapMgr.setMap(g, gameCamera, "TestMap", mainPlayer);
sMain.addActor(mainPlayer);
}
#Override
public void pause() {g.togglePause(true);g.debugOut(TAG, "pause()");}
#Override
public void render(float delta) {
if(!g.isPaused()){
sMain.act(delta);
Gdx.gl.glClearColor(.125f, .125f, .125f, 0);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gameCamera.update();
g.mapMgr.updateNPCS();
sprBatch.setProjectionMatrix(gameCamera.combined);
sprBatch.begin();
g.mapMgr.draw(gameCamera, new int[] {0,1});
sMain.draw(); // Draw player/NPCs
//g.getPlayer().draw(sprBatch, 0f);
g.mapMgr.drawCollisionRectangles(gameCamera);
sprBatch.end();
}
}
#Override
public void resize(int width, int height) {g.debugOut(TAG,"resize("+width+","+height+")");}
#Override
public void resume() {g.togglePause(false);g.debugOut(TAG, "resume()");}
#Override
public void show() {
g.debugOut(TAG, "show()");
g.inputController.addProcessor(sMain);
g.updateInput();
}
}
I am not sure what's going on but was pretty sure I could override draw before.
You must override it like this:
#Override
public void draw(Batch batch, float parentAlpha) {
Gdx.app.log(getName(), "Drawing player");
}
Change the SpriteBatch to Batch. Reference Actor#draw
In LibGDX Is there an actor that is animated (takes an Animation) and when added to a Stage animates itself or do you have to implement your own Image class in and animate it yourself?
I simply created an "AnimatedImage" actor class which only takes an Animation as an argument (no need for a custom Drawable class). I think this solution is much simpler than the one above.
AnimatedImage.java:
public class AnimatedImage extends Image
{
protected Animation animation = null;
private float stateTime = 0;
public AnimatedImage(Animation animation) {
super(animation.getKeyFrame(0));
this.animation = animation;
}
#Override
public void act(float delta)
{
((TextureRegionDrawable)getDrawable()).setRegion(animation.getKeyFrame(stateTime+=delta, true));
super.act(delta);
}
}
Just like you I didn't find animated Actor so I created myself:
AnimatedActor.java:
public class AnimatedActor extends Image
{
private final AnimationDrawable drawable;
public AnimatedActor(AnimationDrawable drawable)
{
super(drawable);
this.drawable = drawable;
}
#Override
public void act(float delta)
{
drawable.act(delta);
super.act(delta);
}
}
AnimationDrawable.java:
class AnimationDrawable extends BaseDrawable
{
public final Animation anim;
private float stateTime = 0;
public AnimationDrawable(Animation anim)
{
this.anim = anim;
setMinWidth(anim.getKeyFrameAt(0).getRegionWidth());
setMinHeight(anim.getKeyFrameAt(0).getRegionHeight());
}
public void act(float delta)
{
stateTime += delta;
}
public void reset()
{
stateTime = 0;
}
#Override
public void draw(SpriteBatch batch, float x, float y, float width, float height)
{
batch.draw(anim.getKeyFrame(stateTime), x, y, width, height);
}
}