Flutter插件sashimi的介绍与使用
Flutter插件sashimi的介绍与使用
Sashimi 是一个基于 Flame 引擎的精灵堆叠框架。
什么是Sashimi?
Sashimi 是一个基于 Flame 引擎的精灵堆叠框架。
文档
目前还没有文档,但可以在 example 目录中找到使用示例。
Flutter插件sashimi快速开始 🚀
前提条件 📝
在开始使用 Sashimi 之前,你需要安装 Flutter SDK。
Flutter插件sashimi安装 🧑💻
在 pubspec.yaml 文件中添加 flame 和 sashimi:
# 📦 安装sashimi和flame
flutter pub add flame sashimi
示例代码
以下是一个完整的示例代码,展示了如何使用 Sashimi 插件创建一个简单的游戏。
import 'dart:math';
import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flame/input.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:sashimi/sashimi.dart';
class ExampleGame extends SashimiGame
    with KeyboardEvents, MultiTouchDragDetector {
  final TextComponent _debugText = TextComponent(
    scale: Vector2.all(0.75),
    textRenderer: TextPaint(
      style: TextPaint.defaultTextStyle.copyWith(color: Colors.green),
    ),
  );
  final rnd = Random();
  [@override](/user/override)
  Future<void> onLoad() async {
    await super.onLoad();
    double value(int max) => rnd.nextInt(max) - max / 2;
    for (final position in [
      for (var i = 0; i < 10; i++) ...[
        Vector3(value(5000) - 2500, value(5000) - 2500, 0),
        Vector3(value(5000) + 2500, value(5000) + 2500, 0),
        Vector3(value(5000) - 2500, value(5000) + 2500, 0),
        Vector3(value(5000) + 2500, value(5000) - 2500, 0),
        Vector3(value(5000), value(5000), 0),
      ],
    ]) {
      final scale = rnd.nextDouble() + 0.5;
      final model = Model(
        position: position,
        size: Vector3(593, 559, 140),
        scale: Vector3(scale, scale, 1),
        angle: rnd.nextInt(180) * degrees2Radians,
        image: await images.load('island.png'),
      );
      await add(model);
      const amountOfSlicesPerColor = 3;
      final colors = [
        for (var i = 0; i < amountOfSlicesPerColor; i++) Colors.red,
        for (var i = 0; i < amountOfSlicesPerColor; i++) Colors.green,
        for (var i = 0; i < amountOfSlicesPerColor; i++) Colors.blue,
      ];
      final SashimiObject object;
      switch (rnd.nextInt(2)) {
        case 0:
          object = ColoredCuboid(
            position: Vector3(position.x, position.y, 140),
            size: Vector3.all(100),
            scale: Vector3.all(1),
            angle: rnd.nextInt(180) * degrees2Radians,
            colors: colors,
          );
          break;
        case 1:
          object = ColoredCylinder(
            position: Vector3(position.x, position.y, 140),
            height: 100,
            diameter: 100,
            scale: Vector3.all(1),
            angle: rnd.nextInt(180) * degrees2Radians,
            colors: colors,
          );
          break;
        default:
          throw UnimplementedError('value: $value');
      }
      await add(object);
    }
    await add(
      Model(
        position: Vector3.zero(),
        size: Vector3(593, 559, 140),
        scale: Vector3(1, 1, 1),
        image: await images.load('island.png'),
      ),
    );
    await add(
      BillboardSprite(
        position: Vector3(0, 0, 140),
        size: Vector2.all(64),
        scale: Vector2.all(2),
        sprite: await Sprite.load('house.png', images: images),
      ),
    );
    kamera
      ..follow(PositionComponent())
      ..viewfinder.zoom = 1;
    // 创建一个单一的切片彩色立方体作为水。
    await add(
      ColoredCuboid(
        position: Vector3(0, 0, 60),
        size: Vector3(40000, 40000, 1),
        colors: [const Color(0xFF2152FF).withOpacity(0.55)],
      ),
    );
    if (kDebugMode) {
      await addAll([FpsComponent(), _debugText]);
    }
  }
  [@override](/user/override)
  void update(double dt) {
    super.update(dt);
    final rotateLeft = _keysPressed.contains(LogicalKeyboardKey.keyQ);
    final rotateRight = _keysPressed.contains(LogicalKeyboardKey.keyE);
    final rotation = rotateLeft ? 1 : (rotateRight ? -1 : 0);
    kamera.rotation += rotation * dt;
    final zoomIn = _keysPressed.contains(LogicalKeyboardKey.keyZ);
    final zoomOut = _keysPressed.contains(LogicalKeyboardKey.keyX);
    final zoom = zoomIn ? 1 : (zoomOut ? -1 : 0);
    kamera.zoom = (kamera.zoom + zoom * dt).clamp(0.1, 5);
    _debugText.text = '''
FPS: ${(firstChild<FpsComponent>()?.fps ?? 0).toStringAsFixed(2)}
Objects: ${descendants().whereType<SashimiObject>().length}
Components: ${descendants().whereType<SashimiSlice>().length}
Zoom: ${kamera.zoom.toStringAsFixed(2)}
Rotation: ${(kamera.rotation * radians2Degrees % 360).toStringAsFixed(2)} degrees
Position: ${kamera.position.x.toStringAsFixed(2)}, ${kamera.position.y.toStringAsFixed(2)}
''';
  }
  Set<LogicalKeyboardKey> _keysPressed = {};
  [@override](/user/override)
  KeyEventResult onKeyEvent(
    RawKeyEvent event,
    Set<LogicalKeyboardKey> keysPressed,
  ) {
    _keysPressed = keysPressed;
    return KeyEventResult.handled;
  }
  final Map<int, Vector2> _dragPositions = {};
  double _previousDistance = 0;
  [@override](/user/override)
  void onDragStart(int pointerId, DragStartInfo info) {
    _dragPositions[pointerId] = info.eventPosition.game;
  }
  [@override](/user/override)
  void onDragEnd(int pointerId, DragEndInfo info) {
    _dragPositions.remove(pointerId);
  }
  [@override](/user/override)
  void onDragCancel(int pointerId) {
    _dragPositions.remove(pointerId);
  }
  [@override](/user/override)
  void onDragUpdate(int pointerId, DragUpdateInfo info) {
    _dragPositions[pointerId] = info.eventPosition.game;
    // 如果有两个手指在屏幕上,进行缩放操作
    if (_dragPositions.length == 2) {
      final distance = _dragPositions.values.first.distanceTo(
        _dragPositions.values.last,
      );
      if (_previousDistance != 0) {
        if (distance < _previousDistance) {
          kamera.zoom = (kamera.zoom * 1.05).clamp(0.1, 5);
        }
        if (distance > _previousDistance) {
          kamera.zoom = (kamera.zoom * (1.0 / 1.05)).clamp(0.1, 5);
        }
      }
      _previousDistance = distance;
    } else {
      kamera.moveBy(
        Vector2.copy(-info.delta.game)
          ..rotate(kamera.viewfinder.angle)
          ..scale(1.0 / kamera.viewfinder.zoom),
      );
    }
  }
}
void main() => runApp(GameWidget(game: ExampleGame()));更多关于Flutter插件sashimi的介绍与使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
        
      
            
            
            
