How to make .tmx map fill the whole screen - java

I'm loading a .tmx map using Libgdx and the map is not filling the whole screen. I cannot figure out the problem so as a last resort I'm asking a question here.I'm following a tutorial on YouTube and he did not cover this problem and as a result I cannot continue. I have tried multiple things with no sucess. The map is width: 240 tiles, height: 13 tiles, and tiles are 16 by 16
,
.
This is the code. I think the problem has to do with
renderer = new OrthogonalTiledMapRenderer(map, 1/DBZ.PPM),
gameCam.position.set(gamePort.getWorldWidth()/2,
gamePort.getWorldHeight()/2, 0);,
gameCam = new OrthographicCamera();
gamePort = new FitViewport(DBZ.V_WIDTH/DBZ.PPM, DBZ.V_HEIGHT/DBZ.PPM, gameCam);
public class PlayScreen implements Screen {
private DBZ game;
private OrthographicCamera gameCam;
private Viewport gamePort;
private Hud hud;
private TmxMapLoader maploader;
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
private World world;
private Box2DDebugRenderer b2dr;
private Goku player;
private TextureAtlas atlas;
public PlayScreen(DBZ game){
atlas = new TextureAtlas("goku.pack");
this.game= game;
gameCam = new OrthographicCamera();
gamePort = new FitViewport(DBZ.V_WIDTH/DBZ.PPM, DBZ.V_HEIGHT/DBZ.PPM, gameCam);
hud = new Hud(game.batch);
maploader= new TmxMapLoader();
map = maploader.load("level1.tmx");
renderer = new OrthogonalTiledMapRenderer(map, 1/DBZ.PPM);
gameCam.position.set(gamePort.getWorldWidth()/2, gamePort.getWorldHeight()/2, 0);
world = new World(new Vector2(0,-10),true);
b2dr = new Box2DDebugRenderer();
new B2WorldCreator(world,map);
player = new Goku(world, this);
}
public TextureAtlas getAtlas(){
return atlas;
}
#Override
public void show() {
}
public void handleInput(float dt){
if (Gdx.input.isKeyJustPressed(Input.Keys.UP))
player.b2body.applyLinearImpulse(new Vector2(0, 4f), player.b2body.getWorldCenter(), true);
if (Gdx.input.isKeyPressed(Input.Keys.RIGHT) && player.b2body.getLinearVelocity().x <= 2)
player.b2body.applyLinearImpulse(new Vector2(0.1f, 0), player.b2body.getWorldCenter(), true);
if (Gdx.input.isKeyPressed(Input.Keys.LEFT) && player.b2body.getLinearVelocity().x >= -2)
player.b2body.applyLinearImpulse(new Vector2(-0.1f, 0), player.b2body.getWorldCenter(), true);
}
public void update(float dt){
handleInput(dt);
world.step(1/60f, 6, 2);
player.update(dt);
gameCam.position.x = player.b2body.getPosition().x;
gameCam.update();
renderer.setView(gameCam);
}
#Override
public void render(float delta) {
update(delta);
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderer.render();
b2dr.render(world, gameCam.combined);
game.batch.setProjectionMatrix(gameCam.combined);
game.batch.begin();
player.draw(game.batch);
game.batch.end();
game.batch.setProjectionMatrix(hud.stage.getCamera().combined);
hud.stage.draw();
}
#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() {
map.dispose();
renderer.dispose();
world.dispose();
b2dr.dispose();
hud.dispose();
}
}
public class DBZ extends Game{
public SpriteBatch batch;
public static final int V_WIDTH = 400;
public static final int V_HEIGHT = 208;
public static final float PPM = 100;
#Override
public void create () {
batch = new SpriteBatch();
setScreen(new PlayScreen(this));
}
#Override
public void render () {
super.render();
}
#Override
public void dispose () {
batch.dispose();
}
}
public class Goku extends Sprite {
public World world;
public Body b2body;
private TextureRegion gokuStand;
public Goku(World world, PlayScreen screen){
super(screen.getAtlas().findRegion("goku_sprite"));
this.world = world;
defineGoku();
gokuStand = new TextureRegion(getTexture(), 5,12,59,85);
setBounds(0,0,59/DBZ.PPM,85/DBZ.PPM);
setRegion(gokuStand);
}
public void defineGoku(){
BodyDef bdef = new BodyDef();
bdef.position.set(32/DBZ.PPM,32/DBZ.PPM);
bdef.type = BodyDef.BodyType.DynamicBody;
b2body = world.createBody(bdef);
FixtureDef fdef = new FixtureDef();
PolygonShape shape = new PolygonShape();
shape.setAsBox(59/2/DBZ.PPM, 85/2/DBZ.PPM);
fdef.shape = shape;
b2body.createFixture(fdef);
}
public void update(float dt){
setPosition(b2body.getPosition().x - getWidth()/2, b2body.getPosition().y - getHeight()/2 );
}
}

Problem is in placement of camera, attach camera with player so that viewport of camera cover whole screen. I am trying to fix this.
public float gokuStartingPositionX;
public PlayScreen(DBZ game){
.....
new B2WorldCreator(world,map);
gokuStartingPositionX=64/DBZ.PPM; //added in your method
player = new Goku(world, this);
}
public void update(float dt){
handleInput(dt);
world.step(1/60f, 6, 2);
player.update(dt);
//camera position is decided by player position and keep camera in this way so it cover whole viewport width with screen
gameCam.position.x = player.b2body.getPosition().x + gamePort.getWorldWidth()/2 - gokuStartingPositionX;
gameCam.update();
renderer.setView(gameCam);
}
Small modification in Goku
public Goku(World world, PlayScreen screen){
super(screen.getAtlas().findRegion("goku_sprite"));
this.world = world;
defineGoku(screen.gokuStartingPositionX);
gokuStand = new TextureRegion(getTexture(), 5,12,59,85);
setBounds(0,0,59/DBZ.PPM,85/DBZ.PPM);
setRegion(gokuStand);
}
public void defineGoku(float startX){
BodyDef bdef = new BodyDef();
bdef.position.set(startX,32/DBZ.PPM);
bdef.type = BodyDef.BodyType.DynamicBody;
b2body = world.createBody(bdef);
...
}

