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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Processing

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

Q&A

解決済

1回答

1545閲覧

弾の当たり判定の書き方,NullPointerの対処がわかりません。

hasegawa2718

総合スコア11

Processing

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

0グッド

0クリップ

投稿2019/01/13 01:24

前提・実現したいこと

Processing3でシューティングゲームを作っているのですが当たり判定の条件文でNullPointerExceptionとエラーが出てどう対処すればよいかわかりません。
80行目の
if(b.isAlive())
の中に

{敵のx座標<弾のx座標+弾の幅 &&
{弾のx座標<敵のx座標+敵の幅 &&
{敵のy座標<弾のy座標+弾の高さ &&
{弾のy座標<敵のy座標+敵の高さ

のように判定文を入れてるのですが、この書き方でいいのかもわかりません。
検索していろいろ調べたのですが結局わかりませんでした。どのようにすれば直るでしょうか。

該当のソースコード

Processing

1import ddf.minim.*; 2import ddf.minim.analysis.*; 3 4Minim minim; 5AudioPlayer BGM; 6AudioSample laser; 7FFT fft; 8int fftSize; 9 10PImage img,img_s,img_ss,pl,en; 11 12float mx = mouseX; 13float my = mouseY; 14int level = 0; 15ME me; 16ENEMY e; 17ArrayList<BEAM> beamList = new ArrayList<BEAM>(); 18ArrayList<ENEMY> enemyList = new ArrayList<ENEMY>(); 19float bvel; 20float bx; 21float by; 22float myGain; 23float bGain; 24int flag; 25boolean right; 26 27void setup(){ 28 size(1280, 720); 29 frameRate(90); 30 colorMode(RGB); 31 rectMode(CENTER); 32 me = new ME(); 33 textAlign(CENTER); 34 imageMode(CENTER); 35 img = loadImage("hosi.png"); 36 img_s = loadImage("hosi_s.png"); 37 img_ss = loadImage("hosi_ss.png"); 38 pl = loadImage("onpu.png"); 39 en = loadImage("enemy.png"); 40 minim = new Minim(this); 41 fftSize = 512; 42 laser = minim.loadSample("laser1.mp3"); 43 BGM = minim.loadFile("BGM.mp3"); 44 BGM.loop(); 45 myGain = BGM.getGain(); 46 bGain = laser.getGain(); 47 myGain = myGain - 20; 48 bGain = bGain - 40; 49 BGM.setGain(myGain); 50 laser.setGain(bGain); 51 fft = new FFT(BGM.bufferSize(), BGM.sampleRate()); 52 enemyList.add(new ENEMY()); 53} 54 55void draw(){ 56 if(level == 0){ 57 background(0); 58 fade(false); 59 textSize(32); 60 noFill(); 61 text("MouseRightButton is clicked to start", width/2, height/2); 62 } 63 64 if(level == 1){ 65 background(0); 66 fade(false); 67 me.move(mouseX,mouseY); 68 me.display(); 69 for(int i = enemyList.size()-1; i >= 0; i--){ 70 ENEMY e = enemyList.get(i); 71 if(e.isAlive()){ 72 e.move(); 73 e.display(); 74 }else{ 75 enemyList.remove(i); 76 } 77 } 78 for(int i = beamList.size()-1; i >= 0; i--){ 79 BEAM b = beamList.get(i); 80 if(b.isAlive()){ 81 b.move(); 82 b.display(); 83 if(e.ex < b.bx+b.bwi/2 && b.bx < e.ex+e.ewi/2 && 84 e.ey < b.by+b.bhe/2 && b.by < e.ey+e.ehe){ 85 beamList.remove(i); 86 } 87 }else{ 88 beamList.remove(i); 89 } 90 } 91 if(right){ 92 if(frameCount % 8 == 0){ 93 laser.trigger(); 94 beamList.add(new BEAM(me.mx, me.my)); 95 } 96 } 97 if(frameCount % 3 == 0){ 98 enemyList.add(new ENEMY()); 99 } 100 } 101} 102 103void mousePressed(){ 104 if(level == 0){ 105 if(mouseButton == RIGHT){ 106 level = 1; 107 } 108 } 109 if(level == 1){ 110 if(mouseButton == LEFT){ 111 right = true; 112 } 113 } 114} 115 116void mouseReleased(){ 117 if(level ==1 ){ 118 if(mouseButton == LEFT){ 119 right = false; 120 } 121 } 122} 123 124 125class ME{ 126 float mx = width/2, my = height/2; 127 128 void move(float x,float y){ 129 mx = x; 130 my = y; 131 } 132 void display(){ 133 fft.forward(BGM.left); 134 for (int i = 0; i < fft.specSize(); i++) { 135 float rectSize = map(fft.getBand(i), 0, fftSize, 0, width/4); 136 137 fill(260, 131, 40); 138 noStroke(); 139 image(pl, mx, my); 140 141 142 noFill(); 143 strokeWeight(1); 144 stroke(255, 187, 0); 145 rect(mx, my, rectSize, rectSize, 10); 146 } 147 fft.forward(BGM.right); 148 for (int i = 0; i < fft.specSize(); i++) { 149 float rectSize = map(fft.getBand(i), 0, fftSize, 0, width/4); 150 151 fill(260, 131, 40); 152 noStroke(); 153 image(pl, mx, my); 154 155 noFill(); 156 strokeWeight(1); 157 stroke(255, 187, 0); 158 rect(mx, my, rectSize, rectSize); 159 } 160 } 161} 162 163class ENEMY{ 164 float ex; 165 float ey; 166 float evel; 167 float ewi; 168 float ehe; 169 float swei; 170 171 ENEMY(){ 172 ex = random(0, width); 173 ey = 0; 174 evel = random(5,15); 175 ehe = 50; 176 ewi = 50; 177 } 178 179 void move(){ 180 ey += evel; 181 } 182 void display(){ 183 image(en, ex, ey); 184 } 185 boolean isAlive(){ 186 if (ex+ewi/2 < 0 || width < ex-ewi/2 || ey+ehe/2 < 0 || height < ey-ehe/2){ 187 return false; 188 } 189 return true; 190 } 191} 192 193class BEAM{ 194 float bx; 195 float by; 196 float bvel; 197 float bwi; 198 float bhe; 199 float ex; 200 float ey; 201 float ehe; 202 203 BEAM(float x, float y){ 204 bx = x; 205 by = y; 206 bwi = 5; 207 bhe = 50; 208 bvel = 15; 209 } 210 211 void move(){ 212 by -= bvel; 213 } 214 void display(){ 215 noFill(); 216 strokeWeight(1); 217 stroke(37, 149, 199); 218 rect(bx, by, bwi, bhe); 219 } 220 boolean isAlive(){ 221 if (bx+bwi/2 < 0 || width < bx-bwi/2 || by+bhe/2 < 0 || height < by-bhe/2){ 222 return false; 223 } 224 return true; 225 } 226} 227 228void fade(boolean _fadeFlag){ 229 if(_fadeFlag){ 230 fill(0); 231 rect(width/2, height/2, width, height); 232 fill(0); 233 }else{ 234 image(img_ss, width/2, (frameCount*8)%height); 235 image(img_s, width/2, (frameCount*12)%height); 236 image(img, width/2, (frameCount*16)%height); 237 } 238} 239 240void stop(){ 241 BGM.close(); 242 minim.stop(); 243 super.stop(); 244}

試したこと

敵やビームをArrayListにした
色々な場所に条件分を置いてみた

補足情報(FW/言語など)

Processing

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

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

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

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

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

guest

回答1

0

ベストアンサー

画像や音声ファイルを用意しないといけないプログラムって他人デバッグが面倒ですね。
あと、「いろいろやってみましたがダメでした」は情報ゼロ。あなたが何をやったか私にはわかりません。その結果何が起こったかもわかりません。結局、何も書いていないのと一緒です。あなたが「頑張ったんだ」と主張するのはいいですけれど、それは解決に何も寄与しません。「これをやった->何が起こった」という「事実」が、変化があったにしてもなかったにしても情報というもの。

Processing

1 for (int i = enemyList.size()-1; i >= 0; i--) { 2 ENEMY e = enemyList.get(i); /////eの宣言...? 3 if (e.isAlive()) { 4 e.move(); 5 e.display(); 6 } else { 7 enemyList.remove(i); 8 } 9 } 10 for (int i = beamList.size()-1; i >= 0; i--) { 11 BEAM b = beamList.get(i); 12 if (b.isAlive()) { 13 b.move(); 14 b.display(); 15 if (e.ex < b.bx+b.bwi/2 && b.bx < e.ex+e.ewi/2 && /////ERROR: eがnull 16 e.ey < b.by+b.bhe/2 && b.by < e.ey+e.ehe) { 17 beamList.remove(i); 18 } 19 } else { 20 beamList.remove(i); 21 } 22 }

コメントで入れたERRORのところでeがnullだと怒られているわけですね。ではこのeはどこで宣言されている変数でしょう? もしかして、その上の「eの宣言...?」とコメントを入れたところ? でも、ここのスコープはfor文の範囲内ですから、エラー箇所は名前はeでも別の実体のはずです。
プログラムを上から見ていくと、グローバル変数として
ENEMY e;
というのが16行目にあります。これのようですね。このeは、宣言されたあと値を設定されることもなく、件の判定で使用されています。当然、nullです。
ここは全ての敵と全ての弾の総当たりチェックをするべきところですか? なら、ちゃんと考えてプログラムを組み直して下さい。当たり判定と移動、描画などの前後関係もちゃんと整理して考えないといけないでしょう。

判定の式がそれでいいかどうかは全く別の話ですね。全然難しい話ではありませんから「検索」に頼るのでなく図でも書いてよく考えてみて下さい。理解できずに検索で出てきたままを使うなら「大抵は希望する結果がでているけど、もしかしたら違う結果になる時もあるかも知れない」です。あなたが「あっている」と説明出来るならあっています。

投稿2019/01/13 04:08

thkana

総合スコア7610

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

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

hasegawa2718

2019/01/13 04:46

私の拙い質問文を指摘して頂き、なおかつ質問の返答までしていただいて申し訳ありません。 このアドバイスをもとにプログラムのeの宣言と順序関係を把握しながら組みなおしていこうと思います。 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問