Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to implement tmx parsing for gdevelop - need help on animated tiles #76

Open
blurymind opened this issue Feb 23, 2020 · 22 comments

Comments

@blurymind
Copy link
Contributor

blurymind commented Feb 23, 2020

Hi, I am one of the devs on gdevelop and we are currently looking into adding support for tilemaps and specifically for tiled tile support

I understand that this is a "in progress" feature on this project and I was wondering if you have made any progress on it.
I couldn't find any test branches or commits trying to add tmx parsing.

Currently we are trying to evaluate whether to use this library vs another one and so far I have found the following pros and cons:

pros:

  • pixi-tilemap is actively developed
  • designed to be performant
  • battle tested on another game engine (rpg maker mv)

cons:

  • It does not support isometric maps or anything other than top down (do you plan on adding support for other map types?)
  • I have to parse the tmx data myself and turn it into something pixi-tilemap will like (i made some progress on that, but can you share any of your progress if you have some?)
  • The way it handles animated tiles is very tied with the image resource that the tileset is using, leading to a real challenge in parsing them properly

Please correct me if you have anything on these points.

In any ways, I am interested to get some feedback from the devs here on potentially making some progress in parsing tmx data properly to this renderer.
Here is the issue at gdevelop's git
4ian/GDevelop#503

I will also publish my test project, which so far can parse most of the tmx data to pixi-tilemap but only for topdown maps and with animated tiles having issues
objectsRendered

Right now I am struggling with how pixi-tilemap requires animated tiles to always have their frame laid one next to each other in the correct order, where as tmx data that comes from tiled lets the developer arrange frames in any order and take them from any position on the atlas. This leads to problems like this:
neckPainTiles

with an atlas like
painAtlas

And this is what pixi-tilemap is expecting to get
https://github.com/Alan01252/pixi-tilemap-tutorial/blob/master/imgs/imgBuildings.png

Do you have any ideas on ways to get around that?
I am getting really close to having the entire tmx data properly parsed to pixi-tilemap with this being the last stumbling block

One idea I had is to make my parser create another tilemap image resource for animated ones, but that could potentially lead to zordering problems

@ivanpopelyshev
Copy link
Collaborator

ivanpopelyshev commented Feb 23, 2020

You're right on point.

I coded it for RpgMaker MV which had only water animation and waterfall animation. I did not even think about tiled animations.

In v5 you can easily write your own mesh generator, either by modifying pixi-tilemap either by using https://pixijs.io/examples/#/mesh-and-shaders/triangle-textured.js + your own multitexture algorithm.

Unfortunately, I'm taking a break for pixi for a month so I cant help you with coding new shader animations. I think you'll need extra uniform data for them, to store used textures in uniform objects as well. Or maybe store texture coords in another texture that will be read in vertex shader. You can try ping @finscn or other people who are proficient with shaders and meshes in our community. I can also invite you to pixijs slack so you find someone there.

My excuse is that I'm working on vector graphics, and its more pressing for people than tilemaps/2.5d stuff/other things. There are no good vector graphics renderers for WebGL. At all. No one implemented SVG/SWF graphics for WebGL so far, well, there are small implementations but they all look like shit or eat too much memory/performance. For this task I need whole my coding focus.

If you dont find anyone , you can make support animations on high-level for some time - just rebuild the tilemap chunk every frame if it has animated parts. In case you will survive till 14th of March or so, we will talk about Tiled animations - I myself cant make all the examples for it, so you have to provide them. Same as for RMMV - i didnt code everything, I just re-coded tilemap when everything else was working :) I have like 10 plugins for pixi so its difficult for me to setup all kinds of apps for testing.

@ivanpopelyshev
Copy link
Collaborator

^^^ comment was updated.

@ivanpopelyshev
Copy link
Collaborator

Check your gmail for slack invitation

@blurymind
Copy link
Contributor Author

blurymind commented Feb 23, 2020

Thank you for clarifying and for the invite. On that I will try to put up my example project today with hope that others here will hop on it and help me fix it.

I tried using pixi's animatedsprite class for animated tiles (kind of a cop out), but it ends up being outside of the tilemap and their zorder is wrong
zOrdering

@ivanpopelyshev
Copy link
Collaborator

I just hope you are patient enough :) That "issue" exists for 4 years: #3 , I just didnt have a person who could help me with setting up everything ;)

@eXponenta
Copy link
Contributor