I believe what you are looking for is the ability to clamp the camera to the map.
This can be achieved using MathUtils.clamp.
gameCam.position.x = MathUtils.clamp(gameCam.position.x, viewportWidth/2 , 38 - viewportWidth/2);
gameCam.position.y = MathUtils.clamp(gameCam.position.y, viewportHeight/2, 208 - viewportHeight/2);
EDIT: Your updated PlayScreen:
package com.edwin.game.Screens;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
import com.edwin.game.DBZ;
import com.edwin.game.Scenes.Hud;
import com.edwin.game.Sprites.Goku;
import com.edwin.game.Tools.B2WorldCreator;
/**
* Created by Edwin on 3/20/2017.
*/
public class PlayScreen implements Screen {
private DBZ game;
private OrthographicCamera gameCam;
private Viewport gamePort;
private Hud hud;
private TmxMapLoader maploader;
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
private World world;
private Box2DDebugRenderer b2dr;
private Goku player;
private TextureAtlas atlas;
private float viewportWidth;
private float viewportHeight;
public PlayScreen(DBZ game){
atlas = new TextureAtlas("goku.pack");
this.game= game;
gameCam = new OrthographicCamera();
gamePort = new FitViewport(DBZ.V_WIDTH/DBZ.PPM, DBZ.V_HEIGHT/DBZ.PPM, gameCam);
hud = new Hud(game.batch);
maploader= new TmxMapLoader();
map = maploader.load("level1.tmx");
renderer = new OrthogonalTiledMapRenderer(map, 1/DBZ.PPM);
viewportWidth = gamePort.getWorldWidth();
viewportHeight= gamePort.getWorldHeight();
world = new World(new Vector2(0,-10),true);
b2dr = new Box2DDebugRenderer();
new B2WorldCreator(world,map);
player = new Goku(world, this);
}
public TextureAtlas getAtlas(){
return atlas;
}
#Override
public void show() {
}
public void handleInput(float dt){
if (Gdx.input.isKeyJustPressed(Input.Keys.UP))
player.b2body.applyLinearImpulse(new Vector2(0, 4f), player.b2body.getWorldCenter(), true);
if (Gdx.input.isKeyPressed(Input.Keys.RIGHT) && player.b2body.getLinearVelocity().x <= 2)
player.b2body.applyLinearImpulse(new Vector2(0.5f, 0), player.b2body.getWorldCenter(), true);
if (Gdx.input.isKeyPressed(Input.Keys.LEFT) && player.b2body.getLinearVelocity().x >= -2)
player.b2body.applyLinearImpulse(new Vector2(-0.1f, 0), player.b2body.getWorldCenter(), true);
}
public void update(float dt){
handleInput(dt);
world.step(1/60f, 6, 2);
player.update(dt);
gameCam.position.x = player.b2body.getPosition().x;
// cam pos / var to clamp / min val / max val
gameCam.position.x = MathUtils.clamp(gameCam.position.x, viewportWidth/2 , 38 - viewportWidth/2);
gameCam.position.y = MathUtils.clamp(gameCam.position.y, viewportHeight/2, 208 - viewportHeight/2);
System.out.println(gameCam.position.x);
gameCam.update();
renderer.setView(gameCam);
}
#Override
public void render(float delta) {
update(delta);
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderer.render();
//
//
b2dr.render(world, gameCam.combined);
game.batch.setProjectionMatrix(gameCam.combined);
game.batch.begin();
player.draw(game.batch);
game.batch.end();
game.batch.setProjectionMatrix(hud.stage.getCamera().combined);
hud.stage.draw();
}
#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() {
map.dispose();
renderer.dispose();
world.dispose();
b2dr.dispose();
hud.dispose();
}
}

Related

How to fix java.lang.UnsatisfiedLinkError: com.badlogic.gdx.physics.box2d.PolygonShape.newPolygonShape()?

