這個「空氣」是個名叫「Trap」的「BodyComponent」。
它的內容完全承襲自「Hole」,差別只是「它應該是透明的」。
class Trap extends BaseRound with TapCallbacks, ContactCallbacks {
Trap({Vector2? initialPosition, double restitution = 0.8, double friction = 0.4, double radius = 5}){
if(initialPosition != null)
this.initialPosition = initialPosition;
this.restitution = restitution;
this.friction = friction;
this.radius = radius;
}
@override
Body createBody() {
return world
.createBody(
BodyDef(
angularDamping: 0.8,
position: initialPosition,
type: BodyType.static,
userData: this,)
)
..createFixture(
FixtureDef(
CircleShape()..radius = radius,
restitution: restitution,
friction: friction,)
// ..filter.categoryBits = holeBodyCategory
// ..filter.maskBits = ~ballBodyCategory
);
}
render(Canvas canvas) {
// canvas.drawCircle(Offset(0, 0), radius, Paint()..color = Color(0xffff0000));
}
@override
void beginContact(Object other, Contact contact) {
if(other is Ball){
// print('begin contact with ball');
world.remove(other);
}
super.beginContact(other, contact);
}
}
很多東西其實是多餘的!
例如:它不需要接受建構產生時可以設定諸多參數的能力,它只需要能設定位置與大小即可。(未來可能還要能設定「碰撞發生時的處理方式」。)
但大致上來說,這樣就可以在「Hole」上設置一個「碰撞後將Ball消除」的區塊,藉此產生「碰到Hole的中心時會將Ball消除(Ball會掉進Hole裡)」的遊戲效果。
(上圖將本該是隱形的碰撞區加上個紅色。)
這樣做的方式有個問題就是:遊戲設計上,「Ball」與「Hole」有大小區別,大的「Ball」不會掉進小的「Hole」中,一旦大的「Ball」與小的「Hole」發生碰撞時,「穿越」會取代「彈開」,但物理引擎預設的效果似乎並不會管這種邏輯,但原本的作法就可以輕鬆克服這點。
if((hole.body.position - body.position).length < hole.radius/2 + radius/2){
world.remove(this);
break;
}
可以看到這段原本「Ball」中用來判斷「是否穿過Hole的中心、是否要消除自己」的程式碼,只要在裡面增加對「hole.radius」與「ball.radius」的判斷即可做到這個效果。
但現在這段功能等於被移除、或無作用,那該怎麼使用標準功能解決呢?.....