Camera does not follow player - android

I use libgdx have one player which moves in x direction from left to right. Now I want the camera to follow it (like in Flappy Bird for example).
What happen is that the player go out off screen when it reaches the right border of screen and the camera don't follow him.
I have tried following options but none of them worked:
camera.position.set(player.getX(), camera.position.y, 0);
camera.position.set(player.getX(), 0, 0);
Vector3 vector3= camera.unproject(new Vector3(player.getX(), 0f, 0f));
player.setX(vector3.x);
I know that this question already exists on SO but none answer works in this case. Maybe I miss something important that i don't know.
The code:
Game.java class
public class Game extends com.badlogic.gdx.Game implements ApplicationListener {
public static Vector2 VIEWPORT = new Vector2(320, 480);
public static int WIDTH;
public static int HEIGHT;
#Override
public void create() {
WIDTH = Gdx.graphics.getWidth();
HEIGHT = Gdx.graphics.getHeight();
// VIEWPORT = new Vector2(WIDTH/2, HEIGHT/2);
VIEWPORT = new Vector2(WIDTH, HEIGHT);
setScreen(new GameScreen(this));
}
#Override
public void resize(int width, int height) {
// TODO Auto-generated method stub
super.resize(width, height);
}
#Override
public void resume() {
}
#Override
public void pause() {
}
}
GameScreen.java class
import android.util.Log;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.Color;
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.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.viewport.FitViewport;
import java.util.Collections;
public class GameScreen implements Screen {
private OrthographicCamera camera;
private Player player;
private PlayerInputHandler inputHandler1, inputHandler2;
private Sound sound;
FitViewport viewp;
public static int WIDTH;
public static int HEIGHT;
int width_spacing = 0;
int height_spacing = 0;
Stage stage;
Skin skin;
public GameScreen(Game game) {
stage = new Stage(new FitViewport(Game.WIDTH, Game.HEIGHT));
camera = (OrthographicCamera) stage.getCamera();
Gdx.input.setInputProcessor(stage);
}
#Override
public void show() {
resetGame();
}
public void resetGame() {
WIDTH = Gdx.graphics.getWidth();
HEIGHT = Gdx.graphics.getHeight();
width_spacing = Game.WIDTH / 24;
height_spacing = Game.HEIGHT / 14;
stage.clear();
skin = new Skin(Gdx.files.internal("data2/uiskin.json"));
prepareInputHandlers();
prepare_stage();
}
public void addPlayer() {
Texture texture = new Texture("player.png");
player = new Player(texture);
player.setPosition(Game.WIDTH / 2, Game.HEIGHT * 2 / 3);
stage.addActor(player);
}
#Override
public void resize(int width, int height) {
stage.getViewport().update(width, height, true);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (delta > 1 / 60f) {
player.setX(player.getX() + (4 * delta));
camera.position.set(player.getX(), camera.position.y, 0);
}
update();
stage.act(delta);
stage.draw();
}
private void update() {
camera.update();
}
private void prepareInputHandlers() {
inputHandler2 = new PlayerInputHandler(player, Input.Keys.LEFT, Input.Keys.RIGHT, Input.Keys.UP, Input.Keys.DOWN);
}
#Override
public void dispose() {
sound.dispose();
player.getTexture().dispose();
}
public void prepare_stage() {
addPlayer();
player.setWidth(64);
player.setHeight(64);
}
#Override
public void resume() {
// TODO Auto-generated method stub
}
#Override
public void hide() {
// TODO Auto-generated method stub
}
#Override
public void pause() {
// TODO Auto-generated method stub
}
}
Player.java class
import com.badlogic.gdx.graphics.Texture;
public class Player extends com.badlogic.gdx.scenes.scene2d.ui.Image{
private Texture texture;
public Player(Texture texture) {
super(texture);
}
public Texture getTexture() {
return texture;
}
#Override
public void act(float delta) {
super.act(delta);
}
}

