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

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

ただいまの
回答率

89.23%

円同士の衝突判定について

受付中

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 992

-noob-

score 13

c++初心者中の初心者です。いま円形のキャラクターをマウスで操作し、周りにいる複数の円形の敵にぶつかったら敵が止まるというプログラムを作っていて、キャラクターと敵を複数作り、動かすとこまでできたのですが、衝突判定の部分がうまくいかずてこずっています。
そこで教えてほしいことがあります、

ネットで調べたところhttp://www.gamecorder.net/collision/collision2.phpにかいてあるような衝突の考え方があったので、その通りにコードを書いたのですが、衝突していないのに敵が止まってしまいます。

#include "ofApp.h"
float x, y,r1, size1;
float X1[50], Y1[50], r[50], dx[50], dy[50];
int width,height,m, n;
//--------------------------------------------------------------
void ofApp::setup(){
    ofBackground(255, 255, 255);
    width = ofGetWidth();
    height = ofGetHeight();
    ofSetCircleResolution(64);
    size1 = 50;
    n = 15;
    r1 = 60;
    x = width / 2;
    y = height / 2;
    for (m = 0; m < n; m++) {
        r[m]= ofRandom(35.0, 50.0);
        X1[m] = r[m];
        Y1[m] = ofRandom(r[m], height - r[m]);
        dx[m] = ofRandom(5,10);
        dy[m] = ofRandom(5,10);
    }





}

//--------------------------------------------------------------
void ofApp::update(){

    for (m = 0; m < n; m++) {
        X1[m] = X1[m] + dx[m];
        if (X1[m] <= r[m] || X1[m] >= width - r[m]) {
            dx[m] = -dx[m];
        }
        Y1[m] = Y1[m] + dy[m];
        if (Y1[m] <= r[m] || Y1[m] >= height - r[m]) {
            dy[m] = -dy[m];
        }
        if (sqrt((x - X1[m])*(x - X1[m]) + (y - Y1[m])*(y - Y1[m])) <= (r[m] + r1)) {
            cout << "GAME OVER";
            dx[m] = 0;
            dy[m] = 0;
            break;
        }
    }

}

//--------------------------------------------------------------
void ofApp::draw(){
    int x = mouseX;
    int y = mouseY;
    //輪郭
    ofSetColor(184, 102, 9);
    ofDrawCircle(x, y, r1);
    //耳
    ofSetColor(184, 102, 9);
    ofDrawEllipse(x - size1 * 0.3067, y - size1 * 0.9833, size1 / 6, size1*0.833);
    ofDrawEllipse(x + size1 * 0.2933, y - size1 * 0.9833, size1 / 6, size1*0.833);
    //白目
    ofSetColor(255, 255, 255);
    ofDrawEllipse(x - size1 * 0.14, y - size1 * 0.333, size1*0.2333, size1*0.4);
    ofDrawEllipse(x + size1 * 0.1267, y - size1 * 0.333, size1*0.233, size1*0.4);
    //黒目
    ofSetColor(0, 32, 96);
    ofDrawEllipse(x - size1 * 0.073, y - size1 * 0.3, size1*0.1, size1*0.2);
    ofDrawEllipse(x + size1 * 0.0667, y - size1 * 0.3, size1*0.1, size1 / 5);
    //鼻
    ofSetColor(0, 32, 96);
    ofDrawEllipse(x + size1 / 30 * 0.1, y, size1 - size1 / 30 * 18.5, size1*0.2667);
    //鼻テカリ
    ofSetColor(255, 255, 255);
    ofDrawRectangle(x - size1 * 0.0733, y - size1 * 0.0667, size1*0.1333, size1*0.067);
    //右眉毛
    ofSetColor(0, 32, 96);
    ofDrawLine(x - size1 / 30 * 10.2, y - size1 / 30 * 13, x - size1 / 30 * 3.2, y - size1 / 30 * 22);
    ofSetLineWidth(4);
    //左眉毛
    ofSetColor(0, 32, 96);
    ofDrawLine(x + size1 / 30 * 9.8, y - size1 / 30 * 13, x + size1 / 30 * 3.3, y - size1 / 30 * 22);
    ofSetLineWidth(4);
    //口
    ofSetColor(0, 32, 96);
    ofDrawLine(x - size1 / 30 * 5.2, y + size1 / 30 * 13, x + size1 / 30 * 5.8, y + size1 / 30 * 13);
    ofSetLineWidth(4);

    //敵
    for (m = 0; m < n; m++) {
        //顔
        ofSetColor(80, 0, 204);
        ofDrawCircle(X1[m], Y1[m], r[m]);
        //白目
        ofSetColor(255, 255, 255);
        ofDrawCircle(X1[m] - r[m] / 2.5, Y1[m], r[m] / 5);
        ofDrawCircle(X1[m] + r[m] / 2.5, Y1[m], r[m] / 5);
        //赤目
        ofSetColor(255,0,0);
        ofDrawCircle(X1[m] - r[m] / 2.5, Y1[m], r[m] / 7);
        ofDrawCircle(X1[m] + r[m] / 2.5, Y1[m], r[m] / 7);
    }

}


