what is the best way?
1) make a method:
Assets.loadAll()
that load all the texture used in the game, and call this method in the splashScreen (so only one time in all the activity life)
OR
2) make one method for each screen (ie. Assets.loadMainMenu, Assets.loadGameScreen, etc..) and call it in the show() of any screen? (and in the hide() call the Assets.disposeMainMenuAssets, Assets.disposeGameScreenAssets, etc etc..)
NOTE: the 2) is slower than the first but in in the first if i block the phone (with classical phisical button) and after go back to the app, the texture disappear (it doesn't happen if i press the 'home' button... but if i lock the phone yes.... and the strange thing is that in libGdx 9.6 if i lock the phone the textures don't disappear, but with libGdx 9.7 this append..)
If it's 5MB's of assets I say just load them on the splash screen. That way there will be little to no "load" time between screen switching. Method 1 is the best for this.
Create a class called Assets. In this have a static method called "load", like so
public class Assets {
private static Texture tex;
public static TextureRegion tree,cloud1,cloud2,cloud3,rock,platform,playerStanding,
rocket, rocketShadow, moon, star;
public static SpriteAnimation playerMoving;
public static void load(){
tex = new Texture(Gdx.files.internal("data/Graphics.png"));
tex.setFilter(TextureFilter.Linear, TextureFilter.Linear);
tree = new TextureRegion(tex, 0,0,246,226);
cloud1 = new TextureRegion(tex, 246,0,225,92);
cloud2 = new TextureRegion(tex, 358,197,88,84);
cloud3 = new TextureRegion(tex, 0,226,105,64);
rock = new TextureRegion(tex, 246,197,112,90);
platform = new TextureRegion(tex, 246,92,193,105);
tex = new Texture(Gdx.files.internal("data/Graphics2.png"));
tex.setFilter(TextureFilter.Linear, TextureFilter.Linear);
playerMoving = new SpriteAnimation(new TextureRegion(tex,0,0,458,555), 4, 5, 0.01f);
playerStanding = new TextureRegion(tex,0,0,112,110);
tex = new Texture(Gdx.files.internal("data/Graphics3.png"));
tex.setFilter(TextureFilter.Linear, TextureFilter.Linear);
rocket = new TextureRegion(tex,0,218,119,201);
rocketShadow = new TextureRegion(tex,0,0,138,218);
tex = new Texture(Gdx.files.internal("data/Graphics4.png"));
tex.setFilter(TextureFilter.Linear, TextureFilter.Linear);
moon = new TextureRegion(tex,0,0,410,382);
star = new TextureRegion(tex,0,382,123,123);
}
public static void dispose(){
tex.dispose();
}
}
(This is just an example from my game. The names aren't important, just the methods)
On your splash screen you can just call Assets.load(); and all your assets will be loaded!
Then you want to use an asset you can just make a call to it via Assets.whatever (which being static is fine)
Hope this helps!
Related
I am developing a main menu screen for a game I'm developing for Android using LibGDX. It requires three ImageTextButtons - Play, Settings, Log out. Each of these three buttons has a different image associated with it, however, when I run the application, each button has the same image - the log out image. I am thinking that this may be to do with the fact that the log out button is the last button declared so perhaps it overwrites the images for the other buttons?
This is a screenshot of how the main menu currently looks:
As you can see, the same log out icon is displayed on all buttons even though I have loaded and used different image files for each of the buttons. Here is the code for constructing and initializing the buttons:
private ImageTextButton playBtn, settingsBtn, logoutBtn;
public void initButtons(){
playBtn = new ImageTextButton("Play", skin, "default");
playBtn.getStyle().imageUp = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("playBtn.png"))));
playBtn.getStyle().imageDown = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("playBtn.png"))));
settingsBtn = new ImageTextButton("Settings", skin, "default");
settingsBtn.getStyle().imageUp = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("settingsBtn.png"))));
settingsBtn.getStyle().imageDown = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("settingsBtn.png"))));
logoutBtn = new ImageTextButton("Log Out", skin, "default");
logoutBtn.getStyle().imageUp = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("logoutBtn.png"))));
logoutBtn.getStyle().imageDown = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("logoutBtn.png"))));
}
Here is the show method in which I make/load the skin and call the method to initialize the buttons:
#Override
public void show() {
Gdx.input.setInputProcessor(stage);
this.skin = new Skin();
this.skin.addRegions(MathsVsZombies.manager.get("UI/uiskin.atlas", TextureAtlas.class));
this.skin.add("default-font", MathsVsZombies.font24);
this.skin.load(Gdx.files.internal("UI/uiskin.json"));
initButtons();
}
In order to get the ImageTextButtonStyle to work I had to add this code to the skin JSON file:
"com.badlogic.gdx.scenes.scene2d.ui.ImageTextButton$ImageTextButtonStyle":{
"default": { "down": "default-round-down", "up": "default-round", "font": "default-font", "fontColor": "white" }
},
It is the same code for the "default" style of a TextButton. Perhaps this is where the issue lies? I am positive that the image files are stored under the correct directory and they are all stored together. This is what they should look like:
Please help solve this as I have very limited knowledge in LibGDX and gamedev in general so I don't know what is wrong, let alone how to fix it.
Skin will use the same instance of style for each button, so when you getStyle() and update the drawables, every button using that style will be updated.
Normally, you'd specify a separate style for each distinct button type in the skin itself, but you can also make a copy of the style before changing the drawables if you like.
I fixed this by making three separate styles in the skin JSON file, one for each specific button.
"com.badlogic.gdx.scenes.scene2d.ui.ImageTextButton$ImageTextButtonStyle":{
"play": { "down": "default-round-down", "up": "default-round", "font": "default-font", "fontColor": "white" },
"settings": { "down": "default-round-down", "up": "default-round", "font": "default-font", "fontColor": "white" },
"logout": { "down": "default-round-down", "up": "default-round", "font": "default-font", "fontColor": "white" }
Then in the initButtons method, I changed each style to it's corresponding style in the JSON file. This way each image file I load for each button gets stored for that specific style (which is why you need three separate styles otherwise the most recently loaded file will be the one associated with the "default" style).
playBtn = new ImageTextButton("Play", skin, "play");
playBtn.getStyle().imageUp = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("playBtn.png"))));
playBtn.getStyle().imageDown = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("playBtn.png"))));
settingsBtn = new ImageTextButton("Settings", skin, "settings");
settingsBtn.getStyle().imageUp = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("settingsBtn.png"))));
settingsBtn.getStyle().imageDown = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("settingsBtn.png"))));
logoutBtn = new ImageTextButton("Log Out", skin, "logout");
logoutBtn.getStyle().imageUp = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("logoutBtn.png"))));
logoutBtn.getStyle().imageDown = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("logoutBtn.png"))));
Outcome:
This is my intended implementation of the main menu screen.
I've launched my new game libGDX on play store and I start getting crash reports.
This problem started when I updated to newer version on libgdx 1.9.7.
Here is my crash report:
java.lang.IllegalStateException:
at com.badlogic.gdx.graphics.glutils.GLFrameBuffer.build (GLFrameBuffer.java:233)
at com.badlogic.gdx.graphics.glutils.GLFrameBuffer.<init> (GLFrameBuffer.java:87)
at com.badlogic.gdx.graphics.glutils.FrameBuffer.<init> (FrameBuffer.java:51)
at com.badlogic.gdx.graphics.glutils.GLFrameBuffer$FrameBufferBuilder.build (GLFrameBuffer.java:474)
at com.dui.Screens.DirectedGame.setScreen (DirectedGame.java:57)
at com.dui.DuiGame.create (DuiGame.java:20)
at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged (AndroidGraphics.java:311)
at android.opengl.GLSurfaceView$GLThread.guardedRun (GLSurfaceView.java:1528)
at android.opengl.GLSurfaceView$GLThread.run (GLSurfaceView.java:1249)
Here is my setScreen method:
public void setScreen(AbstractGameScreen screen, ScreenTransition screenTransition) {
int w = Gdx.graphics.getWidth();
int h = Gdx.graphics.getHeight();
if (!init) {
GLFrameBuffer.FrameBufferBuilder frameBufferBuilder = new GLFrameBuffer.FrameBufferBuilder(w, h);
frameBufferBuilder.addColorTextureAttachment(GL30.GL_RGB8, GL30.GL_RGB, GL30.GL_UNSIGNED_BYTE);
currFbo = frameBufferBuilder.build();
nextFbo = frameBufferBuilder.build();
batch = new SpriteBatch();
init = true;
}
// start new transition
nextScreen = screen;
nextScreen.show(); // activate next screen
nextScreen.resize(w, h);
nextScreen.render(0); // let next screen update() once
if (currScreen != null) currScreen.pause();
nextScreen.pause();
Gdx.input.setInputProcessor(null); // disable input
this.screenTransition = screenTransition;
t = 0;
}
In libgdx news page there is example for building a custom FrameBuffer, but I'm not sure if I implement it correctly?
Can some one give me solution for my problem ?
Thanks
I'm using this for creating a BitmapFont:
Public class MyBitmapFont implements Screen{
public MyBitmapFont(){
font = new BitmapFont();
FreeTypeFontGenerator generator = new
FreeTypeFontGenerator(Gdx.files.internal("font.ttf"));
FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
parameter.size = 10;
font.setColor(Color.BLACK);
generator.dispose();
}
}
When I'm using in another Screen this.setScreen(new MyBitmapFont()) to switch in MyBitmapFont Screen it needs round about 3 seconds to load this Screen. Is there any efficient solution?
First of all, you're not creating BitmapFont from FreeTypeFontGenerator.
Generate font from FreeTypeFontGenerator :
BitmapFont font = generator.generateFont(parameter);
instead of by using BitmapFont default constructor
font = new BitmapFont();
If you notice some delay, use AssetManager and load all your assets (texture, fonts, sound...) asynchronously and get your resource form assetmanager whenever you needed.
Check this answer that explain font loading to AssetManager using .ttf file.
I just started using Rajawali and the Cardboard SDK (the integration that you can find in Rajawali’s repository). Based on the examples provided (loaders) in the repository and following the instructions to set up a new project I have created an example where I create a sphere (and attach a texture to it) and load an OBJ file, the odd thing is that I can actually see the sphere and the texture but not the OBJ object. I created a similar example where the difference just resides on the class that I’m extending, in one example I extend the RajawaliRender class (in this one I see the OBJ file) and in the other I extend the RajawaliCarboardRender. I would really appreciate if you can give a hand or provide me an example because I’m stuck and I have tried everything I can think of.
This is the content of my initScene method in both examples:
public void initScene(){
directionalLight = new DirectionalLight(1f, .2f, -1.0f);
directionalLight.setColor(1.0f, 1.0f, 1.0f);
directionalLight.setPower(2);
getCurrentScene().addLight(directionalLight);
Material material = new Material();
material.enableLighting(true);
material.setDiffuseMethod(new DiffuseMethod.Lambert());
material.setColor(0);
Texture earthTexture = new Texture("Earth", R.drawable.earthtruecolor_nasa_big);
try{
material.addTexture(earthTexture);
} catch (ATexture.TextureException error){
Log.d("DEBUG", "TEXTURE ERROR");
}
earthSphere = new Sphere(1, 24, 24);
earthSphere.setMaterial(material);
getCurrentScene().addChild(earthSphere);
getCurrentCamera().setZ(14.2f);
final LoaderOBJ loaderOBJ = new LoaderOBJ(mContext.getResources(), mTextureManager, R.raw.multiobjects_obj);
loadModel(loaderOBJ, this, R.raw.multiobjects_obj);
}
I have recently been modifying Grafika's TextureMovieEncoder to create a recording of what I displayed onscreen: two Sprite2ds which are overlapping. Using the CameraCaptureActivity example as a reference point, I effectively ported what I created for my rendering thread into the TextureMovieEncoder but the output is jagged lines across the screen. I think I understand what's wrong, but I don't know how to fix it:
Some code:
private void prepareEncoder(EGLContext sharedContext, int width, int height, int bitRate,
File outputFile) {
try {
mVideoEncoder = new VideoEncoderCore(width, height, bitRate, outputFile);
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
mEglCore = new EglCore(sharedContext, EglCore.FLAG_RECORDABLE);
mInputWindowSurface = new WindowSurface(mEglCore, mVideoEncoder.getInputSurface(), true);
mInputWindowSurface.makeCurrent();
textureProgram = new Texture2dProgram(Texture2dProgram.ProgramType.TEXTURE_EXT);
backgroundDrawable = new Drawable2d(Drawable2d.Prefab.RECTANGLE);
backgroundRect = new Sprite2d(backgroundDrawable);
frontDrawable = new Drawable2d(Drawable2d.Prefab.RECTANGLE);
frontRect = new Sprite2d(frontDrawable);
backgroundRect.setTexture(backTextureId);
frontRect.setTexture(frontTextureId);
updateGeometry();
}
private void handleFrameAvailable(Transform transform, long timestampNanos) {
if (VERBOSE) Log.d(TAG, "handleFrameAvailable tr=" + transform);
mVideoEncoder.drainEncoder(false);
backgroundRect.draw(textureProgram, transform.movieMatrix);
frontRect.draw(textureProgram, transform.cameraMatrix);
mInputWindowSurface.setPresentationTime(timestampNanos);
mInputWindowSurface.swapBuffers();
}
I think the problem comes down to my lack of understanding of how to establish the right projection onto the WindowSurface for the VideoEncoder. In the Grafika example, FullFrameRect is used, which is easier since you can just use the identity matrix to stretch a given texture to the surface area. However, since I want to create the overlapping effect, I needed to use Sprite2d. Is the problem the shared EGLContext? Do I need to create a new one so that I can set the viewport to match the WindowSurface size? A bit lost on where to go from here.
Turns out the functionality of the code above was fine. The problem was the interaction between the TextureEncoder and the calling parent.
I was initializing the member variables backTextureId and frontTextureId after prepareEncoder and it was therefore recording garbage data into the output.