I am having a weird issue with just loading my assets, using the assetManager. My assetManager is a separate class I made to make everything shorter and more neat. My Asset class isn't static. I have all the assets loaded in a non static assetDescriptor.
I load my splash screen which in tern loads all my assets while that is displaying. when I call the other screen the assets I have loaded can not be loaded and causes my game to crash. The splash screen does load but when it assigns a new screen it crashes.
I have spent 2 days on this issue. trying more then 15 variations. To no prevail.
My error message is:
com.badlogic.gdx.utils.GdxRuntimeException: Asset not loaded: stuff.png
at com.badlogic.gdx.assets.AssetManager.get(AssetManager.java:144)
at com.badlogic.gdx.assets.AssetManager.get(AssetManager.java:167)
at com.nectar.pewdybird.mainMenu.<init>(mainMenu.java:71)
at com.nectar.pewdybird.pewdyBird.render(pewdyBird.java:68)
at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(AndroidGraphics.java:459)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1523)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
Splash.class:
public Assets assets;
public void create(){
assets = new Assets();
assets.load();
}
public void render(){
if(assets.update()) {
setScreen(new mainMenu(this));
dispose();
} else {
//Splash Screen
gl.glClearColor(0,0,0,1);
gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
//Draws SplashScreen
batch.end();
}
}
public void dispose(){
this.screen.dispose();
this.batch.dispose();
}
mainMenu.class
public Assets assets;
private Texture Stuff;
public mainMenu(Splash game){
assets = game.assets;
Stuff = game.assets.manager.get(game.assets.stuff);
}
Asset.class
public AssetManager manager = new AssetManager(new InternalFileHandleResolver());
public final AssetDescriptor<Texture> stuff =
new AssetDescriptor<Texture>("stuff.png", Texture.class);
public void load(){
manager.load(stuff);
//12 More loads
manager.finishLoading();
}
public boolean update(){
return manager.update();
}
Thank you for reading and possibly helping with my maybe simple issue.
Look at your mainMenu class. You're creating a new Assets object, that don't have any asset so instead of creating a new Assets object use Assets object of Splash because you loaded assets on that object.
public Assets assets;
public Texture Stuff;
public mainMenu(){
assets = new Assets(); // why are you creating new Assets here
Stuff = assets.manager.get(assets.stuff);
}
Actually you're creating object of mainMenu by using parameterised constructor in Splash class
public mainMenu(Splash splash){
assets = splash.assets; // instead of creating new take reference of Splash class assets
Stuff = assets.manager.get(assets.stuff);
}
Related
public static AssetManager assets = new AssetManager(); should be avoided, however how do I handle an AssetManager in multiple screens? Is this a good solution?
public class myGame {
assetMananger manager = new AssetManager();
...
public assetManager getAssetMananger(){
return manager;
}
}
public class GameScreen implements Screen{
private AssetManager manager;
public GameScreen(myGame game){
manager = game.getManager();
}
public void render(){
manager.load(...);
}
Gdx.app.getApplicationListener() return ApplicationListener instance. You can typecast to your implemented class and then easily access any method or data member of that class.
In this way :
((GdxTest)Gdx.app.getApplicationListener()).assets // <-- You can use from where you want in your project.
ApplicationListener implemented class :
public class GdxTest extends ApplicationAdapter {
public Assets assets;
#Override
public void create() {
assets= new Assets();
}
....
#Override
public void dispose() {
assets.dispose();
}
}
Assets class that handle all assets/resources of Game
public class Assets implements Disposable {
public AssetManager assetManager;
public Assets(){
assetManager=new AssetManager();
}
...
#Override
public void dispose() {
assetManager.dispose();
}
}
Either load all resources in create() method and show splash screen while all your data are loading to AssetManager. (best way for small project)
else for big projects having lots of resources unload unnecessary resources -> load new resources, while loading show loading screen to user.
My approach is always like this:-
Create my own manager class that receive instance if AssetsManager and load all game assets when game is initially loaded
public class Assets implements Disposable{
public static final Assets instance = new Assets();
private AssetManager manager;
// Individual assets
public PlayerAssets playerAssets;
private Assets(){}
public void init(AssetManager manager){
this.manager = manager;
manager.load(..);
manager.finishLoading();
TextureAtlas atlas = manager.get(..);
playerAssets = new PlayerAssets(atlas);
}
public void dispose(){
manager.dispose();
}
/** Sample Inner class for catching loaded game assets */
public PlayerAssets{
public final AtlasRegion legs;
PlayerAssets(TextureAtlas atlas){
legs = atlas.find(..);
}
}
}
On your game class you load all game assets.
public class MyGame extends Game {
#Override
public void create(){
Assets.instance.init(new AssetManager()); // loading your resources
setScreen(new GameScreen());
}
}
Update from the comment below
Disposing your assets. You might want to create an abstract class for all your screen as follows
public abstract class AbstractScreen implements Screen{
protected Game game;
public AbstractScreen(Game game){
this.game = game;
}
}
. . . . . .
public void dispose(){
Assets.instance.dispose();
}
Then all of your Screens will extend this class. eg
public class MenuScreen extends AbstractScreen {
public MenuScreen(Game game){
super(game);
}
}
Calling screen instance dispose method will dispose all of the resources,
you can override it for places where you might prefer different behaviour
eg
#everride
public void dispose(){
// super.dispose();
// Release other screen resources
}
Where to call screen dispose is definitely up to you.
Also you might want to show loading screen when you load the assets to avoid blank screen due to loading delays
If you override dispose as above disposing a screen wont dispose the assets
Here is my OOP setup:
Class MainGame extends Game:
...
public void create () {
assets = new Assets(); // my custom Assets object (constructor creates manager and AssetDescriptors
assets.load(); // loads Asset Descriptors into manager
assets.getManager().finishLoading();
batch = new SpriteBatch();
setScreen(new PlayScreen(this, assets));
}
...
public void dispose () {
assets.dispose(); // disposes asset manager
super.dispose();
batch.dispose();
}
Class PlayScreen implements Screen:
public PlayScreen(MainGame game, Assets assets) {
this.assets = assets;
this.game = game;
background = assets.getManager().get(assets.getBackground());
hero = new HeroSprite(290, 1100, this, assets);
// Create Game camera and Hub also
}
public void render(float delta) {
// Clear screen
// Use game batch to draw to screen
}
public void dispose() {
assets.dispose();
}
Class HeroSprite:
public HeroSprite(int x, int y, PlayScreen screen, Assets assets){
this.assets = assets;
this.screen = screen;
// Animation Textures
heroWalking = assets.getManager().get(assets.getWalking()); // This is an Asset Descriptor
walkAnime = new Animation(heroWalking) // my own custom animation class which takes the spritesheet and returns the appropriate frames
...
}
// This does not contain a dispose method
Sorr if there's a lot of code there I tried to minimize as much as possible. My main question is if I am disposing correctly?
It seems ok, my game runs fine. But when I quit the game and re-enter a black screen shows. This happens both on Desktop and Android.
A solution that works is to clear the memory on Android using Super Cleaner App. Since it's a memory issue I figures it has something to do with me disposing incorrectly.
EDIT : Revealing my Assets Class
public class Assets {
private AssetManager manager;
private AssetDescriptor<Texture> background;
private AssetDescriptor<Texture> wood;
public AssetManager getManager() {
return manager;
}
public AssetDescriptor<Texture> getBackground() {
return background;
}
public AssetDescriptor<Texture> getWood() {
return hero;
}
public Assets(){
manager = new AssetManager();
background = new AssetDescriptor<Texture>("textures/static/bg.png", Texture.class);
hero = new AssetDescriptor<Texture>("textures/static/hero.png", Texture.class);
...
}
public void load(){
manager.load(background);
manager.load(hero);
...
}
public void dispose(){
manager.dispose();
}
}
Screen.dispose() does not get called automatically, you should manually call dispose when you exit a screen and not needing the assets anymore. But obviously when you need them again you need to load them again and you need a new AssetManager for that. So if your assets won't take up that much you should just keep it in memory.
On exit however you need to dispose. Game.dispose() does get called automatically. Here you should call getScreen().dispose() and have everything needing disposing in the dispose() method of the effective Screen.
Since currently it does not look like you are disposing between screens it might be because you have a static AssetManager, you should show your Assets() class.
So I start to try to do some game in java with libgdx, and I am trying to use the AssetsManager. but it keeps giving an error. I will put the code (I will try to resume the code) and the output.
The game goes through the loading screen fine but when it reaches the game screen it stops and gives an error, I do believe it's because the assets.
If someone knows why I am getting this error.
DesktopLauncher.java
public class DesktopLauncher {
public static void main (String[] arg) {
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
new LwjglApplication(new pressme(), config);
}
}
pressme.java
public class pressme extends Game {
LoadingScreen loadingscreen;
AssetsManager assetsmanager;
Assets assets;
#Override
public void create() {
assets = new Assets();
assetsmanager = new AssetsManager();
assetsmanager.load();
assets.other();
loadingscreen = new LoadingScreen(this);
setScreen(loadingscreen);
}
}
LoadingScreen.java
public class LoadingScreen implements Screen {
Assets assets;
AssetsManager assetsmanager;
private final pressme game;
public GameScreen game_screen;
public LoadingScreen(final pressme game){
assets = new Assets();
assetsmanager = new AssetsManager();
this.game = game;
}
#Override
public void show() {
assetsmanager.load();
}
private void update(float delta){
System.out.println(progress);
if(assetsmanager.manager.update()) {
game.setScreen(new GameScreen(game));
}
progress = assetsmanager.manager.getProgress();
}
}
GameScreen.java
public class GameScreen implements Screen {
pressme game;
Assets assets;
AssetsManager assetsmanager;
public GameScreen(pressme game){
this.game = game;
assets = new Assets();
assetsmanager = new AssetsManager();
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor( 0.5F, 0.5F, 0.5F, 0.5F);
Gdx.gl.glClear( GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT );
camera.update();
generalUpdate(touch, camera);
batch.setProjectionMatrix(camera.combined);
assets.load();
batch.begin();
batch.draw(assets.back, 0, 0);
batch.end();
}
}
Assets.java
public class Assets {
AssetsManager assetsmanager;
public Sprite back;
public void load(){
assetsmanager = new AssetsManager();
assetsmanager.load();
back = new Sprite(assetsmanager.manager.get(assetsmanager.back, Texture.class));
}
}
AssetsManager.java
public class AssetsManager {
public AssetManager manager = new AssetManager();
public String back = "back.png";
public void load(){
manager.load(back, Texture.class);
}
}
Output
LOADINGGG
0.0
0.0
0.015151516
0.015151516
0.030303031
.
.
.
0.969697
0.9848485
0.9848485
Exception in thread "LWJGL Application" java.lang.NullPointerException
at com.badlogic.gdx.graphics.g2d.SpriteBatch.draw(SpriteBatch.java:586)
at com.david.pressme.GameScreen.render(GameScreen.java:244)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:223)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:124)
EDIT
RC Thank you for the tip
So After I put the "assets.load()" still with some error. I dont know if the "assets.load()" it is on the right place
LOADINGGG
0.0
0.0
0.015151516
0.015151516
0.030303031
.
.
.
0.969697
0.969697
0.9848485
0.9848485
Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException: Asset not loaded: back.png
at com.badlogic.gdx.assets.AssetManager.get(AssetManager.java:144)
at com.david.pressme.Assets.load(Assets.java:254)
at com.david.pressme.GameScreen.render(GameScreen.java:172)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:223)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:124)
EDIT2
RC, Spylot ty for the tips, it was what you said
So its resolved, i puting
"assets.load" on "public void show()"
this way when the screen its load he loads the assest on the begin, and i take it off from the
"public void render(){"
because he was always loading the assests because its a loop (I think so), then on
"Assets.java public load(){" i put "assetsmanager.load();"
Thanks Rc for the tips. Then on the same place I put the
"assetsmanager.manager.finishLoading();"
so it loads all assets before do something. Thank you spylot for the tip.
Thank you all who help or try to help much appreciate.
You should be aware that when you're loading assets, you cannot use them until you call finishLoading. finishLoading blocks all calls trying to grab onto the asset until they are fully loaded in the memory.
I highly suggest you to read the AssetManager API.
So in short, after each time you use load() call, you should finish it off using manager.finishLoading()
i'm begginer programmer and need some help. I'm using eclipse and libgdx. I created a project. When i try to load my file "background.png", i get this error:
"Exception in thread "LWJGL Application"
com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load file:
badlogic.jpg"
. Oh wait, did you see that ? My file's name is "background.png", and error tells me that couldn't load "badlogic.jpg" I searched many forums but didnt find the solution cuz i think im the only one who is getting this error. And dont worry i have written my code correctly.`
This is GameScreen method
Reaction game;
OrthographicCamera camera;
SpriteBatch batch;
public GameScreen(Reaction game){
this.game = game;
camera=new OrthographicCamera();
camera.setToOrtho(true,1920,1080);
batch = new SpriteBatch();
}
#Override
public void show() {
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0.95F, 0.95F, 0.95F, 0.95F);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(Assets.sprite_back,0,0);
batch.end();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
}
this is Assets method
public static Texture texture_back;
public static Sprite sprite_back;
public static void load(){
texture_back= new Texture(Gdx.files.internal("data/background.png"));
texture_back.setFilter(TextureFilter.Linear,TextureFilter.Linear);
sprite_back=new Sprite(texture_back);
sprite_back.setFlip(false, true);
}
}
and this is main game method
public GameScreen game_screen;
#Override
public void create() {
Assets.load();
game_screen = new GameScreen(this);
setScreen(game_screen);
}
}
I'm sure my code is correct cuz i made it with getting help from youtube videos. Please help me, im stuck...
More information: my files are linked, when i put my png file to assets/data folder it appears in desktop's assets too, and eclipse also automatically refresh files and when i manage files on eclipse, it happens to real project folder in my desktop, i tried to make it for you easier, i wish it helps.
I have a very simple Libgdx game, its my first one, and in this game i have a main java file(obviously). This file extends Game and looks like this.
package com.jawdroppergames.penalty;
import com.badlogic.gdx.Game;
public class Penalty extends Game{
public MainGame main_screen;
#Override
public void create(){
Assets.load();
main_screen = new MainGame(this);
setScreen(main_screen);
}
}
And in MainGame.java
private Penalty maingame;
public MainGame(Penalty game){
this.maingame = game;
camera = new OrthographicCamera();
camera.setToOrtho(true,1080,1920);
main_batch = new SpriteBatch();
ball_batch = new SpriteBatch();
}
as well as more code obviously
This works perfectly and opens the MainGame class. Now what i want to do is open ANOTHER screen from within MainGame. Ive tried using the same code and changing the necessary names of files etc, and this calls the show method but doesnt render the actual screen, it calls show() but not render(). Any help?
oh, and MainScreen does extend Game
this should work for u..
game.setScreen(new PlayScreen(game));//playscreen is the another screen
and why are you using two sprite batches, you should avoid this.