Why camera in stage is not required to be centered in libgdx - libgdx

How stage camera is able to see full stage view if (0,0) of the camera is located by default at (0,0) of stage. if update method for viewport is not called nor camera position set method is called.

If you look into the Stage Constructor:
public Stage (Viewport viewport, Batch batch) {
if (viewport == null) throw new IllegalArgumentException("viewport cannot be null.");
if (batch == null) throw new IllegalArgumentException("batch cannot be null.");
this.viewport = viewport;
this.batch = batch;
root = new Group();
root.setStage(this);
viewport.update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
}
We see on the last line viewport.update() with the width, height and true as parameters.
Let's look at this viewport.update() method:
public void update (int screenWidth, int screenHeight, boolean centerCamera) {
apply(centerCamera);
}
Now let's look on the apply() method. We know centerCamera is true:
public void apply (boolean centerCamera) {
HdpiUtils.glViewport(screenX, screenY, screenWidth, screenHeight);
camera.viewportWidth = worldWidth;
camera.viewportHeight = worldHeight;
if (centerCamera) camera.position.set(worldWidth / 2, worldHeight / 2, 0);
camera.update();
}
And here we find the answer: if (centerCamera) camera.position.set(worldWidth / 2, worldHeight / 2, 0);
The stage centered the camera position on her own.

Related

LWJGL/OpenGL -- Not drawing basic quad

I have looked everywhere, and I can't seem to get OpenGL to draw a simple quad.
The window shows up fine with the correct color background, but OpenGL just won't draw the box.
I am using OpenGL 4.4.0 - Build 20.19.15.4463
The window size is 1920x1080
This is the code I currently have:
in Main.java:
public void init(){
if(glfwInit() != true){
System.err.println("GLFW failed to initialize");
}
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
//TODO change name.
window = glfwCreateWindow(width, height, "GameName", NULL, NULL);
if(window == NULL){
System.err.println("Window failed to be created");
}
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window, 100, 100);
glfwMakeContextCurrent(window);
glfwShowWindow(window);
GL.createCapabilities();
glClearColor(0.0f, 0.5f, 1.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
//set up projection matrix; allows us to draw.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
testBox = new EntityBox(3, Color.RED);//just to test right now
System.out.println("OpenGL: "+ glGetString(GL_VERSION));
}
public void update(){
glfwPollEvents();
}
public void render(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glfwSwapBuffers(window);
testBox.draw();
}
in EntityBox:
public void draw(){
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glVertex2f(0,0);
glVertex2f(0,100);
glVertex2f(100,0);
glVertex2f(100,100);
glEnd();
}
I fixed it:
glClear needs to be
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
don't know why, because i was tole depth_buffer is used if you want 3d.
and
glfwSwapBuffers(window);
needs to be called after drawing.

Table elements of a stage using a viewport in libgdx is shown at top right screen per default instead of center

I'm using a Screen.
When I use the Table class in my Stage I want to show my Table at the top left of the screen but per default it is shown at the top right of my screen.
Calling tableLeft.left() moves my table to the top-center of the screen. Using tableLeft.top() moves the tabe out of the screen complettly.
If I'm not using any viewports it works perfectly fine but then I'm running into other issues.
Also note that I'm reading about cameras and viewpoints for about two weeks now and I'm still confused as hell as how it works even after reading like all of the official libgdx tutorials on the wiki and reading everythign else about it I could google. For example I have no clue why I can remove everything from the resize() method and the output does not change at all.
My code looks like that:
#Override
public void show() {
....
camera = new OrthographicCamera(1920, 1080);
viewport = new FitViewport(1920, 1080, camera);
viewport.apply();
....
batch = new SpriteBatch();
....
stage = new Stage(viewport, batch);
Table tableLeft = new Table();
tableLeft.add(new Label("Dummy Label", skin, "default"));
stage.addActor(tableLeft);
.....
}
#Override
public void resize(int width, int height) {
viewport.update(width, height, true);
stage.getViewport().update(width, height, true);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);
}
I guess that you don't need to update viewport nor center camera manualy:
viewport.update(width, height, true);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);
because
stage.getViewport().update(width, height, true);
already does it in your case:
/** Configures this viewport's screen bounds using the specified screen size and calls {#link #apply(boolean)}. Typically called
* from {#link ApplicationListener#resize(int, int)} or {#link Screen#resize(int, int)}.
* <p>
* The default implementation only calls {#link #apply(boolean)}. */
public void update (int screenWidth, int screenHeight, boolean centerCamera) {
apply(centerCamera);
}
/** Applies the viewport to the camera and sets the glViewport.
* #param centerCamera If true, the camera position is set to the center of the world. */
public void apply (boolean centerCamera) {
Gdx.gl.glViewport(screenX, screenY, screenWidth, screenHeight);
camera.viewportWidth = worldWidth;
camera.viewportHeight = worldHeight;
if (centerCamera) camera.position.set(worldWidth / 2, worldHeight / 2, 0);
camera.update();
}

