Как сделать так, чтобы Rect постоянно двигался линейно, трепет / пламя

У меня возникли проблемы с попыткой реализовать метод, который перемещает Rect во флаттере с использованием игрового движка пламени. Конечная цель - провести пальцем в нужном направлении и заставить Rect двигаться в этом направлении с постоянной скоростью. Я нашел этот код:

  void dragUpdate(DragUpdateDetails d)
  {
    final delta = d.delta;
    final size = gameController.screenSize;
    double translateX = delta.dx;
    double translateY = delta.dy;

    // Make sure that the player never goes outside of the screen in the X-axis
    if (playerRect.right + delta.dx >= size.width) {
      translateX = size.width - playerRect.right;
    } else if (playerRect.left + delta.dx <= 0) {
      translateX = -playerRect.left;
    }
    // Make sure that the player never goes outside of the screen in the Y-axis
    if (playerRect.bottom + delta.dy >= size.height) {
      translateY = size.height - playerRect.bottom;
    } else if (playerRect.top + delta.dy <= 0) {
      translateY = -playerRect.top;
    }

    playerRect = playerRect.translate(translateX, translateY);
  }

что, по крайней мере, позволяет свободно перемещать Rect по экрану в зависимости от положения пальцев. Я пробовал возиться с методом translate (), чтобы увеличить / уменьшить x / y в зависимости от предоставленной дельты, но безрезультатно. Мы будем очень признательны за любой намек или указание в правильном направлении.


person EEEEO    schedule 28.12.2020    source источник
comment
Какую версию Flame вы используете?   -  person spydon    schedule 28.12.2020


Ответы (2)


Вместо использования HorizontalDragDetector и VerticalDragDetector вы можете использовать MultiTouchDragDetector, и код будет намного проще.

class MyGame extends BaseGame with MultiTouchDragDetector {
  Rect _rect = const Rect.fromLTWH(0, 0, 50, 50);
  Offset _velocity = Offset.zero;

  MyGame();

  @override
  void onReceiveDrag(DragEvent event) {
    event.onEnd = onDragEnd;
  }

  void onDragEnd(DragEndDetails details) {
    _velocity = details.velocity.pixelsPerSecond;
  }

  @override
  void update(double dt) {
    super.update(dt);
    final timeStepMovement = _velocity * dt;
    _rect = _rect.shift(timeStepMovement);
  }

  @override
  void render(Canvas canvas) {
    super.render(canvas);
    canvas.drawRect(_rect, BasicPalette.white.paint);
  }
}
person spydon    schedule 28.12.2020
comment
@EEEEO, никаких проблем, у нас тоже есть диссонанс-чат, где вы можете задать вопросы, там мы обычно быстрее отвечаем. discord.com/invite/pxrBmy4 - person spydon; 30.12.2020

Вы можете установить дельту перетаскивания X и Y в своем dragUpdate(...){ ... } и использовать эти значения дельты в render(...) { ... }.

Попробуйте запустить этот образец приложения.

import 'dart:ui';

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

void main() {
  BoxGame game = BoxGame();
  runApp(game.widget);

  Util flameUtil = Util();
  flameUtil.fullScreen();
  flameUtil.setOrientation(DeviceOrientation.portraitUp);
}

class BoxGame extends Game
    with HorizontalDragDetector, VerticalDragDetector {
  Size screenSize;

  double posX;
  double posY;
  double dragDX = 0.0;
  double dragDY = 0.0;

  void render(Canvas canvas) {
    // draw a black background on the whole screen
    final Rect bgRect =
        Rect.fromLTWH(0, 0, screenSize.width, screenSize.height);
    final Paint bgPaint = Paint();
    bgPaint.color = Color(0xff000000);
    canvas.drawRect(bgRect, bgPaint);

    // draw a box (make it green if won, white otherwise)
    if (posX == null) {
      final double screenCenterX = screenSize.width / 2;
      final double screenCenterY = screenSize.height / 2;
      posX = screenCenterX - 75;
      posY = screenCenterY - 75;
    }

    posX += dragDX;
    posY += dragDY;

    final Rect boxRect = Rect.fromLTWH(posX, posY, 150, 150);
    final Paint boxPaint = Paint();
    boxPaint.color = Color(0xffffffff);
    canvas.drawRect(boxRect, boxPaint);
  }

  void update(double t) {}

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

  @override
  void onHorizontalDragUpdate(DragUpdateDetails details) {
    dragDX = details.delta.dx;
  }

  @override
  void onVerticalDragUpdate(DragUpdateDetails details) {
    dragDY = details.delta.dy;
  }

  @override
  void onHorizontalDragEnd(DragEndDetails details) {
    dragDX = 0;
  }

  @override
  void onVerticalDragEnd(DragEndDetails details) {
    dragDY = 0;
  }
}
person rickimaru    schedule 28.12.2020