I have a tiled map and an animation. However, the map covers this last and I don't know why. If I add only the animation, I can see it, but not if also I add the map. Please answer me, I can't find the solution!
Here is my code:
public class MyGdxGame extends ApplicationAdapter implements GestureDetector.GestureListener
{
Texture texture;
SpriteBatch batch;
Sprite sprite;
TextureAtlas textureAtlas;
Animation animation;
float time;
OrthographicCamera orthographicCamera;
Texture corridore;
Sprite spriteCorridore;
TiledMap map;
OrthogonalTiledMapRenderer renderer;
#Override
public void create () {
batch = new SpriteBatch();
corridore = new Texture("a.png");
spriteCorridore = new Sprite(corridore);
orthographicCamera = new OrthographicCamera(500,500);
orthographicCamera.position.x=500;
orthographicCamera.position.y=250;
map = new TmxMapLoader().load("mappa.tmx");
renderer = new OrthogonalTiledMapRenderer(map);
textureAtlas = new TextureAtlas(Gdx.files.internal("corsa.atlas"));
animation = new Animation(1/20f,textureAtlas.findRegion("a"),textureAtlas.findRegion("b"),
textureAtlas.findRegion("c"),textureAtlas.findRegion("d"),textureAtlas.findRegion("e"),
textureAtlas.findRegion("f"),textureAtlas.findRegion("g"),textureAtlas.findRegion("h"),
textureAtlas.findRegion("i"));
}
#Override
public void render () {
time = time + Gdx.graphics.getDeltaTime();
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(orthographicCamera.combined);
batch.begin();
batch.draw((TextureRegion)animation.getKeyFrame(time,true),orthographicCamera.position.x-spriteCorridore.getWidth()/2,orthographicCamera.position.y-spriteCorridore.getHeight()/2);
renderer.setView(orthographicCamera);
renderer.render();
orthographicCamera.translate(1, 0);
orthographicCamera.update();
batch.end();
}
}
Render your animation at the top of TiledMapRenderer so change your rendering order.
#Override
public void render () {
time = time + Gdx.graphics.getDeltaTime();
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderer.setView(orthographicCamera);
renderer.render();
batch.setProjectionMatrix(orthographicCamera.combined);
batch.begin();
batch.draw((TextureRegion)animation.getKeyFrame(time,true),orthographicCamera.position.x-spriteCorridore.getWidth()/2,orthographicCamera.position.y-spriteCorridore.getHeight()/2);
batch.end();
orthographicCamera.translate(1, 0);
orthographicCamera.update();
}
Related
I have problems to draw an image ( Texture ) on a TiledMap. When I try to call batch.draw(mytexture,x,y) the only image displayed is the map below; I tried to search on web a feasible solution, but i have not solved the problem yet..
i
Here's my code
public class GameTest implements ApplicationListener{
private Player player;
private Batch batch;
private MyTexture texture;
private OrthographicCamera camera;
private OrthogonalTiledMapRenderer renderer;
private TiledMap map;
public GameTest() {
//init camera and player
}
#Override
public void create() {
background = new Background();
batch = new SpriteBatch();
texture = new MyTexture();
map = new TmxMapLoader().load(Asset.FIRST_LEVEL);
renderer = new OrthogonalTiledMapRenderer(map);
camera.setToOrtho(false, 1280,512);
renderer.setView(camera);
camera.update();
}
#Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
background.update(Gdx.graphics.getDeltaTime());
batch.begin();
if(Gdx.input.isKeyJustPressed(Input.Keys.RIGHT)){
game.movePlayer('r', 1);
camera.position.x += 5;
}
camera.update();
renderer.setView(camera);
renderer.render();
// batch.setProjectionMatrix(camera.combined);
batch.draw(texture.getTexture("100"), (player.getPosition().y) * 64, ((7
- player.getPosition().x) * 64));
batch.end();
}
}
Here's MyTexture class. I create a map where I put a String as a key and a Texture corresponding to the image I want to display
public MyTexture() {
....
map.put("100",new Texture(Gdx.files.internal(Asset.PLAYER)));
}
public static final Texture getTexture(String key){
return map.get(key);
}
And here my Asset class, where I create only static field for imgaes path
public class Asset {
public static Map<String, String> map = new HashMap<String,String>();
public static final String FIRST_LEVEL = "levels/firstLevel.tmx";
public static String BACKGROUND = "asset/Background.png";
public static String PLAYER = "asset/Player.png";
...
}
Are you use you want to draw with a unit-scale of 1.0?
When calling the constructor of OrthogonalTiledMapRenderer that only takes a TmxTileMap as parameter the unit scale is defaulted to 1.0.
That means that a single tile takes up the as many world-units as there are pixels in a tile.
Try calling it with 1.0f / your_tile_size_in_pixels.
So if the tiles for your map are 64 by 64 pixels change
renderer = new OrthogonalTiledMapRenderer(map);
to
renderer = new OrthogonalTiledMapRenderer(map, 1.0f / 64.0f);
I'm trying to use a TiledMap in a test game but I'm having issues with the size. I'm using an ExtendViewport with width 160 and height 90. I guess the problem is that the tiled map is drawing using the screen size, because it's zoomed in. Do I need 2 seperate cameras for the tiled map and the rest of the game (players, enemies, ...)?
This is all of my code:
public class Main extends Game {
private OrthographicCamera camera;
private ExtendViewport viewport;
private TiledMap tiledMap;
TiledMapRenderer tiledMapRenderer;
#Override
public void create () {
camera = new OrthographicCamera(160, 90);
camera.setToOrtho(false, 160, 90);
camera.update();
viewport = new ExtendViewport(160, 90, camera);
viewport.apply();
tiledMap = new TmxMapLoader().load("map1.tmx");
tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap);
}
#Override
public void render () {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
tiledMapRenderer.setView(camera);
tiledMapRenderer.render();
}
#Override
public void resize(int width, int height) {
viewport.update(width, height, false);
}
#Override
public void dispose () {
}
}
Thanks
OrthogonalTiledMapRenderer's second parameter is unitScale. The unit scale tells the renderer how many pixels map to a single world unit. And it defaults to 1.
So in your case one pixel is equals to one unit size in tiled map. Try changing the unitScale parameter.
https://github.com/libgdx/libgdx/wiki/Tile-maps#rendering-tiled-maps
I have an issue in LibGDX where when i call upon Gdx.input.getY(), it selects a pixel that's on the other side of the application relative to the center of the screen.
public class Main extends ApplicationAdapter {
private SpriteBatch batch;
private Texture img;
private OrthographicCamera camera;
int xPos;
int yPos;
private Vector3 tp = new Vector3();
BitmapFont font;
#Override
public void create () {
batch = new SpriteBatch();
img = new Texture("crosshair.png");
camera = new OrthographicCamera();
camera.setToOrtho(false, 1280, 720);
font = new BitmapFont();
}
#Override
public void render () {
yPos = Gdx.input.getY();
xPos = Gdx.input.getX();
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.unproject(tp.set(xPos, yPos, 0));
batch.begin();
font.draw(batch,xPos + " , " + yPos, Gdx.input.getX() - 25, Gdx.input.getY() - 5);
batch.draw(img, xPos, yPos);
batch.end();
}
#Override
public void dispose () {
batch.dispose();
img.dispose();
}
Subtracting the viewport height with the touch location won't work, because that would be subtracting world coordinates with touch coordinates. (and even for a pixel perfect projection it would be height - 1 - y). Instead use the unproject method to convert touch coordinates to world coordinates.
There are two problems with your code:
You are never setting the batch projection matrix.
Even though you are using the unproject method, you are never using its result.
So instead use the following:
#Override
public void render () {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
camera.unproject(tp.set(Gdx.input.getX(), Gdx.input.getY(), 0));
font.draw(batch,tp.x+ " , " + tp.y, tp.x - 25, tp.y - 5);
batch.draw(img, tp.x, tp.y);
batch.end();
}
I would suggest to read the following pages, which describe this and the reasoning behind it in detail:
https://github.com/libgdx/libgdx/wiki/Coordinate-systems
https://xoppa.github.io/blog/pixels/
https://github.com/libgdx/libgdx/wiki/Viewports
It's better to try this
yPos = camera.viewportHeight - Gdx.input.getY();
It may be a dumb question but I need a little help / explanations. I can't manage to resize correctly my textures when I resize the window in libgdx. I want to keep the aspect of my textures or have them at least reduced on a lower screen size, like on a mobile device. Here is a sample of my code, my original window size is 600*700 I tried a lot of things but nothing works :\
Can you help me ? Thanks in advance.
public class GameScreen implements Screen {
private World world;
private int ppxX, ppxY;
private SpriteBatch batch;
private OrthographicCamera camera;
private float cameraX, cameraY;
public GameScreen(World world) {
this.world = world;
camera = new OrthographicCamera();
}
public void show() {
batch = new SpriteBatch();
}
#Override
public void render(float delta) {
world.update(delta);
updateCamera();
ppxX = Gdx.graphics.getWidth() / 600;
ppxY = Gdx.graphics.getHeight() / 700;
Gdx.gl.glClearColor(0f, 0f, 0f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(world.getTexture(), 0, 0, ppxX, ppxY);
for (GameElement e : world.getListElements()) {
e.update(delta);
batch.draw(e.getTexture(), e.getPositionX()*ppxX, e.getPositionY()*ppxY, e.getWidth()*ppxX , e.getHeight()*ppxY );
}
batch.end();
}
You are on the right track, but there is couple of things you have to change.
Use ViewPorts
this.camera = new OrthographicCamera();
this.viewport = new FitViewport(WORLD_SIZE_X, WORLD_SIZE_Y, this.camera);
this.batch = new SpriteBatch();
this.batch.setProjectionMatrix(this.camera.combined);
Resize correctly.
#Override
public void resize(int width, int height) {
this.viewport.update(width, height);
}
Update the camera and render using World Units. Do not make the mistake of thinking in Screen Pixels.
public void render(float delta) {
this.camera.update();
this.batch.setProjectionMatrix(this.camera.combined);
this.batch.begin();
// draw using WORLD_SIZE
this.batch.end();
}
When I run the application my menu screen shows, but when I click the screen to begin playing the game the game begins playing but the menu screen is still their overlaying the game. I know this because the game has music playing. I'm also going to add a splash screen in the future but I'm not concerned about that right now. I'm new at this so please explain things as best as you can. Below are the 3 classes used to make this happen.
public class SlingshotSteve extends Game {
public SpriteBatch batch;
public BitmapFont font;
public void create() {
batch = new SpriteBatch();
//Use LibGDX's default Arial font.
font = new BitmapFont();
this.setScreen(new Menu(this));
}
public void render() {
super.render(); //important!
}
public void dispose() {
batch.dispose();
font.dispose();
}
}
Here is the main menu screen
public class Menu implements Screen {
final SlingshotSteve game;
OrthographicCamera camera;
public Menu(final SlingshotSteve gam) {
game = gam;
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
game.batch.setProjectionMatrix(camera.combined);
game.batch.begin();
game.font.draw(game.batch, "Welcome to Slingshot Steve!!! ", 100, 150);
game.font.draw(game.batch, "Tap anywhere to begin!", 100, 100);
game.batch.end();
if (Gdx.input.isTouched()) {
game.setScreen((Screen) new GameScreen(game));
dispose();
}
}
Here is the game screen
public class GameScreen implements Screen {
final SlingshotSteve game;
OrthographicCamera camera;
// Creates our 2D images
SpriteBatch batch;
TextureRegion backgroundTexture;
Texture texture;
GameScreen(final SlingshotSteve gam) {
this.game = gam;
camera = new OrthographicCamera(1280, 720);
batch = new SpriteBatch();
Texture texture = new Texture(Gdx.files.internal("background.jpg"));
backgroundTexture = new TextureRegion(texture, 0, 0, 500, 500);
Music mp3Sound = Gdx.audio.newMusic(Gdx.files.internal("rain.mp3"));
mp3Sound.setLooping(true);
mp3Sound.play();
}
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(backgroundTexture, 0, 0);
batch.end();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
batch.dispose();
texture.dispose();
}
In addition to Phonbopit's answer. You should probably #Override the render function at GameScreen.
Not sure but I think your render() method on GameScreen not called. you must implement method render(float delta) that use delta time for parameter.
replace
public void render() {
// your code
}
with
public void render(float delta) {
// your code
}