When i run the game in Desktop works fine, but when i run it in my android device, the image looks cuted in a half and when i use the PLAY button the game closes, anyone can help me? thank you.
public class GameScreen extends AbstractScreen {
private Viewport viewport;
private Camera camera;
private SpriteBatch batch;
private Texture texture;
private float escala;
private Paddle Lpaddle, Rpaddle;
private Ball ball;
private BitmapFont font;
private int puntuacion, puntuacionMaxima;
private Preferences preferencias;
private Music music;
private Sound sonidoex;
public GameScreen(Main main) {
super(main);
preferencias = Gdx.app.getPreferences("PuntuacionAppPoints");
puntuacionMaxima = preferencias.getInteger("puntuacionMaxima");
music =Gdx.audio.newMusic(Gdx.files.internal("bgmusic.mp3"));
music.play();
music.setVolume((float) 0.3);
music.setLooping(true);
sonidoex = Gdx.audio.newSound(Gdx.files.internal("explosion5.wav"));
}
public void create(){
camera = new PerspectiveCamera();
viewport = new FitViewport(800, 480, camera);
}
public void show(){
batch = main.getBatch();
texture = new Texture(Gdx.files.internal("spacebg.png"));
Texture texturaBola = new Texture(Gdx.files.internal("bola.png"));
ball = new Ball(Gdx.graphics.getWidth() / 2 - texturaBola.getWidth() / 2, Gdx.graphics.getHeight() / 2 - texturaBola.getHeight() / 2);
Texture texturaPala= new Texture(Gdx.files.internal("pala.png"));
Lpaddle = new LeftPaddle(80, Gdx.graphics.getHeight()/2 -texturaPala.getHeight() /2);
Rpaddle = new RightPaddle(Gdx.graphics.getWidth() -100, Gdx.graphics.getHeight()/2 - texturaPala.getHeight() /2, ball);
font = new BitmapFont();
font.setColor(Color.WHITE);
font.setScale(1f);
puntuacion = 0;
}
public void render(float delta){
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
updatePuntuacion();
Lpaddle.update();
Rpaddle.update();
ball.update(Lpaddle, Rpaddle);
batch.begin();
batch.draw(texture, 0, 0,texture.getWidth(), texture.getHeight());
ball.draw(batch);
Lpaddle.draw(batch);
Rpaddle.draw(batch);
font.draw(batch, "Points: " + Integer.toString(puntuacion), Gdx.graphics.getWidth() / 4 ,Gdx.graphics.getHeight() - 5);
font.draw(batch, "High score: " + Integer.toString(puntuacionMaxima),Gdx.graphics.getWidth() - Gdx.graphics.getWidth() / 4 ,Gdx.graphics.getHeight() - 5);
batch.end();
}
private void updatePuntuacion(){
if(ball.getBordes().overlaps(Lpaddle.getBordes())) {
puntuacion = puntuacion + 1;
if(puntuacion > puntuacionMaxima)
puntuacionMaxima = puntuacion;
}
if(ball.getBordes().x <= 0)
sonidoex.play();
if(ball.getBordes().x <= 0)
puntuacion =0;
if(ball.getBordes().x <=0)
Gdx.input.vibrate(1000);
if(ball.getBordes().x <=0)
Screens.juego.setScreen(Screens.MAINSCREEN);
ball.comprobarPosicionBola();
}
public void hide(){
font.dispose();
texture.dispose();
}
#Override
public void dispose(){
preferencias.putInteger("puntuacionMaxima", puntuacionMaxima);
preferencias.flush();
}
public void resize(int width, int height){
float widthImage = texture.getWidth();
float heightImage = texture.getHeight();
float r = heightImage / widthImage;
if(heightImage > height) {
heightImage = height;
widthImage = heightImage / r;
}
if(widthImage > width) {
widthImage = width;
heightImage = widthImage * r;
}
escala = width / widthImage;
if(Gdx.app.getType()== ApplicationType.Android)
viewport.update(width, height);
}
}
Firstly, use an orthograpic camera.
camera=new OrthographicCamera(800,480);
camera.position.set(800/2f,480/2f,0);
viewport=new FitViewport(800,480,camera);
Now 0,0 is in the left bottom corner of your screen.
And before doing batch.begin don't forget to set your projection matrix
batch.setProjectionMatrix(camera.combined);
batch.begin();
////
////
batch.end();
Related
This is my first try in libGDX and I've not seen an issue like this before, googling didn't help either. What I'm trying to to display a background, Later on I'll make this move, but for me it was a great start to actually display the image. It displays, but it's streched out (See picture below)
And my code is:
private BombArrangement game;
private OrthographicCamera gameCamera;
private Viewport gamePort;
private Texture backGroundTexture;
public PlayScreen(BombArrangement game) {
this.game = game;
gameCamera = new OrthographicCamera();
gamePort = new FitViewport(BombArrangement.V_WIDTH, BombArrangement.V_HEIGHT, gameCamera);
backGroundTexture = new Texture("startbackground.png");
}
#Override
public void show() {
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
game.batch.begin();
game.batch.draw(new TextureRegion(backGroundTexture, 0, 0, BombArrangement.V_WIDTH, BombArrangement.V_HEIGHT), 0, 0);
game.batch.end();
}
#Override
public void resize(int width, int height) {
gamePort.update(width, height);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
}
I tried several things like textureregions, sprites and more but all of them give this result.
not exactly sure what your want to do but i use this to render my background in my main menu:
//Camera
camera = new OrthographicCamera();
camera.setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
//Viewport
ScreenViewport viewport = new ScreenViewport(camera);
//Background
backgroundImage = new Texture(pathToImage);
//Stage
stage = new Stage();
stage.setViewport(viewport);
(this is located in my constructor and camera, backgroundImage and stage are fields in my class)
in render method
(ConfigData holds data of settings applied to the game; DEFAULT_WIDHT and -HEIGHT are just some values I use to initialize the window when not in fullscreen mode; Replace them with your values used in the DesktopLauncher for
config.widht
and
config.height
):
#Override
public void render(float delta) {
//Clear screen
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act();
stage.getBatch().begin();
stage.getBatch().draw(backgroundImage, 0, 0, ConfigData.DEFAULT_WIDTH, ConfigData.DEFAULT_HEIGHT);
stage.getBatch().end();
stage.draw();
}
my resize method:
#Override
public void resize(int width, int height) {
camera.setToOrtho(false, width, height);
stage.getViewport().update(width, height);
}
hopes this helps somehow someone because i figured out this by myself and it costed some effort (:
As a response to your last comment:
You are now scaling down the height correctly but the width remains the same. Try to multiply the width by the same amount you scale the height down, so with some alterations to the code you linked in the comment (not tested):
private Texture texture;
private int x1, x2, speed, scaledHeight, scaledWidth;
public StartBackground() {
texture = new Texture("startbackground.png");
x1 = 0;
x2 = texture.getWidth();
speed = 5;
float imageRatio = Gdx.graphics.getHeight() / texture.getHeight();
scaledHeight = (int) (texture.getHeight() * imageRatio);
scaledWidth = (int) (texture.getWidth() * imageRatio);
}
public void updateAndRender(float deltaTime, SpriteBatch spriteBatch) {
x1 -= speed;
x2 -= speed;
// If image is off screen and not visible
if (x1 + texture.getWidth() <= 0) x1 = x2 + texture.getWidth();
if (x2 + texture.getWidth() <= 0) x2 = x1 + texture.getWidth();
// Render
spriteBatch.draw(texture, x1, 0, scaledWidth, scaledHeight);
spriteBatch.draw(texture, x2, 0, scaledWidth, scaledHeight);
}
I have a animation which i want to flip to the left if key LEFT is pressed, but it doesnt stay flipped. It only flips like 1 frame then turns back again.
Here is my GameScreen where i draw everything:
public class GameScreen extends ScreenManager{
//For the view of the game and the rendering
private SpriteBatch batch;
private OrthographicCamera cam;
//DEBUG
private Box2DDebugRenderer b2dr;
//World, Player and so on
private GameWorld world;
private Player player;
private Ground ground;
//player animations
private TextureRegion currFrame;
public static float w, h;
public GameScreen(Game game) {
super(game);
//vars
w = Gdx.graphics.getWidth();
h = Gdx.graphics.getHeight();
//view and rendering
batch = new SpriteBatch();
cam = new OrthographicCamera();
cam.setToOrtho(false, w/2, h/2);
//debug
b2dr = new Box2DDebugRenderer();
//world, bodies ...
world = new GameWorld();
player = new Player(world);
ground = new Ground(world);
}
#Override
public void pause() {
}
#Override
public void show() {
}
#Override
public void render(float delta) {
//clearing the screen
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//updating
update(Gdx.graphics.getDeltaTime());
player.stateTime += Gdx.graphics.getDeltaTime();
//render
batch.setProjectionMatrix(cam.combined);
currFrame = Player.anim.getKeyFrame(Player.stateTime, true);
batch.begin();
batch.draw(currFrame, Player.body.getPosition().x * PPM - 64, Player.getBody().getPosition().y * PPM- 72);
batch.end();
//debug
b2dr.render(GameWorld.getWorld(), cam.combined.scl(PPM));
}
#Override
public void resize(int width, int height) {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
#Override
public void onKlick(float delta) {
}
public void update(float delta){
world.update(delta);
updateCam(delta);
Player.keyInput(delta);
System.out.println("X-POS" + Player.getBody().getPosition().x);
System.out.println("Y-POS" + Player.getBody().getPosition().y);
}
public void updateCam(float delta){
Vector3 pos = cam.position;
pos.x = Player.getBody().getPosition().x * PPM;
pos.y = Player.getBody().getPosition().y * PPM;
cam.position.set(pos);
cam.update();
}
}
and this is the Player class where the animation is:
public class Player {
public static Body body;
public static BodyDef def;
private FixtureDef fd;
//textures
public static Texture texture;
public static Sprite sprite;
public static TextureRegion[][] region;
public static TextureRegion[] idle;
public static Animation<TextureRegion> anim;
public static float stateTime;
//set form
private PolygonShape shape;
private GameScreen gs;
public Player(GameWorld world){
texture = new Texture(Gdx.files.internal("player/char_animation_standing.png"));
region = TextureRegion.split(texture, texture.getWidth() / 3, texture.getHeight() / 2);
idle = new TextureRegion[6];
int index = 0;
for(int i = 0; i < 2; i++){
for(int j = 0; j < 3; j++){
sprite = new Sprite(region[i][j]);
idle[index++] = sprite;
}
}
anim = new Animation<TextureRegion>(1 / 8f, idle);
stateTime = 0f;
def = new BodyDef();
def.fixedRotation = true;
def.position.set(gs.w / 4, gs.h / 4);
def.type = BodyType.DynamicBody;
body = world.getWorld().createBody(def);
shape = new PolygonShape();
shape.setAsBox(32 / 2 / PPM, 64/ 2 / PPM);
fd = new FixtureDef();
fd.shape = shape;
fd.density = 30;
body.createFixture(fd);
shape.dispose();
}
public static Body getBody() {
return body;
}
public static BodyDef getDef() {
return def;
}
public static Texture getTexture() {
return texture;
}
public static void keyInput(float delta){
int horizonForce = 0;
if(Gdx.input.isKeyJustPressed(Input.Keys.UP)){
body.applyLinearImpulse(0, 300f, body.getWorldCenter().x, body.getWorldCenter().y, true);
//body.applyForceToCenter(0, 1200f, true);
System.out.println("PRESSED");
}
if(Gdx.input.isKeyPressed(Input.Keys.LEFT)){
horizonForce -= 1;
sprite.flip(!sprite.isFlipX(), sprite.isFlipY());
}
if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)){
horizonForce += 1;
}
body.setLinearVelocity(horizonForce * 20, body.getLinearVelocity().y);
}
}
thank you in advance and any answer is appreciated :D
Your sprite variable contain only one frame at the time of pressing left key. So, it flip that current sprite of your animation frame.
To solve the Problem you have to flip all the animation frame on pressing the left key.
You're only flipping last frame of Animation by sprite reference, You need to flip all frames of your Animation anim. You can flip in this way :
if(keycode== Input.Keys.RIGHT) {
for (TextureRegion textureRegion:anim.getKeyFrames())
if(!textureRegion.isFlipX()) textureRegion.flip(true,false);
}
else if(keycode==Input.Keys.LEFT) {
for (TextureRegion textureRegion:anim.getKeyFrames())
if(textureRegion.isFlipX()) textureRegion.flip(true,false);
}
I found some code on the libgdx GitHub that creates a tiled map and populates it. It all works fine until you enlarge the camera to draw ~50x50 tiles. At this point, I get ~5 fps and input is barely responding. Here is the modified code:
public class Core extends ApplicationAdapter {
private AssetManager am;
private SpriteBatch batch;
private BitmapFont font;
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
private OrthographicCamera camera;
private OrthoCamController cameraController;
#Override
public void create() {
am = new AssetManager();
am.load("tiles.png", Texture.class);
am.finishLoading();
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
batch = new SpriteBatch();
batch.disableBlending();
camera = new OrthographicCamera();
camera.setToOrtho(false, (w / h) * 400, 400);
camera.update();
cameraController = new OrthoCamController(camera);
Gdx.input.setInputProcessor(cameraController);
font = new BitmapFont();
map = new TiledMap();
MapLayers layers = map.getLayers();
TiledMapTileLayer layer = new TiledMapTileLayer(200, 200, 8, 8);
TextureRegion[][] splitTiles = TextureRegion.split((Texture)am.get("tiles.png"), 8, 8);
for (int x = 0; x < 1000; x++) {
for (int y = 0; y < 1000; y++) {
int ty = 1;
int tx = 1;
Cell cell = new Cell();
cell.setTile(new StaticTiledMapTile(splitTiles[ty][tx]));
layer.setCell(x, y, cell);
}
layers.add(layer);
}
renderer = new OrthogonalTiledMapRenderer(map, batch);
}
#Override
public void render() {
Gdx.gl.glClearColor(100f / 255f, 100f / 255f, 250f / 255f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
renderer.setView(camera);
renderer.render();
}
#Override
public void resize(int width, int height) {
}
#Override
public void dispose() {
am.dispose();
map.dispose();
}
}
I seriously doubt that Libgdx can't handle that many tiles so my question is: how do I improve performance... or am I being too ambitious?
The only solution I could find was here but it looks like they removed the method used in it.
You probably want to put layers.add(layer); outside the for (int x = 0; x < 1000; x++) loop
I have the following class:
public class AnimationDemo implements ApplicationListener {
private SpriteBatch batch;
private TextureAtlas textureAtlas;
private Animation animation;
private float elapsedTime = 0;
private OrthographicCamera camera;
private int width;
private int height;
private int texturewidth;
private int textureheight;
#Override
public void create() {
width = Gdx.graphics.getWidth();
height = Gdx.graphics.getHeight();
camera = new OrthographicCamera(width, height);
camera.position.set(width / 2, height / 2, 0);
camera.update();
batch = new SpriteBatch();
textureAtlas = new TextureAtlas(Gdx.files.internal("data/packone.atlas"));
textureAtlas.getRegions().sort(new Comparator<TextureAtlas.AtlasRegion>() {
#Override
public int compare(TextureAtlas.AtlasRegion o1, TextureAtlas.AtlasRegion o2) {
return Integer.parseInt(o1.name) > Integer.parseInt(o2.name) ? 1 : -1;
}
});
animation = new Animation(1 / 15f, textureAtlas.getRegions());
}
#Override
public void dispose() {
batch.dispose();
textureAtlas.dispose();
}
#Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
batch.begin();
elapsedTime += Gdx.graphics.getDeltaTime();
batch.draw(animation.getKeyFrame(elapsedTime, true), 0, 0);
batch.end();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
In the above I am using the Animation class to simply draw from a texture atlas. I am following an example from another SO question which is here but the co-ordinates don't fit my equation. How should I set these:
private int texturewidth;
private int textureheight;
Any help would be great :)
you need to care about proper offset - the origin is always at the left bottom corner and that is why you need to subtract half of width and height when drawing.
In a nutshell it should be like:
TextureRegion region = animation.getKeyFrame(elapsedTime, true);
batch.draw(region, 0 - (region.getRegionWidth()/2f), 0 - (region.getRegionHeight()/2f));
I am still new in libgdx and confused, i want some button in my games(always in bottom left screen) for make some event (use item, create soldier,etc). Where can i put this button in my games class? I have worldController class, worldRenderer class and GameScreen class (like in canyon bunny from libgdx ebook)
I have tried add stage and button in worldRenderer class then draw it in one of renderGui methods but nothing is shown. So, how to insert button to inside my game world?
Thanks...
public class WorldRenderer implements Disposable {
private OrthographicCamera camera;
public SpriteBatch batch;
private Stage stage = new Stage();
private Button btnItem;
private Skin skinLibgdx = new Skin(
Gdx.files.internal(Constants.SKIN_LIBGDX_UI),
new TextureAtlas(Constants.TEXTURE_ATLAS_LIBGDX_UI));
private WorldController worldController;
private OrthographicCamera cameraGUI;
public float w = Constants.VIEWPORT_GUI_WIDTH/1366;
public float h = Constants.VIEWPORT_GUI_HEIGHT/768;
public WorldRenderer (WorldController worldController) {
this.worldController = worldController;
init();
}
private void init () {
batch = new SpriteBatch();
camera = new OrthographicCamera(Constants.VIEWPORT_WIDTH, Constants.VIEWPORT_HEIGHT);
camera.position.set(0, 0, 0);
camera.update();
btnItem = new Button(skinLibgdx);
btnItem.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
// TODO Auto-generated method stub
System.out.println("ABC");
}
});
stage.addActor(btnItem);
//background = new ParallaxBackground(layers,camera,batch);
cameraGUI = new OrthographicCamera(Constants.VIEWPORT_GUI_WIDTH,
Constants.VIEWPORT_GUI_HEIGHT);
cameraGUI.position.set(0, 0, 0);
cameraGUI.setToOrtho(true); // flip y-axis
cameraGUI.update();
}
public void render () {
renderWorld(batch);
renderGui(batch);
}
private void renderWorld (SpriteBatch batch) {
//background.render();
worldController.cameraHelper.applyTo(camera);
batch.setProjectionMatrix(camera.combined);
batch.begin();
worldController.level.render(batch);
batch.end();
}
public void resize (int width, int height) {
//camera.viewportWidth = (Constants.VIEWPORT_HEIGHT / height) *width;
camera.update();
cameraGUI = new OrthographicCamera(Constants.VIEWPORT_GUI_WIDTH,
Constants.VIEWPORT_GUI_HEIGHT);
cameraGUI.position.set(0, 0, 0);
cameraGUI.setToOrtho(true); // flip y-axis
cameraGUI.update();
}
#Override
public void dispose() {
// TODO Auto-generated method stub
batch.dispose();
}
private void renderGuiScore (SpriteBatch batch) {
float x = -15;
float y = -15;
batch.draw(Assets.instance.enemies.soldiers,x, y, 50, 50, 100, 100, 0.35f, -0.35f, 0);
Assets.instance.fonts.defaultBig.draw(batch,
"" + worldController.score,
x + 75, y + 37);
//stage.draw(); i have try draw in this line too but UI become dissapear
}
private void renderGuiExtraLive (SpriteBatch batch) {
float x = cameraGUI.viewportWidth - 50 - Constants.LIVES_START*50;
float y = -15*h;
for (int i = 0; i < Constants.LIVES_START; i++) {
if (worldController.lives <= i)
batch.setColor(0.5f, 0.5f, 0.5f, 0.5f);
batch.draw(Assets.instance.hero.hero1,
x + i * 50, y, 50, 50, 120, 100, 0.35f, -0.35f, 0);
batch.setColor(1, 1, 1, 1);
}
}
private void renderGuiHealth (SpriteBatch batch) {
float x = 50;
float y = -15*h;
for (int i = 0; i < Constants.LIVES_START; i++) {
if (worldController.lives <= i)
batch.setColor(Color.RED);
float health = worldController.level.hero.getHealth();
Assets.instance.fonts.defaultBig.draw(batch,
"" + Math.round(health),
x + 75, y + 37);
}
}
private void renderGuiEnergy (SpriteBatch batch) {
float x = 125;
float y = -15*h;
for (int i = 0; i < Constants.LIVES_START; i++) {
if (worldController.lives <= i)
batch.setColor(Color.GREEN);
float energy = worldController.level.hero.getEnergy();
Assets.instance.fonts.defaultBig.draw(batch,
"" + Math.round(energy),
x + 75, y + 37);
}
}
private void renderGuiPlasma (SpriteBatch batch) {
float x = 200;
float y = -15*h;
for (int i = 0; i < Constants.LIVES_START; i++) {
if (worldController.lives <= i)
batch.setColor(Color.BLACK);
Assets.instance.fonts.defaultBig.draw(batch,
"" + worldController.level.hero.getUltimateEnergy() + "-" + worldController.level.hero.getPower() + "-" + worldController.plasma,
x + 75, y + 37);
}
}
private void renderGui (SpriteBatch batch) {
batch.setProjectionMatrix(cameraGUI.combined);
batch.begin();
// draw collected gold coins icon + text
// (anchored to top left edge)
renderGuiScore(batch);
// draw extra lives icon + text (anchored to top right edge)
renderGuiExtraLive(batch);
//draw Health
renderGuiHealth(batch);
//draw Energy
renderGuiEnergy(batch);
//draw Plasma
renderGuiPlasma(batch);
batch.end();
stage.draw();
}
}
You have forgotten:
stage.act();
And set the input processor:
Gdx.input.setInputProcessor(stage);