@blurymind why you use TMX when Tiled support json for export/import?
I implement naive importer based on json
https://exponenta.github.io/pixi-tiled/demo/tilemap.html

@blurymind
Copy link
Contributor Author

@eXponenta is your importer using pixi-tilemap for rendering? If so does it support animated tiles? I am using json file format for my implementation too

@blurymind
Copy link
Contributor Author

blurymind commented Feb 24, 2020

@ivanpopelyshev is there a way to have one animated tile have a different number of frames from another animated tile? How does one manage incrementing frame number of each animated tile within the limits of that tile's animation length?

say I have a tree with 2 frames of animation and a waterfall with 5 frames of animation. How does pixi-tilemap handle looping both?

One tutorial I saw suggests that it cant handle that scenario, since you have one frame offset value for all animated tiles 😨

on here
https://github.com/Alan01252/pixi-tilemap-tutorial
There is this line called on each update
app.renderer.plugins.tilemap.tileAnim[0] = tileAnim * 144;

        if (tick > tileAnimationTick) {
            tileAnimationTick = tick + 300;

            tileAnim = tileAnim + 1;
            if (tileAnim >= 3) {

                tileAnim = 0;
            }
        }

My fear is that tileAnim[0] is x offset of all animated tiles and tileAnim[1] is the y offset. Is there a way to limit incrementing/looping on a per animated tile basis?

Without that my tree is going to show frames from other sprites if I want my waterfal to have all of its 5 frames

@ivanpopelyshev
Copy link
Collaborator

You've got it, its exactly that. If you want something else - please explain it in detail, we can discuss it, though i will only be able to code it in march-april

@ivanpopelyshev
Copy link
Collaborator

According to @englercj gl-tiled has animated tiles support, maybe you can use it for now https://www.html5gamedevs.com/topic/44753-tile-rendering-performance/?do=findComment&comment=248820 . Though I'm not sure about performance of that shader on slow devices.

@blurymind
Copy link
Contributor Author

blurymind commented Feb 24, 2020

@ivanpopelyshev thank you for confirming. Do you think I could apply some simple way to clamp a tile's frame cycle? Like for example if we could pass an extra couple of parameters to addFrame like so
groundTiles.addFrame(texture, x, y, animateX, animateY, animateXClip, animateYClip);
If animateX is greater than animateXClip- set animateX to 0 for that tile...

Edit: can gl-tiled be used with pixi? Gdevelop is limited to using pixijs for all rendering atm

@ivanpopelyshev
Copy link
Collaborator

That might be good idea, we can pass it to vertex shader and do a division there.

Oh, i forgot that gl-tiled is not a pixi plugin :(

@blurymind
Copy link
Contributor Author

blurymind commented Feb 24, 2020

That might be good idea, we can pass it to vertex shader and do a division there.

Is that something that has to happen in
https://github.com/pixijs/pixi-tilemap/blob/f94fb15af88b12f8dcb78881ff5a7f13f0f868ea/src/RectTileLayer.ts#L41
something like animX % animXClip when animClipX is passed
My idea is to let pixi-tilemap handle the cycling of x/y, so instead of this

            tileAnim = tileAnim + 1;
            if (tileAnim >= 3) { // extremely ugly approach imo

                tileAnim = 0;
            }
app.renderer.plugins.tilemap.tileAnim[0] = tileAnim * tileWidth

we can just do
app.renderer.plugins.tilemap.tileAnim[0] += tileWidth;

Actually I wonder if I can just apply a modulo on animx before passing it to pixi-tilemap, that way I dont need to even submit a PR here. I still need to restitch the texture for the other problem though
groundTiles.addFrame(texture, x, y, animateX % tile.animation.length, 0)

Oh, i forgot that gl-tiled is not a pixi plugin :(

Yes unfortunately. It would be nice if we can get pixi-tilemap to the same level though :)

@blurymind
Copy link
Contributor Author

blurymind commented Feb 24, 2020

ah I spoke too early, I will indeed have to pass it to the shader somehow - trying to figure out how atm.
Might do a PR if I manage to get it working

Where is the fragment shader getting its attributes fed from? Are they in some buffer?
I know how to do the shaderpart, just not sure how to pass each tile the modulate value

When I try to add my new value to arr[sz++] =... , the whole shader gets skewed. I think some obscure value somewhere needs to be updated

@ivanpopelyshev
Copy link
Collaborator

ivanpopelyshev commented Feb 24, 2020

In the same values as animX and animY, i suppose :) I can do it tomorrow. Yeah, size needs to be addressed in multiple parts. Just adding something like arr[sz++] = animX + animLoop * 1024 then decoding it in shader should be easier ;)

