Null Pointer Exception when using unProject in Libgdx - java

I have a smasher game project and having problem when the game switches from MainMenuScreen to MainGameScreen, because of camera.unproject.
Texture img;
Array<Rectangle> listBalloon;
long lastSpawnTime;
OrthographicCamera camera;
BalloonPopper game;
public MainGameScreen(BalloonPopper game) {
this.game = game;
listBalloon = new Array<Rectangle>();
spawnBalloon();
}
#Override
public void show() {
img = new Texture("testBalloon.png");
}
#Override
public void render(float delta) {
ScreenUtils.clear(1, 0, 0, 1);
game.batch.begin();
for(Rectangle blns: listBalloon) {
game.batch.draw(img, blns.x, blns.y, blns.width,blns.height);
}
game.batch.end();
if(TimeUtils.nanoTime() - lastSpawnTime > 1000000000) spawnBalloon();
for(Iterator<Rectangle> iter = listBalloon.iterator(); iter.hasNext();) {
Rectangle blns = iter.next();
blns.y += 200 * Gdx.graphics.getDeltaTime();
if(blns.y > 720) iter.remove();
if(Gdx.input.isTouched()) {
Vector3 blnXY = new Vector3();
blnXY.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(blnXY);
if(blns.contains(blnXY.x, blnXY.y)) {
iter.remove();
}
}
}
}
public void spawnBalloon() {
Rectangle bln = new Rectangle();
bln.x = MathUtils.random(0, 480 - 64);
bln.y = -20;
bln.width = 64;
bln.height = 128;
listBalloon.add(bln);
lastSpawnTime = TimeUtils.nanoTime();
}
In for(Iterator<Rectangle> iter = listBalloon.iterator(); iter.hasNext();) in render(), if I remove the camera.unproject, the program will move to MainGameScreen with no problem. However, sometimes clicking the spawned texture won't remove them and i have to click like a bit above of the texture so it can be removed. So the only thing i know to make it precisely find the location when clicking, is by adding camera.unproject. But yeah the problem is the null pointer exception.
So is there a way to fix this? THX !!

Related

How to detect collisions between objects in LibGDX

