CoRサンプル集: 矩形当たり判定サンプル

回転する矩形同士の当たり判定処理を行う
サンプルスクリプトです

_/_/_/_/_/ 操作方法 _/_/_/_/_/
方向キー:画像A(ビーム)の移動
Zキー:画像A(ビーム)の回転

スクリプトの参照はこちらから
プレー:24 (人数:23) クリア: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
投稿者:Cdv30200 aoi icon mini aoihikawa 対象Lv1 公開日:2022年08月19日 04:29:12
プレー内容を公開する

違反を通報する

コメントする

コメントするには、ログインする必要があります。

コメント一覧

Material 71926 1 mini なとおとき(投稿日:2022/08/28 20:06, 履歴)
2線分の交点を求める論理に感動しました。「ABをs:(1-s)に内分する」のsを、Aから見てもBから見ても同符号(正)になれば内分されている、とするのは初めて見た気がします。衝撃です。
プレー履歴

プレー履歴はありません。

全てのプレー履歴を見る

新着レビュー

レビューはまだ投稿されていません。 作品の感想を作者に伝えるためにレビューを投稿してみませんか?

全てのレビュー

フォロー/シェア

ブログ/Wiki/掲示板で共有する

Rmake内(ブログ/Wiki/掲示板)に貼り付ける場合は以下のタグを利用してください。

リンク

プレイヤー

外部ホームページに貼り付ける

外部ホームページに貼り付ける場合は以下のタグを利用してください。