processingで画像のようなプログラムをつくりたいです。
1枚目の画像をクリックすると、2枚目の画像が出てきて、利根川進をクリックするとクリア、木村資生を押すと残念がでるようなプログラムを作成したいです。画像を表示するのではなく、プログラムでテキストなどを表示したいです。これにBGMをつけたいです。クラスを定義し,オブジェクトを生成し,オブジェクトを活用するプログラムという条件では、どのようにすればよいのかわからないです。
class Opening{//画像1
int x;
int y;
Opening(int tempX,int tempY){
x = tempX;
y = tempY;
}
void display(){
pushMatrix();
translate(x,y);
background(0,255,255);
textAlign(CENTER);
fill(0);
textSize(25);
text("ルイザ・グロス・ホロウィッツ賞",width/2, 250);
text("日本人受賞者を覚えよう!",width/2, 285);
textSize(18);
text("ルイザ・グロス・ホロウィッツ賞",width/2, 500);
text("日本人受賞者を全員答えられたらクリアだよ",width/2, 530);
popMatrix();
}
}
class Question{//画像2
int x;
int y;
Question(int tempX,int tempY){
x = tempX;
y = tempY;
}
void display(){
pushMatrix();
translate(x,y);
background(245,100,170);
textAlign(CENTER);
fill(0);
textSize(25);
text("生物学や生化学の研究者に贈られる",width/2, 250);
text("ルイザ・グロス・ホロウィッツ賞を",width/2, 285);
text("現在、日本人で唯一受賞したのは誰?",width/2, 320);
fill(255);
noStroke();
rect(x1,y1,w,h);
fill(0);
textAlign(CENTER);
textSize(30);
text("利根川進",115,600);
fill(255);
rect(x2,y2,w,h);
fill(0);
text("木村資生",335,600);
popMatrix();
}
}
class Correct{//画像3
int x;
int y;
Correct(int tempX,int tempY){
x = tempX;
y = tempY;
}
void display(){
pushMatrix();
translate(x,y);
background(255,255,0);
textAlign(CENTER);
textSize(80);
text("クリア",width/2,300);
textSize(25);
text("1不可説不可説転点",width/2,500);
text("獲得",width/2,535);
popMatrix();
}
}
class Incorrect{//画像4
int x;
int y;
Incorrect(int tempX,int tempY){
x = tempX;
y = tempY;
}
void display(){
pushMatrix();
translate(x,y);
background(255,255,0);
textAlign(CENTER);
textSize(80);
text("残念",width/2,300);
textSize(20);
text("あなたはルイザ・グロス・ホロウィッツ賞の",width/2,500);
text("日本人受賞者を1人も覚えていません",width/2,535);
popMatrix();
}
}
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
どちらも残したいので回答を分けさせていただきます。
とにかく動けばいい場合
Processing
1import ddf.minim.*; 2 3Minim minim; 4AudioPlayer player; 5PFont font; 6 7Opening opening; 8Question question; 9Correct correct; 10Incorrect incorrect; 11 12int x1 = 30; 13int y1 = 500; 14int x2 = 250; 15int y2 = 500; 16int w = 170; 17int h = 170; 18 19int mode; // 0:タイトル 1:問題 2:判定 20 21void setup() { 22 size(460, 800); 23 //minim = new Minim(this); 24 //player = minim.loadFile("QuizKnockのメインテーマ.mp3"); 25 //player.play(); 26 font = createFont("游明朝 Demibold", 24); 27 textFont(font); 28 29 opening = new Opening(); 30 correct = new Correct(); 31 incorrect = new Incorrect(); 32 question = new Question(); 33 opening.display(); 34} 35 36void draw() { 37} 38 39void mouseClicked() { 40 switch (mode) { 41 case 0: 42 mode = 1; 43 question.display(); 44 break; 45 case 1: 46 if (x1 < mouseX && mouseX < x1 + w && y1 < mouseY && mouseY < y1 + h) { 47 mode = 2; 48 correct.display(); 49 } 50 if (x2 < mouseX && mouseX < x2 + w && y2 < mouseY && mouseY < y2 + h) { 51 mode = 2; 52 incorrect.display(); 53 } 54 break; 55 case 2: 56 mode = 0; 57 opening.display(); 58 break; 59 } 60} 61 62 63class Opening { 64 void display() { 65 background(0, 255, 255); 66 textAlign(CENTER); 67 fill(0); 68 textSize(25); 69 text("ルイザ・グロス・ホロウィッツ賞", width / 2, 250); 70 text("日本人受賞者を覚えよう!", width / 2, 285); 71 textSize(18); 72 text("ルイザ・グロス・ホロウィッツ賞", width / 2, 500); 73 text("日本人受賞者を全員答えられたらクリアだよ", width / 2, 530); 74 } 75} 76 77class Question { 78 void display() { 79 background(245, 100, 170); 80 textAlign(CENTER); 81 fill(0); 82 textSize(25); 83 text("生物学や生化学の研究者に贈られる", width / 2, 250); 84 text("ルイザ・グロス・ホロウィッツ賞を", width / 2, 285); 85 text("現在、日本人で唯一受賞したのは誰?", width / 2, 320); 86 fill(255); 87 noStroke(); 88 rect(x1, y1, w, h); 89 fill(0); 90 textAlign(CENTER); 91 textSize(30); 92 text("利根川進", 115, 600); 93 fill(255); 94 rect(x2, y2, w, h); 95 fill(0); 96 text("木村資生", 335, 600); 97 } 98} 99 100class Correct { 101 void display() { 102 background(255, 255, 0); 103 textAlign(CENTER); 104 textSize(80); 105 text("クリア", width / 2, 300); 106 textSize(25); 107 text("1不可説不可説転点", width / 2, 500); 108 text("獲得", width / 2, 535); 109 } 110} 111 112class Incorrect { 113 void display() { 114 background(255, 255, 0); 115 textAlign(CENTER); 116 textSize(80); 117 text("残念", width / 2, 300); 118 textSize(20); 119 text("あなたはルイザ・グロス・ホロウィッツ賞の", width / 2, 500); 120 text("日本人受賞者を1人も覚えていません", width / 2, 535); 121 } 122}
しかしこれでは「クラスを定義し,オブジェクトを生成」はしましたが、とても「オブジェクトを活用」しているとは言えません。
クラスのdisplay()
をopeningDisplay()
等で関数にしたのと大差ありません。
オブジェクトを活用した場合
Processing
1import ddf.minim.*; 2 3Minim minim; 4AudioPlayer player; 5PFont font; 6 7Scene current; // 今の画像?を保持する変数 8 9void setup() { 10 size(460, 800); 11 //minim = new Minim(this); 12 //player = minim.loadFile("QuizKnockのメインテーマ.mp3"); 13 //player.play(); 14 font = createFont("游明朝 Demibold", 24); 15 textFont(font); 16 17 Opening opening = new Opening(); // *1でsetNextしたいのでOpening型変数に入れる 18 //Scene opening = new Opening(); // としたいところだがScene型にはsetNextがない 19 Scene correct = new Correct(opening); // CorrectはScene型に入れられる 20 Scene incorrect = new Incorrect(opening); 21 Scene question = new Question(correct, incorrect); 22 23 opening.setNext(question); // *1 24 current = opening; // 初めの画像?の設定 25} 26 27void draw() { 28 current.display(); // 今の画像?を表示 29} 30 31void mouseClicked() { 32 Scene next = current.getNext(mouseX, mouseY); // 今の画像?に次の画像?を要求する 33 current = next; // 今の画像?変数の中身を次の画像?に入れ替える 34} 35 36 37interface Scene { // それぞれの画像?が共通して持っているべき機能 38 void display(); // きっと何か表示するのかな? 39 Scene getNext(int x, int y); // 座標を引数にSceneをかえす ふーむ? 40} 41// インターフェースからは実際の動作はわかりません クラスで「実装」して初めて意味を持ちます 42// 長くなるので各自で調べてください^^; 43 44 45class Opening implements Scene { // Openingは「Sceneのメソッドを必ず持っています」という約束(実装) 46 Scene next; // 次の画像? 47 48 void setNext(Scene next) { // 次の画像?設定(他と同じようにコンストラクタで渡したいが、循環してるのでどれかはこうするよりない) 49 this.next = next; 50 } 51 52 void display() { 53 background(0, 255, 255); 54 textAlign(CENTER); 55 fill(0); 56 textSize(25); 57 text("ルイザ・グロス・ホロウィッツ賞", width / 2, 250); 58 text("日本人受賞者を覚えよう!", width / 2, 285); 59 textSize(18); 60 text("ルイザ・グロス・ホロウィッツ賞", width / 2, 500); 61 text("日本人受賞者を全員答えられたらクリアだよ", width / 2, 530); 62 } 63 64 Scene getNext(int x, int y) { 65 return next; // 次の画像?(question)を無条件でかえす 66 } 67} 68 69class Question implements Scene { 70 final Scene next1; // finalをつけると変更不可になる(初期化も強制される) 71 final Scene next2; 72 final int x1 = 30; // この辺の変数はほかで使わないのでクラスのメンバーに 73 final int y1 = 500; 74 final int x2 = 250; 75 final int y2 = 500; 76 final int w = 170; 77 final int h = 170; 78 79 Question(Scene next1, Scene next2) { // 分岐があるので2つもらう 80 this.next1 = next1; 81 this.next2 = next2; 82 } 83 84 void display() { 85 background(245, 100, 170); 86 textAlign(CENTER); 87 fill(0); 88 textSize(25); 89 text("生物学や生化学の研究者に贈られる", width / 2, 250); 90 text("ルイザ・グロス・ホロウィッツ賞を", width / 2, 285); 91 text("現在、日本人で唯一受賞したのは誰?", width / 2, 320); 92 fill(255); 93 noStroke(); 94 rect(x1, y1, w, h); 95 fill(0); 96 textAlign(CENTER); 97 textSize(30); 98 text("利根川進", 115, 600); 99 fill(255); 100 rect(x2, y2, w, h); 101 fill(0); 102 text("木村資生", 335, 600); 103 } 104 105 Scene getNext(int x, int y) { 106 if (x1 < x && x < x1 + w && y1 < y && y < y1 + h) { 107 return next1; // もし左の四角内ならcorrectをかえす 108 } 109 if (x2 < x && x < x2 + w && y2 < y && y < y2 + h) { 110 return next2; // もし右の四角内ならincorrectをかえす 111 } 112 113 return this; // どちらでもなければ自身(question)をかえす(無駄というか意味のない動作だが、そういう設計にしたので仕方がない^^; 114 } 115} 116 117class Correct implements Scene { 118 final Scene next; 119 120 Correct(Scene next) { 121 this.next = next; 122 } 123 124 void display() { 125 background(255, 255, 0); 126 textAlign(CENTER); 127 textSize(80); 128 text("クリア", width / 2, 300); 129 textSize(25); 130 text("1不可説不可説転点", width / 2, 500); 131 text("獲得", width / 2, 535); 132 } 133 134 Scene getNext(int x, int y) { 135 return next; 136 } 137} 138 139class Incorrect implements Scene { 140 final Scene next; 141 142 Incorrect(Scene next) { 143 this.next = next; 144 } 145 146 void display() { 147 background(255, 255, 0); 148 textAlign(CENTER); 149 textSize(80); 150 text("残念", width / 2, 300); 151 textSize(20); 152 text("あなたはルイザ・グロス・ホロウィッツ賞の", width / 2, 500); 153 text("日本人受賞者を1人も覚えていません", width / 2, 535); 154 } 155 156 Scene getNext(int x, int y) { 157 return next; 158 } 159}
元のテイストをできるだけ残したので不自然なところもありますが、それなりに「オブジェクトを活用」できたかなと思います。
もちろんこれが「答え」というものではありません。人それぞれいろいろな作りが考えられます。
その辺が面白いところでもあり、難しいところでもありますね。
乗りかかった船なので回答しましたが、
processingのオブジェクトの考え方
とタイトルにある以上、
- 難しすぎて全くわからない
- 理解するのに時間が欲しい
- 実行できない
- ここの意味がよくわからない
- 参考になった
等、回答について何かしらのアクションを期待しているのですが、これでは単なる作業依頼です。
投稿2020/07/11 21:33
編集2023/07/22 08:51総合スコア9807
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
意外とProcessing
でクイズゲームの記事ってないですね。。。(Javaはたくさんありますが)
クラスを定義し,オブジェクトを生成し,オブジェクトを活用するプログラム
個人的には慣れの問題だと思っています(たくさん書いたり見たりする)が、活用していないプログラムと活用しているプログラムを、見比べるのも面白いと思いました。
(ネタに深い意味はありません。過去に書いたものを再利用しただけ)
活用していないプログラム
Processing
1int x1 = 20; 2int y1 = 220; 3int x2 = 210; 4int y2 = 220; 5int w = 170; 6int h = 160; 7int mode = 0; // 0:問題 1:正解 -1:はずれ 8 9void setup() { 10 size(400, 400); 11 textFont(createFont("メイリオ", 24)); 12 textAlign(CENTER, CENTER); 13} 14 15void draw() { 16 background(255); 17 fill(0); 18 19 if (mode == 1) { 20 text("正解!", 20, 20, 360, 200); 21 return; 22 } 23 if (mode == -1) { 24 text("ざんねん", 20, 20, 360, 200); 25 return; 26 } 27 28 text("史上初の家庭用ゲーム機とされるものは?", 20, 20, 360, 200); 29 rect(x1, y1, w, h); 30 rect(x2, y2, w, h); 31 32 fill(255); 33 text("オデッセイ\n(マグナボックス)", x1 + 10, y1 + 10, w - 20, h - 20); 34 text("カラーテレビゲーム15\n(任天堂)", x2 + 10, y2 + 10, w - 20, h - 20); 35} 36 37void mouseClicked() { 38 if (x1 < mouseX && mouseX < x1 + w && y1 < mouseY && mouseY < y1 + h) { 39 mode = 1; 40 } 41 if (x2 < mouseX && mouseX < x2 + w && y2 < mouseY && mouseY < y2 + h) { 42 mode = -1; 43 } 44}
自分で書いておいてなんですが、もうすでにげんなりしています。
int x1, y1, x2, y2, w, h
なんだかわかりにくい。かといって長い名前だと後の計算部分でくどくなる。text("", 20, 20, 360, 200)
同じ数字の繰り返し(これはメソッドにすればいい)rect(x1, y1, w, h)
主語がないのでボタンだとわからない。x1 + 10, y1 + 10, w - 20, h - 20
謎の計算。if (x1 < mouseX && mouseX < x1 + w && y1 < mouseY && mouseY < y1 + h)
定番の処理とはいえくどい。標準でメソッドがあれば。。
このままの流れでボタンのマウスオーバーで色を変えたり、問題数を増やしたりするとさらにゴチャゴチャしてくるでしょう。
活用したプログラム
Processing
1import java.util.*; 2import g4p_controls.*; 3 4GLabel label; 5GButton button1; 6GButton button2; 7 8final MondaiList mondaiList = new MondaiList( 9 new Mondai("史上初の家庭用ゲーム機とされるものは?", "オデッセイ\n(マグナボックス)", "カラーテレビゲーム15\n(任天堂)"), 10 new Mondai("ファミコンのコントローラーにはマイクが付いている?", "○", "×"), 11 new Mondai("スーパーファミコンソフト「ドラゴンクエスト6 幻の大地」の定価(税抜)は?", "11,400円", "6,980円"), 12 new Mondai("PlayStationの同時発売ソフトは?", "リッジレーサー\n(ナムコ)", "チョロQ\n(タカラ)"), 13 new Mondai("PlayStation2で動くLinuxがあった?", "○", "×")); 14 15void setup() { 16 size(400, 400); 17 surface.setTitle("おじさんゲーマークイズ"); 18 19 G4P.setDisplayFont("メイリオ", G4P.PLAIN, 24); 20 21 label = new GLabel(this, 20, 20, 360, 200); 22 label.setTextAlign(GAlign.CENTER, GAlign.MIDDLE); 23 24 button1 = new GButton(this, 20, 220, 170, 160); 25 button2 = new GButton(this, 210, 220, 170, 160); 26 27 next(); 28} 29 30void draw() { 31 background(220); 32} 33 34void next() { 35 Mondai mondai = mondaiList.get(); 36 37 label.setText(mondai.getQuestion()); 38 39 List<String> choices = mondai.getChoices(); 40 button1.setText(choices.get(0)); 41 button2.setText(choices.get(1)); 42} 43 44void handleButtonEvents(GButton button, GEvent event) { 45 if (event != GEvent.CLICKED) return; 46 47 mondaiList.answer(button.getText()); 48 49 if (mondaiList.empty()) { 50 int seikai = mondaiList.getSeikai(); 51 int count = mondaiList.getCount(); 52 float rate = (float) seikai / count; 53 String s = count + "問中" + seikai + "問正解\n"; 54 s += rate == 1 ? "おじさんゲーマー度 100%" : rate >= 0.5 ? "意外とおじさん?" : "一般人です。"; 55 56 label.setText(s); 57 button1.setVisible(false); 58 button2.setVisible(false); 59 } else { 60 next(); 61 } 62} 63 64class MondaiList { 65 private final List<Mondai> mondaiList; 66 private int count; 67 private int seikai; 68 69 public MondaiList(Mondai... array) { 70 mondaiList = new ArrayList<Mondai>(Arrays.asList(array)); 71 reset(); 72 } 73 74 public void reset() { 75 count = 0; 76 seikai = 0; 77 Collections.shuffle(mondaiList); 78 } 79 80 public void answer(String ans) { 81 if (!empty() && mondaiList.get(count).isCorrect(ans)) { 82 seikai++; 83 } 84 count++; 85 } 86 87 public Mondai get() { 88 return mondaiList.get(count); 89 } 90 91 public boolean empty() { 92 return mondaiList.size() <= count; 93 } 94 95 public int getSeikai() { 96 return seikai; 97 } 98 99 public int getCount() { 100 return count; 101 } 102} 103 104class Mondai { 105 private String question; 106 private String answer; 107 private List<String> choices; 108 109 public Mondai(String question, String... choices) { 110 this.question = question; 111 answer = choices[0]; 112 this.choices = Arrays.asList(choices); 113 Collections.shuffle(this.choices); 114 } 115 116 public String getQuestion() { 117 return question; 118 } 119 120 public List<String> getChoices() { 121 return choices; 122 } 123 124 public boolean isCorrect(String ans) { 125 return answer.equals(ans); 126 } 127}
まずボタン等のUIはライブラリ(G4P
)を使いました。ずるい気がしますが便利なものがあるなら活用します(再利用)
おかげで上で箇条書きした点がすべて解消されています。
もちろんGButton
クラスの中では似たような処理があるはずです。しかしクイズゲーム作成中は、ボタンがどう作られているかを気にする必要はありません(カプセル化)
機能が増えたにもかかわらず、グローバル変数(不正確)が7個から4個に減っています(だいぶ恣意的です^^;
変数名やメソッド名が長めなので、文字の密度が上がって圧迫感はあります。
しかし主語(変数名)と操作(メソッド名)に、適切な名前がついていればそのまま読めます。
行数は約3倍になりました。
各メソッドや1行1行は非常に単純で「どういうことだろう?」という点は減りました。
クラスを書いている間はそのクラスの責任だけに集中できるので、規模が大きくなるほどメリットを感じます。
投稿2020/07/08 12:33
総合スコア9807
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/11 13:06
2020/07/11 14:01
2020/07/11 15:42
0
それだけならクラスを使う必要はありません。
公式ページのリファレンスから使いそうな部品を拾うと、
四角を描画するのはrect()
文字を描画するのはtext()/文字サイズを変えるのはtextSize()/フォントを変えるのはtextFont()
mouseのクリックを知るのはmousePressed/mousePressed()/マウス位置を知るのはmouseX,mouserY
グラデーションを描くならlerpColor()/line()
BGMはSoundライブラリのSoundFileクラス
あたりで出来るのではないでしょうか。
どうしてもクラスを使いたいというなら、まずはプログラムの動作の概略を日本語で記述して、その中に登場する「名詞」をピックアップしてそれをクラスに置くことがどうだろうかと検討するのがとっかかりになるかと思います。「n枚目の画像」とか。
(Javaモードで作れば、内部的にはクラスは生成されていますが...)
[追記]結構真面目にやってみました。
Processingでオブジェクト指向っぽくってあまりやったことなかったので出来は保証しません。ツッコミ歓迎。
重視すること:
オブジェクトの「活用」をオブジェクト間の協調動作と捉える。
ストーリー:
プログラムを起動すると、タイトル画面を表示する。
タイトル画面をクリックすると、質問画面を表示する。
質問画面の選択肢のいずれかをクリックすると、正解画面または不正解画面を表示する
正解/不正解画面でクリックすると、タイトル画面に戻る
各画面ではBGMを流す(質問者のプログラムを見ると全編で一つのBGMを流せばよかったみたいですが、作り込んでしまったのでそのまま。変更は難しくはないでしょう)。
さて、このストーリーからクラス候補(名詞)は...これだけのモノしか登場しないと、「画面」をクラスにするぐらいしかなさそうですね。その路線でざっくりのクラス構成を考えましょうか。
Processingの構造(setup()-draw()とmouseClicked())に当てはめるため、これをinterfaceにしてみました。Processingでinterfacaを使うには、ProcessingのIDEでは、新規タブを作成し、例えばFramework.java等の名前を付けて以下を記述する必要があります。
Processing
1//Framework.java 2interface Framework{ 3 void setup(); 4 void draw(); 5 void mouseClicked(); 6}
で、プログラム本体というか。自分に余裕が無かったのでコメントとか付いてません。継承の使い方がイケてない気がしますが...
Processing
1import processing.sound.*; 2enum Results { 3 STAY, 4 GO, 5 CORRECT, 6 WRONG 7} 8 9class Control implements Framework { 10 Screen active;//表示される画面 11 Screen start, question, correct, wrong;//使われる各画面 12 void setup() { 13 start.setup(); 14 active.enter(); 15 question.setup(); 16 correct.setup(); 17 wrong.setup(); 18 } 19 void draw() { 20 active.draw(); 21 Results rc=active.result(); 22 switch(rc) { 23 case STAY: 24 default: 25 break; 26 case GO: 27 if (active==start) { 28 active.exit(); 29 active=question; 30 active.enter(); 31 } else { 32 active.exit(); 33 active=start; 34 active.enter(); 35 } 36 break; 37 case CORRECT: 38 active.exit(); 39 active=correct; 40 active.enter(); 41 break; 42 case WRONG: 43 active.exit(); 44 active=wrong; 45 active.enter(); 46 break; 47 } 48 } 49 Control( Title start, Question question, Title correct, Title wrong ) { 50 this.start=start; 51 active=start; 52 this.question=question; 53 this.correct=correct; 54 this.wrong=wrong; 55 } 56 void mouseClicked() { 57 active.mouseClicked(); 58 } 59} 60 61class Screen implements Framework { 62 String text; 63 SoundFile bgm; 64 color bgColor; 65 boolean done=false; 66 Screen( PApplet app, color bgColor, String text, String bgmFile) { 67 this.bgColor=bgColor; 68 this.text=text; 69 bgm=new SoundFile(app, bgmFile); 70 } 71 void setup() { 72 } 73 void draw() { 74 background(bgColor); 75 textAlign(CENTER, CENTER); 76 textSize(autoSize(text, width*0.8)); 77 fill(0); 78 text(text, width/2, height*0.2); 79 } 80 void enter() { //画面に入る時に行う処理 81 done=false; 82 if (bgm!=null) { 83 bgm.play(); 84 } 85 } 86 void exit() { //画面を終了するときに行う処理 87 if (bgm!=null) { 88 bgm.stop(); 89 } 90 } 91 Results result() { //画面内処理の結果を得る 92 return Results.STAY; 93 } 94 void mouseClicked() { 95 } 96} 97 98class Title extends Screen { 99 String subText; 100 Title( PApplet app, color bgColor, String text, String subText, String bgmFile) { 101 super(app, bgColor, text, bgmFile); 102 this.subText=subText; 103 } 104 @Override void draw() { 105 super.draw(); 106 textAlign(CENTER, CENTER); 107 textSize(autoSize(subText, width*0.7)); 108 fill(0); 109 text(subText, width/2, height*0.7); 110 } 111 @Override Results result() { 112 return done? Results.GO : Results.STAY; 113 } 114 @Override void mouseClicked() { 115 done=true; 116 } 117} 118 119class Question extends Screen { 120 int rightAns; 121 int ansPos; 122 class Button { 123 float left; 124 float top; 125 float w; 126 float h; 127 String text; 128 Button( float left, float top, float w, float h, String text) { 129 this.left=left; 130 this.top=top; 131 this.w=w; 132 this.h=h; 133 this.text=text; 134 } 135 boolean isInside(float x, float y) { 136 return left<=x && x<= left+w && top<=y && y<=top+h; 137 } 138 void draw() { 139 fill(255); 140 rectMode(CORNER); 141 rect(left, top, w, h); 142 fill(0); 143 textSize(autoSize(text, w)); 144 textAlign(CENTER, CENTER); 145 text(text, left+w/2, top+h/2); 146 } 147 } 148 Button[] button; 149 Question( PApplet app, color bgColor, String text, String choice1, String choice2, int right, String bgmFile) { 150 super(app, bgColor, text, bgmFile); 151 button=new Button[2]; 152 button[0]=new Button(width*0.1, height*0.7, width*0.3, height*0.2, choice1); 153 button[1]=new Button(width*0.6, height*0.7, width*0.3, height*0.2, choice2); 154 rightAns=right; 155 } 156 @Override void draw() { 157 super.draw(); 158 for ( Button btn : button) { 159 btn.draw(); 160 } 161 } 162 @Override void enter() { 163 super.enter(); 164 ansPos=0; 165 } 166 @Override void mouseClicked() { 167 for (int i=0; i<button.length; i++) { 168 if (button[i].isInside(mouseX, mouseY)) { 169 ansPos=i+1; 170 } 171 } 172 } 173 @Override Results result() { 174 Results ret; 175 if (ansPos==0) { 176 ret=Results.STAY; 177 } else { 178 if (ansPos==rightAns) { 179 ret=Results.CORRECT; 180 done=true; 181 } else { 182 ret=Results.WRONG; 183 done=true; 184 } 185 } 186 return ret; 187 } 188} 189 190int autoSize(String text, float width) { 191 String[] lines=text.split("\n"); 192 int maxLen=0; 193 for (String line : lines) { 194 if (maxLen<line.length()) { 195 maxLen=line.length(); 196 } 197 } 198 return (int)(width/maxLen); 199} 200 201 202Control ctrl; 203void setup() { 204 size(460, 800); 205 textFont(createFont("游明朝 Demibold", 24)); 206 ctrl=new Control( 207 new Title(this, color(0, 255, 255), 208 "ルイザ・グロス・ホロウィッツ賞\n日本人受賞者を覚えよう!", 209 "ルイザ・グロス・ホロウィッツ賞\n日本人受賞者を全員答えられたらクリアだよ", 210 "https://taira-komori.jpn.org/quick/upl/fanfare2.mp3"), 211 new Question(this, color(245, 100, 170), 212 "生物学や生化学の研究者に贈られる\nルイザ・グロス・ホロウィッツ賞を\n現在、日本人で唯一受賞したのは誰?", 213 "利根川進", "木村資生", 1, "https://taira-komori.jpn.org/sound/anime01/hurry_up.mp3"), 214 new Title(this, color(255, 255, 0), 215 "クリア", 216 "1不可説不可説転点\n獲得", 217 "https://taira-komori.jpn.org/sound/game01/crrect_answer1.mp3"), 218 new Title(this, color(255, 255, 0), 219 "はずれ", 220 "あなたはルイザ・グロス・ホロウィッツ賞の\n日本人受賞者を1人も覚えていません", 221 "https://taira-komori.jpn.org/sound/game01/blip01.mp3") 222 ); 223 ctrl.setup(); 224} 225 226void draw() { 227 ctrl.draw(); 228} 229 230void mouseClicked() { 231 ctrl.active.mouseClicked(); 232}
「画面」というか、結局状態マシンになった気がしますがさて。
「オブジェクトの活用」は、クラス図を描いたときにクラス間に何らかの関連が引ければまぁいいんじゃないでしょうか。
(音源は、'効果音 サンプル 無料'で検索して上位に引っかかったサイトの素材URLを貼っています。昔だと直リンとか嫌われたけど、最近はどうなんでしょう。ただ、ローカルの素材を使っちゃうと他人のソースの試行が面倒なんですよね)
投稿2020/07/07 23:58
編集2020/07/12 01:32総合スコア7703
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/08 07:16
2020/07/08 11:37
2020/07/09 06:24
2020/07/09 13:45
2020/07/10 07:34
2020/07/12 00:59
2020/07/12 03:16
2020/07/12 04:06
2020/07/12 05:09
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。