try to use stage's camera instead of creating your own. Change your GameScreen constructor like this:
public GameScreen(Game game)
{
stage = new Stage(new FitViewport(Game.WIDTH, Game.HEIGHT));
camera = (OrthographicCamera) stage.getCamera();
Gdx.input.setInputProcessor(stage);
}
then in the render method set the camera position just like
camera.position.set(player.getX(), camera.position.y, 0);
before camera.update() call
There is also something strange in your code - why you have camera.position.set() and setting player x in this condition:
if (delta > 1 / 60f) //??
{
player.setX(player.getX() + (4 * delta));
camera.position.set(player.getX(), camera.position.y, 0);
}
I'm pretty sure you don't need this - but even if you need the
camera.position.set(player.getX(), camera.position.y, 0);
should be out of if statement because what is happening now is that even if you are changing your player position (using keybord through PlayerInputHandler object) you **don't update camera position. Try to remove if statement or at least do something like
public void render(float delta)
{
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (delta > 1 / 60f)
{
player.setX(player.getX() + (100 * delta));
}
camera.position.set(player.getX(), camera.position.y, 0);
update();
stage.act(delta);
stage.draw();
}
last thing is that if your stage is empty (excluding player) when camera will start to follow player - you will see as player not moving at all :) Add someting more to stage

Related

LibGdx `ShapeRenderer` on Android does not honor alpha channel

