libGDX: how to make a world to move - java

I'm a newbie in libgdx and working on a simple 2d game and I want that my box2d world(or background) move with the input touch(move upward when I press the button) but I don't know how to move the world and place my player on the center. I want to know:
How to move my world with the input control.
Place my player in the center.
and also it looks like that my player is moving whenever I play that game, not the world.
if you can just provide an example with your answer.
so, Here is my code
public void show() {
world = new World(new Vector2(0, 25), true);
renderer = new Box2DDebugRenderer();
cam = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
/* cam.position.set(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2, 0);
cam.update();*/
shapeRenderer = new ShapeRenderer();
batch = new SpriteBatch();
texture = new Texture("img/imgs.png");
sprite = new Sprite(texture);
sprite.setSize(10, 10);
sprite.setOrigin(sprite.getWidth() / 2, sprite.getHeight() / 2);
sprite.setPosition(Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight()/2);
//sprite.setBounds(200, 200, 64, 64);
//sprite.setPosition(Gdx.graphics.getWidth()/2 -sprite.getWidth()/2, Gdx.graphics.getHeight()/2-sprite.getHeight()/2);
/* //Body definition
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(0, Gdx.graphics.getHeight() / 2 - 250);
box = world.createBody(bodyDef);
//Polygon Shape
PolygonShape shape = new PolygonShape();
shape.setAsBox(10, 20);
//fixture definition
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 5f;
fixtureDef.friction = .5f;
box.createFixture(fixtureDef);
box.setUserData(sprite);
shape.dispose();
*/ }
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
world.step(1 / 60f, 6, 2);
cam.translate(0, 12);
cam.update();
batch.setProjectionMatrix(cam.combined);
if(Gdx.input.isKeyPressed(Input.Keys.A))
spriteY += Gdx.graphics.getDeltaTime() * spriteSpeed;
if(Gdx.input.isKeyPressed(Input.Keys.D))
spriteY += Gdx.graphics.getDeltaTime() * sprite1Speed;
batch.begin();
batch.draw(sprite, spriteX, spriteY);
batch.end();
shapeRenderer.setColor(Color.RED);
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
shapeRenderer.rect(0, 200, 50, 50);
shapeRenderer.translate(1, 0, 0);
shapeRenderer.end();
}
#Override
public void resize(int width, int height) {
cam.viewportWidth = width;
cam.viewportHeight = height;
cam.update();
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
dispose();
}
#Override
public void dispose() {
//world.dispose();
shapeRenderer.dispose();
batch.dispose();
}
}
Sorry, for the mess(I'm a novice) in code and I want that my world moves upwards with input controls and my sprite just placed in the center.
Thank you in advance.

Your question sounds like you want to create a platformer or kinda.
I'll let you know that the best way to build your logic on when creating a (2d) platformer game is your character should always keep it's position the same and the background and other solid objects should move towards the player (based on input controls or automatic) so giving the look like your player is naturally moving and the background & objects appear in his way.
My answer is pretty general as your question is pretty general. If you need code you must provide us code so we know where you're stuck. Good luck :)

Related

Gdx.input.getY is flipped

I have an issue in LibGDX where when i call upon Gdx.input.getY(), it selects a pixel that's on the other side of the application relative to the center of the screen.
public class Main extends ApplicationAdapter {
private SpriteBatch batch;
private Texture img;
private OrthographicCamera camera;
int xPos;
int yPos;
private Vector3 tp = new Vector3();
BitmapFont font;
#Override
public void create () {
batch = new SpriteBatch();
img = new Texture("crosshair.png");
camera = new OrthographicCamera();
camera.setToOrtho(false, 1280, 720);
font = new BitmapFont();
}
#Override
public void render () {
yPos = Gdx.input.getY();
xPos = Gdx.input.getX();
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.unproject(tp.set(xPos, yPos, 0));
batch.begin();
font.draw(batch,xPos + " , " + yPos, Gdx.input.getX() - 25, Gdx.input.getY() - 5);
batch.draw(img, xPos, yPos);
batch.end();
}
#Override
public void dispose () {
batch.dispose();
img.dispose();
}
Subtracting the viewport height with the touch location won't work, because that would be subtracting world coordinates with touch coordinates. (and even for a pixel perfect projection it would be height - 1 - y). Instead use the unproject method to convert touch coordinates to world coordinates.
There are two problems with your code:
You are never setting the batch projection matrix.
Even though you are using the unproject method, you are never using its result.
So instead use the following:
#Override
public void render () {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
camera.unproject(tp.set(Gdx.input.getX(), Gdx.input.getY(), 0));
font.draw(batch,tp.x+ " , " + tp.y, tp.x - 25, tp.y - 5);
batch.draw(img, tp.x, tp.y);
batch.end();
}
I would suggest to read the following pages, which describe this and the reasoning behind it in detail:
https://github.com/libgdx/libgdx/wiki/Coordinate-systems
https://xoppa.github.io/blog/pixels/
https://github.com/libgdx/libgdx/wiki/Viewports
It's better to try this
yPos = camera.viewportHeight - Gdx.input.getY();

Fit Viewport Black Bars

I'm currently developing a game where you have to avoid Asteroids. To make the Game look same on every device I use the FitViewport. Unfortunately I somehow get White Bars on the top and on the Bottom instead of Black ones. My Game Background is also white, so it looks a bit weird.
GameScreen:
#Override
public void create()
{
float aspectRatio = (float)Gdx.graphics.getWidth() / (float)Gdx.graphics.getHeight();
cam = new OrthographicCamera();
viewport = new FitViewport(MyGdxGame.WIDTH * aspectRatio, MyGdxGame.HEIGHT, cam);
[...]
}
#Override
public void render(SpriteBatch batch)
{
cam.update();
batch.setProjectionMatrix(cam.combined);
batch.begin();
em.render(batch); //render Ship and Asteroids
[...]
}
#Override
public void resize(int width, int height)
{
viewport.update(width, height);
cam.position.set(MyGdxGame.WIDTH / 2, MyGdxGame.HEIGHT /2, 0);
}
I dragged the Ship into the white Bar.
LibGDX provides viewports as a more convenient way of dealing with different aspect ratios. You don't have to multiply MyGdxGame.WIDTH with aspectRatio. Just initialize it with MyGdxGame.WIDTH and MyGdxGame.HEIGHT.
Also, in resize function, you can change the cam position using viewport values (instead of using constants):
cam.position.set(cam.viewportWidth / 2, cam.viewportHeight / 2, 0);
I found some issues in your code. for best practice while handling with the different screen ratio just try with the fill viewPort. Here is simply editing your code with the fill viewport . Just try it once.
#Override
public void create()
{
float aspectRatio = (float)Gdx.graphics.getWidth() / (float)Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.position.set(0, 0, 0);
camera.update();
//1280 is the screen width and 800 is screen height
camera.setToOrtho(false, 1280, 800);
viewPort = new FillViewport(1280, 800, camera);
}
#Override
public void render(SpriteBatch batch)
{
batch.setProjectionMatrix(camera.combined);
batch.begin();
em.render(batch); //render Ship and Asteroids
[...]
}
#Override
public void resize(int width, int height)
{
viewPort.update(width, height);
}
just try with the above code . it will definitely work

Libgdx body position and shaperenderer position not the same

i'm fairly new to libgdx in general. Basically I have the ball bouncing world and i am just experimenting with it. Before I had a fixed camera position as such:
http://prntscr.com/567hvo
After I have putted the following line in the render method so the camera keeps following the player (which is the circle) :
camera.position.set(player.getPosition().x, player.getPosition().y, 0);
The player is a Body type.
So when I do this it does follow the player, but the shape renderer acts weird now. Look at what happens:
http://prntscr.com/567i9a
Even though I am referring to the same x and y position of the player to the camera and the shape renderer, they are not in the same position.
Here is my code:
public class Game extends ApplicationAdapter {
World world = new World(new Vector2(0, -9.8f), true);
Box2DDebugRenderer debugRenderer;
OrthographicCamera camera;
static final int PPM = 100;
static float height,width;
Body player;
RayHandler handler;
PointLight l1;
ShapeRenderer shapeRenderer;
#Override
public void create() {
shapeRenderer = new ShapeRenderer();
height = Gdx.graphics.getHeight();
width = Gdx.graphics.getWidth();
//set camera
camera = new OrthographicCamera();
camera.setToOrtho(false, (width)/PPM/2, (height)/PPM/2);
camera.update();
//Ground body
BodyDef groundBodyDef =new BodyDef();
groundBodyDef.position.set(new Vector2(width/PPM/2/2, 0));
Body groundBody = world.createBody(groundBodyDef);
PolygonShape groundBox = new PolygonShape();
groundBox.setAsBox((width/PPM/2/2), 0.1f);
groundBody.createFixture(groundBox, 0.0f);
//wall left
BodyDef wallLeftDef = new BodyDef();
wallLeftDef.position.set(0, 0f);
Body wallLeftBody = world.createBody(wallLeftDef);
PolygonShape wallLeft = new PolygonShape();
wallLeft.setAsBox(width/PPM/20/2, height/PPM/2);
wallLeftBody.createFixture(wallLeft,0.0f);
//wall right
BodyDef wallRightDef = new BodyDef();
wallRightDef.position.set((width/PPM)/2, 0f);
Body wallRightBody = world.createBody(wallRightDef);
PolygonShape wallRight = new PolygonShape();
wallRight.setAsBox(width/PPM/20/2, height/PPM/2);
wallRightBody.createFixture(wallRight,0.0f);
//Dynamic Body
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set((width/PPM)/2/2, (height / PPM)/2/2);
player = world.createBody(bodyDef);
CircleShape dynamicCircle = new CircleShape();
dynamicCircle.setRadius(5f/PPM);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = dynamicCircle;
fixtureDef.density = 0.4f;
fixtureDef.friction = 0.2f;
fixtureDef.restitution = 0.6f;
player.createFixture(fixtureDef);
debugRenderer = new Box2DDebugRenderer();
//Lighting
handler = new RayHandler(world);
handler.setCombinedMatrix(camera.combined);
PointLight l1 = new PointLight(handler,5000,Color.CYAN,width/PPM/2,width/PPM/2/2/2,height/PPM/2/2);
new PointLight(handler,5000,Color.PURPLE,width/PPM/2,width/PPM/2/1.5f,height/PPM/2/2);
shapeRenderer.setProjectionMatrix(camera.combined);
}
public void update() {
if(Gdx.input.isKeyJustPressed(Keys.UP)) {
player.applyForceToCenter(0, 0.75f, true);
}
if(Gdx.input.isKeyJustPressed(Keys.RIGHT)) {
player.applyForceToCenter(0.5f, 0f, true);
}
if(Gdx.input.isKeyJustPressed(Keys.LEFT)) {
player.applyForceToCenter(-0.5f, 0f, true);
}
}
#Override
public void dispose() {
}
#Override
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
debugRenderer.render(world, camera.combined);
world.step(1/60f, 6, 2);
handler.updateAndRender();
shapeRenderer.begin(ShapeType.Filled);
shapeRenderer.setColor(1, 1, 1, 1);
shapeRenderer.circle(player.getPosition().x, player.getPosition().y, 5f/PPM, 100);
shapeRenderer.end();
camera.position.set(player.getPosition().x, player.getPosition().y, 0);
camera.update();
update();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
You are only setting the shapeRenderers projectionmatrix once so it is not updating when you render.
You should put
shapeRenderer.setProjectionMatrix(camera.combined);
to your render method right before
shapeRenderer.begin(ShapeType.Filled);

Using Java's HotSwap functionality with libGDX

I created small test, with the following code, and tried doing these steps to use the hotswap functionality.
Run the program using the Debug button
Create a break point in the render function, to pause the program.
Change the value of rectangle.width
Compile the program
Let intelliJ reload the code.
But this doesn't seem to change the size of the rectangle on the screen.
public class HotSwapTest extends ApplicationAdapter {
OrthographicCamera camera;
ShapeRenderer shapeRenderer;
private static final int SCREEN_WIDTH = 800;
private static final int SCREEN_HEIGHT = 480;
Rectangle rectangle;
#Override
public void create() {
shapeRenderer = new ShapeRenderer();
camera = new OrthographicCamera();
camera.setToOrtho(false, SCREEN_WIDTH, SCREEN_HEIGHT);
rectangle = new Rectangle();
rectangle.x = SCREEN_WIDTH / 2 - 64 / 2;
rectangle.y = 20;
rectangle.width = 100;
rectangle.height = 30;
}
#Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
shapeRenderer.setProjectionMatrix(camera.combined);
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
shapeRenderer.setColor(1, 1, 0, 1);
shapeRenderer.rect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
shapeRenderer.end();
camera.update(); // only if we're moving the screen though
}
}
Realized after typing this that I should have changed the width of the rectangle in the render function. Since create function won't be run again.
The following code works properly.
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
rectangle.width = 5; // Change this line while debugging.
rectangle.height = 10;
shapeRenderer.setProjectionMatrix(camera.combined);
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
shapeRenderer.setColor(1, 1, 0, 1);
shapeRenderer.rect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
shapeRenderer.end();
camera.update(); // only if we're moving the screen though
}

Box2D Libgdx black screen

I am new to Box2D. I am just trying to follow a simple tutorial, but trying to integrate it inside my code:
I start creating my Libgdx game:
public void create() {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera(w, h, 0);
camera.position.set(camera.viewportWidth * .5f, camera.viewportHeight * .5f, 0f);
camera.update();
batch = new SpriteBatch();
viewSwitcher("GameScreen",null);
}
The call to viewSwitcher, creates a new object, which creates a new Screen:
public GameScreenController(SomeGame t, String id) {
somegame = t;
db = t.getDB();
world = new World(new Vector2(0, -20), true);
screen = new GameScreen(this);
[. . .]
}
Inside the Game Screen (which extends Screen class) I have the render method:
#Override
public void render(float delta) {
debugRenderer.render(world, camera.combined);
world.step(BOX_STEP, BOX_VELOCITY_ITERATIONS, BOX_POSITION_ITERATIONS);
stage.act(delta);
//stage.draw();
}
Finally, a Timer, creates periodically new objects. Inside the constructor of these objects, I have the creation of the bodyDef:
public void createBodyLetter() {
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(200, 200);
Body body = controller.getWorld().createBody(bodyDef);
PolygonShape dynamicBox = new PolygonShape();
dynamicBox.setAsBox(1.0f, 1.0f);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = dynamicBox;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.3f;
body.createFixture(fixtureDef);
dynamicBox.dispose();
}
The result when I start the program is just a black screen. Do anyone know where is the problem?
Thank you
initialize camera as
camera = new OrthographicCamera(w, h);
the third parameter you have given is the diamond angle which would be causing problem for you
Check the javadoc on this link
http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/OrthographicCamera.html#OrthographicCamera(float, float, float)

Categories

Resources