LibGdx: Sprite doesn't move smoothly - android

I'm trying to move an image (300x300px) but it doesn't move smoothly, sometimes it stopped suddenly and then continued moving.
Here is my code in class "MyGdxGame" (extends "ApplicationAdapter"):
#Override
public void create() {
batch = new SpriteBatch();
img = new Texture("BG_z1_Moon.png");
}
#Override
public void render() {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// speed = 200px/s
x -= Gdx.graphics.getDeltaTime() * 200.0f;
batch.begin();
batch.draw(img, x, 0);
batch.end();
System.out.println(Gdx.graphics.getDeltaTime() + "\tx=" + x);
}
I've try to translate camera, use Actor but I got the same result.
Thank you in advance and sorry for my poor English.

Related

Attaching a sprite to a Box2d body for movement

Im new on Box2d got a problem and couldnt solve it.
I want to move my player left and right when the user touch my left and right buttons.
I created a fixture I can move body and fixture but not the player sprite
How can I attach my player sprite to my body ?
and How should I control body because I cant stop it.
I want to find a proper way of controlling player in box2d. I couldnt use setLinerVelocity etc.
this is my codes
public World world;
public Body bplayer;
public Box2DDebugRenderer b2dr;
public Matrix4 cameraBox2D;
PlayScreen
buttonimage.addListener(new ClickListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button)
{
bplayer.setLinearVelocity(-5*PPM , 0);
return true;
}
});
world = new World(new Vector2(player.getPosition().x , player.getPosition().y) , false);
b2dr = new Box2DDebugRenderer();
bplayer = createPlayer(player.getPosition().x , player.getPosition().y);
show method
buttonimage.setPosition(160,0);
rightbuttonimage.setPosition(320,0);
pauseimage.setPosition(220,-20);
cameraBox2D = camera.combined.cpy();
Render method
Gdx.gl.glClearColor(0, 0, 2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
sb.setProjectionMatrix(camera.combined);
player.position.y += 500 * Gdx.graphics.getDeltaTime();
sb.begin();
sb.draw(bg, 0, camera.position.y - (camera.viewportHeight/2));
sb.draw(player.sprite, player.getPosition().x , player.getPosition().y);
for (Tube tube : tubes) {
sb.draw(tube.getlefttube(), tube.getposlefttube().x, tube.getposlefttube().y);
sb.draw(tube.getrighttube(), tube.getposrighttube().x, tube.getposrighttube().y);
sb.draw(tube.getLight() , tube.getPoslight().x , tube.getPoslight().y);
}
delta*=speed;
sb.end();
update(delta);
b2dr.render(world , cameraBox2D);
stage.draw();
app.batch.begin();
app.font23.draw(app.batch,"Lights collected :" + dropsGathered , 0, 720);
app.batch.end();
cameraUpdate method
Vector3 position = camera.position;
position.x = player.position.x;
position.y = player.position.y;
camera.position.set(position);
createPlayer method
Body pBody;
BodyDef def = new BodyDef();
def.type = BodyDef.BodyType.DynamicBody;
def.position.set(x * PPM, y * PPM );
def.fixedRotation = true;
pBody = world.createBody(def);
return pBody;
update method
world.step(1 / 60f , 6 , 2);
for(int i = 0; i < tubes.size; i++) {
Tube tube = tubes.get(i);
if (camera.position.y - (camera.viewportWidth/2) > tube.getposlefttube().y + tube.getlefttube().getWidth()) {
tube.reposition(tube.getposlefttube().y + ( TUBE_COUNT) );
}
if (tube.collides(player.getBounds())){
app.setScreen(new GameOver(app));
}
if (tube.gathered(player.getBounds())){
dropsGathered++;
}
if (dropsGathered >= 50){
//app.setScreen(new Stage2(app));
}
}
camera.update();
handleInput();
camera.position.y = player.getPosition().y + 300;
player.update(delta);
camera.update();
cameraUpdate(delta);
stage.act(delta);
Do not use the Sprite class. Use the TextureRegion class instead. Sprite is confusingly subclassed from TextureRegion, so when you call batch.draw(sprite, ...) its position and rotation parameters are ignored because it is being treated as a TextureRegion.
You could use a Sprite by calling sprite.draw(batch) but a Sprite is redundant because your Body already has position and rotation parameters.
Use a TextureRegion directly with the SpriteBatch. You can orient it with rotation parameters passed into the draw method.

libdgx vector3 conversion wrong

Evening Everyone,
I am attempting to get familiar with libdgx and android by going thru the tutorial Here. All seems good except for grabbing the screen coordinates as they get skewed in a Vector3 conversion.
So x input of 101 gets converted to -796, y input of 968 converted to -429 (touching the upper left corner of the screen, same results from emulator as from my phone). When clicking the bottom right corner, the animation fires in the middle of the screen.
It all seems pretty basic so not really sure what I am setting incorrectly to get a skewed conversion. Any help is appreciated!
camera creation:
camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.position.set(camera.viewportWidth * .5f, camera.viewportHeight * .5f, 0f);
Grabbing touch coord:
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
touchCoordinateX = screenX;
touchCoordinateY = screenY;
stateTime = 0;
explosionHappening = true;
return true;
}
Render loop:
public void render () {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stateTime += Gdx.graphics.getDeltaTime();
batch.begin();
if (!explosionAnimation.isAnimationFinished(stateTime) && explosionHappening) {
Vector3 touchPoint = new Vector3();
touchPoint.set(touchCoordinateX,touchCoordinateY,0);
TextureRegion currentFrame = explosionAnimation.getKeyFrame(stateTime, false); // #16
camera.unproject(touchPoint);
batch.draw(currentFrame, touchPoint.x, touchPoint.y);
}
// batch.draw(img, 0, 0);
batch.end();
if (explosionAnimation.isAnimationFinished(stateTime)){explosionHappening = false;}
}
I think you forgot to set camera projection matrix to your SpriteBatch. Just add
batch.setProjectionMatrix(camera.combined);
before
batch.begin();