How to make the camera follow the player?

I'm making a game in libgdx which includes the player being able to move vertically beyond the set screen size.
As for my question, if I have the screen size set at a certain width and height, what is required to make the actual game world larger for the camera to follow the player?
This is of course my targeted screen size in the Main game class:
public static final int WIDTH = 480, HEIGHT = 800;
Below that I currently have :
public static final int GameHeight = 3200;
GameHeight is the value I test for whether the player is going out of bounds.
Here is the problem. With this code, the player is centered on the screen, and moves horizontally, rebounding off the screen bounds (As it would without the camera, but neglecting the change in y-position)
public GameScreen(){
cam = new OrthographicCamera();
cam.setToOrtho(false, 480, 800);
}
#Override
public void render(float delta) {
// TODO Auto-generated method stub
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
cam.position.y = player.getPosition().y;
cam.update();
batch.setProjectionMatrix(cam.combined);
player.update();
player.draw(batch);
}
If I remove:
cam.position.y = player.getPosition().y;
The camera is placed at the bottom of the virtual world and the ball starts at the top (y = 3200) and travels downward. When it reaches y = 800, it shows up as it should.
I've found a lot of examples that indicate in writing that setting the cameras position to the players y position should force the camera to follow the player, whether it's moving up or down, but it either freezes y movement or sets the camera at the bottom the virtual world.
Any help is appreciated, thanks!
I would try doing cam.position.set(player.getPosition().x, player.getPosition().y). This will make the camera follow your player and it should not cause any "freezing."
private val worldTransform = Matrix4()
private val cameraPosition = Vector3()
private val objPosition = Vector3()
private var rot = Quaternion()
private var carTranslation = Vector3(0f, 0f, 0f)
fun focus(obj: BulletObject) {
// worldTransform
obj.entity?.motionState?.getWorldTransform(worldTransform)
// objPosition
worldTransform.getTranslation(objPosition)
obj.entity?.modelInstance?.transform?.getTranslation(carTranslation)
// get rotation
worldTransform.getRotation(rot)
println("rot.angle: ${rot.getAngleAround(Vector3.Y)}")
val rad = Math.toRadians(rot.getAngleAround(Vector3.Y).toDouble())
// pointFromCar
val pointFromCar = Vector2(-3f * sin(rad.toFloat()), -3f * cos(rad.toFloat()));
cameraPosition.set(Vector3(objPosition.x + pointFromCar.x, objPosition.y + 1f, objPosition.z + pointFromCar.y))
// camera set position
camera.position.set(cameraPosition)
camera.lookAt(objPosition)
camera.up.set(Vector3.Y)
camera.update()
}

libGDX 1.4.1 can't slow down animations

