//作成 2020/04/17 //プログラミングの考え方 //結果が2桁までの加算と減算を自動生成する PFont myFont1; //フォントを格納する変数 String Calculation ="" ; String Operation ="" ; String Shiki =""; String Kotae =""; String Mojiretsu =""; String KeisanF ="" ; String KeisanHouhou ="" ; int Counter = 0 ; //カウントダウンタイマー用 int start = -1; int startTime = 0; //ボタンをクリック 1 //http://happy-arduino.blogspot.com/2012/11/processing.html PImage imgAdd ; PImage imgSubt ; PImage imgCheck ; PImage imgNext ; PImage imgContinue; void setup() { //キャンバスを設定。画面サイズ、背景色、色などを最初に設定します。 size(1000, 600); //size([横幅], [縦幅]) background(255); //background([0が黒〜255が白],[透明度]); myFont1 = createFont( "メイリオ", 32 ); //createFont(name, size) フォントを動的に作成する //http://zawaworks.hatenablog.com/entry/2017/03/13/160055 //"MS ゴシック" "MS 明朝" textFont( myFont1 ); //textFont() 使用フォントを選択する。loadFont()やcreateFont()で作成したフォントを使えるようにします。 imgAdd = loadImage("Add.png"); imgSubt = loadImage("Subt.png"); imgCheck = loadImage("CheckP.png"); imgNext = loadImage("Next.png"); imgContinue = loadImage("ContinueP.png"); } void mousePressed() { //●mousePressed() 関数で、マウスボタンが押されたイベントを捕まえる //マウスボタンを押したタイミングをタイムリーに検知したいなら、mousePressed()関数でボタンが押されたタイミングで処理を行う。 //●mouseClicked() 関数で、マウスボタンが押されて離された事を捕まえる //「ボタンが、押されて離されたタイミング」で呼び出される事です。カチッとクリックしたタイミングで処理を行うための関数。 Operation = ""; //マウスの位置情報を取得 mouseX,mouseY if (mouseX>=50 && mouseX<=130 && mouseY>=120 && mouseY<=160) { Calculation ="Add"; } else if (mouseX>=150 && mouseX<=250 && mouseY>=120 && mouseY<=160) { Calculation ="Subt"; } else if (mouseX>=310 && mouseX<=430 && mouseY>=120 && mouseY<=160) { Operation ="Check"; } else if (mouseX>=500 && mouseX<=600 && mouseY>=120 && mouseY<=160) { Operation ="Next"; } else if (mouseX>=630 && mouseX<=900 && mouseY>=120 && mouseY<=200) { Operation ="Continue"; } //右下の状況表示を消す fill(255); noStroke(); rect(400, 500, 600, 100); //rect(基準のx座標, 基準のy座標, 横幅, 縦幅) fill( 60 ); if (mousePressed == true) { text( "true", 400, 550 ); } else { text( "false", 400, 550 ); } text( Calculation, 500, 550 ); text( Operation, 700, 550 ); text( "mouseX = " + str(int(mouseX)), 450, 590 ); text( "mouseY = " + str(int(mouseY)), 700, 590 ); //text(文字列, x座標, y座標) } void mouseClicked () { //void mouseClicked() { //クリックすると、ここの処理が実行される //右下の状況表示を消す fill(255); noStroke(); rect(400, 500, 600, 100); //rect(基準のx座標, 基準のy座標, 横幅, 縦幅) fill( 60 ); } void draw() { fill( 60 ); //fill() 塗りに色を付ける //fill(d) グレースケール。整数dが0なら黒、255なら白、その間の数は数が小さいほど濃い灰色。 //fill(d,a) グレースケールだが、「透明度」を追加指定する。aの0は完全に透明、255は完全に不透明。 text( "2桁までの足し算と引き算の問題を自動生成します。", 45, 50 ); //text(文字列, x座標, y座標) text( "算法(足し算か引き算)をえらんで下さい。", 45, 100 ); //カウントダウンタイマーの前表示を消す noStroke(); fill(255); //fill(0); //領域確認用 rect(470, 360, 75, 50); //カウントダウンタイマーを表示 if (countDown(startTime, start)>=0) { fill( 0, 255, 0 ); text(countDown(startTime, start), 500, 400); if (countDown(startTime, start)==0) { fill(255, 0, 0); text("TIME OVER", 550, 400); } } fill( 60 ); image(imgAdd, 50, 120); image(imgSubt, 150, 120); image(imgCheck, 350, 120); image(imgNext, 500, 120); image(imgContinue, 650, 120); textSize(24); //文字サイズを変更 text( "クリックで答、", 750, 150 ); text( "離すと次の問題を表示。", 670, 190 ); textSize(32); //サイズを戻す if (mousePressed == true) { if (Calculation == "Add") { if (KeisanF == "" || Calculation != KeisanHouhou) { //先の式の表示を消す fill(255); //fill(0); //領域確認用 noStroke(); rect(0, 200, 1000, 210); //rect(基準のx座標, 基準のy座標, 横幅, 縦幅) fill( 60 ); //文字を取り出すには //http://mslabo.sakura.ne.jp/WordPress/make/processing%E3%80%80%E9%80%86 %E5%BC%95%E3%81%8D%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/%E6%96 %87%E5%AD%97%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E3%81%AB%E3%81%AF/ //http://maicommon.ciao.jp/ss/processing_g/string/ Mojiretsu = Keisann(Calculation); KeisanF = "Sumi"; KeisanHouhou = Calculation; Shiki = Mojiretsu.substring(0, 10); text(Shiki, 100, 300); Counter = Counter + 1; Kotae = Mojiretsu.substring(11); //カウントダウンタイマーを初期化 startTime = millis(); start = 10; } } else if (Calculation == "Subt") { if (KeisanF == "" || Calculation != KeisanHouhou) { //先の式の表示を消す fill(255); //fill(0); //領域確認用 noStroke(); rect(0, 200, 1000, 210); //rect(基準のx座標, 基準のy座標, 横幅, 縦幅) fill( 60 ); Mojiretsu = Keisann(Calculation); KeisanF = "Sumi"; KeisanHouhou = Calculation; Shiki = Mojiretsu.substring(0, 10); text(Shiki, 100, 300); Counter = Counter + 1; Kotae = Mojiretsu.substring(10); //カウントダウンタイマーを初期化 startTime = millis(); start = 10; } } } if (Operation =="Check") { Operation = ""; text(Kotae, 300, 300); //先の左下計算数を消す fill(255); //fill(0); //領域確認用 noStroke(); rect(0, 500, 200, 200); //rect(基準のx座標, 基準のy座標, 横幅, 縦幅) fill(0, 100, 100); if (countDown(startTime, start)>=5) { text("はやい!!", 550, 400); } else if (countDown(startTime, start)>=2) { text("がんばれ!", 550, 400); } fill( 60 ); //カウントダウンタイマーを初期化 start = -1; } if (Counter>0) { fill(255, 128, 0); text( "計算数: " + nf(Counter), 10, 550 ); } if (Operation =="Next" && KeisanF != "" ) { Operation = ""; //先の式の表示を消す fill(255); noStroke(); rect(0, 200, 1000, 210); //rect(基準のx座標, 基準のy座標, 横幅, 縦幅) fill( 60 ); Mojiretsu = Keisann(Calculation); KeisanF = "Sumi"; Shiki = Mojiretsu.substring(0, 10); text(Shiki, 100, 300); Counter = Counter + 1; Kotae = Mojiretsu.substring(11); //カウントダウンタイマーを初期化 startTime = millis(); start = 10; } if (Operation =="Continue") { text(Kotae, 300, 300); //先の左下計算数を消す fill(255); //fill(0); //領域確認用 noStroke(); rect(0, 500, 200, 200); //rect(基準のx座標, 基準のy座標, 横幅, 縦幅) fill(0, 100, 100); if (countDown(startTime, start)>=5) { text("はやい!!", 550, 400); } else if (countDown(startTime, start)>=2) { text("がんばれ!", 550, 400); } fill(60); //カウントダウンタイマーを初期化 start = -1; if (Counter>0) { fill(255, 128, 0); text( "計算数: " + nf(Counter), 10, 550 ); { if (Counter>20) { fill(128, 0, 128); text( "計算、たくさんできています!", 100, 470 ); } } } if (Operation =="Continue" && mousePressed == false && KeisanF != "" ) { //先の式の表示を消す fill(255); noStroke(); rect(0, 200, 1000, 210); //rect(基準のx座標, 基準のy座標, 横幅, 縦幅) fill( 60 ); Mojiretsu = Keisann(Calculation); KeisanF = "Sumi"; Shiki = Mojiretsu.substring(0, 10); text(Shiki, 100, 300); Counter = Counter + 1; Kotae = Mojiretsu.substring(11); Operation = ""; //カウントダウンタイマーを初期化 startTime = millis(); start = 10; //右下の状況表示を消す fill(255); noStroke(); rect(400, 500, 600, 100); //rect(基準のx座標, 基準のy座標, 横幅, 縦幅) fill( 60 ); //先の左下計算数を消す fill(255); //fill(0); //領域確認用 noStroke(); rect(0, 500, 200, 200); //rect(基準のx座標, 基準のy座標, 横幅, 縦幅) } } } String Keisann(String AorS ) { String mojiretsu=""; int A; int B; int S; //ループ方法 //http://www.cho-design-lab.com/2013/05/29/processing-repeat/ //while(条件){繰り返す処理;繰り返す処理;…繰り返す処理;} //do {繰り返す処理;繰り返す処理;…繰り返す処理;} while(条件); //do ? whileは「条件の判定をする前に、一度繰り返し処理を行う」という繰り返し処理です。 //for(カウンタ初期化; 条件; カウンタ更新)繰り返す処理; do { A = int(random(99))+1; //random(2) は 0以上 2未満の数を発生する。命令intはこれの小数部分を切り捨てて整数化する。 //int(random(2)) は0または1になる。 B = int(random(99))+1; S = A+B; } while (S >= 100); if (AorS == "Add") { mojiretsu = nf(A) + " + " + nf(B) + " = " + nf(S); } else if (AorS == "Subt") { mojiretsu = nf(S) + " - " + nf(A) + " = "+nf(B); } return mojiretsu; } //millis関数を使ってカウントダウンタイマーを作る //https://blanche-toile.com/web/processing-millis-countdown-timer int countDown(int s, int timeLimit) { s = millis() -s; int ms = s/1000; return int(timeLimit - ms); }