PurpleKingdomGames / indigo

An FP game engine for Scala.
https://indigoengine.io/
MIT License
636 stars 58 forks source link

TiledMap animations & multiple tilesets #67

Open laurensdv opened 4 years ago

laurensdv commented 4 years ago

Hi,

I have been investigating the TiledMap (JSON) example and was looking to extend it to support animated tiles defined. Two issues I encountered:

  1. I have progressed quite far with adding support for reading out the animation tag in JSON TiledMap file and generating the Animation classes and Sprites conditionally.

https://github.com/laurensdv/indigo/commit/9b0cb34e69aaf427d5cb257d472a8a0e0c5d9f8b

But to be able to display the sprites, they must be included in the assets animations. This is not trivial as far as I can tell because the JSON TiledMap must be loaded with the assets as well before being able to create the animations based on the descriptions within the JSON TiledMap.

I have been trying to make a workaround. But I don't see how I can merge it in the BootResult or the AssetCollection in the game.

https://github.com/laurensdv/helloworldindigo/blob/0e40808816879e919f94e954bfbc183e2a2ce44a/src/main/scala/MyGame.scala#L66

If only there would be a way to merge any static defined animations with those read from the JSON to include in the (bootResult.withAnimations(...)) or to register them at another point, but before setup(bootData: Unit, assetCollection: AssetCollection, dice: Dice) is called.

  1. It seems that the current implementation only reads the first TileSet included in a TileMap, is this correct? However according to the TMX and JSON spec, it could happen that there are multiple tilesets in a TileMap?

https://github.com/PurpleKingdomGames/indigo/blob/b316d0bf706046ab76956d5ad3e1f230071586df/indigo/shared/src/main/scala/indigo/shared/formats/TiledMap.scala#L118

davesmith00000 commented 4 years ago

Hi @laurensdv - help and improvements with Tiled support are extremely welcome!

However, reading your description, I think there may be some existing mechanics you perhaps haven't discovered yet that could help. If you're already found all this and I'm misunderstanding, my apologies.

The first is that you can add additional animations at the end of the setup function too, as I am here in the Cursed Pirate Demo: https://github.com/PurpleKingdomGames/indigo-examples/blob/master/demos/pirate/src/main/scala/pirate/core/InitialLoad.scala#L145

This point of this is that you can read test assets (like JSON) and processes them before your game starts.

Here's the class, you can only do it on the success branch: https://github.com/PurpleKingdomGames/indigo/blob/009b2f3a3f88f6d2fb0631dd1378fe9ba6372446/indigo/shared/src/main/scala/indigo/shared/Startup.scala#L53

The next thing is that assets can be loaded at any time, and this re-triggers the setup function to be called again meaning you can add to your animation pool as much as you like. Again I'm doing that in the cursed pirate. The game loads and shows a loading screen which kicks off a second asset load (using an event and a subsystem) which when complete gives me a change to process some JSON and add new animations.

Most unusually, I have actually written some docs about this which include a link to example code: https://indigoengine.io/docs/topics/assets#dynamic-asset-loading

Regarding your other point:

It seems that the current implementation only reads the first TileSet included in a TileMap, is this correct? However according to the TMX and JSON spec, it could happen that there are multiple tilesets in a TileMap?

Yes. The current Tiled import is horribly limited in a number of terrible ways. I implemented just enough of the spec to get a single layer of Tiled to import simple graphics since that was my use case. You'll find there's a lot of stuff like that in the existing implementation. Please don't think I'm being clever or that I know something you don't, I shamelessly did the bare minimum for my own requirements! 😅

My plan was to revisit Tiled at some point. Aside from actually supporting the whole spec, I'd like to do two things specifically:

  1. Get the importer to use Clones for better performance (this might already work, I just haven't tried it)
  2. Look at the performance. If you generate a massive map, and only show part of it on the screen, Indigo will still do all the hard work of pre-processes all the data before most of it is discarded by the renderer. Would be great if there was at least some sort of grouping and frustum culling going on for large maps. However this isn't easy because it means knowing about how the game developer is using the map and whether they've implemented cameras and so on. Needs more thought. 🤔

Hope that helps!

laurensdv commented 4 years ago

Hello,

I didn't consider the documented dynamic asset loading, because I was focusing on having everything parsed at boot time.

However, the addAnimations on the Successobject does exactly that.

animated_tiled_map

Happy to do a pull request or feel free to integrate it, but the code in my branch would need at least some unit tests on TiledMap parsing & the function that creates the Animation objects before it can be done.

Best regards, Laurens