I have a program where I am drawing some lines on each frame using ShapeRenderer. On each frame I want to draw on top the previous, faded by a amount, frame.
So what I am doing is first draw a black rectangle with an alpha less than 1 and then draw the current frame. On desktop it works well and the result is something like this
But on Android it does not work. It renders like this.
I tried enabling blending before drawing rectangle
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Also tried seting the alpha channel to 8 bits in AndroidApplicationConfiguration (config.a = 8)
Nothing of these worked. What else can I try?
Also is there a better way to achieve what I want?
Screen code
package com.waterpaw.trochoids.screen;
import java.util.ArrayList;
import java.util.List;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.utils.viewport.ScreenViewport;
import com.waterpaw.trochoids.Trochoid;
import com.waterpaw.trochoids.Trochoids;
public class GameScreen extends BaseScreen {
private ShapeRenderer sr;
private ScreenViewport viewport;
private List<Trochoid> trochoids = new ArrayList<Trochoid>();
public GameScreen(Trochoids game) {
super(game);
viewport = new ScreenViewport();
Gdx.input.setInputProcessor(this);
sr = new ShapeRenderer();
}
private int resized;
#Override
public void resize(int width, int height) {
viewport.update(width, height);
trochoids.clear();
trochoids.add(new Trochoid(viewport.getWorldWidth(), viewport.getWorldHeight()));
resized = 2;
}
#Override
public void render(float delta) {
if(resized-- > 0) {
Gdx.gl.glClearColor(0f, 0f, 0f, 0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
}
processInput();
if(!trochoids.get(0).isPaused()) {
updateTrochoids();
renderTrochoids();
}
}
private void processInput() {
if(Gdx.input.isKeyJustPressed(Keys.P)) {
if(trochoids.get(0).isPaused()) {
trochoids.get(0).unpause();
} else {
trochoids.get(0).pause();
}
} else if(Gdx.input.isKeyJustPressed(Keys.SPACE)) {
touchDown(0, 0, 0, 0);
}
}
#Override
public void dispose() {
sr.dispose();
}
#Override
public boolean touchDown(int x, int y, int pointer, int button) {
trochoids.get(0).initialize();
return true;
}
public void renderTrochoids() {
sr.setProjectionMatrix(viewport.getCamera().combined);
float w = viewport.getWorldWidth();
float h = viewport.getWorldHeight();
sr.setColor(0, 0, 0, 0.1f);
sr.begin(ShapeRenderer.ShapeType.Filled);
sr.rect(-w / 2, -h / 2, w, h);
sr.end();
sr.begin(ShapeRenderer.ShapeType.Line);
for(int i = 0; i < trochoids.size(); i++) {
trochoids.get(i).render(sr);
}
sr.end();
}
private void updateTrochoids() {
for(int i = 0; i < trochoids.size(); i++) {
trochoids.get(i).update();
}
}
}
LibGDX uses double buffering on Android, so your technique won't work. Draw to a FrameBuffer so you can ensure your previous drawing is not cleared every other frame. Then draw the FrameBuffer's color texture to the screen on every frame.

SplashScene not centered

I am trying out AndEngine and cannot work out why my splashscreen is not centered in the device - see the image below.
I have set a default size for the device (800, 480) and placed the splash at camera.getWidth() / 2. It seems like the corner of my splash hits the center pretty spot on but I want the center of the splash to be centered - makes sense?
MainActivity:
package com.example.caspe.getmeout;
import org.andengine.engine.Engine;
import org.andengine.engine.LimitedFPSEngine;
import org.andengine.engine.camera.Camera;
import org.andengine.engine.handler.timer.ITimerCallback;
import org.andengine.engine.handler.timer.TimerHandler;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.WakeLockOptions;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.engine.options.EngineOptions;
import org.andengine.entity.scene.Scene;
import java.io.IOException;
public class MainActivity extends BaseGameActivity {
private ResourcesManager resourcesManager;
private static final int CAMERA_WIDTH = 800;
private static final int CAMERA_HEIGHT = 480;
private Camera camera;
public EngineOptions onCreateEngineOptions() {
camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(800, 480), this.camera);
engineOptions.getAudioOptions().setNeedsMusic(true).setNeedsSound(true);
engineOptions.setWakeLockOptions(WakeLockOptions.SCREEN_ON);
return engineOptions;
}
#Override
public Engine onCreateEngine(EngineOptions pEngineOptions) {
return new LimitedFPSEngine(pEngineOptions, 60);
}
#Override
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) throws Exception {
ResourcesManager.prepareManager(mEngine, this, camera, getVertexBufferObjectManager());
resourcesManager = ResourcesManager.getInstance();
pOnCreateResourcesCallback.onCreateResourcesFinished();
}
#Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws IOException {
SceneManager.getInstance().createSplashScene(pOnCreateSceneCallback);
}
#Override
public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) throws IOException {
mEngine.registerUpdateHandler(new TimerHandler(2f, new ITimerCallback() {
public void onTimePassed(final TimerHandler pTimerHandler) {
mEngine.unregisterUpdateHandler(pTimerHandler);
// load menu resources, create menu scene
// set menu scene using scene manager
// disposeSplashScene();
}
}));
pOnPopulateSceneCallback.onPopulateSceneFinished();
}
}
And the code for Splash:
package com.example.caspe.getmeout;
import org.andengine.engine.camera.Camera;
import org.andengine.entity.sprite.Sprite;
import org.andengine.opengl.util.GLState;
import com.example.caspe.getmeout.BaseScene;
import com.example.caspe.getmeout.SceneManager.SceneType
public class SplashScene extends BaseScene {
private Sprite splash;
#Override
public void createScene() {
splash = new Sprite(0,0, resourcesManager.splash_region, vbom) {
#Override
protected void preDraw(GLState pGLState, Camera pCamera) {
super.preDraw(pGLState, pCamera);
pGLState.enableDither();
}
};
splash.setScale(1.5f);
splash.setPosition(camera.getWidth() / 2, camera.getHeight() / 2);
attachChild(splash);
}
#Override
public void onBackKeyPressed() {
}
#Override
public SceneType getSceneType() {
return SceneType.SCENE_SPLASH;
}
#Override
public void disposeScene() {
splash.detachSelf();
splash.dispose();
this.detachSelf();
this.dispose();
}
}
Please let me know if you need more code than this.
I am not directly seeking a working piece of code but more where my error is so I can use my braincells and work it out - I have just stared myself blind here.
splash.setPosition(camera.getWidth() / 2, camera.getHeight() / 2);
That is not enough. Your splash is actually centered correctly: the top left corner is in the center.
What you need is to subtract the half width and height of the splash from the position, too.
// untested code
splash.setPosition(camera.getWidth() / 2 - splash.getWidth() / 2, camera.getHeight() / 2 - splash.getHeight() / 2);

Screen does not save its progress when switched

