Flutter 3D游戏开发插件flame_3d的使用

发布于 1周前 作者 yibo5220 来自 Flutter

Flutter 3D游戏开发插件flame_3d的使用

插件介绍

flame_3d 是是 Flame 渲染引擎的一个实验性扩展,它为 Flame 提供了3D支持。 主要目的是探索3D在 Flame 中的潜力,并提供一个熟悉且易于使用的API给现有的 Flame 开发者。

支持平台

平台 支持状态
Android
iOS
macOS
Windows
Linux
Web

使用说明

首先,确保你的项目已经设置好 Impeller。对于 macOS,可以在 Info.plist 文件中添加以下内容:

<dict>
    ...
 <key>FLTEnableImpeller</key>
 <true/>
</dict>

或者通过命令行运行:

flutter run --enable-impeller

接下来,你可以开始编写3D代码。可以查看 example 目录下的示例代码来了解如何设置简单的3D环境。

示例代码

import 'package:flutter/material.dart' show runApp, Color, Colors;
import 'package:example/crate.dart';
import 'package:example/player_box.dart';
import 'package:example/rotating_light.dart';
import 'package:example/touch_controlled_camera.dart';
import 'package:flame/events.dart';
import 'package:flame/game.dart' show GameWidget;
import 'package:flame_3d/camera.dart';
import 'package:flame_3d/components.dart';
import 'package:flame_3d/game.dart';
import 'package:flame_3d/resources.dart';

class ExampleGame3D extends FlameGame3D<World3D, TouchControlledCamera> with DragCallbacks, ScrollDetector {
  ExampleGame3D()
      : super(
          world: World3D(clearColor: const Color(0xFFFFFFFF)),
          camera: TouchControlledCamera(),
        );

  [@override](/user/override)
  FutureOr<void> onLoad() async {
    world.addAll([
      LightComponent.ambient(
        intensity: 1.0,
      ),
      RotatingLight(),

      LightComponent.point(
        position: Vector3(0, 0.1, 0),
        color: const Color(0xFFFF00FF),
      ),
      MeshComponent(
        mesh: SphereMesh(
          radius: 0.05,
          material: SpatialMaterial(
            albedoTexture: ColorTexture(const Color(0xFFFF00FF)),
          ),
        ),
        position: Vector3(0, 0.1, 0),
      ),

      LightComponent.point(
        position: Vector3(-22, 3, 2),
        color: const Color(0xFFFF2255),
      ),
      MeshComponent(
        mesh: SphereMesh(
          radius: 0.05,
          material: SpatialMaterial(
            albedoTexture: ColorTexture(const Color(0xFFFF2255)),
          ),
        ),
        position: Vector3(-22, 4, 2),
      ),
      
      // Add a player box
      PlayerBox(),

      // Floating crate
      Crate(size: Vector3.all(1), position: Vector3(0, 5, 0)),

      // Floating sphere
      MeshComponent(
        position: Vector3(5, 5, 5),
        mesh: SphereMesh(
          radius: 1,
          material: SpatialMaterial(
            albedoTexture: ColorTexture(Colors.green),
          ),
        ),
      ),
      
      // Floor
      MeshComponent(
        mesh: PlaneMesh(
          size: Vector2(32, 32),
          material: SpatialMaterial(albedoTexture: ColorTexture(Colors.grey)),
        ),
      ),
      
      // Front wall
      MeshComponent(
        position: Vector3(16.5, 2.5, 0),
        mesh: CuboidMesh(
          size: Vector3(1, 5, 32),
          material: SpatialMaterial(albedoTexture: ColorTexture(Colors.yellow)),
        ),
      ),
      
      // Left wall
      MeshComponent(
        position: Vector3(0, 2.5, 16.5),
        mesh: CuboidMesh(
          size: Vector3(32, 5, 1),
          material: SpatialMaterial(albedoTexture: ColorTexture(Colors.blue)),
        ),
      ),
      
      // Right wall
      MeshComponent(
        position: Vector3(0, 2.5, -16.5),
        mesh: CuboidMesh(
          size: Vector3(32, 5, 1),
          material: SpatialMaterial(albedoTexture: ColorTexture(Colors.lime)),
          useFaceNormals: false,
        ),
      ),
    ]);

    final rnd = Random();
    for (var i = 0; i < 220; i++) {
      final height = rnd.range(1, 122);

      world.add(
        MeshComponent(
          position: Vector3(rnd.range(-15, 15), height / 2, rnd.range(-15, 15)),
          mesh: CuboidMesh(
            size: Vector3(1, height, 1),
            material: SpatialMaterial(
              albedoTexture: ColorTexture(
                Color.fromRGBO(rnd.iRange(220, 255), rnd.iRange(10, 55), 30, 1),
              ),
            ),
          ),
        ),
      );
    }
  }

