Позиционирование SpriteComponent с помощью Flame

ОБНОВЛЕНИЕ: я создал небольшой пример, который, вероятно, лучше иллюстрирует проблему в этой проблеме: https://github.com/flame-engine/flame/issues/200

укороченная версия:

Я создаю экземпляр SpriteComponents на позициях (50, 50), (50, 100), (100, 50), (100, 100).

Однако при рендеринге они выглядят так:

Что дает такое странное смещение? Как правильно отрендеритьSpriteComponents?

более длинная версия (с кодом): я хотел бы проверить производительность пламени, реализовав что-то вроде bunnymark. В качестве первой попытки сохранить производительность я загружаю одинSprite и используя его для производства многих SpriteComponents.

В SpriteComponent завернут в Bunnyкласс. Пока он ничего не делает, в конечном итоге он будет обрабатывать движение:

import 'dart:ui';

import 'package:flame/components/component.dart';
import 'package:flame/sprite.dart';

class Bunny {
  SpriteComponent bunny;

  Bunny(Sprite bunnySprite, double x, double y, double w, double h)
      : this.bunny =
            SpriteComponent.fromSprite(w, h, bunnySprite) {
    bunny.x = x;
    bunny.y = y;
  }

  void render(Canvas c) {
    bunny.render(c);
  }

  void update(double t) {}
}

Кролики созданы в моем игровом классе:

import 'dart:ui';

import 'package:bunnymark/components/bunny.dart';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flame/sprite.dart';
import 'package:flutter/cupertino.dart';

class BunnyMark extends Game {
  Size screenSize;
  List<Bunny> bunnies;
  Sprite bunnySprite;

  BunnyMark() {
    initialize();
  }

  void initialize() async {
    resize(await Flame.util.initialDimensions());

    bunnies = List<Bunny>();
    bunnySprite = Sprite('rabbitv3_tron.png');

    bunnies.add(Bunny(bunnySprite, 50, 50, 30, 30));
    bunnies.add(Bunny(bunnySprite, 50, 100, 30, 30));
    bunnies.add(Bunny(bunnySprite, 100, 100, 30, 30));
    bunnies.add(Bunny(bunnySprite, 100, 50, 30, 30));
  }

  void render(Canvas canvas) {
    Rect bgRect = Rect.fromLTWH(0, 0, screenSize.width, screenSize.height);
    Paint bgPaint = Paint();
    bgPaint.color = Color(0xff000000);
    canvas.drawRect(bgRect, bgPaint);

    bunnies.forEach((bunny) {
      bunny.render(canvas);
    });
  }

  void update(double t) {
    bunnies.forEach((bunny) => bunny.update(t));
  }

  void resize(Size size) {
    screenSize = size;
    super.resize(size);
  }
}

Игра запускается с main.dart:

import 'package:bunnymark/bunnymark.dart';
import 'package:flame/util.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  Util flameUtil = Util();
  await flameUtil.fullScreen();
  await flameUtil.setOrientation(DeviceOrientation.portraitUp);

  BunnyMark game = BunnyMark();
  runApp(game.widget);
}

1 ответ

Решение

Поскольку вы используете Game и нет BaseGame (который сделает это за вас), вы несете ответственность за свои render реализация для сброса холста для каждого спрайта.

Компонентам разрешено вносить любые изменения, которые они хотят, на холсте, и BaseGame (или, в вашем случае, Game) требуется сбросить.

Итак, когда вы это сделаете

bunnies.forEach((bunny) {
  bunny.render(canvas);
});

Вероятно, вы захотите сделать что-то вроде:

bunnies.forEach((bunny) {
  canvas.save();
  bunny.render(canvas);
  canvas.restore();
});

Или, в качестве альтернативы, взгляните на BaseGame класс, который решает многие из этих проблем за вас:)

Другие вопросы по тегам