iT邦幫忙

2024 iThome 鐵人賽

DAY 11
0
Mobile Development

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

如何新增和消除一個BodyComponent?(如何偵測與其他BodyComponent發生接觸?)

  • 分享至 

  • xImage
  •  

今天的題目其實出乎意料「沒勁」,因為說白了很簡單....


Ball ball0 = Ball(initialPosition: Vector2(-10, -16), radius: 4);
Ball ball1 = Ball(initialPosition: Vector2(10, -16), radius: 4);
world.add(ball0!);
world.add(ball1!);

world的彈性出乎意料的高!
它的ChildrenComponent內容修改彈性極高,但BodyComponent一旦生成,其屬性(大多)不能改變。
(所以刪改BodyComponent才會如此容易,因為需要修改時,其實是「移除舊的、插入新的」。)

接著,我們來做個「移除」同時「偵測接觸」的測試。

首先新增一個「Hole」類別。
為什麼不修改Ball?給它不同的動畫就好?
因為「要讓Ball可以穿過Hall」。

首先要產生兩組數值:


  int ballBodyCategory = 0x0102;
  int holeBodyCategory = 0x0104;

然後在生成「Hole」的方法中使用這兩個參數...


FixtureDef(
  CircleShape()..radius = radius,
  restitution: restitution,
  friction: friction,)
  ..filter.categoryBits = holeBodyCategory
  ..filter.maskBits = ~ballBodyCategory

「Ball」的生成時也要使用,但兩個參數顛倒...


  ..filter.categoryBits = ballBodyCategory
  ..filter.maskBits = ~holeBodyCategory

這樣,兩個類別的物件實體就不會在邊緣互撞時彈開了!
雖然官方文件聲稱這樣設定後碰撞偵測依然有效,但事實是...「Ball」完全失去偵測與「Hole」發生碰撞的能力了!

所以要自己做!改造「Ball」!


  List<Hole> holes = [];
  addHole(Hole hole){
    holes.add(hole);
  }

  removeHole(Hole hole){
    holes.remove(hole);
  }

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

    for(Hole hole in holes){
      if((hole.body.position - body.position).length < hole.radius/2 + radius/2){
        world.remove(this);
        break;
      }
    }

  }

然後...


Hole swapHole = Hole(initialPosition: Vector2(0, 16), radius: 4, type: 0);

...

Ball ball0 = Ball(initialPosition: Vector2(-10, -16), radius: 4);
Ball ball1 = Ball(initialPosition: Vector2(10, -16), radius: 4);
ball0!.addHole(swapHole!);
ball1!.addHole(swapHole!);
world.add(ball0!);
world.add(ball1!);

這樣,「Ball」如果穿越「Hole」時距離中心夠近就會被「吃掉」然後「消失」了。

(但,還有別的辦法可以做,改天研究。)


上一篇
繼續測試Forge2D的基本特性
下一篇
讓遊戲中的BodyComponent跟空氣碰撞...
系列文
用Flutter Flame做遊戲!Live!32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言