@Gjallar
The loader is also responsible for two different things:
- loading images
- storing & supplying images
The latter should rather be extracted into a separate class. Restricting responsibilities is a good thing.
@Gjallar
The loader is also responsible for two different things:
The latter should rather be extracted into a separate class. Restricting responsibilities is a good thing.
Thanks a ton guys.
As I said, I’m quite new to Java. I started learning it at the same time as i started with my diploma. So yeah… when I look at the code now all I can do is shake my head an giggle. At the very beginning every single one of my button-objects loaded the spritesheet, seperated it into the single sprites and finally picked the one the button uses… and all of that happened in the constructor.
I’ve developed “perfectionism” in the last months which lead to the fact that I haven’t finished a single project yet (excluding the diploma). I always felt the urge to rewrite everything. So now I pretty much HATE the code I wrote for my diploma, I couldn’t start all over because there is a deadline (today in fact) and I can finally call it done and NEVER EVER touch this code again
Last question… If i should write the loader in a private way, wouldn’t that mean that every class that uses an image would have to create it’s own object of the loader? Since I’m doing the loading in the constructor, wouldn’t that mean that it would load all the images again, for every object I create from it?
Image loading probably happens once at startup or for level changing maybe. So you only have one place. And there shouldn’t be that many places where you actually need the images. Split your class.
Do not load in the constructor. Do not hardcode images names inside the loader.
Keep on doing.
check.
I’d say that “a large OO entity system” is bad even from a theoretical stand-point.
What we really need is an image of a bunch of really old men sat on a park bench waving their sticks at passing youth. “When I were a lad, all this were static!”
For the OP:
I’ve been using, for the last 10 years or so, a system of resources that is basically a Map<String, Resource>. Everything that is anything in my games is a Resource with a unique name. Every sprite image, every alien definition, every tile definition, everything - all go into the Map. They can then all reference each other by name. I have the notion of “unnamed” resources but these are actually just given an autogenerated name instead at the point they are shoved into the map.
Cas
Having loading the map right at app start up from a simple ObjectInputStream, I then iterate through each entry, telling each Resource to “create” itself. This is where it goes through its internal data referencing other Resources by name and resolves them into other Resources, and also the point at which I “upload” things like textures to OpenGL and sounds to OpenAL.
The act of simply attempting to retrieve a Resource from the map by its name automatically causes it to be “created”; thus you can get any Resource at any time and all its dependent Resources will be automatically “created” ensuring that you’ve always got a completely consistent set of objects. Circular dependencies are managed simply by preventing a Resource from being “created” twice at the same time.
Cas
In my own games, the original data is all stored in (horrors) XML, in multiple files which “include” each other. So I’ve got all my sprite data, animations, particle emitters, alien definitions, all in XML, and I have a little build tool that reads in all the xml and spits out the resulting Map of Resources as a Java object stream. (Interesting factoid: object output streams produced on the desktop are binary compatible with Android - so I’ve been able to use the very same code to do builds on the desktop and then just use the data file on Android - nice).
Cas
One extremely nifty trick I’ve used to facilitate saved games is a writeReplace() mechanism on the Resource base class which replaces actual instances of the Resource - which can be quite big, and certainly aren’t serializable a lot of the time because they contain OpenGL state - with a placeholder simply containing their name.
This means when I save a game, all the sprites and so on are serialized but simply store the reference in the Map to their animation; not the actual “animation” itself. When a saved game is deserialized, all of these references are then resolved using readResolve() on Resource to replace the names back with whatever comes out of the Resource map with that name.
Cas
Do you still do the serialisation thing for new games? Because when I ripped off / rewrote things and turned it into Rebirth I skipped all of that and haven’t really missed it. In fact it’s much nicer not to have the extra build step.
Even doing the sprite sheet generation at runtime it’s still near instantaneous to load.
Yes, I still do - it loads the map instantaneously (versus several seconds for parsing XML). The latest code I have, which is only for Android at the moment, uses annotations and a slightly better way of doing things which is faster, cleaner, and simpler.
How does Rebirth do it?
Cas
It uses annotations and a slightly better way of doing things.
It’s basically the same - parse and xml file and create resource classes by reflection / attribute mapping. The big differences are multithreading things and holding onto resources via handles rather than directly so things can be hot-reloaded while the game is running.
I’m not deploying to android though, so my xml parse time is probably a whole lot less.
Quick question,
Generally when I make my games, the entities in the massive list of entities have a method called tick() that is called in a loop from the list every step. Inside this tick method, I have the two methods that check logic and the other draws itself.
Is this okay, or should I completely separate the logic and drawing?
Still on Gjallar’s problem, this tutorial may helps you to figure it out. Take a look on Kev’s SpriteFactory.
@SkyAphid: better separate them, easier to debug.
I have a tick() method, which is game logic, and an update() method, which updates sprite positions and special effects. tick() may be called several times between an update() if rendering is going slowly.
Neither method does any drawing. I do all drawing after everything has been ticked and updated by telling the sprite engine to go render itself. In other words, a typical game loop looks something like:
while (running) {
tickEverything();
updateEverything();
render();
}
Cas
So for example, your entity would probably have a getSprite() type deal where it checks the actions and what not and returns it based on those?