忙了十天半個月,目的除了「在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;
}
(大致上可以運行,但是需要繼續測試微調。)