You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flame中PositionComponent等游戏对象能否同时支持Collidable和Draggable

问题描述

我已经成功实现了Draggable组件,但给继承自PositionComponent的类添加Hitbox和Collidable混入后,拖拽功能就停止工作了。
是否可以实现同时支持可拖拽和可碰撞的组件?

运行环境

  • Flutter版本:2.2.3
  • Flame版本:1.0.0-releasecandidate.13

相关代码

main.dart

import 'package:flame/game.dart';
import 'package:flutter/material.dart';
import 'DraggablesGame.dart';

void main() {
  runApp(
    GameWidget(
      game: DraggablesGame(),
    ),
  );
}

DraggablesGame.dart

import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'DraggableSquare.dart';

class DraggablesGame extends BaseGame with HasDraggableComponents, HasCollidables {

  @override
  Future<void> onLoad() async {
    add(DraggableSquare());
    add(DraggableSquare()..y = 350);
  }
}

DraggableSquare.dart

import 'package:flame/components.dart';
import 'package:flame/extensions.dart';
import 'package:flame/game.dart';
import 'package:flame/gestures.dart';
import 'package:flutter/material.dart' show Colors;
import 'DraggablesGame.dart';

class DraggableSquare extends PositionComponent
    with Draggable, HasGameRef<DraggablesGame>, Hitbox, Collidable {
  @override
  bool debugMode = true;

  DraggableSquare({Vector2? position})
      : super(
    position: position ?? Vector2.all(100),
    size: Vector2.all(100),
  );

  Vector2? dragDeltaPosition;
  bool get isDragging => dragDeltaPosition != null;

  @override
  void update(double dt) {
    super.update(dt);
    debugColor = isDragging ? Colors.greenAccent : Colors.purple;
  }

  @override
  bool onDragStart(int pointerId, DragStartInfo info) {
    dragDeltaPosition = info.eventPosition.game - position;
    return false;
  }

  @override
  bool onDragUpdate(int pointerId, DragUpdateInfo event) {
    final dragDeltaPosition = this.dragDeltaPosition;
    if (dragDeltaPosition == null) {
      return false;
    }

    position.setFrom(event.eventPosition.game - dragDeltaPosition);
    return false;
  }

  @override
  bool onDragEnd(int pointerId, _) {
    dragDeltaPosition = null;
    return false;
  }

  @override
  bool onDragCancel(int pointerId) {
    dragDeltaPosition = null;
    return false;
  }
}

解决方案更新

有回答建议使用addHitbox(HitboxRectangle());实现功能,但运行时触发如下报错:

The method 'addHitbox' isn't defined for the type 'DraggableSquare'.

调整后的构造函数可同时支持拖拽和碰撞功能,代码如下:

更新后的DraggableSquare构造函数

DraggableSquare({Vector2? position})
      : super(
    position: position,
    size: Vector2.all(100),
  ) {
    final hitBox = HitboxRectangle();
    addShape(hitBox);
  }

内容的提问来源于stack exchange,提问作者crayden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 14:18:03