iT邦幫忙

2024 iThome 鐵人賽

DAY 17
0
Mobile Development

用Flutter Flame做遊戲!Live!系列 第 19

Drag和Contact相衝突嗎?

  • 分享至 

  • xImage
  •  

忙了十天半個月,目的除了「在Flame遊戲引擎框架下研究Canvas/Vector繪圖」外,主要是想要製作一款「紙牌遊戲」。

這款遊戲(部分玩法)設計是「在一張大桌面上,會有很多Slot可以安放紙牌,但玩家拖曳紙牌只要部分接觸到Slot,則鬆開拖曳後,紙牌會自動移動到Slot上、與Slot重合。」

本意是要用BodyComponent同時製作Slot與紙牌,但數次的測試後發現「SlotComponent無法偵測到自己已經與CardComponent發生重疊接觸」,雖然經歷過無數測試,但在添加拖曳功能後,BodyComponent的碰撞偵測功能就是會失效。

所以,還是自己老老實實自己幹一套偵測機制吧!
程式碼主要必須滿足以下兩項功能:
1.要一邊拖曳一邊偵測。
2.要結束拖曳後才會移動紙牌。

以下是「紙牌」物件(CardComponent):


  Vector2? targetPosition;
  Vector2? targetPositionTmp;

  @override
  void update(double dt) {
    super.update(dt);

    if(targetPosition != null){
      Vector2 delta = targetPosition! - body.position;

      // 如果差距足够小,直接将物体的位置设置为目标位置
      if(delta.length <= 0){
        targetPosition = null;
      }
      if (delta.length < 0.1) {
        transform(delta);
      } else {
        // 否则,逐渐移动物体的位置
        Vector2 velocity = delta.normalized() * 0.333; // 5是移动速度,你可以根据需要调整
        transform(velocity);
      }
    }
    // 计算目标位置和当前位置的差距

  }

  transform(Vector2 pos){
    position.add(pos);
    body.setTransform(position, body.angle);
  }

  @override
  void onDragUpdate(DragUpdateEvent event) {
    transform(event.localDelta);

    targetPositionTmp = null;
    for(SlotBody slot in slots){
      if(slot.hitTest(position)){
        targetPositionTmp = slot.position;
        break;
      }
    }

  }

  List<SlotBody> slots = [];

  addSlot(SlotBody slot){
    slots.add(slot);
  }

  removeSlot(SlotBody slot){
    slots.remove(slot);
  }

  @override
  void onDragEnd(DragEndEvent event) {

    super.onDragEnd(event);
    print('drag end');
    targetPosition = targetPositionTmp;
    targetPositionTmp = null;
  }

然後「SlotComponent」要有HitTest的能力。


  bool hitTest(Vector2 point) {
    // Convert the point to the local coordinate system
    Vector2 localPoint = point - position;

    // Check if the point is inside the body's bounding box
    return localPoint.x >= -width / 2 && localPoint.x <= width / 2 &&
        localPoint.y >= -height / 2 && localPoint.y <= height / 2;
  }

(大致上可以運行,但是需要繼續測試微調。)


上一篇
(週末) Canvas.clip的例子
下一篇
關於Flame.World
系列文
用Flutter Flame做遊戲!Live!32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言