質問するログイン新規登録
Processing

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

Q&A

1回答

323閲覧

processingでボタンに当たるとbarが変化するように

doori

総合スコア0

Processing

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

0グッド

0クリップ

投稿2024/01/07 18:55

編集2024/01/08 06:01

0

0

実現したいこと

Processingでブロック崩しを作っていますが、ボタンに当たるとbarが変化するように作りたいです。(赤のボタンはbarが大きくなる、黄色はリセット、青は小さくなる)

発生している問題・分からないこと

ボタンの追加は出来たがその後の当たり判定、barを変化させる方法が全くわからない。

該当のソースコード

//以下途中からになります /** 1フレームごとの描画処理 */ void draw() { int breakBlockNum = 0; // 壊れているブロックの数を初期化 for (int i = 0; i < blockNumY; i++) { for (int j = 0; j < blockNumX; j++) { boolean isBroken = block[i][j].isBroken(); if (isBroken == true) { breakBlockNum ++; } else { block[i][j].show(); block[i][j].collision(ball); } } } if (breakBlockNum < blockNumAll) { ball.move(); // ボールの移動処理 if (ball.collision() == false) { // 壁との衝突判定 fill(0, 0, 0); textSize(35); textAlign(CENTER, CENTER); text("Game Over!!", width / 2, height / 2); } else { bar.collision(ball); // バーとの衝突判定 } } else { // ブロックがすべて壊れているならば textSize(35); textAlign(CENTER, CENTER); // テキストの配置を整える text("Clear!!", width / 2, height / 2); // クリア表示 } fill(0, 0, 0); textSize(12); textAlign(CENTER, CENTER); text("Block:" + (blockNumAll - breakBlockNum), width - 40, height - 25); // 残りブロック数表示 bar.show(); // ボールを打ち返すためのボードを表示 ball.show(); // ボールの描画 for (int i=0; i<3; i++) { button[i].show(); } } } class Button { float x; int y; int d; int r; int g; int b; Button(int x, int y, int d, int r, int g, int b) { this.x=x; this.y=y; this.d=d; this.r=r; this.g=g; this.b=b; } void show() { fill(r, g, b); ellipse(x, y, d, d); } } /** * ボール(主にボールの移動) */ class Ball { int x; // ボールのX座標 int y; // ボールのY座標 int vx; // ボールのX軸速度 float vy; // ボールのY軸速度 int d; // ボールの直径 boolean penetrability; // ボールのブロック貫通性 // コンストラクタ Ball(int x, int y, int vx, int vy, int d) { this.x = x; this.y = y; this.vx = vx; this.vy = vy; this.d = d; penetrability = false; } // ボールの移動 void move() { x += vx; y += vy; } // 壁との衝突判定 boolean collision() { if (x <= d / 2) { // 左壁 x = d / 2; vx = -vx; } if (y <= d / 2) { // 天井 y = d / 2; vy = -vy; } if (x >= (width - d / 2)) { // 右壁 x = width - d / 2; vx = -vx; } if (y >= (height - d / 2)) { // 底面(ゲームオーバー) vx = 0; vy = 0; return false; } return true; } // ボールの描画 void show() { if (penetrability) { fill(255, 0, 0); // 貫通弾の時は赤 } else { fill(0, 0, 0); // 通常時は黒 } ellipse(x, y, d, d); // ボールの描画 } // これ以降、SetterとGetter int getX() { return x; } void setY(int y) { this.y = y; } int getY() { return y; } void setVx(int vx) { this.vx = vx; } int getVx() { return vx; } void setVy(float vy) { this.vy = vy; } float getVy() { return vy; } int getD() { return d; } void setPenetrability(boolean penetrability) { this.penetrability = penetrability; } boolean getPenetrability() { return penetrability; } } /** * バー */ class Bar { final int y = height - 50; // バーの左上のy座標 (底から50で固定) int sizeX; // バー全体の幅(なるべく5の倍数が良い) int sizeY; // バーの高さ int boxSizeX; // 分割した時の箱一つ分の幅(全体の1/5) int[] boxX; // バーの各区切りのx座標(左から0) boolean ballbar; Bar(int sizeX, int sizeY) { this.sizeX = sizeX; this.sizeY = sizeY; boxSizeX = sizeX / 5; boxX = new int[6]; } int getsizey() { return sizeY; } void collision(Ball ball) { if ((ball.getY() >= (y - ball.getD() / 2)) && (ball.getY() <= (y + sizeY - ball.getD() / 2))) { // ボールのy座標がバーと重なる時 if ((ball.getX() >= boxX[0]) && (ball.getX() <= boxX[1])) { // 左黒Boxに衝突 ball.setVx(-2); ball.setY(y - ball.getD() / 2); ball.setVy(-ball.getVy()); ball.setPenetrability(false); // ボールのブロック貫通性なし } else if ((ball.getX() > boxX[1]) && (ball.getX() <= boxX[2])) { // 左白Boxに衝突 ball.setVx(-1); ball.setY(y - ball.getD() / 2); ball.setVy(-ball.getVy()); ball.setPenetrability(false); // ボールのブロック貫通性なし } else if ((ball.getX() > boxX[2]) && (ball.getX() <= boxX[3])) { // 中心赤Boxに衝突 ball.setY(y - ball.getD() / 2); ball.setVy(-ball.getVy()); ball.setPenetrability(true); // ボールのブロック貫通性あり } else if ((ball.getX() > boxX[3]) && (ball.getX() <= boxX[4])) { // 右白Boxに衝突 ball.setVx(1); ball.setY(y - ball.getD() / 2); ball.setVy(-ball.getVy()); ball.setPenetrability(false); // ボールのブロック貫通性なし } else if ((ball.getX() > boxX[4]) && (ball.getX() <= boxX[5])) { // 右黒Boxに衝突 ball.setVx(2); ball.setY(y - ball.getD() / 2); ball.setVy(-ball.getVy()); ball.setPenetrability(false); // ボールのブロック貫通性なし } } } // バー表示メソッド void show() { boxX[0] = mouseX - this.sizeX / 2; // 左黒Boxの左上頂点のx座標 boxX[1] = mouseX - 3 * (boxSizeX / 2); // 左白Boxの左上頂点のx座標 boxX[2] = mouseX - boxSizeX / 2; // 中央赤Boxの左上頂点のx座標 boxX[3] = mouseX + boxSizeX / 2; // 右白Boxの左上頂点のx座標 boxX[4] = mouseX + 3 * (boxSizeX /2); // 右黒Boxの左上頂点のx座標 boxX[5] = mouseX + this.sizeX / 2; // 右黒Boxの"右上"頂点のx座標 // バーの描画 fill(173); rect(boxX[0], y, boxSizeX, sizeY); // 左黒Box fill(255, 255, 255); rect(boxX[1], y, boxSizeX, sizeY); // 左白Box fill(255, 120, 130); rect(boxX[2], y, boxSizeX, sizeY); // 中央赤Box fill(255, 255, 255); rect(boxX[3], y, boxSizeX, sizeY); // 右黒Box fill(173); rect(boxX[4], y, boxSizeX, sizeY); // 右白Box } int getX(int i) { return boxX[i]; } int getY() { return y; } int getSizeX() { return sizeX; } int getSizeY() { return sizeY; } } /** * ブロック(ボールとブロックの衝突判定など) */ class Block { int x; // 左上頂点のx座標 int y; // 左上頂点のy座標 int sizeX; // ブロックの幅 int sizeY; // ブロックの高さ boolean broken; // ブロックが破壊されているか否か int R=255; int G=150; int B=240; int count; // コンストラクタ Block(int x, int y, int sizeX, int sizeY) { this.x = x; this.y = y; this.sizeX = sizeX; this.sizeY = sizeY; broken = false; } // ブロックの描画メソッド void show() { fill(R, G, B); // ブロックの色は青 rect(x, y, sizeX, sizeY); } // ボールとブロックとの衝突と破壊判定 // 今回,ボールの衝突判定はボールの中心座標のみで行っている void collision(Ball ball) { // ボールが貫通弾でないなら、衝突した際にボールの進行方向を変える(速度を変える) if (!ball.getPenetrability()) { // ブロック左側に当たった場合 if ((ball.getX() >= x) && (ball.getX() <= (x + 5)) && (ball.getY() >= y) && (ball.getY() <= (y + sizeY))) { ball.setVx(-1 * ball.getVx()); } // ブロック右側に当たった場合 if ((ball.getX() >= (x + sizeX - 5)) && (ball.getX() <= (x + sizeX)) && (ball.getY() >= y) && (ball.getY() <= (y+sizeY))) { ball.setVx(-1 * ball.getVx()); } // ブロック上側に当たった場合 if ((ball.getX() >= x) && (ball.getX() <= (x + sizeX)) && (ball.getY() >= y) && (ball.getY() <= (y + 5))) { ball.setVy(-1 * ball.getVy()); } // ブロック下側に当たった場合 if ((ball.getX() >= x) && (ball.getX() <= (x + sizeX)) && (ball.getY() >= (y + sizeY - 5)) && (ball.getY() <= (y + sizeY))) { ball.setVy(-1 * ball.getVy()); } } // 衝突による破壊判定 if ((ball.getX() >= x) && (ball.getX() <= (x + sizeX)) && (ball.getY() >= y) && (ball.getY() <= (y + sizeY))) { count+=1; if (count==1) { R=150; G=255; B=190; } if (count==2) { R=150; G=250; B=255; } if (count==3) { broken = true; } } } boolean isBroken() { return broken; } }

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

