mirror of
https://github.com/flame-engine/flame.git
synced 2025-10-30 00:17:20 +08:00
Update IsometricTileMapComponent to have better defined position and size. Before, the isometric component "zero" would be the center of the 0,0 block. However, that does not play nicely with our component system if you want to know the size (i.e. bounding box) of a component. This changes so that the 0,0 of the component is the 0,0 of the AABB around the isometric tiles. Then, it also computes the size of the component accordingly. This also changes the example to allow toggling between half and full size more easily. In our example, this is what it looks like:  The example still shows how to compute the previous origin (the purple dot) if you want to. With full size blocks:  This is a minor breaking change as you might need to "reposition" your tile components, essentially remove the "compensation" for its location that you probably did yourself. If you were centering the tile component based on the available methods such as `map.getBlockCenterPosition`, then just make sure you are adding the `map.position` to that and it should work as before.
101 lines
2.6 KiB
Dart
101 lines
2.6 KiB
Dart
import 'dart:ui';
|
|
|
|
import 'package:flame/components.dart';
|
|
import 'package:flame/events.dart';
|
|
import 'package:flame/extensions.dart';
|
|
import 'package:flame/game.dart';
|
|
import 'package:flame/input.dart';
|
|
import 'package:flame/sprite.dart';
|
|
|
|
class IsometricTileMapExample extends FlameGame with MouseMovementDetector {
|
|
static const String description = '''
|
|
Shows an example of how to use the `IsometricTileMapComponent`.\n\n
|
|
Move the mouse over the board to see a selector appearing on the tiles.
|
|
''';
|
|
|
|
final topLeft = Vector2.all(500);
|
|
|
|
static const scale = 2.0;
|
|
static const srcTileSize = 32.0;
|
|
static const destTileSize = scale * srcTileSize;
|
|
|
|
final originColor = Paint()..color = const Color(0xFFFF00FF);
|
|
final originColor2 = Paint()..color = const Color(0xFFAA55FF);
|
|
|
|
final bool halfSize;
|
|
late final tileHeight = scale * (halfSize ? 8.0 : 16.0);
|
|
late final suffix = halfSize ? '-short' : '';
|
|
|
|
late IsometricTileMapComponent base;
|
|
late Selector selector;
|
|
|
|
IsometricTileMapExample({required this.halfSize});
|
|
|
|
@override
|
|
Future<void> onLoad() async {
|
|
final tilesetImage = await images.load('tile_maps/tiles$suffix.png');
|
|
final tileset = SpriteSheet(
|
|
image: tilesetImage,
|
|
srcSize: Vector2.all(srcTileSize),
|
|
);
|
|
final matrix = [
|
|
[3, 1, 1, 1, 0, 0],
|
|
[-1, 1, 2, 1, 0, 0],
|
|
[-1, 0, 1, 1, 0, 0],
|
|
[-1, 1, 1, 1, 0, 0],
|
|
[1, 1, 1, 1, 0, 2],
|
|
[1, 3, 3, 3, 0, 2],
|
|
];
|
|
add(
|
|
base = IsometricTileMapComponent(
|
|
tileset,
|
|
matrix,
|
|
destTileSize: Vector2.all(destTileSize),
|
|
tileHeight: tileHeight,
|
|
position: topLeft,
|
|
),
|
|
);
|
|
|
|
final selectorImage = await images.load('tile_maps/selector$suffix.png');
|
|
add(selector = Selector(destTileSize, selectorImage));
|
|
}
|
|
|
|
@override
|
|
void render(Canvas canvas) {
|
|
super.render(canvas);
|
|
canvas.renderPoint(topLeft, size: 5, paint: originColor);
|
|
canvas.renderPoint(
|
|
base.position + base.getBlockCenterPosition(const Block(0, 0)),
|
|
size: 5,
|
|
paint: originColor2,
|
|
);
|
|
}
|
|
|
|
@override
|
|
void onMouseMove(PointerHoverInfo info) {
|
|
final screenPosition = info.eventPosition.widget;
|
|
final block = base.getBlock(screenPosition);
|
|
selector.show = base.containsBlock(block);
|
|
selector.position.setFrom(topLeft + base.getBlockRenderPosition(block));
|
|
}
|
|
}
|
|
|
|
class Selector extends SpriteComponent {
|
|
bool show = true;
|
|
|
|
Selector(double s, Image image)
|
|
: super(
|
|
sprite: Sprite(image, srcSize: Vector2.all(32.0)),
|
|
size: Vector2.all(s),
|
|
);
|
|
|
|
@override
|
|
void render(Canvas canvas) {
|
|
if (!show) {
|
|
return;
|
|
}
|
|
|
|
super.render(canvas);
|
|
}
|
|
}
|