This is from day 6 of the flappy bird recreation tutorial
-http://www.kilobolt.com/day-6-adding-graphics---welcome-to-the-necropolis.html
Here is the image file i am using for texture in my game. It is a 256px x 64px .png file.
Here is the class that I used for loading the texture and the specific TextureRegion(part of the texure) that I want the SpriteBatch to draw.
public class AssetLoader {
public static Texture texture;
public static TextureRegion bg;
public static void load() {
texture = new Texture(Gdx.files.internal("data/texture.png"));
bg = new TextureRegion(texture, 0, 0, 136, 43);
}
}
And I call AssertLoader.load(), along with setting up game screen from
public class MyGdxGame extends Game{
#Override
public void create() {
AssetLoader.load();
setScreen(new GameScreen());
}
}
And inside GameScreen.java
public class GameScreen implements Screen {
//delegate render task
private GameRenderer renderer;
public GameScreen() {
float screenHeight = Gdx.graphics.getHeight();
float screenWidth = Gdx.graphics.getWidth();
float gameWidth = 136;
float gameHeight = screenHeight / (screenWidth / gameWidth);
renderer = new GameRenderer((int)gameHeight);
}
}
And inside GameRederer, the class I delegate to render the game
public class GameRenderer {
private int gameHeight;
private SpriteBatch batch;
private OrthographicCamera cam;
public GameRenderer(int gameHeight) {
this.gameHeight = gameHeight;
cam = new OrthographicCamera();
batch = new SpriteBatch();
batch.setProjectionMatrix(cam.combined);
cam.setToOrtho(true, 136, gameHeight);
}
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.disableBlending();
batch.draw(AssetLoader.bg, 0, (gameHeight/2) + 23, 136, 43);
batch.end()
}
}
What I get when I run the desktop version of the game is the black screen shown above(black because i set the background to black with these lines of code
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Does anyone know why the SpritchBatch drawing isn't showing up? I extracted the texture portion of the texture I wanted with this line of code(starts from 0,0, width of 136, height of 43) - used GIMP - to find out portion to cut.
bg = new TextureRegion(texture, 0, 0, 136, 43);
I also put a few log statements(removed them from view) to ensure that before drawing, bg's width and height were set correctly, which they were. And the issue can't be game height because I used a print statement and found that to be 204 which means that this expression, (gameHeight/2) + 23 will evaluate to 125 which is in bounds between 0 and game height.
I checked out other threads as well.
My issue can't be libgdx spritebatch not rendering textures because the SpriteBatch should overwrite the background.
And it can't be LibGDX: Android SpriteBatch not drawing because i am running mine on desktop, not andorid.
could be that you have to first put cam.setToOrtho(true, 136, gameHeight);before the batch, so I can not confirm hopefully help
public GameRenderer(int gameHeight) {
this.gameHeight = gameHeight;
cam = new OrthographicCamera();
batch = new SpriteBatch();
cam.setToOrtho(true, 136, gameHeight);
batch.setProjectionMatrix(cam.combined);
}
If anyone's having a similar issue, the way I solved the problem was to call
batch.setProjectionMatrix(cam.combined);
after
cam.setToOrtho(true, 136, gameHeight);
Which didn't really make sense to me because it's still the same Matrix4 in Camera.java, that is
public final Matrix4 combined = new Matrix4();
Was hoping someone else could clarify that.
Related
The way I have been doing it so far is copying the same font, saving under another name and loading it with different parameters. I am trying to develop an app in LibGDX and by saving the font as different files takes more memory than necessary. Isn't there a way of loading 1 font multiple times, each time with different parameters?
Take a look of this example, I am creating a list of BitmapFont object having different size by simply changing attributes of FreeTypeFontGenerator.FreeTypeFontParameter.
public class MainGame extends Game {
SpriteBatch spriteBatch;
BitmapFont font[];
OrthographicCamera camera;
#Override
public void create() {
camera=new OrthographicCamera();
camera.setToOrtho(false,400,640);
spriteBatch = new SpriteBatch();
int size[]=new int[]{5,8,10,13,15,20,30,40,50,60};
font=new BitmapFont[size.length];
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("BUBBLEGUM.TTF"));
FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
parameter.color = Color.WHITE;
parameter.magFilter = Texture.TextureFilter.Linear; // used for resizing quality
parameter.minFilter = Texture.TextureFilter.Linear;
for(int i=0;i<size.length;i++){
parameter.size=size[i];
font[i]=generator.generateFont(parameter);
font[i].getRegion().getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
font[i].setColor(1.0f, 0.0f, 0.0f, 1.0f);
}
generator.dispose(); // Don't forget to dispose
}
#Override
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.gl.glClearColor(1,1,0,1);
spriteBatch.setProjectionMatrix(camera.combined);
spriteBatch.begin();
for (int i=0;i<font.length;i++)
font[i].draw(spriteBatch,"LIBGDX FONT",10,100+i*55);
spriteBatch.end();
}
#Override
public void resize(int width, int height) {
camera.setToOrtho(false,width,height);
}
#Override
public void dispose() {
spriteBatch.dispose();
for(BitmapFont bmfont:font)
bmfont.dispose();
}
}
EDIT
https://github.com/libgdx/libgdx/blob/master/tests/gdx-tests/src/com/badlogic/gdx/tests/extensions/FreeTypeFontLoaderTest.java
I'm trying to render a sprite/texture on top of a tiled map in libgdx/android studio. Note that my map is 20x25 with 8 pixel tiles and splitTiles is a Texture Region.
public void show() {
cam = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
cam.setToOrtho(false, 20, 25);
batch = new SpriteBatch();
map = new TmxMapLoader().load("centipedeMap.tmx");
renderer = new OrthogonalTiledMapRenderer(map,1/8f)
}
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderer.setView(cam);
renderer.render();
player.update();
ex.update();
batch.setProjectionMatrix(cam.combined);
cam.update();
batch.begin();
Texture tilesImage = new Texture(Gdx.files.internal("tile.png"));
TextureRegion[][] splitTiles = TextureRegion.split(tilesImage, 8, 8);
batch.draw(splitTiles[0][0],50,50);
batch.end();
}
Your camera viewport dimension is 20, 25 and you're drawing your TextureRegion at 50,50 so your image is rendered out of screen so not visible.
Recommendation : Texture is heavy object so try to avoid creating multiple instance of same Texture.
you've camera viewport is in dimension of 20,25 that is same as tileMap(20,25) dimension so camera 1 unit denotes one cell of TileMap.
you can detect collision with Tiles,it is not necessary to create Rectangle object.
On my 854 x 480 LG Leon it renders fine, but on a larger screen resolution (2560 x 1440) this happens: http://imgur.com/a/rcbJK.
The code for processing the text is: http://imgur.com/a/c316e.
I've tried expanding the bounds of the Label because I thought that it might be constricting the text, but it still won't display properly.
What could be causing this?
The different mobile phone has the different aspect ratio in their screen size . that is the reason it shows different different screen. to avoid this problem you must use the viewPort. So you will be able to handle the different screen size. for more details, you must read the libgdx documentation. here I'm posting a sample code which can help you to handle the different screen size. there are three kinds of viewports mainly using
1) fillviewport
2) fitviewPort
3)stretchviewport
here is the documentation in detail.
https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/viewport/FillViewport.html
public class myGame extends ApplicationAdapter {
public OrthographicCamera camera;
public Viewport viewPort;
private SpriteBatch batch;
public myGame() {
}
#Override
public void create() {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.position.set(0, 0, 0);
camera.update();
camera.setToOrtho(false, 1280, 800);
viewPort = new FillViewport(1280, 800, camera);
}
#Override
public void dispose() {
batch.dispose();
}
#Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
float deltaTime = Gdx.graphics.getDeltaTime();
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(sprie,0,0)
batch.end();
}
#Override
public void resize(int width, int height) {
viewPort.update(width, height);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
// don't copy paste it . just try to understand and implement it.
You should use Scene2D and ViewPort.
Also , be careful to use coordinates (i.e : x: 64 , y:32 changes in every different screen size)
This is the common issue when your running your game in multiple devices. Because your game is running in different aspect ratios in different screens . it's generally called the multi screen issue. To solve this problem the libgdx is providing it's on class called the viewPort. Mainly you can see three viewpors.
1)Fill viewPort.
2)Fit viewPort.
3)stretch viewport.
For more details you can go through the libgdx documentation. Here im posting some example code which can solve your multi screen issues.
public class myGame extends ApplicationAdapter {
public OrthographicCamera camera;
public Viewport viewPort;
private SpriteBatch batch;
private BitmapFont myScoreFont;
//General screen resolution
public int APP_WIDTH=1280;
public int APP_HEIGHT=800;
public int fontPositionIn_X=600;
public int fontPositionIn_Y=400;
public myGame() {
}
#Override
public void create() {
myScoreFont = new BitmapFont(Gdx.files.internal(Constants.PATH_TO_MY_SCORE_FONT), true);
batch = new SpriteBatch();
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.position.set(0, 0, 0);
camera.update();
camera.setToOrtho(false, APP_WIDTH, APP_HEIGHT);
viewPort = new fillViewPort(1280, 800, camera);
}
#Override
public void dispose() {
batch.dispose();
}
#Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
float deltaTime = Gdx.graphics.getDeltaTime();
batch.setProjectionMatrix(camera.combined);
batch.begin();
myScoreFont.draw(batch,"any texts", fontPositionIn_X, fontPositionIn_Y)
batch.end();
}
#Override
public void resize(int width, int height) {
viewPort.update(width, height);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
so by using the viewPort you can be able to play your game in all the different screens.
I have tried to make a ellipse object in libgdx. Sorry if i can't describe properly but im a newbie in java.
My code looks like:
public class GameScreen implements Screen{
MyGame game;
OrthographicCamera camera;
SpriteBatch batch;
...
Ellipse playBounds;
public GameScreen(MyGame game) {
this.game = game;
camera = new OrthographicCamera();
camera.setToOrtho(false, 1080, 1920);
batch = new SpriteBatch();
state = GAME_READY;
touchPoint = new Vector3();
pauseBounds = new com.badlogic.gdx.math.Rectangle(1080-128,1920-128,128,128);
playBounds= new Ellipse()
}
...
public void render(float delta) {
Gdx.gl.glClearColor(1F, 1F, 1F, 1F);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
generalupdate();
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(Assets.sprite_bg, 0, 0);
switch (state){
case GAME_READY:{
batch.draw(Assets.sprite_startScreen, 0, 0);
batch.draw(Assets.sprite_playButton,218,800,644,225);
break;
}
Basically it draws background, a welcome screen and a button(with "play" on it)
So here i made a touch detection.
if (Gdx.input.justTouched()) {
camera.unproject(touchPoint.set(Gdx.input.getX(), Gdx.input.getY(), 0));
if (state==GAME_READY);
if (playBounds.contains(touchPoint.x, touchPoint.y)) {
state=GAME_RUNNING;
Drawing works fine but the problem is when i touch the button it doesnt work instead if i touch near it game starts as it should
Alright, ignoring the several errors in the code which I will just assume were made here instead of the actual code, I believe the problem could be that you are not setting the values in the Ellipse. By this I mean the width, height, x, and y.
An nice way to do this would be to use the constructor:
Ellipse(float x, float y, float width, float height)
instead of just :
Ellipse()
That way you can set the values right away. Refer to this website for more info in Ellipses for LibGDX.
If that doesn't solve your problem you may have to post a little more of the relevant parts of your code.
http://badlogicgames.com/forum/viewtopic.php?f=11&t=2447
http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/OrthographicCamera.html
There's hundreds of other links I could show you that I've looked at, but it's just not worth it because they all say the same thing.
public class InGame implements Screen {
SpriteBatch batch;
GameWorld world;
OrthographicCamera camera;
#Override
public void show() {
batch = new SpriteBatch();
world = new GameWorld();
camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.setToOrtho(true, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0f, 0f, 0f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
world.render(batch, delta);
batch.end();
}
}
What am I doing wrong? WHY is my world still being rendered with the 0,0 being at the bottom right. The math behind this while trying to work on my Tile-System is driving me absolutely insane.
World->Render
public void render(SpriteBatch batch, float delta) {
for(int xAxis = 0; xAxis < worldColumns; xAxis++) {
for(int yAxis = 0; yAxis < worldRows; yAxis++) {
tiles[xAxis][yAxis].render(batch, delta);
}
}
}
WorldTile->Render
public void render(SpriteBatch batch, float delta) {
myShape.begin(ShapeType.Filled);
myShape.setColor(tileColor);
myShape.rect(pos.getX(), pos.getY(), TILE_WIDTH, TILE_HEIGHT);
myShape.end();
}
The "pos" is the Position(x, y) that was passed in the World class.
If you are drawing a Sprite or TextureRegion using your SpriteBatch the code should work fine. However, you pass your SpriteBatch 'batch' all the way down to WorldTile.render and never use it?! Instead you use myShape which I assume is a ShapeRenderer. You need to set the projection matrix for the ShapeRenderer as well otherwise it will draw 'upside-down'.
Try calling myShape.setProjectionMatrix(camera.combined); before you use your myShape.
Its probably best to declare and initialise myShape in your InGame class, usemyShape.setProjectionMatrix(camera.combined);, and then pass myShape down to tiles.render() as you did with your SpriteBatch.
Hope this helps.