質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.11%

Processingの円の当たり判定

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,070

score 32

球の当たり判定

キャラクターをマウスで動かして、ランダムな位置に置かれた円に触れたら、また別のランダムな位置に円を置くというプログラムを作成したいです。
操作する円を bullet 、ランダムに描かれる円を target としました。

疑問点は、

・if以下に打ち込むべきコードがわからない
・sqrt()を用いると良い とヒントが与えられているのですが、調べても求める検索結果が出てこないのでわからない

です

```processing
float targetX = random(380);
float targetY = random(380);
int manX;
int manY;
int random;
float r1; //bulletの半径
float r2; //targetの半径
float d = r1 + r2; 

void man() {
fill(0);
rect(manX, manY, 50, 30);
rect(manX - 10, manY + 20, 70, 10);
fill(255);
rect(manX, manY + 10, 50, 10);
rect(manX + 2, manY + 30, 46, 25);
circle(manX + 20, manY + 40, 15);
circle(manX + 45, manY + 40, 15);
}

void bullet() {
fill(#FF0000);
ellipse(manX, manY, 30, 30);
}

void target() {
fill(#DCE83D);
circle(targetX, targetY, 50);
}

void draw() {
background(255);

manX = 100 - 30;
manY = 100 - 30;
man();

manX = mouseX;
manY = mouseY;
bullet();

bullet();
target();

if ((targetX - mouseX) * (targetX - mouseX) + (targetY - mouseY) * (targetY - mouseY) <= (r1 + r2) * (r1 + r2)) {

}
}

void setup() {
size(480, 480);
}

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

まずr1とr2を初期化しましょう
この場合の初期化とは
「変数に最初に具体的な値を代入する事」です

例えばコードの1・2行目であなたは変数の宣言と初期化を同時にやっています

float targetX = random(380);
float targetY = random(380);

しかしr1とr2に関してはこれが行われている所がありません

またr1とr2は
bullet()とtarget()の関数定義の中で使用されていないので
このままだとr1とr2はそれぞれ半径としての役割を果たせません

上の2カ所を修正しさえすれば
あなたの書いた下の条件式は
書き直さなくてもあなたの要求を一応は満たします

(targetX - mouseX) * (targetX - mouseX) + (targetY - mouseY) * (targetY - mouseY) <= (r1 + r2) * (r1 + r2)


※この式は「距離」を比較する式ではなく「距離の2乗」を比較する式になっています


おたずねのif文の中に何を書けばいいかですが
単純にターゲットの座標を初期化すればいいでしょう
この場合の初期化
「今までの流れとは無関係に変数に新たな値を代入する事」を意味します


ちなみに
様々なコーディングスタイルがあると思いますが
私は下のような感じでProcessingのコードを書いています

この形のほうが変数の初期化・変化など見通しが良くなると思うのですが......

int num = 120;//プログラム実行中、変化しない値はここで宣言+初期化
float a,b,c,d;//プログラム実行中、変化する値は宣言のみ

//setup 関数
//プログラムの開始に1回実行される
void setup()
{
        size(480, 480);

        //プログラム実行中、変化する値はここで初期化
        a = 10.0;
        b = 30.0;

        //初期化用の関数を使って初期化することもある
        reset();
}

//draw 関数
//setupの実行後、自動的に繰り返し実行される
void draw()
{
        background(255);

        c += 3.0;
        d += 3.0;
        func0();

        if(frameCount%num==0){
                func1();
                reset();
        }

        if(frameCount%(num*5)==0){
                setup();//setup 関数を使用すると強制的に最初の状態にすることができる
        }
}



//↓以降その他の関数定義
void reset()
{
        c =  20.0;
        d =  40.0;
}

void func0()
{
        ellipse(c,d,a,a);
        ellipse(c+2*a,d+2*a,b,b);
}

void func1()
{
        a +=  10.0;
        b +=  30.0;
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/07/05 22:50

    私だったら、定数にはfinalを付けて変更不可にしちゃいます。あと、定数名は大文字(これはC系の文化かな?)。
    final int NUM=12; //NUMの値は変更できない

    キャンセル

0

プログラミングってのは検索の結果を写すものじゃないんですけど...

・if以下に打ち込むべきコードがわからない

「別のランダムな位置に円を置く」でいいんでしょ? 細かく言うと「別の」がちょっと引っかかるけど(ランダムというのは今の状況と関係なく新しい場所が決まるわけだから、本当にランダムにすると今と同じ位置になる可能性はわずかながらある)、
とりあえずプログラムの最初に「ランダムな位置に円を置く」をやっているのだから、それに準じた(そのまま、じゃダメかもね)処理をすればいいんじゃないですか?

・sqrt()を用いると良い とヒントが与えられているのですが

それが絡みそうなのは(targetX - mouseX) * (targetX - mouseX) + (targetY - mouseY) * (targetY - mouseY) <= (r1 + r2) * (r1 + r2)のところぐらいですけれど、これにsqrtを絡ませたところで当たり判定の結果に影響はないので、意味がないです。むしろ計算が増えるだけ無駄と言えましょう。Processingでは2点間の距離を求めるdist()という関数があるので、これを使えというならまだ理解できます。用意されている関数をわざわざ自分で再現するのは訓練以外には全く利がありません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.11%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る