Flutter等距视图插件flame_isometric的使用
Flutter等距视图插件flame_isometric的使用
概述
flame_isometric
是一个用于在 Flutter 的游戏引擎 Flame 中渲染等距(Isometric)地图的插件。它生成渲染等距地图所需的矩阵,并支持多层和多个图块集(tileset)。
特性
- 支持多层地图
- 支持多个图块集
- 可以轻松地从 Tiled Map Editor 导入地图数据
使用方法
导入 IsometricTileMapComponent
类
在 Flame 1.6.0 版本中,IsometricTileMapComponent
不直接支持从 Tiled Map Editor 导入地图数据,而是通过 tilesetImage
和 matrix
来生成地图。你需要使用 package:tiled/tiled.dart
和 package:flame/sprite.dart
来解析 TMX 数据并生成矩阵。
生成矩阵
final flameIsometric = await FlameIsometric.create(
tileMap: 'tile_map.png',
tmx: 'tiles/tile_map.tmx',
);
生成的矩阵按层存储在 flameIsometric
实例的 matrixList
中。
渲染地图
for (var i = 0; i < flameIsometric.layerLength; i++) {
add(
IsometricTileMapComponent(
flameIsometric.tileset,
flameIsometric.renderMatrixList[i],
destTileSize: flameIsometric.srcTileSize,
position: Vector2(gameSize.x / 2, flameIsometric.tileHeight.toDouble()),
),
);
}
支持多个图块集
你也可以支持多个图块集:
final flameIsometric = await FlameIsometric.create(
tileMap: ['tile_map.png', 'tile_map2.png'],
tsxList: ['tiles/tile_map.tsx', 'tiles/tile_map2.tsx'],
tmx: 'tiles/tile_map2.tmx',
);
使用 CustomIsometricTileMapComponent
为了更方便地渲染多层地图,可以使用 CustomIsometricTileMapComponent
:
for (var renderLayer in flameIsometric.renderLayerList) {
add(
CustomIsometricTileMapComponent(
renderLayer.spriteSheet,
renderLayer.matrix,
destTileSize: flameIsometric.srcTileSize,
position: Vector2(gameSize.x / 2, flameIsometric.tileHeight.toDouble()),
),
);
}
注意事项
- 不同大小的图块集可以显示,但绘制时的位置可能需要调整。
- 目前,Flame 1.6.0 不支持矩形地图,因此在 Tiled Map Editor 中创建地图时,必须选择 “Isometric”(而不是 “Isometric (Staggered)”)。
创建参考
使用 Tiled Map Editor 创建等距地图
- 打开 Tiled Map Editor。
- 选择 “Isometric”(不是 “Isometric (Staggered)”)作为地图的方向。
- 选择合适的地图形状和图块集。
图层
- Bottom 层:主要用于放置地板。
- Middle 层:主要用于放置墙壁等。
- Top 层:主要用于放置屋顶等。
示例代码
以下是一个完整的示例代码,展示了如何使用 flame_isometric
插件来渲染等距地图。
import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flame_isometric/flame_isometric.dart';
import 'package:flame_isometric/custom_isometric_tile_map_component.dart';
import 'package:flutter/material.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const App());
}
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
title: 'IsometricMap Sample',
home: MainGamePage(),
);
}
}
class MainGamePage extends StatefulWidget {
const MainGamePage({Key? key}) : super(key: key);
@override
MainGameState createState() => MainGameState();
}
class MainGameState extends State<MainGamePage> {
MainGame game = MainGame();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
GameWidget(game: game),
],
),
);
}
}
class MainGame extends FlameGame with HasGameRef {
@override
Future<void> onLoad() async {
super.onLoad();
final gameSize = gameRef.size;
// 单个图块集
// final flameIsometric = await FlameIsometric.create(
// tileMap: 'tile_map.png', tmx: 'tiles/tile_map.tmx');
//
// for (var i = 0; i < flameIsometric.layerLength; i++) {
// add(
// IsometricTileMapComponent(
// flameIsometric.tileset,
// flameIsometric.renderMatrixList[i],
// destTileSize: flameIsometric.srcTileSize,
// position: Vector2(gameSize.x / 2, flameIsometric.tileHeight.toDouble()),
// ),
// );
// }
// 多个图块集
final flameIsometric = await FlameIsometric.create(
tileMap: ['tile_map.png', 'tile_map2.png'],
tsxList: ['tiles/tile_map.tsx', 'tiles/tile_map2.tsx'],
tmx: 'tiles/tile_map2.tmx',
);
for (var renderLayer in flameIsometric.renderLayerList) {
add(
CustomIsometricTileMapComponent(
renderLayer.spriteSheet,
renderLayer.matrix,
destTileSize: flameIsometric.srcTileSize,
position: Vector2(gameSize.x / 2, flameIsometric.tileHeight.toDouble()),
),
);
}
}
}
贡献者
版权持有者
- isometric-64x64-medieval-building-tileset: Seth Galbraith
- basic isometric tiles 128x128: ToxSickProductions.com
作者
更多关于Flutter等距视图插件flame_isometric的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter等距视图插件flame_isometric的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter中使用flame_isometric
插件来实现等距视图效果的代码案例。flame_isometric
是一个基于flame
游戏引擎的插件,用于创建等距投影(Isometric Projection)的游戏视图。
首先,确保你的Flutter项目已经添加了flame
和flame_isometric
依赖。在pubspec.yaml
文件中添加以下依赖:
dependencies:
flutter:
sdk: flutter
flame: ^1.0.0 # 请使用最新版本号
flame_isometric: ^0.x.x # 请使用最新版本号,注意替换x为实际版本号
然后运行flutter pub get
来安装依赖。
接下来,我们编写一个简单的示例,展示如何使用flame_isometric
来创建等距视图。
main.dart
import 'package:flutter/material.dart';
import 'package:flame/flame.dart';
import 'package:flame_isometric/flame_isometric.dart';
import 'package:flutter/services.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
Flame.images.loadAll([
'tile.png', // 假设你有一个名为tile.png的瓦片图像
]);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Isometric View with flame_isometric'),
),
body: IsometricGameWidget(),
),
);
}
}
class IsometricGameWidget extends StatefulWidget {
@override
_IsometricGameWidgetState createState() => _IsometricGameWidgetState();
}
class _IsometricGameWidgetState extends State<IsometricGameWidget> {
late IsometricTileMap _tileMap;
@override
void initState() {
super.initState();
_createTileMap();
}
void _createTileMap() {
// 定义瓦片大小
final tileSize = Vector2(64.0, 32.0);
// 定义地图层
final layers = [
IsometricTileLayerData.fromTileGrid(
tiles: [
// 这里填入你的瓦片ID,假设每个瓦片都是0(即使用相同的瓦片图像)
for (int y = 0; y < 10; y++) ...[
for (int x = 0; x < 10; x++) 0,
],
tileSize: tileSize,
),
],
);
// 创建地图
_tileMap = IsometricTileMap(
layers: layers,
tilesetImage: 'tile.png', // 瓦片图像路径
tileWidth: tileSize.x,
tileHeight: tileSize.y,
);
}
@override
Widget build(BuildContext context) {
return IsometricCamera(
tileMap: _tileMap,
cameraSize: Vector2(800, 600), // 相机视图大小
cameraPosition: Vector2(0, 0), // 相机初始位置
child: IsometricGameRenderBox(
tileMap: _tileMap,
),
);
}
}
资源准备
确保你在项目的assets
文件夹中有一个名为tile.png
的瓦片图像。同时,在pubspec.yaml
文件中添加该资源:
flutter:
assets:
- assets/tile.png # 确保路径正确
解释
- 依赖加载:在
main.dart
中,我们确保Flutter和Flame库已初始化,并加载了瓦片图像。 - IsometricGameWidget:这是一个StatefulWidget,用于包含等距视图游戏逻辑。
- _createTileMap:此方法创建了一个等距瓦片地图。我们定义了瓦片大小、瓦片网格数据以及瓦片图像。
- IsometricCamera:这是一个Widget,用于控制相机的视图。你可以调整
cameraSize
和cameraPosition
来更改视图大小和位置。 - IsometricGameRenderBox:这是一个RenderBox,用于渲染等距瓦片地图。
这个示例展示了如何使用flame_isometric
插件来创建一个简单的等距视图。你可以根据需要进一步扩展和自定义,例如添加交互、动画等。