For some reason, my Box2d Object code works in one Class but does not work in the other even though it is the exact same code I have read it has something to do with importing the correct library but the library is imported correctly but still, it is not working. I'm kind of desperate and don't know what to do, to be honest, maybe someone here can give me a pointer. I know this is a lot of code, but I really don't know what to do, I hope someone can give me a pointer, maybe I am just overlooking something
Here is the code with the Object:
public class Tank extends Sprite implements Renderable, PhysicsObject, Updatable {
public Body body;
public Sprite SpriteBody;
public Sprite SpriteTurret;
public Playscreen playScreen;
public InputProvider input;
public Vector2 aim;
public int readytoshoot=0;
public float canonrotation;
public World world;
public Body b2Body;
TextureRegion TankBlues;
SpriteBatch sb;
public Texture texture;
public Texture arm;
Sprite sprite;
Sprite sparm;
int horizontalForce;
float dt;
float Richtung;
float Speed = 2f;
public float Radius;
private TankType type;
public ArrayList<Flower> flowers;
float PosX,PosY;
Body TankBody,CanonBody;
RevoluteJoint joint;
private Map<ControlSpecification, Integer> controlMap;
private boolean useController;
private int currentLife;
private int maxLife;
private int fullLifeWidth;
// Playscreen playscreen, Vector2 aim, Input Inputprovider,
public Tank(World world, Playscreen screen, SurvivalMode2 survivalMode, TankType tankType) {
flowers = new ArrayList<Flower>();
// super(screen.getAtlas().findRegion("tankBody_blue"));
this.world = world;
canonrotation=0;
// TankBlues = new TextureRegion(getTexture(),0,0 , 46,46);
// setBounds(0, 0, 46 / SEPGame.PPM, 46 / SEPGame.PPM);
// setRegion(TankBlues);
sb = new SpriteBatch();
texture = new Texture(Gdx.files.internal("tankBody_.png"));
arm = new Texture(Gdx.files.internal("b-tankBlue_barrel2_outline.png"));
sprite = new Sprite(texture);
sparm = new Sprite(arm);
PosX=Gdx.graphics.getWidth() / 2 ;
PosY= Gdx.graphics.getHeight() / 2;
sprite.setPosition(PosX,PosY);
sparm.setPosition(Gdx.graphics.getWidth() / 2 - sprite.getWidth() / 2, Gdx.graphics.getHeight() / 2);
useController = false;
// defineTank();
// registerController();
controlMap = StandardControlSpecification.getMapping(tankType);
this.type = tankType;
// defineTank();
// registerController();
// TankBody erstellen
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(PosX, PosY);
PolygonShape shape = new PolygonShape();
shape.setAsBox(sprite.getWidth()/2-1, sprite.getHeight()/2-1);
Radius=(float)Math.sqrt((double)(sprite.getWidth()*sprite.getWidth()/4+sprite.getHeight()*sprite.getHeight()/4) );
FixtureDef fixDef = new FixtureDef();
fixDef.shape = shape;
fixDef.density = 1f;
fixDef.restitution = .1f;
fixDef.friction = .5f;
TankBody = world.createBody(bodyDef);
TankBody.createFixture(fixDef);
TankBody.setLinearDamping(2f);
TankBody.setAngularDamping(2f);
TankBody.setUserData(42);
this.type = tankType;
maxLife = 100;
currentLife = maxLife;
fullLifeWidth = 300;
}
public Rectangle getRect() {
Rectangle Rectanlge = new Rectangle(sprite.getX(), sprite.getY(), sprite.getWidth(), sprite.getHeight());
return Rectanlge;
}
private void registerController() {
for (Controller controller : Controllers.getControllers()) {
controller.addListener(new GamepadInputProvider(this));
}
}
public float getX() {
return sprite.getX();
}
public float getY() {
return sprite.getY();
}
public float getRotation() {
return sparm.getRotation();
}
public void collision() {
}
public void takeDamage(int damage) {
currentLife -= damage;
}
public void defineTank() { //verwenden wir net physic engine
BodyDef bDef = new BodyDef();
bDef.position.set(sprite.getX(), sprite.getY());
bDef.type = BodyDef.BodyType.DynamicBody;
b2Body = world.createBody(bDef);
FixtureDef fDef = new FixtureDef();
PolygonShape shape = new PolygonShape();
shape.setAsBox(70, 70);
// fDef.density = 1f;
fDef.shape = shape;
b2Body.createFixture(fDef);
}
public void render()
{
sb.begin();
float x=TankBody.getPosition().x-sprite.getWidth()/2;
float y=TankBody.getPosition().y-sprite.getHeight()/2;
sprite.setPosition(x, y);
sprite.setRotation((float)(TankBody.getAngle()/Math.PI*180f));
sparm.setPosition(x, y);
sparm.setRotation((float)(TankBody.getAngle()/Math.PI*180f+canonrotation) );
sprite.draw(sb);
sparm.draw(sb);
sb.end();
Flower destroy = null;
boolean del=false;
for (Flower flower : flowers)
{
if(flower.todelete==0)
{
del=true;
destroy=flower;
}
else
{
flower.render();
}
}
if(del)
{
flowers.remove(destroy);
destroy.delete();
del=false;
}
renderLifebar();
}
Here is the class where it works:
public class Playscreen extends WorldMap implements Screen {
public World world;
public SpriteBatch batch;
public float timeToSimulate;
private SEPGame game;
SpriteBatch sb;
public Tank tank;
public Target ziel;
private Tank gegner1;
boolean treffer;
public float width = Gdx.graphics.getWidth();
public float heights = Gdx.graphics.getHeight();
public WorldMap worldMap;
public Box2DDebugRenderer debugRenderer;
public Obstacle leftwall,upperwall,rightwall,lowerwall;
public Obstacle O1,O2,O3,O4;
public TextureAtlas atlas;
public MenuScreen menuScreen;
int anzahlTotePanzer = 0;
public Playscreen(SEPGame game)
{
world= new World(new Vector2(0,0), false);
ziel = new Target(MathUtils.random(Gdx.graphics.getWidth()-48),MathUtils.random(Gdx.graphics.getHeight()-48),world);
tank = new Tank(world,this, null,TankType.PLAYER_2);
gegner1 = new Tank(world, this, null,TankType.KI);
menuScreen = new MenuScreen(game);
atlas = new TextureAtlas("TanksGesamt.atlas");
leftwall=new Obstacle(world,1);
upperwall=new Obstacle(world,2);
rightwall=new Obstacle(world,3);
lowerwall=new Obstacle(world,4);
O1=new Obstacle(world, 200, 523, 30, 100, 90);
Texture t=new Texture(Gdx.files.internal("crateMetal.png"));
O2=new Obstacle(world, 400, 100, t);
O3=new Obstacle(world, 1200, 900, t);
worldMap = new WorldMap();
this.game = game;
debugRenderer = new Box2DDebugRenderer( true, true,
false, true, true, true );
world.setContactListener(new ContactListener()
{
#Override
public void beginContact(Contact contact)
{
}
#Override
public void endContact(Contact contact)
{
Fixture fixtureA = contact.getFixtureA();
Fixture fixtureB = contact.getFixtureB();
Body BodyA=contact.getFixtureA().getBody();
if(BodyA.equals(ziel.TargetBody))
{
treffer=true;
}
for (Flower flower : tank.flowers)
{
if(flower.FlowerBody.equals(contact.getFixtureB().getBody())
||flower.FlowerBody.equals(contact.getFixtureA().getBody()))
{
flower.todelete-=1;
}
}
}
#Override
public void preSolve(Contact contact, Manifold oldManifold)
{
}
#Override
public void postSolve(Contact contact, ContactImpulse impulse)
{
}
});
}
public void show() {
}
public void create() {
}
public void update(float fval) {
world.step(1 / 60f, 6, 2);
mapRenderer.setView(mainCamera);
}
public void openMenu(){
if(Gdx.input.isKeyJustPressed(Input.Keys.ESCAPE)){
game.setScreen(new MenuScreen(game));
this.dispose();
}
}
public void render(float delta) {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
world.step(1 / 60f, 6, 2);
menuScreen.stage.dispose();
worldMap.render();
worldMap.mainCamera.update();
tank.render();
//tank.moveSprite();
tank.ControllerInput();
gegner1.render();
ziel.render();
tank.moveBody();
if(ziel!=null)
{
ziel.render();
}
if (tank.readytoshoot>0)
{
tank.readytoshoot-=1;
}
debugRenderer.render( world, worldMap.mainCamera.combined );
collision();
if (collision()) {
ziel = new Target(MathUtils.random(Gdx.graphics.getWidth()-48),
MathUtils.random(Gdx.graphics.getHeight()-48),world);
anzahlTotePanzer++;
System.out.println(anzahlTotePanzer);
}
if (treffer)
{
treffer=false;
ziel.delete();
ziel = new Target(MathUtils.random(Gdx.graphics.getWidth()-48),MathUtils.random(Gdx.graphics.getHeight()-48),world);
}
O2.render();
}
public boolean collision() {
boolean col = false;
Rectangle rectangle2 = ziel.bounds();
for(Flower f: tank.flowers) {
Rectangle rec1= f.getRec();
if(rec1.overlaps(rectangle2)){
col= true;
}else {
col= false;
}
}
return col;
}
this is the class which calls the same tank class but gives me a java.lang.UnsatisfiedLinkError: com.badlogic.gdx.physics.box2d.PolygonShape.newPolygonShape()
public class SurvivalMode2 extends WorldMap implements Screen {
public EnemyTank enemyTank;
public SEPGame game;
public WorldMap worldMap;
public Tank tank;
public int anzahlPanzer;
public int spawnPanzer;
public ArrayList<EnemyTank> tankListe;
public Obstacle O1,O2,O3,O4;
public Obstacle leftwall,upperwall,rightwall,lowerwall;
public Box2DDebugRenderer debugRenderer;
boolean treffer;
public SurvivalMode2(SEPGame game) {
enemyTank = new EnemyTank(world, this,null ,TankType.KI);
tank = new Tank(world,null,this,TankType.PLAYER_1);
this.game = game;
world = new World(new Vector2(0,0), false);
worldMap = new WorldMap();
debugRenderer = new Box2DDebugRenderer
( true, true, false, true, true, true );
world.setContactListener(new ContactListener()
{
#Override
public void beginContact(Contact contact)
{
}
#Override
public void endContact(Contact contact)
{
Fixture fixtureA = contact.getFixtureA();
Fixture fixtureB = contact.getFixtureB();
Body BodyA=contact.getFixtureA().getBody();
if(BodyA.equals(enemyTank.enemyBody))
{
treffer=true;
}
for (Flower flower : tank.flowers)
{
if(flower.FlowerBody.equals(contact.getFixtureB().getBody())
||flower.FlowerBody.equals(contact.getFixtureA().getBody()))
{
flower.todelete-=1;
}
}
}
#Override
public void preSolve(Contact contact, Manifold oldManifold)
{
}
#Override
public void postSolve(Contact contact, ContactImpulse impulse)
{
}
});
}
public void update(){
mapRenderer.setView(mainCamera);
}
#Override
public void show() {
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
worldMap.render();
worldMap.mainCamera.update();
enemyTank.render();
tank.render();
}
the error I am getting:
Caused by: java.lang.UnsatisfiedLinkError: com.badlogic.gdx.physics.box2d.PolygonShape.newPolygonShape()J
at com.badlogic.gdx.physics.box2d.PolygonShape.newPolygonShape(Native Method)
at com.badlogic.gdx.physics.box2d.PolygonShape.<init>(PolygonShape.java:29)
at de.paluno.game.gameobjects.EnemyTank.<init>(EnemyTank.java:51)
at de.paluno.game.screens.SurvivalMode2.<init>(SurvivalMode2.java:54)
at de.paluno.game.screens.MenuScreen.survivalMode(MenuScreen.java:63)
at de.paluno.game.screens.MenuScreen$2.changed(MenuScreen.java:97)
at com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.handle(ChangeListener.java:28)
at com.badlogic.gdx.scenes.scene2d.Actor.notify(Actor.java:183)
at com.badlogic.gdx.scenes.scene2d.Actor.fire(Actor.java:148)
at com.badlogic.gdx.scenes.scene2d.ui.Button.setChecked(Button.java:131)
at com.badlogic.gdx.scenes.scene2d.ui.Button$1.clicked(Button.java:94)
at com.badlogic.gdx.scenes.scene2d.utils.ClickListener.touchUp(ClickListener.java:88)
at com.badlogic.gdx.scenes.scene2d.InputListener.handle(InputListener.java:59)
at com.badlogic.gdx.scenes.scene2d.Stage.touchUp(Stage.java:350)
at com.badlogic.gdx.backends.lwjgl.LwjglInput.processEvents(LwjglInput.java:342)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:217)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:126)
Here is my code from Enemytank its identical to tank except a few lines like moveBody method or:
package de.paluno.game.gameobjects;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.physics.box2d.*;
import de.paluno.game.SEPGame;
import de.paluno.game.screens.Playscreen;
import de.paluno.game.screens.SurvivalMode2;
import java.util.ArrayList;
public class EnemyTank extends Sprite {
public ArrayList<EnemyTank> enemyList;
public Sprite enemySprite;
public SpriteBatch enemyBatch;
public PolygonShape shape;
public Texture texture;
private int currentLife;
private int maxLife;
private int fullLifeWidth;
public TankType type;
float PosX,PosY;
public Body enemyBody;
public BodyDef bdef;
public FixtureDef fdef;
public float Radius;
public EnemyTank(World world, SurvivalMode2 survivalScreen, Playscreen screen, TankType tankType){
enemyBatch = new SpriteBatch();
texture = new Texture("tankBody_huge.png");
enemySprite = new Sprite(texture);
PosX= MathUtils.random(Gdx.graphics.getWidth()-48);
PosY= MathUtils.random(Gdx.graphics.getHeight()-48);
bdef = new BodyDef();
fdef = new FixtureDef();
// TankBody erstellen
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(PosX, PosY);
PolygonShape shape = new PolygonShape();
shape.setAsBox(enemySprite.getWidth()/2-1, enemySprite.getHeight()/2-1);
Radius=(float)Math.sqrt((double)(enemySprite.getWidth()*
enemySprite.getWidth()/4+enemySprite.getHeight()*enemySprite.getHeight()/4) );
FixtureDef fixDef = new FixtureDef();
fixDef.shape = shape;
fixDef.density = 1f;
fixDef.restitution = .1f;
fixDef.friction = .5f;
enemyBody = world.createBody(bodyDef);
enemyBody.createFixture(fixDef);
enemyBody.setLinearDamping(2f);
enemyBody.setAngularDamping(2f);
enemyBody.setUserData(42);
this.type = tankType;
maxLife = 100;
currentLife = maxLife;
fullLifeWidth = 300;
}
public float getX() {
return enemySprite.getX();
}
public float getY() {
return enemySprite.getY();
}
public void render() {
enemyBatch.begin();
float x=enemyBody.getPosition().x-enemySprite.getWidth()/2;
float y=enemyBody.getPosition().y-enemySprite.getHeight()/2;
enemySprite.setPosition(x, y);
enemySprite.setRotation((float)(enemyBody.getAngle()/Math.PI*180f));
enemySprite.draw(enemyBatch);
enemyBatch.end();
}
public void setupBody() {
}
public Body getBody() {
return null;
}
public void setBodyToNullReference() {
}
public void update(float fval) {
}
}
java.lang.UnsatisfiedLinkError: com.badlogic.gdx.physics.box2d.PolygonShape.newPolygonShape()J means Java tries to bind Java method marked native long newPolygonShape() to underlying non-java native method and cannot find it.
In other words there is mismatch between com.badlogic.gdx.physics.box2d Java library and corresponding native library.
I think there reason why it works for one class and does not work for other is you call different methods of PolygonShape and one method is found & binded and other is not.

How to add background image in libgdx?

I want to add a background like blockbunny and I have a background image image in my assets/images folder under the android folder. I have tried to separate the image into three sections and add it as sky, clouds and mountains in Background class. For some reason, it is throwing null pointer exception because spritebatch is null in MyMainGame class. I have initialised SpriteBatch in create method of MyMainGame class.
Here is my MyMainGame.class
package com.mygdx.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.GL30;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.mygdx.manager.Content;
import com.mygdx.manager.GameInputProcessor;
import com.mygdx.manager.GameStateManager;
import com.mygdx.manager.MyInput;
import javafx.scene.layout.Background;
import static com.mygdx.manager.Box2DVariables.PPM;
public class MyMainGame implements ApplicationListener {
SpriteBatch batch;
Texture img;
public static final int Width=320;
public static final int Height=240;
public static final int SCALE=2;
public static final float STEP= 1/60f; //60 frames per second
private float accumulator;
private SpriteBatch sb;
protected OrthographicCamera cam;
protected OrthographicCamera hud;
private Texture tex;
private Background[] backgrounds;
private GameStateManager gsm;
public SpriteBatch getSb() {
return sb;
}
public OrthographicCamera getCam() {
return cam;
}
public OrthographicCamera getHud() {
return hud;
}
public static Content con;
#Override
public void create () {
Gdx.input.setInputProcessor(new GameInputProcessor());
con=new Content();
con.loadTexture("images//sprite.jpg","sprite");
con.loadTexture("images//background.png","background");
gsm=new GameStateManager(this);
sb=new SpriteBatch();
cam=new OrthographicCamera(160,120);
cam.setToOrtho(false,Width/2,Height/2);
hud=new OrthographicCamera();
hud.setToOrtho(false,Width/2,Height/2);
}
#Override
public void render () {
cam.update();
hud.update();
accumulator +=Gdx.graphics.getDeltaTime();
while(accumulator>=STEP){
accumulator-=STEP;
gsm.update(STEP);
gsm.render();
MyInput.update();
}
}
public void resize(int width,int height){
sb.getProjectionMatrix().setToOrtho2D(0, 0, width, height);
}
public void dispose(){
con.disposeTexture("sprite");
con.disposeTexture("background");
}
public void pause(){
}
public void resume(){
gsm.setState(GameStateManager.PLAY);
}
}
GameState is an abstract class containing unimplemented methods
package com.mygdx.gamestate;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.mygdx.game.MyMainGame;
import com.mygdx.manager.GameStateManager;
public abstract class GameState {
protected GameStateManager gsm;
protected MyMainGame game;
protected SpriteBatch sb;
protected OrthographicCamera cam;
protected OrthographicCamera hud;
protected GameState(GameStateManager gsm){
this.gsm=gsm;
game=gsm.game();
sb=game.getSb();
cam=game.getCam();
hud=game.getHud();
init();
}
public abstract void init();
public abstract void update(float dt);
public abstract void draw();
public abstract void render();
public abstract void handleInput();
public abstract void dispose();
}
The Play class is extending GameState class
public class Play extends GameState{
// private BitmapFont font=new BitmapFont();
private World world;
private Body playerBody;
private int viewportWidth= 10 * 32 ;
int viewportHeight= 8 * 32 ;
private Box2DDebugRenderer b2d;
private OrthographicCamera B2DCAM;
private TiledMap tileMap;
private OrthogonalTiledMapRenderer orthomap;
private MyContactListener cl;
private float tileSize;
private Background[] backgrounds;
private Texture back;
//file name
private final String LEVEL_1 ="maps/tilemap1.tmx";
public Play(GameStateManager gsm) {
super(gsm);
//setup box2d
world=new World(new Vector2(0,-9.8f),true);
cl=new MyContactListener();
world.setContactListener(cl);
sb=new SpriteBatch(1000);
//cam=new OrthographicCamera();
b2d=new Box2DDebugRenderer();
//create Player
createPlayer();
//create Tiles
createTiles();
orthomap = new OrthogonalTiledMapRenderer(tileMap,1/32f);
//setup Box2D Cam
B2DCAM=new OrthographicCamera();
B2DCAM.setToOrtho(false, MyMainGame.Width/PPM,MyMainGame.Height/PPM);
cam=new OrthographicCamera();
cam.setToOrtho(false,10,7);
back = MyMainGame.con.getTexture("background");
TextureRegion sky = new TextureRegion(back, 0, 0, 320, 240);
TextureRegion clouds = new TextureRegion(back, 0, 240, 320, 240);
TextureRegion mountains = new TextureRegion(back, 0, 480, 320, 240);
backgrounds = new Background[3];
backgrounds[0] = new Background(sky,cam, 0f);
backgrounds[1] = new Background(clouds, cam, 0.1f);
backgrounds[2] = new Background(mountains, cam, 0.2f);
/* //TODO - remove me
File file = new File(LEVEL_1);
if(file.exists())
System.out.println("file exists");*/
}
#Override
public void init() {
}
#Override
public void update(float dt) {
handleInput();
world.step(dt,6,2);
MyMainGame.con.getTexture("sprite");
for (Background b : backgrounds) {
b.update(dt);
}
}
#Override
public void draw() {
}
#Override
public void render() {
//clear screen
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
//
cam.position.set(playerBody.getPosition().x * PPM +MyMainGame.Width / 4,MyMainGame.Height / 2,0);
// cam.setToOrtho(false,playerBody.getPosition().x * PPM +MyMainGame.Width / 4,MyMainGame.Height / 2);
//cam.setPosition(playerBody.getPosition().x * PPM +MyMainGame.Width / 4, MyMainGame.Height / 2);
cam.setToOrtho(false,10,7);
cam.update();
sb.setProjectionMatrix(cam.combined);
for(int i = 0; i < backgrounds.length; i++) {
backgrounds[i].render(sb);
}
orthomap.setView(cam);
orthomap.render();
b2d.render(world,B2DCAM.combined);
}
#Override
public void handleInput() {
if(MyInput.isPressed((MyInput.SPACE))){
System.out.println("space pressed");
if(cl.isPlayerOnGround())
System.out.println(cl.isPlayerOnGround());
playerBody.applyForceToCenter(0,200,true);
}
}
#Override
public void dispose() {
world.dispose();
b2d.dispose();
tileMap.dispose();
orthomap.dispose();
}
private void createPlayer(){
BodyDef bodydef=new BodyDef();
FixtureDef fixdef=new FixtureDef();
PolygonShape shape=new PolygonShape();
//create player
bodydef.position.set(160/PPM,200/PPM);
bodydef.type= BodyDef.BodyType.DynamicBody;
playerBody=world.createBody(bodydef);
shape.setAsBox(5/PPM,5/PPM);
fixdef.shape=shape;
fixdef.filter.categoryBits= BIT_PLAYER;
fixdef.filter.maskBits=Box2DVariables.BIT_BLUE;
playerBody.createFixture(fixdef).setUserData("PLAYER");
//create foot sensor
shape.setAsBox(2/PPM,2/PPM,new Vector2(0,-5/PPM),0);
fixdef.shape=shape;
fixdef.filter.categoryBits= BIT_PLAYER;
fixdef.filter.maskBits=Box2DVariables.BIT_BLUE;
fixdef.isSensor=true;
playerBody.createFixture(fixdef).setUserData("FOOT");
}
private void createTiles(){
//load tile map
tileMap = new TmxMapLoader().load(LEVEL_1);
//orthomap = new OrthogonalTiledMapRenderer(tileMap,1);
tileSize=(int)tileMap.getProperties().get("tilewidth", Integer.class);
System.out.println("Tile Size " +tileSize);
TiledMapTileLayer layer;
layer=(TiledMapTileLayer)tileMap.getLayers().get("Blue");
createLayer(layer,Box2DVariables.BIT_BLUE);
layer=(TiledMapTileLayer)tileMap.getLayers().get("Green");
createLayer(layer,Box2DVariables.BIT_GREEN);
layer=(TiledMapTileLayer)tileMap.getLayers().get("Red");
createLayer(layer,Box2DVariables.BIT_RED);
System.out.println("Layer Height " +layer.getHeight());
System.out.println("Layer Width " +layer.getWidth());
}
private void createLayer(TiledMapTileLayer layer,short bits){
BodyDef bodydef=new BodyDef();
FixtureDef fixdef=new FixtureDef();
//go through cells in layer
for(int row=0;row<layer.getHeight();row++){
for(int col=0;col<layer.getWidth();col++){
//get cells
TiledMapTileLayer.Cell cell=layer.getCell(col,row);
//check if cell exists
if(cell==null) continue;
if(cell.getTile()==null) continue;
//create body and fixture from cell
bodydef.type= BodyDef.BodyType.StaticBody;
bodydef.position.set((col+0.5f)*tileSize/PPM,(row+0.5f)*tileSize/PPM);
ChainShape cs=new ChainShape();
Vector2[] v=new Vector2[3];
//bottom left
v[0]=new Vector2(-tileSize/2/PPM,-tileSize/2/PPM);
//top left
v[1]=new Vector2(-tileSize/2/PPM,tileSize/2/PPM);
//top right corner
v[2]=new Vector2(tileSize/2/PPM,tileSize/2/PPM);
cs.createChain(v);
fixdef.friction=0;
fixdef.shape =cs;
fixdef.filter.categoryBits=Box2DVariables.BIT_BLUE;
fixdef.filter.maskBits=BIT_PLAYER;
fixdef.isSensor=false;
world.createBody(bodydef).createFixture(fixdef);
}
}
}
}
I have loaded the Texture in MyMainClass.java and it is stored in HashMap in Content class
I am getting the background image as Texture named 'back', and seperating them as TextureRegions sky,clouds and mountains in Play constructor of Play class and passing them in Background class.
TextureRegion sky = new TextureRegion(back, 0, 0, 320, 240);
TextureRegion clouds = new TextureRegion(back, 0, 240, 320, 240);
TextureRegion mountains = new TextureRegion(back, 0, 480, 320, 240);
backgrounds = new Background[3];
backgrounds[0] = new Background(sky,cam, 0f);
backgrounds[1] = new Background(clouds, cam, 0.1f);
backgrounds[2] = new Background(mountains, cam, 0.2f);
Background class
package com.mygdx.manager;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.mygdx.game.MyMainGame;
public class Background {
private TextureRegion image;
private OrthographicCamera camera;
private float scale;
private float x;
private float y;
private int drawX;
private int drawY;
private float dx;
private float dy;
public Background(TextureRegion image, OrthographicCamera camera, float scale) {
this.image = image;
this.camera = camera;
this.scale = scale;
drawX = MyMainGame.Width / image.getRegionWidth() + 1;
drawY = MyMainGame.Height / image.getRegionHeight() + 1;
System.out.println("Image width"+image.getRegionWidth());
System.out.println("Image height"+image.getRegionHeight());
}
public void setVector(float dx, float dy) {
this.dx = dx;
this.dy = dy;
}
public void update(float ts) {
x += (dx * scale) * ts;
y += (dy * scale) * ts;
}
public void render(SpriteBatch sb) {
float x = ((this.x + camera.viewportWidth / 2 - camera.position.x) * scale) % image.getRegionWidth();
float y = ((this.y + camera.viewportHeight / 2 - camera.position.y) * scale) % image.getRegionHeight();
sb.begin();
int colXOffset = x > 0 ? -1 : 0;
int rowYOffset = y > 0 ? -1 : 0;
for (int rowY = 0; rowY < drawY; rowY++) {
for (int colX = 0; colX < drawX; colX++) {
sb.draw(image, x + (colX + colXOffset) * image.getRegionWidth(), y + (rowY + rowYOffset) * image.getRegionHeight());
}
}
sb.end();
}
}
I am getting an error in Play class in render method as null pointer exception.Dont really know whats going on! sb.setProjectionMatrix is giving nullpointer exception!
public void render() {
//clear screen
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
//
cam.position.set(playerBody.getPosition().x * PPM +MyMainGame.Width / 4,MyMainGame.Height / 2,0);
// cam.setToOrtho(false,playerBody.getPosition().x * PPM +MyMainGame.Width / 4,MyMainGame.Height / 2);
//cam.setPosition(playerBody.getPosition().x * PPM +MyMainGame.Width / 4, MyMainGame.Height / 2);
cam.setToOrtho(false,10,7);
cam.update();
sb.setProjectionMatrix(cam.combined);
for(int i = 0; i < backgrounds.length; i++) {
backgrounds[i].render(sb);
}
orthomap.setView(cam);
orthomap.render();
b2d.render(world,B2DCAM.combined);
}
How do I split the background image and add it as shown above in my Game?

libGDX - My Box2D Body doesnt jump

I'm trying to make a little game with the java game engine called libGDX. I already got the player but he can't jump and I dont know why.
This is my GameScreen class:
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;
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 ...
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, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//updating
update(Gdx.graphics.getDeltaTime());
//render
batch.setProjectionMatrix(cam.combined);
//debug
b2dr.render(world.getWorld(), cam.combined);
}
#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);
player.keyInput();
System.out.println(player.getBody().getPosition().x);
System.out.println(player.getBody().getPosition().y);
}
}
and this is my Player class:
public class Player {
public static Body body;
public static BodyDef def;
private FixtureDef fd;
//set form
private PolygonShape shape;
private GameScreen gs;
public Player(GameWorld world){
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, 32 / 2);
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 void keyInput(){
if(Gdx.input.isKeyPressed(Input.Keys.UP)){
body.applyForceToCenter(0, 900, false);
System.out.println("PRESSED");
}
}
}
this finally is my GameWorld class:
public class GameWorld {
public static World world;
public GameWorld(){
world = new World(new Vector2(0f, -10f), false);
}
public void update(float delta){
world.step(1 / 60f, 5, 2);
System.out.println("WorldUPDATE");
}
public static World getWorld() {
return world;
}
}
I don't know why the body can't jump please help me if you can (: Thank you in advance.
Force pushes the body each timestep, while gravity pushes it back down again. There is a function applyLinearImpulse() which pushes it like once with all its "force" before gravity interferention.
When you are using applyForceToCenter() body should be pushed up, but its very slow process compared to impulse.

LIBGDX horizontal and vertical parallax background

Im trying to do a little game in LibGdx, right now i have a spaceship that can move with a touchpad in every directions and the camera follows it.
Im tryng to accomplish a parallax background made of stars that moves depending of where the spaceship is going.
Here it is the code, Im giving you all the class just to be sure to not mess up, for im new with this programming code.
public class TouchPadTest extends OrthographicCamera implements ApplicationListener {
public static final int WIDTH=480;
public static final int HEIGHT=800;
private OrthographicCamera camera;
private Stage stage;
private SpriteBatch batch;
private Touchpad touchpad;
private TouchpadStyle touchpadStyle;
private Skin touchpadSkin;
private Drawable touchBackground;
private Drawable touchKnob;
private Texture blockTexture;
private Sprite blockSprite;
private float blockSpeed;
public void create() {
batch = new SpriteBatch();
//Create camera
float aspectRatio = (float) Gdx.graphics.getWidth() / (float) Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.setToOrtho(false, TouchPadTest.WIDTH, TouchPadTest.HEIGHT);
//Create a touchpad skin
touchpadSkin = new Skin();
//Set background image
touchpadSkin.add("touchBackground", new Texture("data/touchBackground.png"));
//Set knob image
touchpadSkin.add("touchKnob", new Texture("data/touchKnob.png"));
//Create TouchPad Style
touchpadStyle = new TouchpadStyle();
//Create Drawable's from TouchPad skin
touchBackground = touchpadSkin.getDrawable("touchBackground");
touchKnob = touchpadSkin.getDrawable("touchKnob");
//Apply the Drawables to the TouchPad Style
touchpadStyle.background = touchBackground;
touchpadStyle.knob = touchKnob;
//Create new TouchPad with the created style
touchpad = new Touchpad(10, touchpadStyle);
//setBounds(x,y,width,height)
touchpad.setBounds(15, 15, 200, 200);
//Create a Stage and add TouchPad
stage = new Stage(new FitViewport(Gdx.graphics.getWidth(),Gdx.graphics.getHeight()));
stage.addActor(touchpad);
Gdx.input.setInputProcessor(stage);
//Create block sprite
blockTexture = new Texture(Gdx.files.internal("data/shuttle2.png"));
blockSprite = new Sprite(blockTexture);
//Set position to centre of the screen
blockSprite.setPosition(Gdx.graphics.getWidth()/2-blockSprite.getWidth()/2, Gdx.graphics.getHeight()/2-blockSprite.getHeight()/2);
blockSpeed=5;
}
public void movePlayer(){
Vector2 v = new Vector2(touchpad.getKnobPercentX(), touchpad.getKnobPercentY());
float angle = v.angle();
if (touchpad.isTouched()){
blockSprite.setRotation(angle);
}
blockSprite.setX(blockSprite.getX() + touchpad.getKnobPercentX()*blockSpeed);
blockSprite.setY(blockSprite.getY() + touchpad.getKnobPercentY()*blockSpeed);
//Draw
camera.position.set(blockSprite.getX() + blockSprite.getWidth() / 2, blockSprite.getY() + blockSprite.getHeight() / 2, 0);
camera.update();
batch.setProjectionMatrix(camera.combined);
}
public void renderBackground() {
//---------------PARALLAX BACKGROUND---------------------//
}
public void dispose() {
}
public void render() {
Gdx.gl.glClearColor(0/255f,5/255f,15/255f,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//Move blockSprite with TouchPad
movePlayer();
batch.begin();
renderBackground();
blockSprite.draw(batch);
batch.end();
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void resize(int width, int height) {
}
}
For a better exemple, this is the kind of result that i want to achieve: https://www.youtube.com/watch?v=zA91SaOR-Io, if you can help me it will be amazing. Thank You.
This working example of a 3 layer parallax background was adapted from the LibGdx Parallax test and should give you an idea on how to implement a parallax effect. The three images used are all 1024x1024px.
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
public class Test extends ApplicationAdapter implements InputProcessor{
private SpriteBatch batch;
private ParallaxCamera camera;
private Texture bgClose;
private Texture bgMid;
private Texture bgFar;
final Vector3 curr = new Vector3();
final Vector3 last = new Vector3(-1, -1, -1);
final Vector3 delta = new Vector3();
#Override
public void create () {
bgClose = new Texture(Gdx.files.internal("starbg-close.png"));
bgMid = new Texture(Gdx.files.internal("starbg-mid.png"));
bgFar = new Texture(Gdx.files.internal("starbg-far.png"));
camera = new ParallaxCamera(1920,1080);
batch = new SpriteBatch();
Gdx.input.setInputProcessor(this);
}
#Override
public void render () {
//clear screen
Gdx.gl.glClearColor(0f, 0f, 0f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// background layer, no parallax, centered around origin
batch.setProjectionMatrix(camera.calculateParallaxMatrix(0, 0));
batch.disableBlending();
batch.begin();
batch.draw(bgFar, -(int)(bgFar.getWidth() / 2), -(int)(bgFar.getHeight() / 2));
batch.end();
batch.enableBlending();
batch.setProjectionMatrix(camera.calculateParallaxMatrix(0.25f, 0.25f));
batch.begin();
for (int i = 0; i < 9; i++) {
batch.draw(bgMid, i * bgClose.getWidth() - 512, -512);
}
batch.end();
batch.setProjectionMatrix(camera.calculateParallaxMatrix(.5f, .5f));
batch.begin();
for (int i = 0; i < 9; i++) {
batch.draw(bgClose, i * bgClose.getWidth() - 512, -512);
}
batch.end();
}
//.. omitted empty methods ..//
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
last.set(-1, -1, -1);
return false;
}
#Override
public boolean touchDragged(int x, int y, int pointer) {
camera.unproject(curr.set(x, y, 0));
if (!(last.x == -1 && last.y == -1 && last.z == -1)) {
camera.unproject(delta.set(last.x, last.y, 0));
delta.sub(curr);
camera.position.add(delta.x, delta.y, 0);
}
last.set(x, y, 0);
return false;
}
private class ParallaxCamera extends OrthographicCamera {
Matrix4 parallaxView = new Matrix4();
Matrix4 parallaxCombined = new Matrix4();
Vector3 tmp = new Vector3();
Vector3 tmp2 = new Vector3();
public ParallaxCamera (float viewportWidth, float viewportHeight) {
super(viewportWidth, viewportHeight);
}
public Matrix4 calculateParallaxMatrix (float parallaxX, float parallaxY) {
update();
tmp.set(position);
tmp.x *= parallaxX;
tmp.y *= parallaxY;
parallaxView.setToLookAt(tmp, tmp2.set(tmp).add(direction), up);
parallaxCombined.set(projection);
Matrix4.mul(parallaxCombined.val, parallaxView.val);
return parallaxCombined;
}
}
}

libgdx world to screen pos and factors

I want to draw a texture on a body, which is a box.
How do I convert the coordinates of the body to screen coordinates?
I know that the other way around is with camera.unproject(pos), is it similar to this?
I see a lot of people using constants such as WORLD_TO_SCREEN = 32, but I currently don't have that in my game. Is that a problem, and how can I implement it now? Because it seems like people that are using these factors can convert world to screen positions easily. I currently have a camera and an ExtendViewport
camera = new OrthographicCamera(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
viewport = new ExtendViewport(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, camera);
camera.position.set(VIEWPORT_WIDTH/2, VIEWPORT_HEIGHT/2, 0f);
Viewport width and height are set to this
public static final int VIEWPORT_WIDTH = 20;
public static final int VIEWPORT_HEIGHT = 22;
I don't really know what I'm doing, I read documentation and read some tutorials, but if someone could give some explanation about these variables and the world_to_screen factor that would really help me out.
I also set APP_WIDTH=1280, APP_HEIGHT = 720
Do viewport width and height mean that for box2d my screen is 20 meters wide and 22 meters high?
(asking it again because I added a lot the question and I would really like to know these things)
[EDIT]
So I'm trying to draw a ground picture on the ground body
float x = stage.getGround().getX();
float y = stage.getGround().getY();
float w = stage.getGround().getWidth();
float h = stage.getGround().getHeight();
stage.act(delta);
stage.draw();
stage.updateCamera();
Texture texture = new Texture(Gdx.files.internal("ground.png"));
Sprite sprite = new Sprite(texture);
sprite.setSize(w, h);
sprite.setPosition(x-sprite.getWidth()/2, y-sprite.getHeight()/2);
But I don't see it anywhere
[EDIT 2]
Stage Class
public class Mission1Stage extends Stage{
public static final int VIEWPORT_WIDTH = 20;
public static final int VIEWPORT_HEIGHT = 22;
private World world;
private Ground ground;
private LeftWall leftWall;
private Rocket rocket;
private static final float TIME_STEP = 1 / 300f;
private float accumulator = 0f;
private OrthographicCamera camera;
private Box2DDebugRenderer renderer;
private Viewport viewport;
private SpriteBatch spriteBatch = new SpriteBatch();
private Vector3 touchPoint;
private ShapeRenderer shapeRenderer;
private Button boostButton;
private Skin boostSkin;
private Button boostLeftButton;
private Skin boostLeftSkin;
private Button boostRightButton;
private Skin boostRightSkin;
private Button resetButton;
private Skin resetSkin;
private Game game;
private boolean isTouched = false;
public Mission1Stage(Game game) {
setUpWorld();
renderer = new Box2DDebugRenderer();
shapeRenderer = new ShapeRenderer();
setupCamera();
setUpButtons();
addActor(new Background(ground));
}
private void setUpWorld() {
world = WorldUtils.createWorld();
setUpGround();
setUpRocket();
}
private void setUpGround() {
ground = new Ground(WorldUtils.createGround(world));
addActor(ground);
}
private void setUpLeftWall() {
leftWall = new LeftWall(WorldUtils.createLeftWall(world));
}
private void setUpRocket() {
rocket = new Rocket(WorldUtils.createRocket(world));
addActor(rocket);
}
private void setupCamera() {
camera = new OrthographicCamera(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
viewport = new ExtendViewport(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, camera);
camera.position.set(VIEWPORT_WIDTH/2, VIEWPORT_HEIGHT/2, 0f);
camera.update();
}
private void setUpButtons() {
boostSkin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json"));
boostButton = new Button(boostSkin);
boostButton.setSize(80,80);
boostButton.setPosition(Gdx.graphics.getWidth()-boostButton.getWidth()*2,0);
boostButton.setTransform(true);
boostButton.scaleBy(0.5f);
Gdx.input.setInputProcessor(this);
addActor(boostButton);
boostLeftSkin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json"));
boostLeftButton = new Button(boostLeftSkin);
boostLeftButton.setSize(100, 100);
boostLeftButton.setPosition(0, 0);
addActor(boostLeftButton);
boostRightSkin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json"));
boostRightButton = new Button(boostRightSkin);
boostRightButton.setSize(100, 100);
boostRightButton.setPosition(boostLeftButton.getWidth(), 0);
addActor(boostRightButton);
resetSkin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json"));
resetButton = new Button(resetSkin);
resetButton.setSize(100, 100);
resetButton.setPosition(Gdx.graphics.getWidth()-100, Gdx.graphics.getHeight()-100);
addActor(resetButton);
}
#Override
public void act(float delta) {
super.act(delta);
handleInput();
accumulator += delta;
while(accumulator >= delta) {
world.step(TIME_STEP, 6, 2);
accumulator -= TIME_STEP;
}
}
#Override
public void draw() {
super.draw();
renderer.render(world, camera.combined);
float x = getGround().getBody().getPosition().x;
float y = getGround().getBody().getPosition().y;
float w = getGround().getWidth() * 2;
float h = getGround().getHeight() * 2;
spriteBatch.setProjectionMatrix(getCamera().combined);
Texture texture = new Texture(Gdx.files.internal("ground.png"));
Sprite sprite = new Sprite(texture);
sprite.setSize(w, h);
sprite.setPosition(x-sprite.getWidth()/2, y-sprite.getHeight()/2);
spriteBatch.begin();
sprite.draw(spriteBatch);
spriteBatch.end();
}
public void handleInput() {
if(boostButton.isPressed()) {
rocket.boost();
}
if(boostLeftButton.isPressed()) {
rocket.turnLeft();
}
if(boostRightButton.isPressed()) {
rocket.turnRight();
}
if(resetButton.isPressed()) {
}
}
public boolean resetScreen() {
if(resetButton.isPressed()) return true;
return false;
}
public void updateCamera() {
}
public Ground getGround() {
return ground;
}
public void resize(int width, int height) {
viewport.update(width, height);
camera.position.x = VIEWPORT_WIDTH / 2;
camera.position.y = VIEWPORT_HEIGHT /2;
}
private void translateScreenToWorldCoordinates(int x, int y) {
getCamera().unproject(touchPoint.set(x, y, 0));getCamera();
}
}
Screen class
public class Mission1Screen implements Screen{
private Game game;
private Mission1Stage stage;
private SpriteBatch spriteBatch = new SpriteBatch();
private Skin boostSkin;
private Button boostButton;
public Mission1Screen(Game game) {
this.game = game;
stage = new Mission1Stage(game);
}
#Override
public void show() {
}
#Override
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if(stage.resetScreen()) {
game.setScreen(new Mission1Screen(game));
}
stage.act(delta);
stage.draw();
stage.updateCamera();
}
#Override
public void resize(int width, int height) {
stage.resize(width, height);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
}
[EDIT 3]
public class Main extends Game {
#Override
public void create () {
this.setScreen(new Mission1Screen(this));
}
#Override
public void render () {
super.render();
}
#Override
public void dispose () {
}
}
We mostly use Pixel to meter conversion because box2d best works in meters (0-10) but you can avoid this conversion by using small worldwidth and height of your viewport. I mostly prefer 48 and 80 as viewport width and height.
You can use unproject(vector3) method of camera that translate a point given in screen coordinates to world space. I am using this method in touchdown because I get screen coordinate as parameter then I need to convert it into camera world space so that I can generate object at a particular position in world.
public class MyGdxTest extends Game implements InputProcessor {
private SpriteBatch batch;
private ExtendViewport extendViewport;
private OrthographicCamera cam;
private float w=20;
private float h=22;
private World world;
private Box2DDebugRenderer debugRenderer;
private Array<Body> array;
private Vector3 vector3;
#Override
public void create() {
cam=new OrthographicCamera();
extendViewport=new ExtendViewport(w,h,cam);
batch =new SpriteBatch();
Gdx.input.setInputProcessor(this);
world=new World(new Vector2(0,-9.8f),true);
array=new Array<Body>();
debugRenderer=new Box2DDebugRenderer();
vector3=new Vector3();
BodyDef bodyDef=new BodyDef();
bodyDef.type= BodyDef.BodyType.StaticBody;
bodyDef.position.set(0,0);
Body body=world.createBody(bodyDef);
ChainShape chainShape=new ChainShape();
chainShape.createChain(new float[]{1,1,55,1});
FixtureDef fixtureDef=new FixtureDef();
fixtureDef.shape=chainShape;
fixtureDef.restitution=.5f;
body.createFixture(fixtureDef);
chainShape.dispose();
}
#Override
public void render() {
super.render();
Gdx.gl.glClearColor(0,1,1,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
world.step(1/60f,6,2);
batch.setProjectionMatrix(cam.combined);
batch.begin();
world.getBodies(array);
for (Body body:array){
if(body.getUserData()!=null) {
Sprite sprite = (Sprite) body.getUserData();
sprite.setPosition(body.getPosition().x-sprite.getWidth()/2, body.getPosition().y-sprite.getHeight()/2);
sprite.setRotation(body.getAngle()*MathUtils.radDeg);
sprite.draw(batch);
}
}
batch.end();
debugRenderer.render(world,cam.combined);
}
#Override
public void resize(int width, int height) {
super.resize(width,height);
extendViewport.update(width,height);
cam.position.x = w /2;
cam.position.y = h/2;
cam.update();
}
private void createPhysicsObject(float x,float y){
float sizeX=2,sizeY=2;
BodyDef bodyDef=new BodyDef();
bodyDef.position.set(x,y);
bodyDef.type= BodyDef.BodyType.DynamicBody;
Body body=world.createBody(bodyDef);
PolygonShape polygonShape=new PolygonShape();
polygonShape.setAsBox(sizeX,sizeY);
FixtureDef fixtureDef=new FixtureDef();
fixtureDef.shape=polygonShape;
fixtureDef.restitution=.2f;
fixtureDef.density=2;
body.createFixture(fixtureDef);
body.setFixedRotation(false);
polygonShape.dispose();
Sprite sprite=new Sprite(new Texture("badlogic.jpg"));
sprite.setSize(2*sizeX,2*sizeY);
sprite.setPosition(x-sprite.getWidth()/2,y-sprite.getHeight()/2);
sprite.setOrigin(sizeX,sizeY);
body.setUserData(sprite);
}
#Override
public void dispose() {
batch.dispose();
debugRenderer.dispose();
world.dispose();
}
#Override
public boolean keyDown(int keycode) {
return false;
}
#Override
public boolean keyUp(int keycode) {
return false;
}
#Override
public boolean keyTyped(char character) {
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
vector3.set(screenX,screenY,0);
Vector3 position=cam.unproject(vector3);
createPhysicsObject(vector3.x,vector3.y);
return false;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
#Override
public boolean scrolled(int amount) {
return false;
}
}

Categories

Resources