This is my first post on stack overflow so I apologize in advance if I'm breaking any rules about posting, etc. I have been working on a an asteroids-esque shooting game and I can't figure out how to get the collision detection working between the rocks and the laser.
The source code can be found here. I had to make some changes to the update method of LevelScreen because the original code is dependent on using the BlueJ IDE. I found a fix in this post and got the collision working between the spaceship and the rocks.
The LevelScreen class
package com.mygdx.game;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import java.util.ArrayList;
public class LevelScreen extends BaseScreen {
private Spaceship spaceship;
private boolean gameOver;
private boolean rocksNeedRemoved;
private Rock toRemove;
private ArrayList<Rock> rocks;
private ArrayList<Laser> lasers;
public void initialize() {
gameOver = false;
toRemove = null;
rocksNeedRemoved = false;
BaseActor space = new BaseActor(0, 0, mainStage);
space.loadTexture("space.png");
space.setSize(800, 600);
BaseActor.setWorldBounds(space);
spaceship = new Spaceship(400, 300, mainStage);
rocks = new ArrayList<Rock>();
lasers = new ArrayList<Laser>();
rocks.add(new Rock(600, 500, mainStage));
rocks.add(new Rock(600, 300, mainStage));
rocks.add(new Rock(600, 100, mainStage));
rocks.add(new Rock(400, 100, mainStage));
rocks.add(new Rock(200, 100, mainStage));
rocks.add(new Rock(200, 300, mainStage));
rocks.add(new Rock(200, 500, mainStage));
rocks.add(new Rock(400, 500, mainStage));
lasers.add(new Laser(400, 500, mainStage));
}
public void update(float dt) {
//Code from book(Throws class not found error)
/*
for (BaseActor rockActor : BaseActor.getList(mainStage,
"Rock")) {
if (rockActor.overlaps(spaceship)) {
if (spaceship.shieldPower <= 0) {
Explosion boom = new Explosion(0, 0,
mainStage);
boom.centerAtActor(spaceship);
spaceship.remove();
spaceship.setPosition(-1000, -1000);
BaseActor messageLose = new BaseActor(0, 0,
uiStage);
messageLose.loadTexture("message-
lose.png");
messageLose.centerAtPosition(400, 300);
messageLose.setOpacity(0);
messageLose.addAction(Actions.fadeIn(1));
gameOver = true;
}
else {
spaceship.shieldPower -= 34;
Explosion boom = new Explosion(0, 0,
mainStage);
boom.centerAtActor(rockActor);
rockActor.remove();
}
}
for (BaseActor laserActor :
BaseActor.getList(mainStage, "Laser")) {
if (laserActor.overlaps(rockActor)) {
}
Explosion boom = new Explosion(0, 0,
mainStage);
boom.centerAtActor(rockActor);
laserActor.remove();
rockActor.remove();
}
}
if (!gameOver && BaseActor.count(mainStage, "Rock") ==
0) {
BaseActor messageWin = new BaseActor(0, 0,
uiStage);
messageWin.loadTexture("message-win.png");
messageWin.centerAtPosition(400, 300);
messageWin.setOpacity(0);
messageWin.addAction(Actions.fadeIn(1));
gameOver = true;
}
}
*/
// loop I used to get collision working between rocks
and spaceship
for (Rock each : rocks)
if (spaceship.overlaps(each) && !each.crashed &&
spaceship.shieldPower <= 0) {
Explosion boom = new Explosion(0, 0,
mainStage);
Explosion boom2 = new Explosion(0, 0,
mainStage);
boom.centerAtActor(spaceship);
boom2.centerAtActor(each);
spaceship.remove();
spaceship.setPosition(-1000, -1000);
each.crashed = true;
each.clearActions();
each.addAction(Actions.fadeOut(1));
each.addAction(Actions.after(Actions.removeActor()));
rocksNeedRemoved = true;
toRemove = each;
} else if (spaceship.overlaps(each) &&
!each.crashed) {
Explosion boom = new Explosion(0, 0,
mainStage);
boom.centerAtActor(each);
spaceship.shieldPower -= 34;
each.crashed = true;
each.clearActions();
each.addAction(Actions.fadeOut(1));
each.addAction(Actions.after(Actions.removeActor()));
rocksNeedRemoved = true;
toRemove = each;
}
//check for collision between rocks and lasers (Not
working correctly)
for (int i = rocks.size() - 1; i >= 0; i--) {
Rock rock = rocks.get(i);
for (int j = lasers.size() - 1; j >= 0; j--) {
Laser laser = lasers.get(j);
if(rock.getBounds().overlaps(laser.getBounds())) {
Explosion boom = new Explosion(0, 0,
mainStage);
boom.centerAtActor(rock);
rock.crashed = true;
rock.clearActions();
rock.addAction(Actions.fadeOut(1));
rock.addAction(Actions.after(Actions.removeActor()));
rocksNeedRemoved = true;
toRemove = rock;
}
}
}
}
//override default InputProcessor method
public boolean keyDown(int keycode) {
if (keycode == Keys.X)
spaceship.warp();
if (keycode == Keys.SPACE)
spaceship.shoot();
return false;
}
}
The Spaceship class.
package com.mygdx.game;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.math.MathUtils;
public class Spaceship extends BaseActor {
private Thrusters thrusters;
private Shield shield;
public int shieldPower;
public Spaceship(float x, float y, Stage s) {
super(x, y, s);
loadTexture("spaceship.png");
setBoundaryPolygon(8);
setAcceleration(100);
setMaxSpeed(100);
setDeceleration(10);
thrusters = new Thrusters(0, 0, s);
addActor(thrusters);
thrusters.setPosition(-thrusters.getWidth(),
getHeight() / 2 - thrusters.getHeight() / 2);
shield = new Shield(0, 0, s);
addActor(shield);
shield.centerAtPosition(getWidth() / 2, getHeight() /
2);
shieldPower = 100;
}
public void act(float dt) {
super.act(dt);
float degreesPerSecond = 160; //rotation speed
if (Gdx.input.isKeyPressed(Keys.LEFT))
rotateBy(degreesPerSecond * dt);
if (Gdx.input.isKeyPressed(Keys.RIGHT))
rotateBy(-degreesPerSecond * dt);
if (Gdx.input.isKeyPressed(Keys.UP)) {
accelerateAtAngle(getRotation());
thrusters.setVisible(true);
}
else {
thrusters.setVisible(false);
}
shield.setOpacity(shieldPower / 100f);
if (shieldPower <= 0)
shield.setVisible(false);
applyPhysics(dt);
wrapAroundWorld();
}
public void warp() {
if(getStage() == null)
return;
Warp warp1 = new Warp(0, 0, this.getStage());
warp1.centerAtActor(this);
setPosition(MathUtils.random(800),
MathUtils.random(600));
Warp warp2 = new Warp(0, 0, this.getStage());
warp2.centerAtActor(this);
}
public void shoot() {
if (getStage() == null)
return;
Laser laser = new Laser(0, 0, this.getStage());
laser.centerAtActor(this);
laser.setRotation(this.getRotation());
laser.setMotionAngle(this.getRotation());
}
}
The Laser class.
package com.mygdx.game;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.Action;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
public class Laser extends BaseActor {
Rectangle bounds;
public Laser(float x, float y, Stage s) {
super(x, y, s);
bounds = new Rectangle((int)getX(), (int)getY(),
(int)getWidth(), (int)getHeight());
loadTexture("laser.png");
addAction(Actions.delay(1));
addAction(Actions.after(Actions.fadeOut(0.5f)));
addAction(Actions.after(Actions.removeActor()));
setSpeed(400);
setMaxSpeed(400);
setDeceleration(0);
}
public void act(float dt) {
super.act(dt);
applyPhysics(dt);
wrapAroundWorld();
}
public Rectangle getBounds() {
return bounds;
}
private void setXY(float pX,float pY) {
setPosition(pX, pY);
bounds.setX((int)pX);
bounds.setY((int)pY);
}
}
The Rock class
package com.mygdx.game;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.Action;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.math.MathUtils;
import com.mygdx.game.BaseActor;
public class Rock extends BaseActor {
public boolean crashed;
Rectangle bounds;
public Rock(float x, float y, Stage s) {
super(x, y, s);
bounds = new Rectangle((int)getX(), (int)getY(),
(int)getWidth(), (int)getHeight());
loadTexture("rock.png");
float random = MathUtils.random(30);
addAction(Actions.forever(Actions.rotateBy(30 + random,
1)));
setSpeed(50 + random);
setMaxSpeed(50 + random);
setDeceleration(0);
setMotionAngle(MathUtils.random(360));
crashed = false;
}
public void act(float dt) {
super.act(dt);
applyPhysics(dt);
wrapAroundWorld();
}
public boolean isCrashed() {
return crashed;
}
public void crashed() {
crashed = true;
clearActions();
addAction(Actions.fadeOut(1));
addAction(Actions.after(Actions.removeActor()));
}
public Rectangle getBounds() {
return bounds;
}
private void setXY(float pX,float pY) {
setPosition(pX, pY);
bounds.setX((int)pX);
bounds.setY((int)pY);
}
}
Boundary and overlap methods from BaseActor class
public void setBoundaryPolygon(int numSides) {
float w = getWidth();
float h = getHeight();
float[] vertices = new float[2 * numSides];
for(int i = 0; i < numSides; i ++) {
float angle = i * 6.28f / numSides;
//x coordinate
vertices[2 * i] = w / 2 * MathUtils.cos(angle) + w / 2;
//y coordinate
vertices[2 * i + 1] = h / 2 * MathUtils.sin(angle) + h / 2;
}
boundaryPolygon = new Polygon(vertices);
}
public Polygon getBoundaryPolygon() {
boundaryPolygon.setPosition(getX(), getY());
boundaryPolygon.setOrigin(getOriginX(), getOriginY());
boundaryPolygon.setRotation(getRotation());
boundaryPolygon.setScale(getScaleX(), getScaleY());
return boundaryPolygon;
}
public boolean overlaps(BaseActor other) {
Polygon poly1 = this.getBoundaryPolygon();
Polygon poly2 = other.getBoundaryPolygon();
//initial text to improve performance
if(!poly1.getBoundingRectangle().overlaps(poly2.getBoundingRectangle()))
return false;
return Intersector.overlapConvexPolygons(poly1, poly2);
}
So I guess the real question would be how would I go about checking for collisions between the rocks ArrayList and the lasers fired by the player? At this point I just want to finish the game even if it's not using best practices. I tried using the method described here and received no errors but also no collision between lasers and rock. Even if I manually add a laser to the lasers ArrayList. This last post I found leads me to believe I need something like a getAllLasers() but I'm not 100% sure how to go about that. Would it be easier to just learn Box2D or Quadtree?
I realize this is a complex problem and want to thank you in advance for taking taking the time to read it. I'm happy to provide any more information you need.
You already have Rectangle bounds for both of this entities, this is all you need. You can use Rectangle.overlaps()
for(Laser laser: lasers){
for(Rock rock: rocks){
if(laser.getBounds().overlaps(rock.getBounds())){
//collided!
}
}
}
Make sure you are getting a updated rectangle/bounds. Add this extra line in both Rock and Laser getBounds() method:
public Rectangle getBounds() {
bounds.set(getX(),getY(),getWidth(),getHeight());
return bounds;
}
if your actors scales or rotate you should update bounds accordingly
I think problem may be with update your actors bounds, i can't find where you update it. I wrote similiar game and i change Bounds of actors on each update step and all works well in some lines...
public void update() {
...
// changing bounds
bounds = new Rectangle(position.x,position.y,
actorWidth,
actorHeight);
}
Or if you use other approach check that your bounds changing in time