Libgdx sprites displaced touching areas

when setting up the sprite buttons in my libgdx project, i get displaced their touching area if i give a screen size that is bigger than my device one.
This is a simple example of the code i wrote. The main class extends Game...
public class Application extends Game
{
public SpriteBatch batch;
public OrthographicCamera camera;
public Vector3 touchPosition;
protected TitleScreen screen_title;
protected SettingsScreen screen_settings;
public PlayScreen screen_play;
#Override
public void create()
{
batch = new SpriteBatch();
camera = new OrthographicCamera(Constants.VIEWPORT_WIDTH, Constants.VIEWPORT_HEIGHT);
camera.setToOrtho(false,Constants.VIEWPORT_WIDTH, Constants.VIEWPORT_HEIGHT);
touchPosition = new Vector3();
//SCREENS
screen_title = new TitleScreen(this);
screen_settings = new SettingsScreen(this);
screen_play = new PlayScreen(this);
this.setScreen(screen_title);
}
}
And a simple screen with an image to detect if is touched...
public TitleScreen(final Application game)
{
this.game = game;
game.camera = new OrthographicCamera(Constants.VIEWPORT_WIDTH, Constants.VIEWPORT_HEIGHT);
game.camera.position.set(Constants.VIEWPORT_WIDTH / 2, Constants.VIEWPORT_HEIGHT / 2, 0);
background = new Sprite(new Texture(Gdx.files.internal(Constants.PATH_BACKGROUND + "bg.png")));
img = new Sprite(new Texture(Gdx.files.internal("badlogic.jpg")));
}
#Override
public void render(float delta)
{
Gdx.gl.glClearColor(0.7f, 0.7f, 0.9f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
game.camera.update();
game.batch.setProjectionMatrix(game.camera.combined);
game.batch.begin();
background.draw(game.batch);
img.setPosition( Constants.VIEWPORT_WIDTH / 2, Constants.VIEWPORT_HEIGHT /2);
img.draw(game.batch);
game.batch.end();
//detect touch position
if(Gdx.input.justTouched())
{
game.touchPosition.set(Gdx.input.getX(), Gdx.input.getY(), 0);
game.camera.unproject(game.touchPosition);
if ((Gdx.input.getX() > img.getX()) &&
Gdx.input.getX() < img.getX() + img.getWidth() &&
Gdx.input.getY() < Gdx.graphics.getHeight() - img.getY() &&
Gdx.input.getY() > Gdx.graphics.getHeight() - (img.getY() + img.getHeight()))
{
System.out.println("TOUCHED BUTTON!!!");
System.out.println("X: " + Gdx.input.getX() + "/ Y: " + Gdx.input.getY());
}
}
}
As mentioned, this code sample works fine in desktop (any size) and my phone (if it has same or smaller screen size), but not when i use a bigger viewport size, and don't really understand why :)
Thanks a lot for the help :)

Infinite Scrolling Texture