This is what I have:
...
private Array<Sprite> fireballFadeOutAnim;
private Array<Sprite> bucketFadeOutAnim;
private TextureAtlas fballAnimSheet;
private TextureAtlas bucketAnimSheet;
private Animation catch_animation;
private Animation visual_feedback;
private float elapsedTime = 0f;
...
#Override
public void create () {
...
fballAnimSheet = new TextureAtlas("animations/fireball_fadeout.txt");
bucketAnimSheet = new TextureAtlas("animations/bucket_fadeout.txt");
fireballFadeOutAnim = fballAnimSheet.createSprites("fireball_fadeout");
bucketFadeOutAnim = bucketAnimSheet.createSprites("bucket_fadeout");
catch_animation = new Animation(1/15f, fballAnimSheet.getRegions(), Animation.PlayMode.NORMAL);
visual_feedback = new Animation(1/15f, bucketAnimSheet.getRegions(), Animation.PlayMode.LOOP);
...
}
#Override
public void render () {
...
// Set the anim_elipsed_time
elapsedTime += Gdx.graphics.getDeltaTime();
...
// I try to draw them later on (under the render method) like this:
// Start and draw animation of fireball catch
batch.begin();
batch.draw(catch_animation.getKeyFrame(elapsedTime, true), fireBallRect.getX(), fireBallRect.getY());
batch.end();
}
I can see both animations happening extremely fast (they look like a white-flash), they do not loop even if the animation mode is set to "LOOP".
What am I doing wrong ? I can't seem to be able to slow them down or to have them LOOP. Thanks much.
Edited:
As requested, I upload all the code
public class MainActivity extends ApplicationAdapter {
public enum State {
PAUSE,
RUN,
RESUME,
STOPPED
}
public static State state = State.RUN;
private SpriteBatch batch;
private OrthographicCamera camera;
private Stage stage;
private Texture backgroundImage;
private Texture bucketImage;
private Texture fireballImage;
private Texture heart;
private TextureRegion criticalTexture;
private Sprite backgroundSprit;
private Sprite bucketSprite;
private Sprite fireballSprite;
private Sprite heartSprite;
private Rectangle bucketRect;
private Rectangle fireBallRect;
private Rectangle bucketSpriteRect;
private ShapeRenderer bucketRenderer;
private ShapeRenderer fireballRenderer;
private Button pauseButton;
private Array<Rectangle> fireballArray;
private Skin progressBarSkin;
private long lastFireballTime;
public static Sound bucket_tap;
public static Sound bucket_drag;
private Sound fireball_missed_sound;
private Sound catchFireball;
private Sound pauseBtnSound;
private Music bgMusic;
private float volume = 0.30f; // music and sfx volume control
public static int w;
public static int h;
private int barLength = 325;
private int numberOfFails = 10; // change numberOfFails to increase or decrese
// the total num. of missed fireballs the player
private int deductedBarSegment = barLength / numberOfFails;
private int numOfBallsLeft = numberOfFails; // use this var to check how many fballs left
private long fireballFrequency = 1000000000L; // change fireballFrequency to increase or decrease
// the number of fireballs on the screen
private int fireballSpeed = 400; // change the fireballSpeed to increase or decrease
// the speed at which the fireballs fall
private InputProcessor gameInputProcessor; // this sets the game input controller for the bucket
private InputMultiplexer multiplexer; // this sets the input processors from the game and UI
/************************************ Animation Properties ************************************/
private TextureAtlas fballAtlas;
private TextureAtlas bucketAtlas;
private Animation catch_animation;
private Animation visual_feedback;
private float elapsedTime = 0f;
private Actor feedbackPanel;
/**********************************************************************************************/
#Override
public void create () {
// Parse Test
//ParseObject testObject = new ParseObject("TestObject");
//testObject.put("foo", "bar");
//testObject.saveInBackground();
// Catch the dynamic size of the screen based on the device that's ran on
w = Gdx.graphics.getWidth();
h = Gdx.graphics.getHeight();
// Set up the camera
camera = new OrthographicCamera();
camera.setToOrtho(false, (float)w, (float)h);
// Instantiate the batch
batch = new SpriteBatch();
/***************************** These renders are for debugging only *****************************/
bucketRenderer = new ShapeRenderer();
fireballRenderer = new ShapeRenderer();
/**************************************************************************************************/
/******************************************** Stage and HUD ***************************************/
stage = new Stage();
pauseButton = new Button(new TextureRegionDrawable(
new TextureRegion(new Texture(Gdx.files.internal("images/pase_button_red.png")))),
new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("images/pase_button_white.png")))));
pauseButton.setX(flipCoordinates(w, 150));
pauseButton.setY(flipCoordinates(h, 170));
pauseButton.act(Gdx.graphics.getDeltaTime());
stage.addActor(pauseButton);
pauseButton.addListener(new ChangeListener() {
#Override
public void changed (ChangeEvent event, Actor actor) {
// Do something when the pauseButton is pressed
// Control multiple touches on the pauseButton
if(state == State.RUN) {
state = State.PAUSE;
pauseBtnSound.play();
// Set the pauseButton icon to the white version
//pauseButton.setColor(Color.WHITE);
}
else {
state = State.RUN;
pauseBtnSound.play();
}
}
});
// Add the critical_life indicator to the stage as an actor
criticalTexture = new TextureRegion(new Texture(Gdx.files.internal("images/critical_life.png")));
feedbackPanel = new Actor() {
public void draw(Batch batch, float alpha) {
batch.draw(criticalTexture, getX(), getY(), getOriginX(), getOriginY(), getWidth(), getHeight(),
getScaleX(), getScaleY(), getRotation());
}
};
feedbackPanel.setBounds(w / 2, h / 2,
criticalTexture.getRegionWidth(), criticalTexture.getRegionHeight());
// Set up an Action for the critical life actor
feedbackPanel.addAction(forever(sequence(scaleTo(2, 2, 0.5f), scaleTo(1, 1, 0.5f), delay(0.5f))));
feedbackPanel.act(Gdx.graphics.getDeltaTime());
stage.addActor(feedbackPanel);
/**************************************************************************************************/
/*********************************** Set up the Input Controllers *********************************/
// The multiplexer helps target several input processes (in this case, the stage and the
// InputProcessor.class)
multiplexer = new InputMultiplexer();
multiplexer.addProcessor(stage);
multiplexer.addProcessor(new GameInputProcessor());
// InputAdaptor
Gdx.input.setInputProcessor(multiplexer);
/**************************************************************************************************/
backgroundImage = new Texture("images/bg.jpg");
bucketImage = new Texture("images/bucket_small.png");
fireballImage = new Texture("images/fireball_small.png");
heart = new Texture("images/heart.png");
/*************************************** Animations Setup *****************************************/
fballAtlas = new TextureAtlas("animations/fireball_fadeout.txt");
bucketAtlas = new TextureAtlas("animations/bucket_fadeout.txt");
catch_animation = new Animation(0.50f, fballAtlas.getRegions());
visual_feedback = new Animation(0.15f, bucketAtlas.getRegions());
/**************************************************************************************************/
// Instantiate all sounds
bucket_tap = Gdx.audio.newSound(Gdx.files.internal("sounds/bucket_tap.ogg"));
bucket_drag = Gdx.audio.newSound(Gdx.files.internal("sounds/bucket_drag.ogg"));
fireball_missed_sound = Gdx.audio.newSound(Gdx.files.internal("sounds/fireball_missed.ogg"));
catchFireball = Gdx.audio.newSound(Gdx.files.internal("sounds/fastSteam.ogg"));
pauseBtnSound = Gdx.audio.newSound(Gdx.files.internal("sounds/pauseBtn_sound.ogg"));
bgMusic = Gdx.audio.newMusic(Gdx.files.internal("sounds/music_bg.mp3"));
bgMusic.setLooping(true);
bgMusic.play(); // <----------- turn bg music on/off
// Instantiate the progressBarSkin
progressBarSkin = new Skin();
progressBarSkin.add("progressBarBg", new Texture("images/progress-bar_bg.png"));
progressBarSkin.add("progressBar", new Texture("images/progress-bar_dynamic_red.png"));
// Create bg sprite
backgroundSprit = new Sprite(backgroundImage);
//backgroundSprit.setPosition((float)w / 2, (float)h / 2);
//backgroundSprit.setSize((float)w, (float)h);
// Bucket sprite
bucketSprite = new Sprite(bucketImage);
// Fireball sprite
fireballSprite = new Sprite(fireballImage);
// Heart sprite
heartSprite = new Sprite(heart);
// Set the bucketRect into the rect from the bucketSprite (THE GREEN ONE)
bucketSpriteRect = bucketSprite.getBoundingRectangle();
bucketSpriteRect.x = w / 2 - 100 / 2;
bucketSpriteRect.y = 20;
bucketSpriteRect.setSize(200, 200);
// Set the collision rectangle (THE RED ONE)
bucketRect = new Rectangle();
bucketRect.x = bucketSpriteRect.getX() + 70; // <---- adjust position left/right
bucketRect.y = bucketSpriteRect.getY() + 150; // <---- adjust position up/down
bucketRect.setSize(100, 10);
// Set a rectangle for each fireball sprite (THE WHITE ONE)
fireBallRect = new Rectangle();
fireBallRect.x = fireballSprite.getX();
fireBallRect.y = fireballSprite.getY();
fireBallRect.width = 55;
fireBallRect.height = 55;
fireballArray = new Array<Rectangle>();
}
#Override
public void render () {
// Devide the Render method into a few switch cases based on the game's state
switch (state) {
case RUN:
// Do all the batch drawing here
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
elipsedTime += Gdx.graphics.getDeltaTime();
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(backgroundSprit, 0, 0, w, h);
batch.draw(bucketSprite, bucketSpriteRect.x, bucketSpriteRect.y,
bucketSprite.getWidth() - 160, bucketSprite.getHeight() - 140);
for(Rectangle fireball: fireballArray) {
batch.draw(fireballSprite, fireball.x, fireball.y,
fireballSprite.getWidth() - 20, fireballSprite.getHeight() - 20);
}
batch.draw(progressBarSkin.getSprite("progressBarBg"), 200, flipCoordinates(h, 170));
batch.draw(progressBarSkin.getSprite("progressBar"),
210, flipCoordinates(h, 162), barLength, 6); // <---- modify x, x, <x>, x to adjust the length of the life-bar
batch.draw(heartSprite, 95, flipCoordinates(h, 200), 90, 76);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
batch.end();
/***************************************Debugging Rectangles************************************/
// Draw rects around sprites
// bucketRenderer.begin(ShapeRenderer.ShapeType.Line);
// bucketRenderer.setColor(Color.GREEN);
// bucketRenderer.rect(bucketSpriteRect.getX(), bucketSpriteRect.getY(),
// bucketSprite.getWidth() - 160, bucketSprite.getHeight() -140);
// bucketRenderer.end();
//
// bucketRenderer.begin(ShapeRenderer.ShapeType.Line);
// bucketRenderer.setColor(Color.RED);
// bucketRenderer.rect(bucketRect.getX(), bucketRect.getY(), 100, 10);
// //bucketRenderer.point(bucketRect.getX(), bucketRect.getY(), 0f);
// bucketRenderer.end();
//
// fireballRenderer.begin(ShapeRenderer.ShapeType.Line);
// fireballRenderer.setColor(Color.WHITE);
// fireballRenderer.rect(fireBallRect.x, fireBallRect.y,
// fireballSprite.getWidth() - 20, fireballSprite.getHeight() - 20);
// fireballRenderer.end();
// To avoid sprite flickering, surround batch.draw with a game state check
if (state != State.PAUSE) {
Iterator<Rectangle> iter = fireballArray.iterator();
while(iter.hasNext()) {
fireBallRect = iter.next();
fireBallRect.y -= fireballSpeed * Gdx.graphics.getDeltaTime();
// Remove the fireBallRect from the array as soon as it leaves the screen
if(fireBallRect.y + 106 < 0) {
iter.remove();
// The player missed the fireball, play a the fireball_missed_sound
fireball_missed_sound.play();
// Subtract a ball from the total number allowed to be missed
numOfBallsLeft --;
// Call life deduction
deductLifePoints();
// Check to see if this is the last fball left to fail
if (numOfBallsLeft == 1) {
}
// Check to see if life points are 0 or < 0
if (numOfBallsLeft <= 0) {
// Game over logic
barLength = 0;
// Set the game state to PAUSED
//state = State.PAUSE;
//bucketSprite.setColor(Color.RED);
batch.begin();
batch.draw(bucketSprite, bucketSpriteRect.x, bucketSpriteRect.y,
bucketSprite.getWidth() - 160, bucketSprite.getHeight() - 140);
batch.end();
}
}
// Collision detector
if(bucketRect.overlaps(fireBallRect)) {
catchFireball.play(volume);
// Start and draw animagion of fireball catch
batch.begin();
batch.draw(catch_animation.getKeyFrame(elapsedTime, true), fireBallRect.getX(), fireBallRect.getY());
batch.end();
// Remove the fireball that collides with the bucket
iter.remove();
}
}
}
// Touch input controller
if(Gdx.input.isTouched()) {
Vector3 touchPos = new Vector3();
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
if(touchPos.y <= 250) {
bucketSpriteRect.setX(touchPos.x - 115);
bucketRect.setX(touchPos.x - 50); // <---- adjust position left/right on touch
}
}
if(TimeUtils.nanoTime() - lastFireballTime > fireballFrequency) {
fireBallRect = new Rectangle();
fireBallRect.x = MathUtils.random(50, w - 270);
fireBallRect.y = h;
fireBallRect.width = 75;
fireBallRect.height = 75;
fireballArray.add(fireBallRect);
lastFireballTime = TimeUtils.nanoTime();
}
/**************************************************************************************************/
break;
case PAUSE:
// Pause the game here
/******************************** Redraw the sprites to avoid flickering **************************/
batch.begin();
batch.draw(backgroundSprit, 0, 0, w, h);
batch.draw(bucketSprite, bucketSpriteRect.x, bucketSpriteRect.y,
bucketSprite.getWidth() - 160, bucketSprite.getHeight() - 140);
for(Rectangle fireball: fireballArray) {
batch.draw(fireballSprite, fireball.x, fireball.y,
fireballSprite.getWidth() - 20, fireballSprite.getHeight() - 20);
}
batch.draw(progressBarSkin.getSprite("progressBarBg"), 200, flipCoordinates(h, 170));
batch.draw(progressBarSkin.getSprite("progressBar"),
210, flipCoordinates(h, 162), barLength, 6); // <---- modify x, x, <x>, x to adjust the length of the life-bar
batch.draw(heartSprite, 95, flipCoordinates(h, 200), 90, 76);
//pauseButton.draw(batch, 1);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
batch.end();
/**************************************************************************************************/
break;
case RESUME:
break;
default:
break;
}
}
/************************************* Implement Dispose **************************************/
#Override
public void dispose() {
batch.dispose();
bucketRenderer.dispose();
fireballRenderer.dispose();
backgroundImage.dispose();
bucketImage.dispose();
fireballImage.dispose();
bucket_tap.dispose();
bucket_drag.dispose();
catchFireball.dispose();
bgMusic.dispose();
fireball_missed_sound.dispose();
progressBarSkin.dispose();
fballAtlas.dispose();
stage.dispose();
}
/************************************* Flip Coordinates Method ********************************/
public static float flipCoordinates(float height, float xORy) {
float newPosition = height - xORy;
return newPosition;
}
/************************************** Deduces Life Points ***********************************/
private void deductLifePoints() {
barLength -= deductedBarSegment;
}
/************************************** Set the Game's state **********************************/
public void setGameState(State s) {
this.state = s;
}
/******************************** Android's Lyfe-Cycle Overrides ******************************/
#Override
public void pause() {
super.pause();
this.state = State.PAUSE;
}
#Override
public void resume() {
super.resume();
this.state = State.PAUSE;
}
}
The first parameter of the Animation constructor is the frameDuration in seconds. You are passing it 1/15f, which is really fast. Try something greater, like 0.15f.