ボタン設置の方法を調べたが出てこなかった。
初心者のため、調べ方も分からなかった。

補足

特になし

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

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

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

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

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

TN8001

2024/01/07 22:41

「Processing」タグがありますので、(質問を編集し)付けてください。 [タグ一覧 | Processing](https://teratail.com/tags/Processing) > ボタンに当たるとbarが変化するように作りたいです。 ボタンに当たるとボールは反射するのでしょうか?
doori

2024/01/08 06:00

修正いたしました。 はい。ボールは反射するようにしたいです。 よろしくお願いいたします。
guest

回答1

0

その後の当たり判定

円同士の反射はわたしも(数学が苦手なので)解説できる立場にないですが、(個人的には)こちらが分かりやすかったです。
反射・壁ずり・鏡像ベクトルの考え方
円同士が衝突したときにモンストのような反射の挙動をしてほしい

barを変化させる方法

(キレイかどうかは置いといて)↓のようなメソッドがあればいいんじゃないですかね?

java

1class Button { 2 boolean collision(Ball ball) { } 3} 4 5class Bar { 6 void big() { } 7 void small() { } 8 void reset() { } 9}

他気になった点

  • getter・setter
    Processingでは内部クラスになる仕様上、privateフィールドもいじり放題なので(フィールドを素通しするなら)あまり意味がないです。
  • getD() / 2が多い
    最初から半径を持つようにしておけばよいのでは?
    ellipseMode() / Reference / Processing.org
  • float x; int y;int vx; float vy;
    組になる変数の型が違うのは気持ちが悪いです。
    円の反射でintは厳しいのと計算が面倒なので、PVectorにしたほうが楽そうです。
    PVector / Reference / Processing.org
  • rgb
    color型を使うと便利です。
    color / Reference / Processing.org

Processing

1Ball ball; 2Bar bar; 3Button[] button; 4 5void setup() { 6 size(300, 400); 7 ellipseMode(RADIUS); 8 9 ball = new Ball(width/2, height/2, 2, -2, 10); 10 bar = new Bar(100, 10); 11 button = new Button[]{ 12 new Button(width / 5, height / 3, 20, #FF0000), 13 new Button(width / 2, height / 3, 20, #FFFF00), 14 new Button(width / 5 * 4, height / 3, 20, #0000FF), 15 }; 16} 17 18void draw() { 19 background(255); 20 21 ball.move(); 22 //mouseX = int(ball.position.x); 23 24 if (ball.collision()) { 25 bar.collision(ball); 26 } else { 27 fill(0, 0, 0); 28 textSize(35); 29 textAlign(CENTER, CENTER); 30 text("Game Over!!", width/2, height/2); 31 } 32 33 if (button[0].collision(ball)) bar.big(); 34 if (button[1].collision(ball)) bar.reset(); 35 if (button[2].collision(ball)) bar.small(); 36 for (Button b : button) b.show(); 37 38 bar.show(); 39 ball.show(); 40} 41 42 43class Button { 44 PVector position; 45 int r; 46 color c; 47 48 Button(int x, int y, int r, color c) { 49 position = new PVector(x, y); 50 this.r = r; 51 this.c = c; 52 } 53 54 void show() { 55 fill(c); 56 circle(position.x, position.y, r); 57 } 58 59 boolean collision(Ball ball) { 60 float d = position.dist(ball.position); 61 if (d < r + ball.r) { 62 // 円の反射 63 PVector n = PVector.sub(ball.position, position); 64 n.normalize(); 65 float length = PVector.mult(ball.velocity, -1).dot(n); 66 PVector de = n.mult(length); 67 PVector dh = PVector.add(ball.velocity, de.mult(2)); 68 ball.velocity = dh; 69 70 return true; 71 } 72 return false; 73 } 74} 75 76class Ball { 77 PVector position, velocity; 78 int r; 79 80 Ball(int x, int y, int vx, int vy, int r) { 81 position = new PVector(x, y); 82 velocity = new PVector(vx, vy); 83 this.r = r; 84 } 85 86 void move() { 87 position.add(velocity); 88 } 89 90 boolean collision() { 91 if (position.x <= r) { 92 position.x = r; 93 velocity.x = -velocity.x; 94 } 95 if (position.y <= r) { 96 position.y = r; 97 velocity.y = -velocity.y; 98 } 99 if (width - r <= position.x) { 100 position.x = width - r; 101 velocity.x = -velocity.x; 102 } 103 if (height - r <= position.y) { 104 velocity = new PVector(); 105 return false; 106 } 107 return true; 108 } 109 110 void show() { 111 fill(0); 112 circle(position.x, position.y, r); 113 } 114} 115 116class Bar { 117 final int y = height - 50; 118 final int _sizeX, sizeY; 119 int sizeX, boxSizeX; 120 final int[] boxX = new int[6]; 121 122 Bar(int sizeX, int sizeY) { 123 this.sizeX = _sizeX = sizeX; 124 this.sizeY = sizeY; 125 boxSizeX = sizeX / 5; 126 } 127 128 void collision(Ball ball) { 129 if (ball.position.x < mouseX - sizeX / 2 - ball.r) return; 130 if (mouseX + sizeX / 2 + ball.r < ball.position.x) return; 131 if ((ball.position.y < y - ball.r) || (y + sizeY + ball.r < ball.position.y)) return; 132 133 ball.position.y = y - ball.r; 134 ball.velocity.y = -ball.velocity.y; 135 if ((boxX[0] <= ball.position.x) && (ball.position.x <= boxX[1])) ball.velocity.x = -2; 136 else if ((boxX[1] < ball.position.x) && (ball.position.x <= boxX[2])) ball.velocity.x = -1; 137 else if ((boxX[3] < ball.position.x) && (ball.position.x <= boxX[4])) ball.velocity.x = 1; 138 else if ((boxX[4] < ball.position.x) && (ball.position.x <= boxX[5])) ball.velocity.x = 2; 139 } 140 141 void show() { 142 boxX[0] = mouseX - sizeX / 2; 143 boxX[1] = mouseX - 3 * boxSizeX / 2; 144 boxX[2] = mouseX - boxSizeX / 2; 145 boxX[3] = mouseX + boxSizeX / 2; 146 boxX[4] = mouseX + 3 * boxSizeX / 2; 147 boxX[5] = mouseX + sizeX / 2; 148 149 fill(173); 150 rect(boxX[0], y, boxSizeX, sizeY); 151 fill(255, 255, 255); 152 rect(boxX[1], y, boxSizeX, sizeY); 153 fill(255, 120, 130); 154 rect(boxX[2], y, boxSizeX, sizeY); 155 fill(255, 255, 255); 156 rect(boxX[3], y, boxSizeX, sizeY); 157 fill(173); 158 rect(boxX[4], y, boxSizeX, sizeY); 159 } 160 161 void big() { 162 sizeX += 20; 163 if (width / 2 < sizeX) sizeX = width / 2; 164 boxSizeX = sizeX / 5; 165 } 166 void small() { 167 sizeX -= 20; 168 if (sizeX < 10) sizeX = 10; 169 boxSizeX = sizeX / 5; 170 } 171 void reset() { 172 sizeX = _sizeX; 173 boxSizeX = sizeX / 5; 174 } 175}

アプリ動画

投稿2024/01/08 07:29

TN8001

総合スコア10118

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問