processingでブロック崩しを作っています。
前提
processingでブロック崩しを作りたい。
画面をクリックするとスタートするようにしているのですが、クリックしてもボールが動きません。この原因が分かりません。
また、上から降ってくる玉が自機に当たるとダメージを受けてしまい、3回当たると失敗
という風ににしたいのですが、実行すると当たってないのに体力が減ってしまいます(当たり判定がおかしい)
どのようにすれば解決できるか教えていただけたらありがたいです。
よろしくお願いします。
実現したいこと
始めに画面をクリックしたらボールが動き、ゲームが始まる。
発生している問題・エラーメッセージ
・始めに画面をクリックしてもボールが動かない
・降ってくる玉と自機との当たり判定がよくわからない
該当のソースコード
processing
1int block[][] = new int[10][10]; 2float x, y =60; 3float b_w = 10, b_h = 10, dx, dy; 4float r_w = 50.0, r_h = 3.0; 5int hp = 3; 6int enemy_x[]=new int[10]; 7int enemy_y[]=new int[10]; 8int enemy_speed[]=new int[10]; 9int r_x = mouseX; 10int r_y = height-50; 11int gseq; 12int mcnt; 13void setup() { 14 size(600,700); 15 initBall(); 16 initBlocks(); 17 showEnemy(); 18} 19 20void draw() { 21 22 background(192, 192, 255); 23 rect(x, y, b_w, b_h); // ball 24if(gseq == 0){ 25 gameTitle(); 26}else if(gseq == 1){ 27 x += dx; // dx は1フレームごとにx方向に動く距離(速度) 28 y += dy; // dy は1フレームごとにy方向に動く距離(速度) 29 gameplay(); 30}else{ 31 gameover(); 32} 33 checkBlocks(); 34 showBlocks(); 35 36 checkAndShowRacket(height-50); 37 38 // 壁との衝突 39 if (y + b_h >= height) { 40 //initBall(); 41 initBlocks(); 42 gseq = 2; 43 } 44 if (x < 0 || x+b_w >=width) {dx = -dx;} 45 if (y < 0) {dy = -dy;} 46} 47void initBall() { 48 x = 40; 49 y = 400; 50 dx = 1; 51 dy = 2; 52} 53float bw, bh = 40.0; 54 55/* 56 10個のブロックを初期化する 57*/ 58void initBlocks() { 59 for(int j=0; j<3; j++){ 60 for (int i = 0; i < block.length ; i++) { 61 block[i][j] = 1; 62 } 63 bw = width / block.length; // ブロックの幅を決める 64 } 65} 66 67/* 68 10個のブロックのどれかにぶつかっていたら跳ね返る 69*/ 70void checkBlocks() { 71 for (int j = 0; j < 3; j++) { 72 for (int i = 0; i < block.length ; i++) { 73 if (block[i][j] > 0) { 74 int ret = blockHitCheck(i*bw,j*bh+200,bw,bh,x,y,b_w,b_h,dx,dy); 75 if (ret > 0) { 76 if (ret == 1) { 77 dx = -dx; 78 block[i][j]--; 79 } else if (ret == 2) { 80 dy = -dy; 81 block[i][j]--; 82 } else if (ret == 3) { 83 dx = -dx; 84 dy = -dy; 85 block[i][j]--; 86 } 87 return; 88 } 89 } 90 } 91 } 92} 93 94/* 95 10個のブロックを表示する 96*/ 97void showBlocks() { 98 for (int j = 0; j < 3; j++) { 99 for (int i = 0; i < block.length ; i++) { 100 if (block[i][j] > 0) { 101 fill(255); 102 rect(i * bw, j*bh+200, bw, bh); // ブロックの形の表示 103 } 104 } 105 } 106} 107void enemymove(){ 108 for(int i=0;i<10;i++){ 109 fill(255,0,0); 110 rect(enemy_x[i],enemy_y[i],10,10); 111 enemy_y[i]+=enemy_speed[i]; 112 if(enemy_y[i]>height){ 113 enemy_x[i]=int(random(width)); 114 enemy_y[i]=-50; 115 enemy_speed[i]=int(random(2,6)); 116 } 117 } 118} 119 120void hitEnemy(){ 121 for(int i=0;i<10;i++){ 122 if((enemy_x[i]<r_x+50 || r_x<enemy_x[i]) && enemy_y[i]==r_y){ 123 hp=hp-1; 124 } 125 } 126} 127void showMyhp(){ 128 fill(255); 129 text("hp:"+hp,10,30); 130} 131 132 133void showEnemy(){ 134 for(int i=0;i<10;i++){ 135 enemy_x[i]=int(random(width)); 136 enemy_y[i]=-50; 137 enemy_speed[i]=int(random(2,6)); 138 } 139} 140/* 141 ふたつの長方形が重なるかどうかをしらべて、 142 重なったとき:true, 重ならないとき:false を返す 143*/ 144boolean isOverlap(float x1, float y1, float w1, float h1, 145 float x2, float y2, float w2, float h2) { 146 return x1 < x2+w2 && x2 < x1+w1 && y1 < y2+h2 && y2 < y1+h1; 147} 148 149/* 150 ブロックの位置と大きさ、 151 ボールの位置と大きさ、ボールの移動速度の情報を与えて 152 跳ね返る方向(x軸、y軸の別)を返す 153 跳ね返らない時: 0 154 x軸のみの時: 1 155 y軸のみの時: 2 156 x軸, y軸両方の時: 3 157*/ 158int blockHitCheck(float x, float y, float w, float h, 159 float bx, float by, float bw, float bh, float dx, float dy) { 160 int xflag = 0, yflag = 0; 161 162 if (!isOverlap(x,y,w,h,bx+dx,by+dy,bw,bh)) { 163 return 0; // ぶつからなかったら 0を返す 164 } 165 166 if (isOverlap(x,y,w,h,bx+dx,by,bw,bh)) xflag = 1; 167 if (isOverlap(x,y,w,h,bx,by+dy,bw,bh)) yflag = 2; 168 if (xflag + yflag > 0) { return xflag + yflag;} 169 return 3; 170} 171/* 172 checkAndShowRacket() 173 float r_y; // r_hはラケットのy座標 174*/ 175void checkAndShowRacket(float r_y) { 176 float r_x = mouseX; // r_x はラケットの左側のx座標 177 178 if (r_x + r_w > width) { // 右に寄りすぎていたら補正する 179 r_x = width - r_w; 180 } 181 182 /* ブロックがぶつかっていたら上に跳ね返る */ 183 if (blockHitCheck(r_x,r_y,r_w,r_h,x,y,b_w,b_h,dx,dy) > 0) { 184 dy = -2; 185 } 186 187 rect(r_x, r_y, r_w, r_h); // racketを表示する 188} 189 void gameTitle(){ 190 checkAndShowRacket(height-50); 191 showBlocks(); 192 mcnt++; 193 if((mcnt%60)<40){ 194 textSize(20); 195 fill(255,0,0); 196 text("Click to start!!", 220,400); 197 } 198} 199 200void gameInit(){ 201 x += dx; // dx は1フレームごとにx方向に動く距離(速度) 202 y += dy; // dy は1フレームごとにy方向に動く距離(速度) 203 gseq = 0; 204 //initBall(); 205 showBlocks(); 206 mcnt = 0; 207} 208 209void gameplay(){ 210 x += dx; // dx は1フレームごとにx方向に動く距離(速度) 211 y += dy; // dy は1フレームごとにy方向に動く距離(速度) 212 checkAndShowRacket(height-50); 213 showBlocks(); 214 initBall(); 215 enemymove(); 216 hitEnemy(); 217 showMyhp(); 218} 219void gameover(){ 220 checkAndShowRacket(height-50); 221 showBlocks(); 222 textSize(50); 223 fill(0); 224 text("GAME OVER", 200, 500); 225 mcnt++; 226 if((mcnt%60) < 40){ 227 textSize(20); 228 fill(0); 229 text("Click to retry!!", 170,400); 230 } 231} 232void mousePressed(){ 233 if(gseq == 2){ 234 gameInit(); 235 return; 236 } 237 if(gseq == 0){ 238 gseq = 1; 239 } 240}
試したこと
ボールが動かないことに関しては、gameplay()やgameInit()の中を色々変えてみた。
当たり判定に関しては、ボールと同じようにやろうとしたが、分からなくなった。
回答1件
あなたの回答
tips
プレビュー
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。
2022/06/16 12:35
2022/06/16 13:58 編集
2022/06/16 15:11
2022/06/16 15:52
2022/06/16 15:54
2022/06/16 16:04
2022/06/16 16:16