Libgdx: screen resize and ClickListener (libgdx)

I develope a 2D game and use OrthographicCamera and Viewport to resize virtaul board to real display size. I add images to stage and use ClickListener to detect clicks. It works fine, but when I change resolution it works incorrent(can't detect correct actor, I think the problem with new and original x and y). Is there any way to fix this?
You will need to translate the screen coordinates to world coordinates.
Your camera can do that. You can do both ways, cam.project(...) and cam.unproject(...)
Or if you are already using Actors, don't initialize a camera yourself, but use a Stage. Create a Stage and add the actors to it. The Stage will then do coordinate translation for you.
Once me too suffered from this problem but at end i got the working solution, for drawing anything using SpriteBatch or Stage in libgdx. Using orthogrphic camera we can do this.
first choose one constant resolution which is best for game. Here i have taken 1280*720(landscape).
class ScreenTest implements Screen{
final float appWidth = 1280, screenWidth = Gdx.graphics.getWidth();
final float appHeight = 720, screenHeight = Gdx.graphics.getHeight();
OrthographicCamera camera;
SpriteBatch batch;
Stage stage;
Texture img1;
Image img2;
public ScreenTest(){
camera = new OrthographicCamera();
camera.setToOrtho(false, appWidth, appHeight);
batch = new SpriteBatch();
batch.setProjectionMatrix(camera.combined);
img1 = new Texture("your_image1.png");
img2 = new Image(new Texture("your_image2.png"));
img2.setPosition(0, 0); // drawing from (0,0)
stage = new Stage(new StretchViewport(appWidth, appHeight, camera));
stage.addActor(img2);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(img, 0, 0);
batch.end();
stage.act();
stage.act(delta);
stage.draw();
// Also You can get touch input according to your Screen.
if (Gdx.input.isTouched()) {
System.out.println(" X " + Gdx.input.getX() * (appWidth / screenWidth));
System.out.println(" Y " + Gdx.input.getY() * (appHeight / screenHeight));
}
}
//
:
:
//
}
run this code in Any type of resolution it will going to adjust in that resolution without any disturbance.
I just think Stage is easy to use.
If there are some wrong,i consider you should check your code:
public Actor hit(float x, float y)