[LibGDX] Drawing sprite on scrolling map [Solved]

Hello there! New member in JavaGaming. :slight_smile:

And the best way to start in a community is with a good coding question xD Well, my problem is the following: I’m working with LibGDX. I’ve loaded a .tmx map with a camera. Changing the value of camera.position I can move the camera to see the map. Now, I want to draw an sprite over the map. And I did the following:

  • First I tried with batch.draw, using some vector calculus. The object is drawn well in its initial position, but when I move the camera, it goes crazy. I think my vector calculus is well-done…

  • After that, I read that I can use batch.setProjectionMatrix(camera.combined); to do the camera move. Of course, using this method I can’t use a batch.draw() but a sprite.draw(batch). That’s what I’ve done, but, if a write the batch.setProjectionMatrix line, it won’t draw. Here’s my code:

public void render(SpriteBatch batch, float stateTime)
{
		currentFrame = anim.getKeyFrame(stateTime, true); //Get animation frame
		sprite.setPosition(getDrawCoords().x, getDrawCoords().y); //set the position (drawn without the batch.setProjection)
		sprite.setSize(currentFrame.getTexture().getWidth()/2, currentFrame.getTexture().getHeight());  //set a size
		sprite.setRegion(currentFrame); //set the currentframe
		sprite.draw(batch); //...and draw
	}
	
	public Vector2 getDrawCoords()
	{
		int x =  (int) (map.camera.viewportWidth/2-map.camera.position.x + map.tilePixelWidth * xMap); //xMap: tile x
		int y = (int) (map.camera.viewportHeight/2-map.camera.position.y+ map.tilePixelHeight * yMap); //yMap: tile y
		return new Vector2(x,y);
	}

EDIT: This piece of code is my class’ render method, NOT the main render method. The main is this:

@Override
	public void render() {		
		Gdx.gl.glClearColor(1, 1, 1, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		
		map.update(); //control the camera
		stateTime += Gdx.graphics.getDeltaTime();
		map.render(); //render the map (include camera.update()
		batch.setProjectionMatrix(camera.combined); //if this is here, my sprite is not drawn.
		batch.begin();
		units.get(0).render(batch, stateTime); //the above render method
		batch.end();
		
		
	}

Please note the left down corner of the map is drawn at (camera.viewportWidth/2, camera.viewportHeight/2) so you have to take that coordinate as the (0,0).

I don’t know what to do. I’ve proved lot of coordinates but it is never drawn when I write that line. Any help is appreciated.
Thank you very much!! :smiley:

Are you using a Tiled map?, are you also using the OrthogonalTiledMapRenderer?

Here is an example of what I mean:

renderMap = new OrthogonalTiledMapRenderer(map);

renderMap.setView(cam); // Set the cam to view the map
renderMap.render(); // This will render the map etc
renderMap.getSpriteBatch().setProjectionMatrix(cam.combined); // Notice how renderMap is using 'getSpriteBatch' and then setting the projection matrix

Of course, this is only if you are using a Tiled map.

Also make sure that you are using the same sprite batch for your rendering as this can cause conflicting issues and may be why your sprite isn’t being drawn. You can just pass the batch as a method parameter and use it that way to make life easier.

Sorry if this isn’t much help, if I could see more of your code I could take a better look :slight_smile:

I’m using a Tiled map with OrthogonalTiledMapRenderer. The render of my map is the same code you wrote, except the last line. I added it, however, I haven’t seen changes in the result.

I’m using only one SpriteBach for rendering, and I pass it as a paramenter. I’m totally lost, I don’t know what’s the problem.
Here you are my map constructor and render, if it helps:

public WarMap(String path, OrthographicCamera camera, int unitScale)
	{
		float w = Gdx.graphics.getWidth();
		float h = Gdx.graphics.getHeight();
		map = new TmxMapLoader().load(path);
		renderer = new OrthogonalTiledMapRenderer(map, unitScale);
	 
		MapProperties prop = map.getProperties();
		mapWidth = prop.get("width", Integer.class);
		mapHeight = prop.get("height", Integer.class);
		tilePixelWidth = prop.get("tilewidth", Integer.class);
		tilePixelHeight = prop.get("tileheight", Integer.class);
		
		mapPixelWidth = mapWidth * tilePixelWidth;
		mapPixelHeight = mapHeight * tilePixelHeight;
		
		this.camera = camera;
		this.camera.setToOrtho(false, w * unitScale, h * unitScale);
	}
	
	public void render()
	{
		camera.update();
		renderer.setView(camera);
		renderer.render();
		renderer.getSpriteBatch().setProjectionMatrix(camera.combined); //added after your reply. No visible effect.
	}

What would you need to check? Do you want the whole code?

And thanks for the reply and help. As I said, I don’t know what to do to solve this :frowning:

I have it! I have it! I’ll explain here the solution ;D

The engine was really drawing the sprite, but it was too little. The problem is that the unitscale I was using in the above code was 32 (my tilesize), not 1/32f. After changing that, I can change also

 this.camera.setToOrtho(false, w * unitScale, h * unitScale);

To the number of tiles I want to see (for example, 25x18). Now, the sprite is drawn, REALLY BIG. To change it to its normal size, I simple divide the size by 32f:

sprite.setSize(currentFrame.getTexture().getWidth()/(2*32f), currentFrame.getTexture().getHeight()/32f);  //set a size

And finally, LibGDX recongnises the (0,0) as the left down corner of the tilemap, so I have to change

sprite.setPosition(getDrawCoords().x, getDrawCoords().y);

By

sprite.setPosition(0,0);

And solved. Now I can move my camera and the sprite is in (0,0) position of the map.
Thanks for the support, SauronWatchesYou. I want to be more active here in the community. :slight_smile: