I set the background image like this -
batch.draw(Assets.back_sprite, 0, 0, ResX, ResY);
The problem is when i move the camera -
camera.translate(2,0);
The image starting to move backwards and eventually disappears, because I drew it at (0,0)
and the camera is moving in a speed of (2,0), that's why the the image goes away.
The camera is ortho not perspective.
How can i make the image to be static and always stay there?
Any ideas?
Thanks in advance :P
Render it with another camera
OrthographicCamera mStageCamera;
OrthographicCamera mFixedCamera;
SpriteBatch mBatch;
#Override
public void render() {
mBatch.setProjectionMatrix(mFixedCamera.combined);
mBatch.begin();
//render "static" elements
mBatch.end();
mBatch.setProjectionMatrix(mStageCamera.combined);
mBatch.begin();
//render "movable" elements
mBatch.end();
}
Related
I've got a problem to draw a sprite to my project.
I have a map (960x900) divided into tiles (64x64).
As you can see in the picture, when i click on the bottom left corner of the purple square, the position is (0;0), and when I click on the top right corner of purple square, the position is (36;47)
The problem is that the picture of the purple square has a size of 32x32, and when I draw this picture with libgdx on the screen, the size doesn't match.
Another example: the square with black border has a size of 64x64. So if I draw the purple square in front of the black, the purple should be the half (in height and in width) of the black, no?
Does anyone know why libgdx resizes the purple square?
Sprite sprite = new Sprite(new Texture("assets/purpleSquare.png"));
i draw it in a method
public void render(SpriteBatch batch) {
batch.draw(sprite, 0, 0);
}
I don't know why the picture is resized by libgdx.. I have also tried to do
batch.draw(sprite, 0, 0, width, heigth);
To precise the sprite's size but it doesn't work too..
The size on screen bears no direct relation to the size of the original image. When you draw a sprite you provide the SpriteBatch with a position, width, and height in world coordinates. The sprite will be stretched to fit these world coordinates, regardless of the original image size.
When you click the screen, you are clicking in screen coordinates. The relation between screen and world coordinates is determined by the projection matrix that you use with the SpriteBatch. The projection matrix is typically controlled with a Camera or Viewport object, which you can use to convert between the two coordinate systems using the project and unproject methods.
I'm happy to see that after many hours i found a solution, even if i know which is not correct.
I would like some help to understand the problem's origin.
With this parts of code :
public void update(float delta) {
batch.begin();
drawBackground(); // Draw the background
drawButton(); // Draw the play/pause button
batch.end();
drawMap(); // draw a tmx map made with tiled
batch.begin();
if(!world.isInitial()) {
renderMonster(); // method which draw the monster
}
renderTower(); // method which draw the tower's level
batch.end();
}
I don't understand why i have to do "batch.begin()" and "batch.end()" twice.
I dont' understant why with this code, the purple square is resized.
With this code :
public void update(float delta) {
batch.begin();
drawBackground();
drawButton();
batch.end();
drawMap();
------->sb = new SpriteBatch();
sb.begin();
if(!world.isInitial()) {
renderMonster();
}
renderTower();
sb.end();
}
this line that i add fix the bug with the purple square. If i work with two SpriteBatch (because with one, if i reinitialize SpriteBatch in update method, my pause/play button diseapper) and i initialise the second (SpriteBatch sb) in the update method.
It is correct to initialise a SpriteBatch every time i'm passing on the update method ? There's no method with a SpriteBatch to avoid this problem ?
so I'm working on a game where I would like to have the camera in game centered on the middle of the screen for all device lengths. I hope this picture can better explain what I'm trying to achieve. I have tried setting the position of the camera but that hasn't worked for me.
scrnHeight = Gdx.graphics.getHeight();
if (scrnHeight <= HEIGHT) {
cam.setToOrtho(false, 480, 800);
} else {
cam.setToOrtho(false, 480, scrnHeight);
}
//This is the part that seems to be giving me all the issues
cam.position.set(cam.viewportWidth/2,cam.viewportHeight/2, 0);
cam.update();
Gdx.input.setInputProcessor(this);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
gsm.update(Gdx.graphics.getDeltaTime());
gsm.render(batch);
batch.begin();
batch.draw(border, -(border.getWidth() - WIDTH) / 2, -(border.getHeight() / 4));
batch.end();
I don't know if I'm giving it the wrong coordinates when I'm setting the position or what is happening that causes the lack of vertical centering. Any help would be much appreciated.
The orthographic camera position in LibGDX means position in-game, not on the device screen, therefore changing it won't actually move the game screen on the device.
Therefore, you use the camera position to move and position the camera in-game.
For example, in response to player input movement:
if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
cam.translate(-3, 0, 0); // Moves the camera to the left.
}
if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
cam.translate(3, 0, 0); // Moves the camera to the right.
}
As you can see, we are moving the camera in-game, left and right according to the player's input.
However, your code has a few more issues like not setting the batch projection matrix:
batch.setProjectionMatrix(cam.combined);
And resetting the camera position to the center of the viewport each frame:
// Don't run this each frame, it resets the camera position!
cam.position.set(cam.viewportWidth/2,cam.viewportHeight/2, 0);
cam.update(); // <- However, you must run this line each frame.
Finally, centering the LibGDX app on the device screen should be done outside of Libgdx, otherwise, if you intend to use the spare screen for the same LibGDX app, then you should create another camera to work full screen and render it before the actual game camera, usually used for HUD and such...
I'm testing my sprite that has the game title, and on my Motorola Moto G 2nd generation the dimensions of the sprite looks good but I'm testing also on my mothers phone, a Samsung GT-S5830i, and the height of the sprite looks stretched out.
I'm also trying to understand the concept of Viewport (I'm using the StretchViewport), but I don't know if I'm doing right. My game are designed for mobile, not desktop.
I did that to my SplashScreen:
this.gameTitle = new Sprite(new Texture(Gdx.files.internal("images/GameTitle.png")));
this.gameTitle.setSize(Configuration.DEVICE_WIDTH - 50, this.gameTitle.getHeight() * Configuration.DEVICE_HEIGHT / Configuration.DEVICE_WIDTH);
The DEVICE_HEIGTH and DEVICE_WIDTH are constants about the dimension of the screen. And the "-50" is a margin to the sprite
In my Viewport I used the real size of the screen for the dimensions, or should I use a virtual dimension? But how it works?
This is a part of my main class, what can I change?
// Create the Orthografic camera
this.orthoCamera = new OrthographicCamera(Configuration.DEVICE_WIDTH, Configuration.DEVICE_HEIGHT);
this.orthoCamera.setToOrtho(false, Configuration.VIRTUAL_GAME_WIDTH, Configuration.VIRTUAL_GAME_HEIGHT);
this.orthoCamera.position.set(this.orthoCamera.viewportWidth / 2f, this.orthoCamera.viewportHeight / 2f, 0);
this.orthoCamera.update();
// Combine SpriteBatch with the camera
this.spriteBatch.setTransformMatrix(this.orthoCamera.combined);
// Create the ViewPort
this.viewPort = new ExtendViewport(Configuration.DEVICE_WIDTH, Configuration.DEVICE_HEIGHT);
I updated my viewport to the ExtendViewport as you said.
Main class render method:
public void render() {
super.render();
// Update Orthographic camera
this.orthoCamera.update();
// Combine SpriteBatch with the camera
this.spriteBatch.setTransformMatrix(this.orthoCamera.combined);
}
Screen class render method:
#Override
public void render(float delta) {
// OpenGL clear screen
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(Gdx.gl.GL_COLOR_BUFFER_BIT | Gdx.gl.GL_DEPTH_BUFFER_BIT);
// SpriteBatch begins
this.game.spriteBatch.begin();
// Display the ClimbUp logo
this.gameTitle.draw(this.game.spriteBatch);
this.character.draw(this.game.spriteBatch);
// SpriteBatch ends
this.game.spriteBatch.end();
}
If you don't want stuff to look distorted on some devices and you don't want black bars (which none of your customers will like), you need to use an ExtendViewport instead of StretchViewport. And the dimensions you give it should be virtual dimensions based on whatever units you would like to work with.
For example, assuming a landscape orientation game, you could use 800 x 480 as virtual dimensions, and then you know that anything within that area (in world units) will be shown on the screen and you can design your game for that. On narrower devices (4:3 ratio) there will be more than 480 vertical units shown, and on wider devices (16:9 ratio) there will be more than 800 horizontal units shown.
There's one other option that avoids black bars and distortion, and that's FillViewport. But I think in general that's not a good option because you have no easy way to predict how much of your virtual dimensions are going to get cropped off.
Based on your edited question, here's what I would change in your code:
//No need to create your own camera. ExtendViewport creates its own.
// Pointless to call this now before resize method is called. Call this in render
//XXX this.spriteBatch.setTransformMatrix(this.orthoCamera.combined);
//This is where you give the viewport its minimum virtual dimensions
this.viewPort = new ExtendViewport(Configuration.VIRTUAL_GAME_WIDTH, Configuration.VIRTUAL_GAME_HEIGHT);
//Get reference to the viewport's camera for use with your sprite batch:
this.orthoCamera = (OrthographicCamera) this.viewport.getCamera();
Then in the resize method:
orthoCamera.setPosition(/*wherever you want it*/);
viewport.update(width, height, false); //these are actual device width and height that are provided by the resize method parameters.
You might want to position your camera in relation to the size calculated by the viewport. Then you should omit the setPosition line above, and instead calculate it after calling viewport.update. For example if you want 0,0 in the bottom left of the screen:
viewport.update(width, height, false);
orthoCamera.setPosition(orthoCamera.viewportWidth/2f, orthoCamera.viewportHeight/2f);
In your render method you can put this before spriteBatch.begin():
orthoCamera.update(); //good idea to call this right before applying to SpriteBatch, in case you've moved it.
spriteBatch.setProjectionMatrix(orthoCamera.combined);
Hi I'm just starting to learn about LibGDX and I was wondering how to draw an actual circle.
I'm using a orthographic camera object and shape renderer but whenever I draw a circle it's more of an ellipse
#Override //Circle paint function
public void paint(OrthographicCamera camera) {
renderer.setProjectionMatrix(camera.combined);
renderer.begin(ShapeType.Filled);
renderer.setColor(Color.CYAN);
renderer.scale(1f, 1f, 1f);
renderer.circle(getX(), getY(), getSize());
renderer.end();
}
//How I initialize the camera
camera = new OrthographicCamera(500, 500);
How it ends up looking:
I mean I don't know about you, but I don't think that'
Your orthographic camera ratio should be the same as the viewport ratio, otherwise perspective gets skewed as you've observed. If your viewport is 1.3 ratio (it looks like it is), the ratio of your camera should be the same.
Try: camera = new OrthographicCamera(650, 500);
I'm using the Processing language to do a little game, but I'm having trouble with images and rotation. My sprite displays fine if I apply no rotation to it, but it disappears completely if it is rotated. Here's the rotation code:
void display(boolean alternate) {
pushMatrix();
if(!isHead && !isTail && alternate) rotate(radians(180));
rotate(radians(90*direction));
image(snake, x, y, linkSize, linkSize);
popMatrix();
}
When direction is 0, or alternate is true and direction is 2, then the image displays. Otherwise, no image is displayed. I'm not sure if it matters or not, but snake is a .png image with an alpha transparency. The declaration for snake is snake = loadImage("SnakeLink.png");.
You are actually rotating the image from it's origin (top left corner), so it disappears from the screen.
You have to translate to the center of the image, rotate, translate back to it's origin and then display it.
translate(image.width/2, image.height/2);
rotate(radians);
translate(-image.width/2, -image.height/2);