  [@override](/user/override)
  void onScroll(PointerScrollInfo info) {
    const scrollSensitivity = 0.01;
    final delta = info.scrollDelta.global.y.clamp(-10, 10) * scrollSensitivity;

    camera.distance += delta;
  }

  [@override](/user/override)
  void onDragUpdate(DragUpdateEvent event) {
    camera.delta.setValues(event.deviceDelta.x, event.deviceDelta.y);
    super.onDragUpdate(event);
  }

  [@override](/user/override)
  void onDragEnd(DragEndEvent event) {
    camera.delta.setZero();
    super.onDragEnd(event);
  }

  [@override](/user/override)
  void onDragCancel(DragCancelEvent event) {
    camera.delta.setZero();
    super.onDragCancel(event);
  }
}

void main() {
  final example = ExampleGame3D();

  runApp(GameWidget(game: example));
}

更多关于Flutter 3D游戏开发插件flame_3d的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter 3D游戏开发插件flame_3d的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用flame_3d插件进行3D游戏开发的简单代码示例。请注意,flame_3d是一个相对较新的插件,其API和功能可能会随时间变化,因此请确保查阅最新的官方文档以获取最新信息。

首先,确保你的Flutter项目已经设置好,并且已经添加了flameflame_3d依赖。在你的pubspec.yaml文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  flame: ^1.0.0  # 请使用最新版本号
  flame_3d: ^0.1.0  # 请使用最新版本号,注意此版本号仅为示例

然后运行flutter pub get来获取依赖。

接下来,创建一个简单的3D场景。以下是一个基本的示例代码,展示如何设置3D场景并添加一个3D对象。

import 'package:flutter/material.dart';
import 'package:flame/flame.dart';
import 'package:flame_3d/flame_3d.dart';

void main() {
  // 初始化Flame
  Flame.images.loadAll(<String>[
    // 在这里加载你的3D模型资源,例如gltf文件
    'assets/models/my_model.gltf',
  ]);

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter 3D Game with flame_3d'),
        ),
        body: GameWidget(),
      ),
    );
  }
}

class GameWidget extends StatefulWidget {
  @override
  _GameWidgetState createState() => _GameWidgetState();
}

class _GameWidgetState extends State<GameWidget> with SingleTickerProviderStateMixin {
  late FlameController _flameController;

  @override
  void initState() {
    super.initState();
    // 初始化FlameController
    _flameController = FlameController(
      size: Size(double.infinity, double.infinity),
    )..add(My3DScene());
  }

  @override
  void dispose() {
    _flameController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return FlameWidget(_flameController);
  }
}

class My3DScene extends Scene {
  @override
  void render(Canvas canvas) {
    super.render(canvas);
    // 在这里渲染你的3D场景
    // 注意:由于flame_3d的具体API可能会变化,这里只是一个概念性的展示
    // 你需要查阅最新的flame_3d文档来了解如何正确加载和渲染3D模型
    final gltfModel = Flame3D.gltf('assets/models/my_model.gltf');
    // 假设有一个方法可以将gltfModel添加到场景中
    // add3DObject(gltfModel); // 这是一个假设的方法,具体实现请查阅文档
  }

  // 注意:由于flame_3d的API可能不包括直接添加到Scene的方法,
  // 你可能需要使用其他方式管理3D对象的渲染,比如通过Camera和Renderer。
  // 这里只是一个简化的示例,实际使用时请查阅flame_3d的API文档。
}

重要提示

  1. 资源加载:确保你的3D模型资源(如.gltf文件)已经放置在assets目录下,并在pubspec.yaml中正确声明。
  2. API变动:由于flame_3d是一个相对较新的插件,其API可能会频繁变动。因此,强烈建议查阅最新的flame_3d官方文档(如果可用)以获取准确的信息和示例代码。
  3. 渲染循环:在真实的3D游戏开发中,你通常需要处理渲染循环、动画、物理模拟等。这个示例仅展示了如何开始设置3D场景,并没有涵盖这些高级功能。

希望这个示例能帮助你开始使用flame_3d进行Flutter 3D游戏开发!

回到顶部