for API it also can help - secret feature of pixi-tilemap, pass loop as multiple of 1024 for animX.

@blurymind
Copy link
Contributor Author

blurymind commented Feb 24, 2020

In the same values as animX and animY, i suppose :) I can do it tomorrow. Yeah, size needs to be addressed in multiple parts. Just adding something like arr[sz++] = animX + animLoop * 1024 then decoding it in shader should be easier ;)

for API it also can help - secret feature of pixi-tilemap, pass loop as multiple of 1024 for animX.

I managed to get it to the shader
Can you give it a try tomorrow? If you dont have time I will keep going :)
My shader knowledge is actually kind of limited
I tried doing this
vec2 anim = aAnim * vec2(mod(animationFrame.x,aFramesX),animationFrame.y);

Edit2: This formula actually works!, I just wasnt feeding it with tiled data that takes into account the other problem that can be resolved by re-stitching the texture into strips for animated tiles

               TILEMAP.addFrame(
                      TILESET.getFrame(tileUid),
                      xPos,
                      yPos,
                      1,
                      0,
                      tileData.animation.length * tileWidth
                    );

does the trick, but I wonder if we should do the same for y. Technically aFramesX is the total width of the animation strip that I am feeding to pixi-tilemap. The modulo makes sure it's cycling. But what if its a vertical strip? This workaround is just to appease tiled parsing so as to render animated tiles with different frame counts but it only partially resolves the problem. Its not taking into account the fact that frames can exist anywhere on the tilemap.

Ideally it would be awesome if we could feed to the shader an array of tileIds and use that for animation. It would completely solve the issues

@ivanpopelyshev
Copy link
Collaborator

ivanpopelyshev commented Feb 25, 2020

aAnim * mod(animationFrame, vec2(aFramesX, aFramesY))

also dont forget about a case where aFramesX or aFramesY is zero, default mode that pixi-tilemap works.

Yes, storing tile types in uniforms or textures , but thats different level of hack, I hope you understand that I dont have time for it before enough people actually need it. I can make that mod hack you are proposing as soon as i have enough free coding time, but uniformed tileId's are more difficult and require more focus.

@blurymind
Copy link
Contributor Author

blurymind commented Feb 25, 2020

I can do a PR for the mod hack if you like :)

The proper uniform tileIds one is what we need to do proper tiled format parsing though.
I still have to restitch the entire tilemap when I load it from an image - or at least thats what I will try to do to get around the other problem that uniformed tileIds would solve

@blurymind
Copy link
Contributor Author

blurymind commented Feb 25, 2020

I created a pr to the pixi4 branch due to pixi4 being currently used by gdevelop
#77

if the PR gets merged, I will cherrypick and refactor (if needed) and do a PR for master branch (pixi5)

@blurymind
Copy link
Contributor Author

blurymind commented Feb 26, 2020

@eXponenta we will review using your library VS using pixi-tilemap and a bunch of other libraries that do this for gdevelop soon.

I plan to release a demo pixi project that compares them and having other devs help me decide.
To be fair if you plan to add pixi-tilemap renderer to your parser,you will encounter the exact same issues with animated tiles as me. I already made a parser that sorts out all the other data and feeds it to pixi-tilemap, so you might be interested in having a look at it once I release the demo example project :)

@josiahbryan
Copy link

@blurymind did you ever release your demo example project? I'm coming up on a pixi project that I'm struggling to find a good way to take Tiled (TMX) maps > render in PixiJS - all repos I find are either old, outdated, or not working with Pixi since v6+ - any guidance or pointers to what you used?

I did a pixijs app "back in the day" (~2019, around v4 time - sleepcatgame.com if you're curious) but I rendered all the tiles manually - and that was painful. Would love to use a tile editor like the Tiled project to make the levels this time with TMX (or the json equiv).

Or...as I fear, is this method of rendering (tiled sprites) falling "out of favor" with graphics moving more towards 3D (what with https://www.babylonjs.com/ being so awseome, etc)?

@ivanpopelyshev
Copy link
Collaborator

Im implementing new animation methods for tilemap, will be released in next version for pixijs 7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants