CoRサンプル集: 矩形当たり判定サンプル
回転する矩形同士の当たり判定処理を行う
サンプルスクリプトです
_/_/_/_/_/ 操作方法 _/_/_/_/_/
方向キー:画像A(ビーム)の移動
Zキー:画像A(ビーム)の回転
スクリプトの参照はこちらから
サンプルスクリプトです
_/_/_/_/_/ 操作方法 _/_/_/_/_/
方向キー:画像A(ビーム)の移動
Zキー:画像A(ビーム)の回転
スクリプトの参照はこちらから
プレー:22
(人数:21)
クリア:0
評価: 10 (1回)
#-------------------
#矩形当たり判定
#-------------------
#_/_/_/_/_/ 構造体 _/_/_/_/_/
#ポインタ
S_pointer = Struct.new(:name, :x, :y)
#_/_/_/_/_/ ユーザ関数 _/_/_/_/_/
#角度をラジアンに変更
def getRad(r)
return (r * Math::PI / 180)
end
#ラジアンを角度に変更
def getAngle(r)
return (180 / Math::PI * r)
end
#開始座標と角度と距離から終点座標を求める
def getDistancePos(s_p, r, ren)
wrk_r = getRad(r)
wrk_p = S_pointer.new('wrk_p', nil, nil)
wrk_p.x = s_p.x - Math.cos(wrk_r) * ren
wrk_p.y = s_p.y - Math.sin(wrk_r) * ren
return wrk_p
end
#線分同士の当たり判定
def getIntersection(a_p1, a_p2, b_p1, b_p2)
ret = false
if(((a_p1.x - a_p2.x) * (b_p1.y - a_p1.y) + (a_p1.y - a_p2.y) * (a_p1.x - b_p1.x)) *
((a_p1.x - a_p2.x) * (b_p2.y - a_p1.y) + (a_p1.y - a_p2.y) * (a_p1.x - b_p2.x)) < 0)
if(((b_p1.x - b_p2.x) * (a_p1.y - b_p1.y) + (b_p1.y - b_p2.y) * (b_p1.x - a_p1.x)) *
((b_p1.x - b_p2.x) * (a_p2.y - b_p1.y) + (b_p1.y - b_p2.y) * (b_p1.x - a_p2.x)) < 0)
ret = true
end
end
return ret
end
#矩形同士の当たり判定
def getCollision(a_pos_x, a_pos_y, a_size_w, a_size_h, a_r,
b_pos_x, b_pos_y, b_size_w, b_size_h, b_r)
ret = false
#--- 各矩形の4点の座標を求める ---
#Aの中心点
A_C = S_pointer.new('A_C', a_pos_x, a_pos_y)
wrk_ren = Math.sqrt((a_size_w / 2) ** 2 + (a_size_h / 2) ** 2)
#Aの左上
wrk_r = getAngle(Math.atan2((a_size_h / 2) * (1), (a_size_w / 2) * (1)))
wrk_pos = getDistancePos(A_C, (a_r + wrk_r), wrk_ren)
wrk_pos_x = wrk_pos.x; wrk_pos_y = wrk_pos.y
A_u_l = S_pointer.new('A_u_l', wrk_pos_x, wrk_pos_y)
#Aの右上
wrk_r = getAngle(Math.atan2((a_size_h / 2) * (1), (a_size_w / 2) * (-1)))
wrk_pos = getDistancePos(A_C, (a_r + wrk_r), wrk_ren)
wrk_pos_x = wrk_pos.x; wrk_pos_y = wrk_pos.y
A_u_r = S_pointer.new('A_u_r', wrk_pos_x, wrk_pos_y)
#Aの左下
wrk_r = getAngle(Math.atan2((a_size_h / 2) * (-1), (a_size_w / 2) * (1)))
wrk_pos = getDistancePos(A_C, (a_r + wrk_r), wrk_ren)
wrk_pos_x = wrk_pos.x; wrk_pos_y = wrk_pos.y
A_d_l = S_pointer.new('A_d_l', wrk_pos_x, wrk_pos_y)
#Aの右下
wrk_r = getAngle(Math.atan2((a_size_h / 2) * (-1), (a_size_w / 2) * (-1)))
wrk_pos = getDistancePos(A_C, (a_r + wrk_r), wrk_ren)
wrk_pos_x = wrk_pos.x; wrk_pos_y = wrk_pos.y
A_d_r = S_pointer.new('A_d_r', wrk_pos_x, wrk_pos_y)
#Bの中心点
B_C = S_pointer.new('B_C', b_pos_x, b_pos_y)
wrk_ren = Math.sqrt((b_size_w / 2) ** 2 + (b_size_h / 2) ** 2)
#Bの左上
wrk_r = getAngle(Math.atan2((b_size_h / 2) * (1), (b_size_w / 2) * (1)))
wrk_pos = getDistancePos(B_C, (b_r + wrk_r), wrk_ren)
wrk_pos_x = wrk_pos.x; wrk_pos_y = wrk_pos.y
B_u_l = S_pointer.new('B_u_l', wrk_pos_x, wrk_pos_y)
#Bの右上
wrk_r = getAngle(Math.atan2((b_size_h / 2) * (1), (b_size_w / 2) * (-1)))
wrk_pos = getDistancePos(B_C, (b_r + wrk_r), wrk_ren)
wrk_pos_x = wrk_pos.x; wrk_pos_y = wrk_pos.y
B_u_r = S_pointer.new('B_u_r', wrk_pos_x, wrk_pos_y)
#Bの左下
wrk_r = getAngle(Math.atan2((b_size_h / 2) * (-1), (b_size_w / 2) * (1)))
wrk_pos = getDistancePos(B_C, (b_r + wrk_r), wrk_ren)
wrk_pos_x = wrk_pos.x; wrk_pos_y = wrk_pos.y
B_d_l = S_pointer.new('B_d_l', wrk_pos_x, wrk_pos_y)
#Bの右下
wrk_r = getAngle(Math.atan2((b_size_h / 2) * (-1), (b_size_w / 2) * (-1)))
wrk_pos = getDistancePos(B_C, (b_r + wrk_r), wrk_ren)
wrk_pos_x = wrk_pos.x; wrk_pos_y = wrk_pos.y
B_d_r = S_pointer.new('B_d_r', wrk_pos_x, wrk_pos_y)
#--- 各矩形の4点の座標から線分の当たり判定を求める ---
#--- (何れか1本でも交われば、当たっていると判定) ---
#Aの上、Bの上
wrk_flg = getIntersection(A_u_l, A_u_r, B_u_l, B_u_r)
if wrk_flg then ret = true; end
#Aの上、Bの下
wrk_flg = getIntersection(A_u_l, A_u_r, B_d_l, B_d_r)
if wrk_flg then ret = true; end
#Aの上、Bの左
wrk_flg = getIntersection(A_u_l, A_u_r, B_u_l, B_d_l)
if wrk_flg then ret = true; end
#Aの上、Bの右
wrk_flg = getIntersection(A_u_l, A_u_r, B_u_r, B_d_r)
if wrk_flg then ret = true; end
#Aの下、Bの上
wrk_flg = getIntersection(A_d_l, A_d_r, B_u_l, B_u_r)
if wrk_flg then ret = true; end
#Aの下、Bの下
wrk_flg = getIntersection(A_d_l, A_d_r, B_d_l, B_d_r)
if wrk_flg then ret = true; end
#Aの下、Bの左
wrk_flg = getIntersection(A_d_l, A_d_r, B_u_l, B_d_l)
if wrk_flg then ret = true; end
#Aの下、Bの右
wrk_flg = getIntersection(A_d_l, A_d_r, B_u_r, B_d_r)
if wrk_flg then ret = true; end
#Aの左、Bの上
wrk_flg = getIntersection(A_u_l, A_d_l, B_u_l, B_u_r)
if wrk_flg then ret = true; end
#Aの左、Bの下
wrk_flg = getIntersection(A_u_l, A_d_l, B_d_l, B_d_r)
if wrk_flg then ret = true; end
#Aの左、Bの左
wrk_flg = getIntersection(A_u_l, A_d_l, B_u_l, B_d_l)
if wrk_flg then ret = true; end
#Aの左、Bの右
wrk_flg = getIntersection(A_u_l, A_d_l, B_u_r, B_d_r)
if wrk_flg then ret = true; end
#Aの右、Bの上
wrk_flg = getIntersection(A_u_r, A_d_r, B_u_l, B_u_r)
if wrk_flg then ret = true; end
#Aの右、Bの下
wrk_flg = getIntersection(A_u_r, A_d_r, B_d_l, B_d_r)
if wrk_flg then ret = true; end
#Aの右、Bの左
wrk_flg = getIntersection(A_u_r, A_d_r, B_u_l, B_d_l)
if wrk_flg then ret = true; end
#Aの右、Bの右
wrk_flg = getIntersection(A_u_r, A_d_r, B_u_r, B_d_r)
if wrk_flg then ret = true; end
return ret
end
#画像オブジェクトの透明度を設定
def setAlpha(obj, a)
wrk_obj = obj.instance_variable_get('@js_sprite')
wrk_obj.alpha = a
end
scene 'start' do
#_/_/_/ ローカル変数の定義 _/_/_/
#キー入力
key_flg_up_st = nil; key_flg_up_do = nil; key_flg_up_en = nil
key_flg_down_st = nil; key_flg_down_do = nil; key_flg_down_en = nil
key_flg_left_st = nil; key_flg_left_do = nil; key_flg_left_en = nil
key_flg_right_st = nil; key_flg_right_do = nil; key_flg_right_en = nil
key_flg_z_st = nil; key_flg_z_do = nil; key_flg_z_en = nil
#画像オブジェクト
obj_image_A_key_up = nil
obj_image_A_key_down = nil
obj_image_A_key_left = nil
obj_image_A_key_right = nil
obj_image_A_key_z = nil
obj_image_A_spr = nil
obj_image_A_pos_x = nil
obj_image_A_pos_y = nil
obj_image_A_size_w = nil
obj_image_A_size_h = nil
obj_image_A_r = nil
obj_image_A_pos_x_old = nil
obj_image_A_pos_y_old = nil
obj_image_A_r_old = nil
obj_image_B_spr = nil
obj_image_B_pos_x = nil
obj_image_B_pos_y = nil
obj_image_B_size_w = nil
obj_image_B_size_h = nil
obj_image_B_r = nil
obj_image_B_alpha = nil
obj_image_B_alpha_old = nil
preload do
#_/_/_/ 素材のロード _/_/_/
#画像A
image 'img_image_A', id: 77342
#画像B
image 'img_image_B', id: 79094
end
create do
#_/_/_/ 変数の初期化 _/_/_/
#--- キー入力 ---
key_flg_up_st = false; key_flg_up_do = false; key_flg_up_en = false
key_flg_down_st = false; key_flg_down_do = false; key_flg_down_en = false
key_flg_left_st = false; key_flg_left_do = false; key_flg_left_en = false
key_flg_right_st = false; key_flg_right_do = false; key_flg_right_en = false
key_flg_z_st = false; key_flg_z_do = false; key_flg_z_en = false
#--- 画像オブジェクト ---
obj_image_A_key_up = false
obj_image_A_key_down = false
obj_image_A_key_left = false
obj_image_A_key_right = false
obj_image_A_key_z = nil
obj_image_A_pos_x = (800 / 2)
obj_image_A_pos_y = (600 - 128)
obj_image_A_size_w = (14 * 2)
obj_image_A_size_h = (64 * 2)
obj_image_A_r = 0
obj_image_A_pos_x_old = obj_image_A_pos_x
obj_image_A_pos_y_old = obj_image_A_pos_y
obj_image_A_r_old = obj_image_A_r
obj_image_B_pos_x = (800 / 2)
obj_image_B_pos_y = (600 / 2)
obj_image_B_size_w = (32 * 2)
obj_image_B_size_h = (32 * 2)
obj_image_B_r = 0
obj_image_B_alpha = 1
obj_image_B_alpha_old = obj_image_B_alpha
#_/_/_/ 素材の初期化 _/_/_/
#画像A
obj_image_A_spr = put_sprite 'spr_image_A' do
position obj_image_A_pos_x, obj_image_A_pos_y
src_rect 0, 0, 16, 64
end
obj_image_A_spr.scale 2, 2
#画像B
obj_image_B_spr = put_sprite 'spr_image_B' do
position obj_image_B_pos_x, obj_image_B_pos_y
src_rect (32 * 7), (32 * 5), 32, 32
end
obj_image_B_spr.scale 2, 2
end
update do
#_/_/_/ 入力の判定 _/_/_/
#キー入力判定
if keyboard.down?('UP')
key_flg_up_st = true
else
key_flg_up_st = false
key_flg_up_do = false
end
if keyboard.down?('DOWN')
key_flg_down_st = true
else
key_flg_down_st = false
key_flg_down_do = false
end
if keyboard.down?('LEFT')
key_flg_left_st = true
else
key_flg_left_st = false
key_flg_left_do = false
end
if keyboard.down?('RIGHT')
key_flg_right_st = true
else
key_flg_right_st = false
key_flg_right_do = false
end
if keyboard.down?('Z')
key_flg_z_st = true
else
key_flg_z_st = false
key_flg_z_do = false
end
#_/_/_/ メイン処理 _/_/_/
#キー入力処理
if (key_flg_up_st && !key_flg_up_do)
key_flg_up_do = true
obj_image_A_key_up = true
elsif key_flg_up_do
key_flg_up_en = true
obj_image_A_key_up = true
elsif key_flg_up_en
key_flg_up_en = false
obj_image_A_key_up = false
end
if (key_flg_down_st && !key_flg_down_do)
key_flg_down_do = true
obj_image_A_key_down = true
elsif key_flg_down_do
key_flg_down_en = true
obj_image_A_key_down = true
elsif key_flg_down_en
key_flg_down_en = false
obj_image_A_key_down = false
end
if (key_flg_left_st && !key_flg_left_do)
key_flg_left_do = true
obj_image_A_key_left = true
elsif key_flg_left_do
key_flg_left_en = true
obj_image_A_key_left = true
elsif key_flg_left_en
key_flg_left_en = false
obj_image_A_key_left = false
end
if (key_flg_right_st && !key_flg_right_do)
key_flg_right_do = true
obj_image_A_key_right = true
elsif key_flg_right_do
key_flg_right_en = true
obj_image_A_key_right = true
elsif key_flg_right_en
key_flg_right_en = false
obj_image_A_key_right = false
end
if (key_flg_z_st && !key_flg_z_do)
key_flg_z_do = true
obj_image_A_key_z = true
elsif key_flg_z_do
key_flg_z_en = true
obj_image_A_key_z = true
elsif key_flg_z_en
key_flg_z_en = false
obj_image_A_key_z = false
end
#画像Aの操作
#移動
if obj_image_A_key_up
obj_image_A_pos_y -= 2
end
if obj_image_A_key_down
obj_image_A_pos_y += 2
end
if obj_image_A_key_left
obj_image_A_pos_x -= 2
end
if obj_image_A_key_right
obj_image_A_pos_x += 2
end
#回転
if obj_image_A_key_z
obj_image_A_r += 1
end
#画像Bをゆっくりと回転させる
obj_image_B_r += 1
if obj_image_B_r > 360
obj_image_B_r -= 360
end
#********************
#画像Aと画像Bの当たり判定を求める
wrk_flg = getCollision(obj_image_A_pos_x, obj_image_A_pos_y,
obj_image_A_size_w, obj_image_A_size_h,
obj_image_A_r,
obj_image_B_pos_x, obj_image_B_pos_y,
obj_image_B_size_w, obj_image_B_size_h,
obj_image_B_r)
#********************
#当たっていた場合、画像Bの透明度を変更する
if wrk_flg
obj_image_B_alpha = 0.5
else
obj_image_B_alpha = 1
end
end
render do
#画像Aの移動
if (obj_image_A_pos_x != obj_image_A_pos_x_old) ||
(obj_image_A_pos_y != obj_image_A_pos_y_old)
obj_image_A_pos_x_old = obj_image_A_pos_x
obj_image_A_pos_y_old = obj_image_A_pos_y
obj_image_A_spr.position obj_image_A_pos_x, obj_image_A_pos_y
end
#画像Aの回転
if obj_image_A_r != obj_image_A_r_old
obj_image_A_r_old != obj_image_A_r
wrk_r = getRad(obj_image_A_r)
obj_image_A_spr.rotation wrk_r
end
#画像Bの回転
wrk_r = getRad(obj_image_B_r)
obj_image_B_spr.rotation wrk_r
#画像Bの透明度
if obj_image_B_alpha != obj_image_B_alpha_old
obj_image_B_alpha_old = obj_image_B_alpha
setAlpha(obj_image_B_spr, obj_image_B_alpha)
end
end
end
#_/_/_/_/_/ 素材の定義 _/_/_/_/_/
#画像A
sprite 'spr_image_A' do
image 'img_image_A'
origin :center
end
#画像B
sprite 'spr_image_B' do
image 'img_image_B'
origin :center
end
#_/_/_/_/_/ シーンの開始 _/_/_/_/_/
start_scene 'start'
コード一覧
- start.rb
プレー内容を公開する
コメントする
コメントするには、ログインする必要があります。
コメント一覧
なとおとき(投稿日:2022/08/28 20:06,
履歴)
2線分の交点を求める論理に感動しました。「ABをs:(1-s)に内分する」のsを、Aから見てもBから見ても同符号(正)になれば内分されている、とするのは初めて見た気がします。衝撃です。
プレー履歴
プレー履歴はありません。
新着レビュー
レビューはまだ投稿されていません。 作品の感想を作者に伝えるためにレビューを投稿してみませんか?
フォロー/シェア