Polygon2Dを分割するサンプルを作りました
目次
Polygon2Dを分割するサンプル
今回はソースコードとサンプルプロジェクトのみです。まだ不十分なところも多いので、今後修正される可能性があります
- 分割する対象を最初に存在するオブジェクト($obj)のみとしています(切れなかったときの判定が未実装)
- 分割後にオブジェクトの Rigidbody2D の移動値が初期化されています
サンプルコード
extends Node2D
# マウス開始座標
var start_pos = Vector2()
# カットするオブジェクト(Rigit2D)
onready var obj = $obj
func _process(delta: float) -> void:
if Input.is_action_just_pressed("ui_click"):
start_pos = get_global_mouse_position()
if Input.is_action_just_released("ui_click"):
var end_pos = get_global_mouse_position()
var dir = end_pos - start_pos
var distance = dir.length()
dir = dir.normalized() # 方向はノーマライズ必須.
var ofs = obj.position
var pos = start_pos - ofs # オフセットを消しておく
# カットするシェイプを作成
var cut_shape = create_beam_polygon(dir, distance, 3, 3, pos)
var cut_p = Polygon2D.new()
# 表示用は位置が異なる
var cut_shape2 = create_beam_polygon(dir, distance, 3, 3, start_pos)
cut_p.set_polygon(cut_shape2)
add_child(cut_p)
# ポリゴン分割する
var new_polygons:Array = Geometry.clip_polygons_2d($obj/Polygon2D.polygon, cut_shape)
obj.queue_free()
# 分割したポリゴンを生成
for p in new_polygons:
var rigid = RigidBody2D.new()
var poly = Polygon2D.new()
var col = CollisionPolygon2D.new()
poly.set_polygon(p)
poly.modulate = Color.red
col.set_polygon(p)
rigid.position = ofs # オフセットを足し込む
rigid.add_child(poly)
rigid.add_child(col)
add_child(rigid)
#creates a beam with a seperate start and end width
# https://github.com/SoloByte/godot-polygon2d-fracture
# @param dir 方向
# @param distance 距離
# @param start_width 開始の幅
# @param end_width 終端の幅
# @param start_point_local
func create_beam_polygon(dir : Vector2, distance : float, start_width : float, end_width : float, start_point_local := Vector2.ZERO) -> PoolVector2Array:
var beam : PoolVector2Array = []
if distance == 0:
return beam
if start_width <= 0.0 and end_width <= 0.0:
return beam
if distance < 0:
dir = -dir
distance *= -1.0
var end_point : Vector2 = start_point_local + (dir * distance)
var perpendicular : Vector2 = dir.rotated(PI * 0.5)
if start_width <= 0.0:
beam.append(start_point_local)
beam.append(end_point + perpendicular * end_width * 0.5)
beam.append(end_point - perpendicular * end_width * 0.5)
elif end_width <= 0.0:
beam.append(start_point_local + perpendicular * start_width * 0.5)
beam.append(end_point)
beam.append(start_point_local - perpendicular * start_width * 0.5)
else:
beam.append(start_point_local + perpendicular * start_width * 0.5)
beam.append(end_point + perpendicular * end_width * 0.5)
beam.append(end_point - perpendicular * end_width * 0.5)
beam.append(start_point_local - perpendicular * start_width * 0.5)
return beam
マウスの移動に対応する線分のポリゴンを作るために、create_beam_polygon() という関数を使っています。この関数は、参考にしたプロジェクトからお借りしたものとなります