🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

Q&A

解決済

1回答

3066閲覧

弾幕ゲームの作成に関して

plarex

総合スコア12

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

0グッド

0クリップ

投稿2018/05/05 06:47

編集2018/05/06 12:57

使用している画像

pStart
pGameclear
pGameover
pGameback

実現したいこと

レーザーとボス、自機と弾幕の当たり判定がうまくいきません

発生している問題・エラーメッセージ

動くことは動くが当たり判定が出ない

該当のソースコード

PImage pStart;
PImage pGameback;
PImage pGameover;
PImage pGameclear;

Bullet bullet;
Ship ship;
Boss boss;
GameStage gamestage;

private ArrayList<Bullet> danmaku = new ArrayList<Bullet>();
enum GameScene {
START, PLAY, CLEAR, OVER;
}
private GameScene scene = GameScene.START;

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

frameRate(30);

noCursor(); // clear mouse cursor

pStart = loadImage("start.png");
pGameback = loadImage("back.png");
pGameover = loadImage("gameover.png");
pGameclear = loadImage("gameclear.png");

bullet = new Bullet(width/2, height/2, 20, 0, 0 );//クラスからインスタンスを生成
ship = new Ship(mouseX,mouseY);
gamestage = new GameStage() ;
boss = new Boss(160, 150);
}