どうすれば正常に動きますか?
ぜひとも回答をお願いします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • y_waiwai

    2018/11/09 08:00

    エラーメッセージを提示してください。省略せずに、そのまま貼り付けてください

    キャンセル

  • -noob-

    2018/11/09 16:05

    exitについて「'void ofBaseApp::exit(ofEventArgs &)':引数1を'int'から'ofEventArgs &'へ変換できません」と表示されています。

    キャンセル

回答 2

0

こんにちは。

#include "ofApp.h"をコメントアウトしてみましたが、とりあえず記載されている行ではエラーはでませんでした。(gcc, VC++) 該当のエラー・メッセージを全て記載するか、エラーを再現可能な最小のソースをご提示された方が正確な回答が付きやすいですよ。
    //↓エラーが出ますの行ではエラーがでましたが、恐らく質問の際に追加された行と思います。その際に全角スペースでインデントされているのだろうと思います。

「オーバーロードされた関数のインスタンスが引数リストと合致しません」は,ofApp.hの中でexit()関数が定義されているのではないかと思います。それは引数が1個ではないはずです。(だから引数リストが合わない)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/09 15:07

    全角スペース押してました。笑

    exit()についてですが、ofApp.hの中で定義はされていないと思います。
    ↓ofApp.h
    #pragma once

    #include "ofMain.h"

    class ofApp : public ofBaseApp{

    public:
    void setup();
    void update();
    void draw();

    void keyPressed(int key);
    void keyReleased(int key);
    void mouseMoved(int x, int y );
    void mouseDragged(int x, int y, int button);
    void mousePressed(int x, int y, int button);
    void mouseReleased(int x, int y, int button);
    void mouseEntered(int x, int y);
    void mouseExited(int x, int y);
    void windowResized(int w, int h);
    void dragEvent(ofDragInfo dragInfo);
    void gotMessage(ofMessage msg);

    }

    キャンセル

  • 2018/11/09 16:29

    ということは、ご提示のソースでは再現しないということですので、私にも分からないです。
    問題を再現できる最小のソースを提示されると解決しやすいですよ。
    そのようなソースを作っている過程で問題が解決することも多いです。解決しなければそのまま質問するとよいです。

    キャンセル

0

float X1[50], Y1[50], r[50], dx[50], dy[50];

if ((x - X1[50])*(x - X1[50]) + (y - Y1[50])*(y - Y1[50]) >= (r[50] + r1)*(r[50] + r1)) {

そもそも配列X1の有効なインデックス値は0~49なので、50はアクセス違反です。
ここはループでやるところではないでしょうか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/09 14:57

    確かにその通りでした。
    書き直します。

    キャンセル

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

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