Sprite Animation Pictures are Overlapping

I'm trying to make an animation out of an png file, that has various states of an action. My problem is, that the pictures overlap each other while rendering. Is there a solution, where i can only show one picture?
I use the LibGDX lib.
#Override public void show()
{
batch = new SpriteBatch();
img = new Texture("core/assets/ghosty.png");
regions = TextureRegion.split(img, 32, 32);
sprite = new Sprite (regions[0][0]);
Timer.schedule(new Timer.Task(){
#Override
public void run(){
frame++;
if (frame>27){
frame = 0;
if (zeile ==1){
zeile = 0;
}
else
{
zeile = 1;
}
}
sprite.setRegion(regions[zeile][frame]);
}
}, 0, 1/20f);
}
#Override public void render(float delta)
{
//stage.draw();
batch.begin();
sprite.draw(batch);
batch.end();
}
You don't need an extra Timer task and a Sprite instead you need an Animation<>.
Here is a little example of how you render an Animation:
private SpriteBatch batch;
private Texture img;
private Animation<TextureRegion> animation;
private TextureRegion[][] regions;
private Array<TextureRegion> frames;
#Override
public void show() {
batch = new SpriteBatch();
img = new Texture(Gdx.files.internal("ghosty.png")); //Get Texture from asset folder
regions = TextureRegion.split(img, 32, 32);
frames = new Array<TextureRegion>();
int rows = 5, columns = 5; //How many rows and columns the region have
//Fill Frames array with the regions of Texture
for(int i = 0; i < rows; i++){
for(int j = 0; j < columns; j++){
frames.add(regions[i][j]);
}
}
//Create Animation. 0.1f is the time how long a frame will occur,
//is the animation to fast set this number to a higher value
//so the single frames will stay for a longer time
animation = new Animation<TextureRegion>(0.1f, frames, Animation.PlayMode.LOOP);
}
private float stateTime = 0;
#Override
public void render(float delta) {
//Clear the screen
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//update state time so animation will go further
stateTime += delta;
batch.begin();
//Draw the current frame
batch.draw(animation.getKeyFrame(stateTime), 50, 50);
batch.end();
}
Hope this will help you.
A more efficient and easier way to run animation is to use TextureAtlas instead of Texture. Here is an example for using TextureAtlas: Libgdx Animation not working