//GameStage class
class GameStage {

void update() { boss.doShinking(); //画面切り替え if (ship.hp == 0) { scene = GameScene.OVER; } if (boss.hp == 0) { scene = GameScene.CLEAR; } }

}

// ship(自機) class
class Ship {
private int sx, sy;
private int hp = 1;
boolean is_Alive() {
//return is_alive;
return hp != 0;
}
Ship(int x, int y) {
sx = x;
sy = y;
}
void update(int x, int y) {
sx = x;
sy = y;
stroke(255, 255, 255);
noFill();

} //hit check void damage() { if (abs(ship.sx -boss.tx) < (boss.bw/2)) { boss.hp--; } }

}

// Boss class
class Boss {
private int tx, ty;
private int dx, dy;
private int bw = 20;
private int bh = 10;
private long routine = 0;
private int hp = 10;
boolean isAlive() {
//return is_alive;
return hp != 0;
}

Boss(int x, int y) { tx = x; ty = y; dx = 10; dy = -8; } void move() { tx += dx; ty += dy; if (tx < 0 || tx > width) { dx*= -1; } if (ty < 0 || ty > height/3) { dy*= -1; } stroke(255, 204, 0); } void doShinking() { routine++; if (routine % 10 == 0) { move(); } if (routine % 30 == 0) { danmaku.addAll(this.shot()); println("#shot!!" +routine + ":" + tx + "," + ty); } } //hit check  void damage() { if (dist(tx, ty, ship.sx, ship.sy) < bullet.tr/2) { ship.hp--; } } ArrayList<Bullet> shot() { ArrayList<Bullet> danmaku = new ArrayList(); for (int i = 0; i < 360; i+= 10) { //インスタンス(弾幕)の作成 double rad = radians(i); danmaku.add(new Bullet(this.tx, this.ty, 10, Math.cos(rad), Math.sin(rad))); } return danmaku;

}

// Bullet(弾幕) class

class Bullet {
private double tx, ty;
private final double tr;
private double dx, dy;
private boolean is_alive = true;
Bullet(double x, double y, double r, double temp_dx, double temp_dy ) {
tx = x;
ty = y;
tr = r;
dx = temp_dx;
dy = temp_dy;
}
boolean isAlive() {
return is_alive;
}
void update() {
tx += dx;
ty += dy;
//area check
if (Math.min(tx, ty) < 0) {
is_alive = false;
//println("#" + tx + "," + ty);
return ;
}
if (tx > width || ty > height) {
is_alive = false;
return ;
}

stroke(255, 0, 0); ellipse((float)tx, (float)ty, (float)tr, (float)tr); }

}
void draw() {
rect(boss.tx - boss.bw/2, boss.ty + boss.bh/2, boss.bw, boss.bh);
fill(255,0,0);
text("boss.hp",100,100);
fill(255,255,255);

background(0); // clear triangle(mouseX, mouseY -7, mouseX - 10, mouseY + 7, mouseX + 10, mouseY + 7); boss.damage(); ship.damage(); //レーザーの描写 if (mousePressed) { line(mouseX, mouseY - 7, mouseX, 0); } for (int i = danmaku.size() -1; i >= 0; i--) { Bullet b = (Bullet)danmaku.get(i); if (!b.isAlive()) { danmaku.remove(i); continue; } b.update(); } if (scene == GameScene.START) { image(pStart, 0, 0); } if (mousePressed) { if (mouseButton == LEFT) { scene = GameScene.PLAY; } } if (scene == GameScene.PLAY) { gamestage.update(); //image(pGameback,0,0); } if (scene == GameScene.OVER) { image(pGameover, 0, 0); } if (scene == GameScene.CLEAR) { image(pGameclear, 0, 0); }

}

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

umyu

2018/05/05 21:34

1,start.pngなどの画像がないので、デバックできません。質問文に追記してくださいな。2,一般的な衝突検知と衝突応答の基礎知識については大丈夫でしょうか?
guest

回答1

0

ベストアンサー

ship(mouseX, mouseY);

shipクラスのインスタンスをsetup()メソッドで生成していないような。


質問内容が全面的に変わっている(汗)ので追記。

弾幕の判定に関して矩形の衝突とはなにか。
物体Aと物体Bの座標が重なっている部分があること。
イメージ説明
逆にいうと座標が重なっていなければの判定ができれば、背理法で衝突検知はできます。

自機から発射するレーザーも消える条件が特殊な弾の一種と考えるとよいですよ。
自機から発射した弾なのか。
ボスが発射した弾なのか。
Bulletクラスを生成時に渡して、それで判断すれば良いです。

この2つの条件が両方ともtrueならば衝突しているという事です。

Java

1if((A.Left < B.Right) && (A.Right > B.Left)) { 2 return true; 3} 4return false;

Java

1if((A.Top < B.Bottom) && (A.Bottom > B.Top)) { 2 return true; 3} 4return false;

判定を纏めると以下になります。

Java

1if((A.Top < B.Bottom) && (A.Bottom > B.Top)) { 2 if((A.Left < B.Right) && (A.Right > B.Left)) { 3 return true; 4 } 5} 6return false;

衝突検知はパフォーマンスの問題が出てくると思うので、
弾幕データのY軸で事前にソートして衝突検知は二分探索で判定する事をお勧めします。

最後に回答に対するフィードバックが一切無い方みたいなので、私はここでギブアップさせて頂きます。
あとは頑張ってくださいな。
◇参考情報
4-2. どのように解決したのかを伝えましょう

投稿2018/05/05 07:03

編集2018/05/05 22:21
umyu

総合スコア5846

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

plarex

2018/05/06 13:13

画像載せ忘れてました。すみません。 レーザーとボスの衝突判定はこれでいけましたが【 if (abs(mouseX -boss.tx) < 10) { boss.hp--; } 】 弾と自機は【if (Math.abs(bullet.tx - ship.sx) < 5 && Math.abs(bullet.ty - ship.sy) < 5) { ship.hp--; }】でいけるかなと思ったのですがまだうまくいってませんが、頑張って動くようにしたいと思います。 二分分割もまだ勉強不足なので勉強します。。。 それと、回答に対するフィードバックをしてなくてすみません気を付けます。。。今まで質問に回答していただきありがとうございました。
plarex

2018/05/06 13:13

画像載せ忘れてました。すみません。 レーザーとボスの衝突判定はこれでいけましたが【 if (abs(mouseX -boss.tx) < 10) { boss.hp--; } 】 弾と自機は【if (Math.abs(bullet.tx - ship.sx) < 5 && Math.abs(bullet.ty - ship.sy) < 5) { ship.hp--; }】でいけるかなと思ったのですがまだうまくいってませんが、頑張って動くようにしたいと思います。 二分分割もまだ勉強不足なので勉強します。。。 それと、回答に対するフィードバックをしてなくてすみません気を付けます。。。今まで質問に回答していただきありがとうございました。
umyu

2018/05/06 13:49 編集

>plarexさんへ フィードバック情報ありがとうございました。 えっとですね、私としてはお礼の言葉はあまり気にしてなくて、 plarexさんと同じ課題(問題)を持った人が将来このページを見た時にplarexさんがどう解決したのかが知りたいと思うのです。それだけですー。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問