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

json support #18

Merged
merged 28 commits into from May 12, 2021
Merged

json support #18

merged 28 commits into from May 12, 2021

Conversation

synchronisator
Copy link
Contributor

This PR enables json support for tiled maps.
The compare-test shows, that the test.tmx and the same map as test.json have the same output.
A user jan load a json, but decide to use the tmx strusture instead by converting it.

json_structure.puml Outdated Show resolved Hide resolved
Copy link
Contributor

@wolfenrain wolfenrain left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a quick review, few comments.

lib/src/object_group.dart Outdated Show resolved Hide resolved
lib/src/tmx_object.dart Outdated Show resolved Hide resolved
json_structure.puml Outdated Show resolved Hide resolved
lib/src/layer.dart Outdated Show resolved Hide resolved
@synchronisator synchronisator deleted the jsonsupport branch January 25, 2021 08:10
@synchronisator synchronisator restored the jsonsupport branch January 25, 2021 08:13
@luanpotter
Copy link
Member

Sorry for the long delay @synchronisator I had some harsh weeks at work. But lets get back to this as I think json support is very useful. I will re-open and address any remaining comments myself.

@luanpotter luanpotter reopened this Feb 16, 2021
@synchronisator
Copy link
Contributor Author

Sorry for the long delay @synchronisator I had some harsh weeks at work. But lets get back to this as I think json support is very useful. I will re-open and address any remaining comments myself.

I have rewritten everything, but have not yet made a new pr. Look here: https://github.com/synchronisator/tiled.dart/tree/jsonsupport

@luanpotter
Copy link
Member

@synchronisator ah sounds good! I will wait for your PR then. lmk if I can help with anything :)

@synchronisator
Copy link
Contributor Author

synchronisator commented Mar 4, 2021

Hi,
sorry for the long time not changing anything. Had much work here...
Now i try to answer all of your questions:

"computeDrawRect": "can we just move it up the data hierarchy? if not ok to put on flame_tiled"

We could add this to "tileset" like this:

  Rectangle computeDrawRect(Tile tile) {
    if (tile.image != null) {
      return Rectangle(0, 0, tile.image.width, tile.image.height);
    }
    final row = (tile.gid - firstGId) ~/ columns;
    final column = (tile.gid - firstGId) % columns;
    final x = margin + (column * (tileWidth + spacing));
    final y = margin + (row * (tileHeight + spacing));
    return Rectangle(x, y, tileWidth + spacing, tileHeight + spacing);
  }

Is this a solution you would like?

@synchronisator
Copy link
Contributor Author

synchronisator commented Mar 4, 2021

"make sure we have fallbacks so the old TMX files still work"

The old test.tmx failes with the current version of my code. This is because the tilecount is missing in the file. But the tilecount is important to create the tileMatrix.
The old Code is buggy at this point. It uses the tileWidth and tileHeight

      width = dsl.intOr('tilewidth', width);
      height = dsl.intOr('tileheight', height);

But this is wrong.

I could recreate this buggy behavior if the tileCount is not available but i dont think this is a good solution....

Edit: Hm...something is not right here... i will have a look at my tileset code again. no time now, but the code where i use tilecount is not for TileMatrix (thats in layer) but for tiles-List. I will have a deeper look later.

Edit2: ok, i got it. Sorry i was a little bit confused.
The Code

    final iterator = tilelist.iterator;
    Tile t = iterator.moveNext() ? iterator.current : Tile(-1);
    for (var i = 0; i < tileCount; ++i) {
      if(t.gid == i){
        tiles.add(t);
        if(iterator.moveNext()) {
          t = iterator.current;
        }
      }else{
        tiles.add(Tile(i));
      }
    }

is needed to add every "empty" tile to the tiles.
The file only contains the tilecount and every "not empty" tile. So it has to be filled up here.
But for that i need the tilecount.

SOLUTION:
If there is not tileCount i will use the last found GId to fill empty tiles up:

    if(tileCount == null && tilelist.isNotEmpty){
      tileCount = tilelist.last.gid;
    }

That is a hack for very old maps (older than 5 years)
Additionaly i think i found a bug in my code because my loop only go < tileCount. But the tiles include the empty 0 tile without counting it in tileCount so i had to go until <= tileCount.
I changed this. please have a look

@synchronisator
Copy link
Contributor Author

So. we reach the last three questions:

  1. uncommented Code:
    i will fix this ... soon.
  2. make sure we keep an example for the old TMX format not throwing errors
    I added it again as test_old.tmx
  3. you added a few images, is that ok in terms of licensing? ie are they all open source?
    I have the maps from three other repos on github:
    floortileset.png and tilesets_deviant_milkian_1.png are from Workadventu.re
    https://github.com/thecodingmachine/workadventure/tree/develop/maps/Lyon

isometric_grass_and_water.png is from Tiled
https://github.com/mapeditor/tiled/tree/55175d1930b98087672a2f83ac9f30ddb8fed2c4/examples

And coins.png is from flutter_tiled
https://github.com/flame-engine/flame_tiled/tree/master/example/assets/images

If the images are ok, the only open task would be to make the tests clean and without uncommented code. I will work on that in the next time.
If you have more comments please let me know.

@synchronisator
Copy link
Contributor Author

synchronisator commented Mar 18, 2021

Hi, i updated the tests.
There are 2 problems left.

  1. The computeDrawRect is moved to TileSet, but return "other" results and i have no clue why.
  2. In tmx_object_test.dart there is a test for tiledObject.isRectangle but there is no value inside the files to see if its a rectangle, and i dont know how to compute this from the polygon.