So, this is too hard for me to explain this in short, so the title looks so creepy. Well, I am writing a small android application and i have like three screens: the main-menu one, and two in-game screens. I can switch between the last two ones with a switch button. The problem is, that when i switch back to the last screen I've been to, all its acting stuff starts again from the very beginning. I have also seen a similar question here, but i did not work for me(( So, is there any way to keep the screen rendering, while I am using the other one?
Thank you!
The first screen:
public class InGameScreen implements Screen {
TinyBattles game;
public static OrthographicCamera camera;
public static Button switchButton1;
public InGameScreen(TinyBattles game) {
this.game = game;
}
#Override
public void show() {
camera = new OrthographicCamera(Global.VIEWPORT_WIDTH, Global.VIEWPORT_WIDTH*Global.actualHeight/Global.actualWidth);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);
camera.update();
switchButton1 = new Button();
switchButton1.create(10, 800, 150, 150);
Assets.loadSwitchButton();
}
#Override
public void render(float delta) {
Global.cleanScreen();
touchHandler(camera, Global.touch);
switchButton1.act();
switchButton1.render(Assets.buttonSwitchStateUpSprite, Assets.buttonSwitchStateDownSprite);
Global.debugRender();
localDebugRender();
leaveScreen();
Global.batch.getProjectionMatrix().setToOrtho2D(0, 0, Global.actualWidth, Global.actualHeight);
Global.batch.setProjectionMatrix(camera.combined);
Global.shapeRenderer.setProjectionMatrix(camera.combined);
}
public void localDebugRender(){
switchButton1.debugRender();
}
public void touchHandler(OrthographicCamera camera, Vector3 touch){
if (Gdx.input.isTouched()){
touch.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touch);
Global.finger.bounds.x = touch.x - 64;
Global.finger.bounds.y = touch.y - 64;
}else{
Global.finger.bounds.x = 10000;
Global.finger.bounds.y = 10000;
}
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
public void leaveScreen(){
if (switchButton1.isPressed == true){
game.setScreen(TinyBattles.inGameVirtualScreen);
}
}
}
The second screen:
public class InGameVirtualScreen implements Screen {
TinyBattles game;
public static World world;
public static OrthographicCamera camera;
public static Button switchButton2;
public static Balls balls;
public InGameVirtualScreen(TinyBattles game) {
this.game = game;
}
#Override
public void show() {
world = new World(new Vector2(0, 0), true);
camera = new OrthographicCamera(Global.VIEWPORT_WIDTH, Global.VIEWPORT_WIDTH*Global.actualHeight/Global.actualWidth);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);
camera.update();
switchButton2 = new Button();
switchButton2.create(10, 800, 150, 150);
balls = new Balls();
Assets.loadBallSprites();
balls.create();
balls.setup();
}
#Override
public void render(float delta) {
Global.tweenManager.update(1 / 60f);
Global.cleanScreen();
world.step(1 / 60f, 10, 10);
touchHandler(camera, Global.touch);
switchButton2.act();
balls.act();
renderLayerOne();
renderInterfaceLayer();
renderDebugLayer();
leaveScreen();
Global.batch.getProjectionMatrix().setToOrtho2D(0, 0, Global.actualWidth, Global.actualHeight);
Global.batch.setProjectionMatrix(camera.combined);
Global.shapeRenderer.setProjectionMatrix(camera.combined);
}
public void renderLayerOne(){
balls.render();
}
public void renderInterfaceLayer(){
switchButton2.render(Assets.buttonSwitchStateUpSprite, Assets.buttonSwitchStateDownSprite);
}
public void renderDebugLayer(){
Global.debugRender();
localDebugRender();
}
public void localDebugRender(){
switchButton2.debugRender();
}
public void touchHandler(OrthographicCamera camera, Vector3 touch){
if (Gdx.input.isTouched()){
touch.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touch);
Global.finger.bounds.x = touch.x - 64;
Global.finger.bounds.y = touch.y - 64;
}else{
Global.finger.bounds.x = 10000;
Global.finger.bounds.y = 10000;
}
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
public void leaveScreen(){
if (switchButton2.isPressed){
game.setScreen(TinyBattles.inGameScreen);
}
}
}
There is a leaveScreen() method at the bottom of the each class
You should move all your code in each screen from show() to the constructor. show() is called every time the screen becomes the active screen, so you don't want to do initialization there.
By the way, you should never keep static references to anything that implements Disposable, such as SpriteBatch, or anything that keeps a reference to something that implements Disposable, such as Button or Stage. If you do, when the user backs out of your game activity and reopens it, there will be memory leaks and incorrect textures, etc.
Its been a while since I used libgdx, but it seems you are creating a new screen on each leaveScreen function.
See here for a better approach, where when you create the Game class you create the screens as well:
public class MyGame extends Game {
MainMenuScreen mainMenuScreen;
AnotherScreen anotherScreen;
#Override
public void create() {
mainMenuScreen = new MainMenuScreen(this);
anotherScreen = new AnotherScreen(this);
setScreen(mainMenuScreen);
}
}
Then, you change the screens like this:
public void leaveScreen(){
if (switchButton2.isPressed){
game.setScreen(game.anotherScreen);
}
}
As I said it's been a while, but give it a shot :)

Box2D body lags/jumps when a camera is centered on it

I'm trying to set the camera position to the position of a body, but when I do this, the body will jump very noticeably. You can see this with the debug renderer but I have a sprite attached in my code. The jump is always in the direction that the sprite is headed. I've got a fixed time step with interpolation, and I update the sprites position to an interpolated value of the current and last position of a box2d body every frame. Then set the camera to the interpolated position.
import java.util.Random;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Input.Orientation;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.JointEdge;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.TimeUtils;
import com.badlogic.gdx.utils.viewport.FitViewport;
public class GameScreen implements Screen {
private static learnGame game;
private static OrthographicCamera camera;
private static FitViewport viewport;
private static Random rand;
private static BitmapFont font;
private static Vector3 touch;
private static double frameTime;
private static double accumulator;
private static float animTime = 0f;
private static float step = 1f / 60f;
private static boolean killBody;
private static Buttons buttons;
public static Player tom;
public static InputMultiplexer multiplexer;
public static Bodies world;
public static boolean paused;
private static Sprite tomSprite = new Sprite(new Texture(Gdx.files.internal("chars/bob.png")));
public GameScreen(learnGame learngame) {
GameScreen.game = learngame;
multiplexer = new InputMultiplexer();
Gdx.input.setInputProcessor(multiplexer);
camera = new OrthographicCamera();
viewport = new FitViewport(40, 22.5f, camera);
buttons = new Buttons(game, multiplexer, viewport); //HUD stuff
world = new Bodies(viewport, multiplexer); //creates a box2d world
tom = new Player(world.box2d, 10, 15, 1f, multiplexer); //creates a body with a CircleShape with a radius of 1. Catches user input to apply forces to the body
Assets.loadSprites();
world.box2d.getBodies(world.bodies);
font = new BitmapFont();
touch = new Vector3();
rand = new Random();
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
learnGame.batch.setProjectionMatrix(camera.combined);
frameTime = 0;
if (!paused) {
frameTime = Math.min(Gdx.graphics.getRawDeltaTime(), 0.25);
accumulator += frameTime;
tom.update(); //here I apply forces to the body that I attach a camera to
generalUpdate(delta, touch, camera);
updatePositions(); //get previous positions for interpolation
while (accumulator >= step) {
world.box2d.step(step, 6, 2);
accumulator -= step;
interpolate((float) (accumulator / step));
}
world.box2d.clearForces();
learnGame.batch.begin();
if (tom.getBody().isActive()) {
tomSprite.setSize(tom.getHeight(), tom.getHeight());
tomSprite.setOriginCenter();
tomSprite.setRotation(Assets.tom.angle);//this doesn't work right but not the point.
tomSprite.setPosition(Assets.tom.pos.x, Assets.tom.pos.y);
tomSprite.draw(learnGame.batch);
}
learnGame.batch.end();
cameraUpdate(); //update the camera to the same position as the sprite
} else { //else pause the game
learnGame.batch.begin();
learnGame.batch.draw(Assets.pauset, viewport.getCamera().position.x
- (viewport.getCamera().viewportWidth / 2), viewport.getCamera().position.y
- (viewport.getCamera().viewportHeight / 2), viewport.getWorldWidth(), viewport.getWorldHeight());
learnGame.batch.end();
if (Gdx.input.isKeyJustPressed(Keys.SPACE) || Gdx.input.justTouched()) {
paused = false;
}
}
//destroy fixtures and bodies outside of the world step
for (Fixture fixture : Bodies.fixturesToDestroy) {
if (Bodies.destroyJoint == true) {
world.box2d.destroyJoint(Bodies.joint);
Bodies.joint = null;
Bodies.destroyJoint = false;
}
fixture.getBody().destroyFixture(fixture);
Bodies.fixturesToDestroy.removeValue(fixture, true);
}
for (Body body : Bodies.bodiesToDestroy) {
world.box2d.destroyBody(body);
body.setActive(false);
Bodies.bodiesToDestroy.removeValue(body, true);
}
}
#Override
public void show() {
Assets.firstSound.play();
}
#Override
public void resize(int width, int height) {
viewport.update(width, height, true);
Assets.reloadFont();
}
#Override
public void pause() {
paused = true;
}
#Override
public void resume() {
}
#Override
public void hide() {
paused = true;
}
#Override
public void dispose() {
Bodies.box2d.dispose();
Bodies.debugRenderer.dispose();
Buttons.stage.dispose();
Assets.cFrame.getTexture().dispose();
Assets.firstSound.dispose();
System.out.println("disposed");
}
public void generalUpdate(float delta, Vector3 touch, OrthographicCamera camera) {
if (Gdx.input.isKeyPressed(Keys.PAGE_UP)) {
camera.zoom -= 2f * Gdx.graphics.getDeltaTime();
;
} else if (Gdx.input.isKeyPressed(Keys.PAGE_DOWN)) {
camera.zoom += 2f * Gdx.graphics.getDeltaTime();
}
}
public static void cameraUpdate() {
camera.position.set(Assets.tom.pos, 0);
System.out.println("cam:" + Assets.tom.pos.x);
camera.update();
}
public static void kill() {
world.box2d.dispose();
world.debugRenderer.dispose();
Assets.cFrame.getTexture().dispose();
}
public void updatePositions() {
for (MySprite name : Assets.spriteList) {
name.prevPos = name.body.getTransform().getPosition();
name.prevAngle = name.body.getTransform().getRotation();
}
}
public void interpolate(float alpha) {
for (MySprite name : Assets.spriteList) {
name.pos.x = (name.body.getTransform().getPosition().x) * alpha + name.prevPos.x * (1.0f - alpha);
name.pos.y = (name.body.getTransform().getPosition().y) * alpha + name.prevPos.y * (1.0f - alpha);
name.angle = (name.body.getTransform().getRotation() * alpha + name.prevAngle * (1.0f - alpha));
}
}
}
I have tested my interpolation implementation without the camera moving and it appears to work fine. I've been able to test this on my desktop and on my android. The sprite "jumps" a lot more on my android but it happens on both devices. Not sure where I went wrong here, would really appreciate some input!
It's an old question, I know, but I just solved my Problem today.
I have implemented a fixed Timestep and interpolation, but my body lagged and jittered and jumped like there would be no tomorrow.
Please do following things to your camera Movement:
Use the interpolated Position from the body, NOT the original body position.
Use camera.position.slerp(x, y, z, alpha) to do a smooth movement. (You need to play a bit with the variables.
A really simple Example:
static Vector3 desiredPosition;
static {
desiredPosition = new Vector3(0, 0, 0);
}
public static moveCam(Player player, Camera camera){
desiredPosition.x = player.interpolatedPos.x;
desiredPosition.y = player.interpolatedPos.y;
camera.slerp(desiredPosition, Gdx.graphics.getDeltaTime * 5);
camera.update();
}
and in your render do the following
render(float delta){
moveCam(player, camera);
}
(Instant position setting caused jitter for my moving Object)
I wanted to give up my project, because of this bug. But I managed to do it. I hope it'll help people out there.
€dit: A guess why the jumping body is happening:
The interpolated position is not synchron with the camera (set Position then update world(now interpolated pos is offset with camera), then draw)
But I'm not sure with this.

how to open another class by clicking on a button on libgdx? (android development eclipse)

I am making my own game. I have already made a splash screen and a main menu. I have made a button "Play" in my menu but I can't link it to my main game, while I can link it to other classes.
Here is the code of the class I can't open:
package com.mygdx.Papermadness.screens;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureWrap;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Vector2;
public class PaperMadness extends InputAdapter implements ApplicationListener, Screen {
float timer;
public static Preferences prefs;
public static int counter; // The variable you want to save
private BitmapFont font;
//public int counter = 0;
boolean touch = false;
SpriteBatch batch;
SpriteBatch spriteBatch;
Texture spriteTexture;
Sprite sprite;
float scrollTimer = 0.0f;
Player player;
Paper paper;
Huiz huiz;
Lijn lijn;
String money = String.valueOf(counter);
ShapeRenderer sr;
public boolean kukar = false;
public void create() {
font = new BitmapFont();
Gdx.input.setInputProcessor(this);
player = new Player(new Vector2(50, 100), new Vector2(100, 100));
huiz = new Huiz(new Vector2(200, 300), new Vector2(110, 110));
// huiz = new Huiz(new Vector2(200, 300), new Vector2(110, 110));
paper = new Paper(new Vector2(Gdx.input.getX(),
Gdx.graphics.getHeight() - Gdx.input.getY()), new Vector2(50,
50));
lijn = new Lijn(new Vector2(0, 200), new Vector2(600, 2));
// sr = new ShapeRenderer();
spriteBatch = new SpriteBatch();
spriteTexture = new Texture("b9.png");
spriteTexture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
sprite = new Sprite(spriteTexture);
sprite.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch = new SpriteBatch();
}
#Override
public void render(float delta) {
// bounds.set(Gdx.input.getX(),
// Gdx.graphics.getHeight() - Gdx.input.getY(),
// secondTexture.getWidth(), secondTexture.getHeight());
scrollTimer += Gdx.graphics.getDeltaTime();
if (scrollTimer > 1.0f)
scrollTimer = 0.0f;
sprite.setV(scrollTimer + 2);
sprite.setV2(scrollTimer);
player.update();
paper.update();
lijn.update();
huiz.update();
/*
* if (tree.getBounds().overlaps(ball.getBounds())) {
* System.out.println("Swendley Programinateur"); }
*
* if (tree.getBounds().overlaps(paper.getBounds())) {
* System.out.println("Souk Programinateur"); }
*/
spriteBatch.begin();
sprite.draw(spriteBatch);
spriteBatch.end();
batch.begin();
player.draw(batch);
huiz.draw(batch);
// paper.draw(batch);
if (Gdx.graphics.getHeight() / 1.25 < Gdx.input.getY()
&& Gdx.graphics.getWidth() / 2.7 < Gdx.input.getX()
&& Gdx.graphics.getWidth() / 1.7 > Gdx.input.getX()
&& Gdx.input.isTouched() && kukar == false && touch == false) {
kukar = true;
touch = true;
} else if (Gdx.input.isTouched() && kukar == true && touch == true) {
paper.draw(batch);
if (paper.getBounds().overlaps(huiz.getBounds())
|| paper.getBounds().overlaps(huiz.getBounds1())) {
// System.out.println("Huis Geraakt!");
touch = false;
counter++;
checkSpeed();
money = Integer.toString(counter);
// System.out.println(counter);
}
}
if (huiz.getBounds().overlaps(lijn.getBounds())
|| huiz.getBounds1().overlaps(lijn.getBounds())){
//System.out.println("Game Over");
}
font.draw(batch, money, Gdx.graphics.getWidth() / 2.06f,
Gdx.graphics.getHeight() / 1.05f);
font.setColor(Color.BLACK);
font.setScale(2, 2);
// house.draw(batch);
// house1.draw(batch);
lijn.draw(batch);
batch.end();
// sr.begin(ShapeType.Filled);
// sr.setColor(Color.YELLOW);
// sr.rect(Gdx.input.getX(), Gdx.graphics.getHeight() -
// Gdx.input.getY(),
// paper.getSize().x, paper.getSize().y);
// sr.setColor(Color.BLACK);
// sr.rect(huiz.getPosition().x, huiz.getPosition().y,
// huiz.getSize().x, huiz.getSize().y);
// sr.rect(house1.getPosition().x, house1.getPosition().y,
// house1.getSize().x, house1.getSize().y);
// sr.end();
}
public static void savePrefs(){
prefs = Gdx.app.getPreferences("game-prefs"); // The name of your prefs files
prefs.putInteger("counter", counter);
prefs.flush();
System.out.println(prefs);
}
public static void loadPrefs(){
prefs = Gdx.app.getPreferences("game-prefs");
counter = prefs.getInteger("counter",0); //Load counter, default to zero if not found
}
public void checkSpeed() {
if (counter <= 7) {
huiz.huisVelocity = 500f;
}
if (counter > 7 && counter <= 17) {
huiz.huisVelocity = 550f;
}
if (counter > 17 && counter <= 30) {
huiz.huisVelocity = 650f;
}
if (counter > 30 && counter <= 50) {
huiz.huisVelocity = 750;
}
if (counter > 50 && counter <= 75) {
huiz.huisVelocity = 900;
}
if (counter > 75 && counter <= 100) {
huiz.huisVelocity = 1000;
}
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
kukar = false;
touch = false;
return true;
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
}
#Override
public void hide() {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
}
#Override
public void render() {
}
}
Here is the menu class:
package com.mygdx.Papermadness.screens;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.mygdx.Papermadness.Papermadness;
public class MainMenu implements Screen {
private Stage stage;// done
private TextureAtlas atlas;// done
private Skin skin;// done
private Table table;// done
private TextButton buttonPlay, buttonExit;
private BitmapFont white, black;// done
private Label heading;
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Table.drawDebug(stage);
stage.act(delta);
stage.draw();
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
stage = new Stage();
Gdx.input.setInputProcessor(stage);
atlas = new TextureAtlas("ui/button.pack");
skin = new Skin(atlas);
table = new Table(skin);
table.setBounds(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
white = new BitmapFont(Gdx.files.internal("font/white.fnt"), false);
black = new BitmapFont(Gdx.files.internal("font/black.fnt"), false);
// maakt buttons
TextButtonStyle textButtonStyle = new TextButtonStyle();
textButtonStyle.up = skin.getDrawable("button.up");
textButtonStyle.down = skin.getDrawable("button.down");
textButtonStyle.pressedOffsetX = 1;
textButtonStyle.pressedOffsetY = -1;
textButtonStyle.font = black;
buttonExit = new TextButton("EXIT", textButtonStyle);
buttonExit.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
Gdx.app.exit();
}
});
buttonExit.pad(15);
buttonPlay = new TextButton("PlAY", textButtonStyle);
buttonPlay.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
((Game) Gdx.app.getApplicationListener())
.setScreen(new PaperMadness());
}
});
buttonPlay.pad(15);
// maakt header
heading = new Label(Papermadness.TITLE, new LabelStyle(white,
Color.WHITE));
heading.setFontScale(2);
table.add(heading);
table.getCell(heading).spaceBottom(100);
table.row();
table.add(buttonPlay);
table.getCell(buttonPlay).spaceBottom(15);
table.row();
table.add(buttonExit);
// table.debug();
stage.addActor(table);
}
#Override
public void hide() {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
stage.dispose();
atlas.dispose();
skin.dispose();
white.dispose();
black.dispose();
}
}
public class MyGdxGame extends Game{
public static MenuScreen menuScreen;
public static GameScreen gameScreen;
#Override
public void create(){
menuScreen = new MenuScreen(this);
gameScreen = new GameScreen (this);
setScreen(menuScreen);
}
}
Here is MenuScreen
public class MenuScreen implements Screen{
MyGdxGame game;
public MenuScreen(MyGdxGame game){
this.game = game;
}
////////////when you want to change screen type game.setScreen(game.gameScreen)
...........
...........
}
and this is GameScreen
public class GameScreen implements Screen{
...........
...........
...........
}
this is a simple example , try to do the same in your code.
Here is a good tutorial
https://github.com/libgdx/libgdx/wiki/Extending-the-simple-game
If it helped , let me know about it.

Categories

Resources