I am using the libgdx framework and trying to repeat a background of spikes forever. The issue I am having is that the texture is moving extremely fast forever, but I want to slow it down. I was looking at a tutorial from Google Code and another user had this same issue. The "supposed" solution was this:
if(scrollTimer>1.0f)
scrollTimer = 0.0f;
scrollTimer = 3f;
This was to make it scroll 3 times faster, so I attempted this and substituted 0.3f instead of 3f, but this makes the background at a standstill.
Here is some relevant code that might help in solving this issue:
public class PlayScreen implements Screen{
final Rectangle upSpikeBounds = new Rectangle(0,0,Gdx.graphics.getWidth() * 2, 25);
final Rectangle downSpikeBounds = new Rectangle(0,Gdx.graphics.getHeight() - 25,Gdx.graphics.getWidth() * 2, 25);
Rectangle blockBounds;
float total_time = 0f;
Sprite spikeUpSprite, spikeDownSprite, spriteBlock;
public PlayScreen(Game game){
batch = new SpriteBatch();
player = new Player(new Vector2(Gdx.graphics.getWidth()/10, Gdx.graphics.getHeight()/2), batch);
stage = new Stage();
this.game = game;
Texture spikeUp = new Texture(Gdx.files.internal("spikes.png"));
Texture spikeDown = new Texture(Gdx.files.internal("spikes.png"));
spikeUp.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
spikeDown.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
spikeUpSprite = new Sprite(spikeUp, 0, 0, Gdx.graphics.getWidth(), 25);
spikeDownSprite = new Sprite(spikeDown, 0, 25, Gdx.graphics.getWidth(), -25);
spikeDownSprite.setPosition(0, Gdx.graphics.getHeight() - 20);
spikeUpSprite.setSize(1200, 25);
spikeDownSprite.setSize(1200, 25);
}
public void render(float deltaTime) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
label.setText("Score: " + player.score);
cam.position.set(player.getPosition().x + Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight () / 2,0);
batch.setProjectionMatrix(cam.combined);
cam.update();
total_time += Gdx.graphics.getDeltaTime();
if (total_time > 1.0f){
total_time = 0.0f;
}
spikeUpSprite.setU(total_time);
spikeUpSprite.setU2((total_time+1));
spikeDownSprite.setU(total_time);
spikeDownSprite.setU2(total_time+1);
stage.act();
batch.begin();
spikeUpSprite.draw(batch);
spikeDownSprite.draw(batch);
batch.end();
stage.draw();
}
}
Can anyone help me?
You should look up the tween engine, it will enable you to use 'tween animation', which is an animation of values, who with a duration. For instance if you animate from zero to 700 with a 700ms duration, the value will start from zero and increase by 1 every ms
While micnubinub's answer is certainly interesting and worth checking out, I have figured out a quick fix for my issue. The problem lies in this line:
total_time += Gdx.graphics.getDeltaTime();
This is where the speed of the background lies. Because delta time is so fast (probably to the microsecond), the background scrolls by too fast. If I change it to a manual number, such as 0.0093f, I get a background that scrolls at the speed I desire.

LibGDX: Android SpriteBatch not drawing

I'm having a hard time getting a spriteBatch to render in LibGDX. It shows when I run it for the desktop, but not on Android. I sprite I'm trying to render is the star background.
Desktop:
http://i.stack.imgur.com/6a4m5.png
Android:
http://i.stack.imgur.com/mOvo2.png
Here's my code:
#Override
public void render(float delta) {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
Gdx.gl.glClearColor(0, 0, 0, 1);
update(delta);
spriteBatchBack.begin();
sprite.draw(spriteBatchBack);
spriteBatchBack.end();
stage.act(delta);
stage.draw();
}
public void update(float delta) {
scrollTimer += delta * 0.03f;
if (scrollTimer > 1.0f)
scrollTimer = 0.0f;
sprite.setU(scrollTimer);
sprite.setU2(scrollTimer + 1);
}
int width = Gdx.graphics.getWidth();
int height = Gdx.graphics.getHeight();
#Override
public void resize(int width, int height) {
if (stage == null) {
stage = new Stage(width, height, true);
stage.clear();
addMusic();
addBackground();
addScence();
stage.addActor(play);
stage.addActor(options);
stage.addActor(quit);
stage.addActor(logoHead);
stage.addActor(lblPlay);
stage.addActor(lblOptions);
stage.addActor(lblQuit);
}
Gdx.input.setInputProcessor(stage);
}
public void addBackground() {
spriteBatchBack = new SpriteBatch();
Texture spriteTexture = new Texture(
Gdx.files.internal("pictures/menuBackground.png"));
spriteTexture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
sprite = new Sprite(spriteTexture, 0, 0, spriteTexture.getWidth(), spriteTexture.getHeight());
sprite.setSize(width, height);
}
If there's anything important that I am leaving out, comment and let me know. Thanks!
I found my problem. It turned out to be simply that the phones I used didn't support Open GL 2.0. To fix this I re-sized all my textures to the power-of-two, and changed the configuration settings to Open GL 1.1.
try to use "Image" actor as background in stage instead of using spritebatch and drawing yourself.

Categories

Resources