Maybe you have an idea.
Thanks

@Akida31
Copy link

Akida31 commented Mar 29, 2021

@synchronisator after testing with the TiledMapEditor, rectangles have no certain property set and no polygon/ polyline but only width and height. The width and height could be zero, that would mean that the rectangle has the size of one tile (from what i can see).
Probably it would be good to add the getter tiledObject.isRectangle so that not only the tests but also the users could use this.

The question is if isRectangle should check the polygon if it has 4 points creating a rectangle (which could be done be some math)

@synchronisator
Copy link
Contributor Author

@synchronisator after testing with the TiledMapEditor, rectangles have no certain property set and no polygon/ polyline but only width and height. The width and height could be zero, that would mean that the rectangle has the size of one tile (from what i can see).
Probably it would be good to add the getter tiledObject.isRectangle so that not only the tests but also the users could use this.

The question is if isRectangle should check the polygon if it has 4 points creating a rectangle (which could be done be some math)

@Akida31
Yes, this is exactly the thing i wrote as my second problem. I dont know how to do this check correct. From where do you have the information about "empty width/height means tilewidth/tileheight"?
Yes, math would do the "4points creating a rectangle"-job. I was not sure if this is the way i should do that. But if the others think the same way, i will calculate if its a rectangle.

@Akida31
Copy link

Akida31 commented Mar 30, 2021

I just created a map with different shapes and looked into the Json-Export-file. Probably not the cleanest way. Would be nice if you could verify that my assumptions are true.
It was an addition to your second question and I thought it would help you to hear an opinion/ some information related to the problem. If you want I could write the implementation the way I would solve that

@synchronisator
Copy link
Contributor Author

@Akida31 Thanks for your testing.
I looks like you are right. If i dont "drag a size" to a rectangle in Tiled it has a default width/height but its not tileheight/tilewidth. In my testmap i have 32x32 Tiles. But the created rectangle is 20x20. its strange.

Something similar is happening with an ellipse without dragging. here is the height 20 again without a height in the json. Maybe its a tiled default.

After a little bit of analysing. I think the rule is: If its NOT a polygon or polyline or ellipse or point it IS a rectangle.
This includes "rotated" rectangles without math calculations.

Question to all of you: Is it needed to calculate rectangles from polygons?

@synchronisator
Copy link
Contributor Author

I asked some people in the tiled discord and learned two things:

  1. This is correct: If its NOT a polygon or polyline or ellipse or point it IS a rectangle.
  2. the "defaultsize 20" is a hack in tiled to "show an object with 0 size". So i would let the size empty and will not set 20.

@spydon
Copy link
Member

spydon commented Apr 21, 2021

@synchronisator great work! How is it going, anything you need help with? :)

Once this is in we will start migrating this package to null-safety.

@synchronisator
Copy link
Contributor Author

@spydon thanks
The last thing is (I quote myself)
"The computeDrawRect is moved to TileSet, but return "other" results and i have no clue why."

If someone has any ideas on this, please comment. I have no idea what is going wrong here...

@spydon
Copy link
Member

spydon commented Apr 21, 2021

@spydon thanks
The last thing is (I quote myself)
"The computeDrawRect is moved to TileSet, but return "other" results and i have no clue why."

If someone has any ideas on this, please comment. I have no idea what is going wrong here...

Thanks for the quick reply! I'll have a look with the team.
What does it mean with "other" results btw, do you have an example?

@synchronisator
Copy link
Contributor Author

I am not at my pc right now. But I think there was a test for this method that fails now... But I am not 100% sure. Will have a look later

@synchronisator
Copy link
Contributor Author

@spydon
It is part of the parser_test.dart line 158 following
i uncommented it.

Other things:
There are 4 other TODOs in the code. Maybe someone has things to say to clear them out.

  • tile_test.dart: // TODO no default constructor on Tileset
    so the test is diffrent than before, but i think that is ok.

  • layer.dart: //TODO zstd compression not supported in dart
    There is no zstd compression in dart so i think this is ok as well

  • template.dart: // TODO is it possible to have an externel tsx here?
    I have no idea if this is possible, but i dont think so...

  • tile.dart: //TODO correct?
    A Question about json parsing and if the default is correct. This could be good to be reviewed by someone.

@luanpotter
Copy link
Member

Haven't dug deep into what each one is, but my initial 2cents:

// TODO no default constructor on Tileset
can't we just add a default constructor? no issues for me if it's needed

//TODO zstd compression not supported in dart
just leave out this feature for now

// TODO is it possible to have an externel tsx here?
just leave out this option for now

//TODO correct?
that I will take a look into the code to see what it's about haha

@luanpotter
Copy link
Member

Since this PR is so useful and so big, I think we can be a bit lenient with missing features and followups, as long as they are well documented here :)

@synchronisator
Copy link
Contributor Author

Hi,
this PR is waiting now for a long time.
What do i have to change? What do you expect happens next?
Who would approve/merge this?
Thanks

expect(
layer.tileIDMatrix[8], equals([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]));
expect(
layer.tileIDMatrix[9], equals([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor comment, these should have a trailing comma since it is split on two lines.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can do that as a followup

Copy link
Member

@luanpotter luanpotter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's merge this and address things as needed

@luanpotter luanpotter merged commit 14a87cd into flame-engine:main May 12, 2021
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

Successfully merging this pull request may close these issues.

None yet

5 participants