getDeltaTime() method giving me null Exception? [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
For some reason, when I try to pass through Gdx.graphics.getDeltaTime() into my player class, the float delta time is null giving a null pointer exception. I already tried to check if the getDeltaTime method worked, and its counting, but when i try to pass through the function it doesn't work.
My Main Code
public class MyGdxGame extends ApplicationAdapter implements InputProcessor {
SpriteBatch batch;
private Player1 player1;
private TiledMap iceLevel;
private OrthogonalTiledMapRenderer renderer;
private OrthographicCamera camera;
float elaspedTime;
#Override
public void create() {
batch = new SpriteBatch();
Gdx.input.setInputProcessor(this);
TmxMapLoader loader = new TmxMapLoader();
iceLevel = loader.load("IceLevel.tmx");
renderer = new OrthogonalTiledMapRenderer(iceLevel);
camera = new OrthographicCamera();
camera.setToOrtho(false);
player1 = new Player1(new Sprite(new Texture("player1Right.png")), (TiledMapTileLayer) iceLevel.getLayers().get("Land"));
player1.setPosition(player1.getCollisionLayer().getTileWidth(), 6 * player1.getCollisionLayer().getTileHeight());
}
#Override
public void render() {
player1.update(Gdx.graphics.getDeltaTime());
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
camera.update();
renderer.setView(camera);
renderer.render();
renderer.getBatch().begin();
player1.draw(renderer.getBatch());
renderer.getBatch().end();
batch.end();
}
#Override
public void dispose() {
batch.dispose();
iceLevel.dispose();
renderer.dispose();
player1.getTexture().dispose();
}
A part of my player class
public class Player1 extends Sprite implements InputProcessor {
private Vector2 velocity;
private float speed = 60 * 2;
private float gravity = 60 * 1.8f;
private TiledMapTileLayer collisionLayer;
public Player1(Sprite sprite, TiledMapTileLayer collisionLayer) {
super(sprite);
this.collisionLayer = collisionLayer;
}
public void draw(SpriteBatch spriteBatch) {
update(Gdx.graphics.getDeltaTime());
super.draw(spriteBatch);
}
public void update(float delta) {
//gravity
velocity.y -= gravity * delta;
//set limit
if (velocity.y > speed) {
velocity.y = speed;
} else if (velocity.y < -speed) {
velocity.y = -speed;
}
// save old position
float oldX = getX();
float oldY = getY();
boolean collisionX = false;
boolean collisionY = false;
// move on x
setX(getX() + velocity.x * delta);
if (velocity.x < 0) { //going left
collisionX = collidesLeft();
} else if (velocity.x > 0) { //going right
collisionX = collidesRight();
}
// react to x collision
if (collisionX) {
setX(oldX);
velocity.x = 0;
}
// move on y
setY(getY() + velocity.y * delta * 5f);
if (velocity.y < 0) { // going down
collisionY = collidesBottom();
} else if (velocity.y > 0) { // going up
collisionY = collidesTop();
}
if (collisionY) {
setY(oldY);
velocity.y = 0;
}
}
Just to rule out delta time refactor you code like this:-
#Override
public void render() {
float delta = Gdx.graphics.getDeltaTime();
// Log or print this
if(delta > 0){
player1.update(Gdx.graphics.getDeltaTime());
Gdx.gl.glClearColor(1, 0, 0, 1);
.......
.......
}
Sounds like your player class update() method is the issue, but not the float delta. Looks like it is velocity. It is null.
private Vector2 velocity;
...
//gravity
velocity.y -= gravity * delta;
You are trying to set the y public float value of velocity (Vector2) but you don't have a velocity object instantiated.
Try
private Vector2 velocity = new Vector2();

LibGDX: Can't seem to draw the objects in an array

Enemy Class
public class Enemy extends Sprite{
private Vector2 velocity = new Vector2(0,0);
private float speed = 30, gravity = 30 * 1.8f;
public Enemy(Sprite sprite){
super(sprite);
}
public void draw(SpriteBatch spriteBatch){
update(Gdx.graphics.getDeltaTime());
super.draw(spriteBatch);
}
public void update(float delta) {
velocity.y -= gravity * delta;
setY(velocity.y + speed * delta);
}
}
PlayScreen Class
public class PlayScreen implements Screen {
private Player player;
private OrthographicCamera camera;
private OrthogonalTiledMapRenderer renderer;
private TiledMap map;
private Rectangle rightRectangle, leftRectangle, playerRectangle;
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderer.render();
renderer.getSpriteBatch().begin();
player.draw(renderer.getSpriteBatch());
boolean wallLeft = leftRectangle.overlaps(player.rectangle);
boolean wallRight = rightRectangle.overlaps(player.rectangle);
if(wallLeft){
System.out.println("wallLeft Overlap");
player.velocity.x = 0;
}
else if(wallRight){
System.out.println("wallRight Overlap");
player.velocity.x = 0;
}
enemies = new ArrayList<Enemy>();
enemy = new Enemy(new Sprite(new Texture("img/player.png"))));
enemies.add(new Enemy(new Sprite(new Texture("img/player.png"))));
enemies.add(new Enemy(new Sprite(new Texture("img/player.png"))));
for(it = enemies.iterator(); it.hasNext();){
enemy.draw(renderer.getSpriteBatch());
enemy.setOrigin(500, 500);
}
renderer.getSpriteBatch().end();
}
#Override
public void resize(int width, int height) {
camera.viewportWidth = width;
camera.viewportHeight = height;
camera.update();
}
#Override
public void show() {
camera = new OrthographicCamera();
map = new TiledMap();
renderer = new OrthogonalTiledMapRenderer(map);
player = new Player(new Sprite(new Texture("img/player.png")));
rightRectangle = new Rectangle(1280,0,0,720);
leftRectangle = new Rectangle(0,0,0,720);
player.setPosition(
Gdx.graphics.getWidth()/2f - player.getWidth()/2f,
Gdx.graphics.getHeight()/2f - player.getHeight()/2f
- Gdx.graphics.getHeight()/5f);
}
}
So if I were to run this, the application would just freeze up and would not respond anymore. I believe the problem is when I try adding the 'Enemy' into the PlayScreen class. It ran fine before, when I didn't put the 'Enemy' class into the project. What I'm trying to do is, to draw each enemy within the array of enemies then set their position.
Yes, you are missing an it.next() in here to advance the loop.
for(it = enemies.iterator(); it.hasNext();){
enemy.draw(renderer.getSpriteBatch());
enemy.setOrigin(500, 500);
}
I think you dont want to be drawing the same enemy each time either, so you should set enemy = it.next() at the beginning of this loop
Also, Im not %100 sure on how the backend of this works, but I'm pretty sure you don't want to load up 3 copies of the same sprite in the following snippet. You should load the sprite once, and use the same one for each enemy
enemy = new Enemy(new Sprite(new Texture("img/player.png"))));
enemies.add(new Enemy(new Sprite(new Texture("img/player.png"))));
enemies.add(new Enemy(new Sprite(new Texture("img/player.png"))));

Sprite not moving properly. libgdx

I'm new to libgdx, I'm trying to make a sprite move while the camera follows. I can make the sprite move perfectly until I attach the camera to it. When I click, the sprite will move wherever it feels like (it seems) and the camera will follow properly. I've tried a few different things but at this point its just guessing and checking.
public class MyGdxGame implements ApplicationListener {
OrthographicCamera mCamera;
SpriteBatch mBatch;
Texture mTexture, mMap;
Sprite sprite;
float touchX, touchY;
float spriteX, spriteY, speed = 5;
#Override
public void create() {
float CAMERA_WIDTH = 480, CAMERA_HEIGHT = 320;
mBatch = new SpriteBatch();
mTexture = new Texture(Gdx.files.internal("data/logo.png"));
mMap = new Texture(Gdx.files.internal("data/sc_map.png"));
mCamera = new OrthographicCamera(CAMERA_WIDTH, CAMERA_HEIGHT);
mCamera.setToOrtho(false, CAMERA_WIDTH, CAMERA_HEIGHT);
}
#Override
public void dispose() {
}
#Override
public void render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
mBatch.setProjectionMatrix(mCamera.combined);
mCamera.update();
mBatch.begin();
updateInput();
drawD();
mBatch.end();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
public void drawD() {
mCamera.position.set(spriteX, spriteY, 0);
mBatch.draw(mMap, 0, 0);
mBatch.draw(mTexture, spriteX, spriteY);
}
public void updateInput() {
if (Gdx.input.justTouched()) {
touchX = Gdx.input.getX();
touchY = Gdx.input.getY();
}
if (touchX != spriteX) {
if (spriteX < touchX) {
spriteX += speed;
}
if (spriteX > touchX) {
spriteX -= speed;
}
}
if (touchY != spriteY) {
if (spriteY > Gdx.graphics.getHeight() - touchY) {
spriteY -= 10;
}
if (spriteY < Gdx.graphics.getHeight() - touchY) {
spriteY += 10;
}
}
}
}
Since you have spent a decent amount of time and are trying to get it working, I will give you a little push forward closer to what you are looking for. Look over the changes I made and below I will outline what I did to help you understand the code better.
Orthographic Camera, when you setup the camera 0,0 is the center of the screen. The width and the height are what you specified into the constructor. So the top edge would be x, 160 and the bottom edge would be x, -160. The left edge would be -240, y and the right edge would be 240, y.
drawD() Notice that I'm drawing the sprite in the middle of the image and it isn't moving. I instead move the map around in the opposite direction (y is inverted).
updateInput() Notice I pass in a delta value (this is the time in seconds between frames) this allows you to smoothly move things. The speed is 120, so this will smoothly move your character at a rate of 120/second.
The if condition is basically a simply way to compare the float values so it stops when it gets close enough. This prevents it from over shooting the target position and then bouncing back and forth because it might not be able to get to the exact value.
I added dispose calls for the textures you loaded, these are important as you don't want to fill up your memory.
I hope this helps get you started and pointed in the right direction. Working on games is a lot of work and takes time, so be patient and be ready to learn lots along the way!
Based on your comment I believe what you are looking for is something closer to this:
public class MyGdxGame implements ApplicationListener {
OrthographicCamera mCamera;
SpriteBatch mBatch;
Texture mTexture, mMap;
float touchX, touchY;
float spriteX, spriteY, speed = 120;
final float CAMERA_WIDTH = 480, CAMERA_HEIGHT = 320;
#Override public void create() {
mCamera = new OrthographicCamera(CAMERA_WIDTH, CAMERA_HEIGHT);
mBatch = new SpriteBatch();
mTexture = new Texture(Gdx.files.internal("data/logo.png"));
mMap = new Texture(Gdx.files.internal("data/sc_map.png"));
}
#Override public void dispose() {
mTexture.dispose();
mMap.dispose();
}
#Override public void render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
updateInput(Gdx.graphics.getDeltaTime());
mCamera.update();
mBatch.setProjectionMatrix(mCamera.combined);
mBatch.begin();
drawD();
mBatch.end();
}
#Override public void resize(final int width, final int height) {}
#Override public void pause() {}
#Override public void resume() {}
public void drawD() {
mBatch.draw(mMap, -spriteX - (mMap.getWidth() / 2), spriteY - (mMap.getHeight() / 2));
mBatch.draw(mTexture, -32, -32, 64, 64);
}
public void updateInput(final float delta) {
if (Gdx.input.justTouched()) {
touchX = Gdx.input.getX() - (Gdx.graphics.getWidth() / 2);
touchY = Gdx.input.getY() - (Gdx.graphics.getHeight() / 2);
}
final float dv = delta * speed;
if (Math.abs(touchX - spriteX) > 1) {
if (spriteX < touchX) {
spriteX += dv;
}
if (spriteX > touchX) {
spriteX -= dv;
}
}
if (Math.abs(touchY - spriteY) > 1) {
if (spriteY > touchY) {
spriteY -= dv;
}
if (spriteY < touchY) {
spriteY += dv;
}
}
}
}

Categories