Skip to content

Conversation

@Schnurber
Copy link
Contributor

The map should be more flexible. For some game concepts, it could be useful to change the map at runtime.
In the proposed version, you can show and hide layers.

var layer = tiles.tileMap.map.layers[1] as TileLayer;
layer.visible = false;

In addition, you can change the tile data and the cache can be updated afterwards.

layer.tileData![3,2] = const Gid(0, Flips.defaults());
tiles.tileMap.update();

See small example

Copy link
Member

@spydon spydon left a comment

Choose a reason for hiding this comment

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

Looks good to me, just a few fixes that needs to be done.

Copy link
Member

@spydon spydon left a comment

Choose a reason for hiding this comment

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

Looks good! But you haven't run flutter format on it.

@spydon
Copy link
Member

spydon commented Jan 18, 2022

@lfraker could you review this small change too? :)

@Schnurber
Copy link
Contributor Author

OK!

Copy link
Member

@spydon spydon left a comment

Choose a reason for hiding this comment

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

It would be good to have a function that updates the visibilty of a layer and then calls refreshCache, because right now it will be a bit confusing for the user that doesn't know that updateCache needs to be called after a change to the map.

And some more dartdocs on the refreshCache function about when it should be used would be good too.

@Schnurber
Copy link
Contributor Author

Well, I also added convenience functions to change the tileData and read all values: setLayerVisibility, getLayerVisibility, setTileData, getTileData


/// Gets the Gid of the corresponding layer at the given position
Gid? getTileData({required int layerId, required int x, required int y}) {
final layer = map.layers[layerId] as TileLayer;
Copy link
Contributor

Choose a reason for hiding this comment

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

How do you know that this particular Layer is a TileLayer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Better now?

Copy link
Contributor

@st-pasha st-pasha left a comment

Choose a reason for hiding this comment

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

It looks to me that all 4 new methods operate on a layer, selected by its layerId. In this case it is better to have one method in RenderableTileMap to retrieve a layer with the given id, and then all other methods would belong to that layer class. Thus, instead of .setLayerVisibility(layerId, value), we'd have .layer(id).visibility = value;.

@Schnurber
Copy link
Contributor Author

It looks to me that all 4 new methods operate on a layer, selected by its layerId. In this case it is better to have one method in RenderableTileMap to retrieve a layer with the given id, and then all other methods would belong to that layer class. Thus, instead of .setLayerVisibility(layerId, value), we'd have .layer(id).visibility = value;.

Layer is from the tiled package and has no reference to Flame. Thus, the cache cannot be refreshed from there.

@st-pasha
Copy link
Contributor

Unless you wrap it into your own Layer object (similarly how RenderedTiledMap wraps TiledMap).

@spydon
Copy link
Member

spydon commented Jan 19, 2022

It looks to me that all 4 new methods operate on a layer, selected by its layerId. In this case it is better to have one method in RenderableTileMap to retrieve a layer with the given id, and then all other methods would belong to that layer class. Thus, instead of .setLayerVisibility(layerId, value), we'd have .layer(id).visibility = value;.

How do you propose this should be done without creating new objects, an extension? We also need a reference to the RenderableTileMap in there so that the cache can be updated after a change. I agree that they all could be grouped as a layer, but I think the current solution works too.

@Schnurber
Copy link
Contributor Author

Schnurber commented Jan 19, 2022

@st-pasha I agree with @spydon That would be difficult. I would prefer a simple solution.
The situation is as follows,

In package tiled there is:

abstract class Layer {
	...
	bool visible;
	...
}

class TileLayer extends Layer {...}

class TiledMap {
...
	List<Tileset> tilesets;
	List<Layer> layers;
...
}

and in flame:

class RenderableTiledMap {
...
	final TiledMap map;

	void refreshCache() {...}

	void setLayerVisibility(int layerId, bool visibility) {
		...
		refreshCache();
		... 
	}
 	
	void setTileData( ... ) { ... }
...
}

Unfortunately, it is not possible to work with extension methods, as the references to RenderableTileMap are not possible this way.
You would have to create subclasses RenderableLayer and RenderableTilset in flame, change RenderableTiledMap and define it as a subclass of TiledMap. It would then be complicated because you would have to convert the nested list entries List<Tileset> and List<Layer> layers into lists filled with subclasses of type RenderableTilset and RenderableLayer. You would actually have to generate everything new to provide it with references to the RenderableTileMap.

@spydon
Copy link
Member

spydon commented Jan 19, 2022

@Schnurber did you see my response on the suggestion with the null check?

Copy link
Member

@erickzanardo erickzanardo left a comment

Choose a reason for hiding this comment

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

LGTM

@spydon spydon merged commit b56d5f3 into flame-engine:main Jan 20, 2022
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.

5 participants