見出し画像

今日は何が起こる?生年月日占いを作ろう!クミタテ式プログラミングドリル(p5JavaScript / Processing)

- 組み合わせは365通り

今回作るのは生年月日占いです。
誕生月と誕生日でカラムをわけ、組み合わせで複雑な占い結果を導き出します。
ガチンコの占いというよりはクスっとくる占いを目指しましょう。

デモアプリはこちらから。https://openprocessing.org/sketch/1595613

- クミタテ式プログラミングドリルとは?

クミタテ式は英語のp5JavaScriptのコードを、日本語で書かれた図解(通称、図解くん)を使って解説し、プラモデルのように図解通りにコードを組み立てていきながら学習する、プログラミング教材です。
プログラミング的思考を学ぶよりも、コードの書き方を優先的に学習することを目的としています。

OpenProcessing基本のコード図解

- 動画を見ながら学習する

動画と並行しながら学習するとより効率的に学習できるようになっています。
たくさんのゲームジャンルのプログラミング方法をお伝えしているのでチャンネル登録もよろしくお願いします。
動画を見るだけでなく、必ず自分でプログラミングして動かすことを心がけてください。見るだけでは理解したつもりにしかなりません。

- 開発環境

OpenProcessingを使ったp5.jsを使いましょう。


■[ここからスタート!]画面のサイズを決める

画面サイズを600x400の固定サイズにしましょう。


■背景を黄色で塗りつぶし続ける

drawの中で背景を黄色で塗りつぶし続けましょう。drawの中で毎回背景を塗りつぶすことでアニメーションが実現できます。


■四角形のマスを、とりあえず1つだけ表示する

固定の(50, 20)の位置座標に四角形を表示します。


■後半は有料となりました。

後半では引き続きテキスト教材と動画解説が付属されています。

■12ヶ月分のマスを表示する

繰り返し処理forを使って12個の四角形を表示します。


■月のラベルを表示する

1〜12月のラベルを表示します。

- 注意 -
Processing Javaの場合、日本語を使って文字サイズを変えると文字化けしてしまいます。
回避方法:https://codeaid.jp/processing-jp/


■31日分のマスを表示する

続けて31日分のマスを表示しましょう。もちろん繰り返し処理forを使います。
ただ、月と違って31個のマスが縦に入り切らないため18個で折り返し処理を入れています。折り返しのアルゴリズムにも注意しましょう。


■実行画面を確認しよう

ここまでの実行画面は以下のようになるはずです。違っていたら何か見落としがあるのかもしれません。確認しましょう。

(みなさんの実行結果もこうなってますか?)

■占い結果を配列で管理する

月の結果リストと、日の結果リストを配列で管理し、表示します。

//p5.js
let monthList = [
  "国語の先生に", "保健室に行ったら", "給食の時に", "クラスの女子に",
  "隣のクラスの先生と", "ドッジボールで", "テストの時に", "校門の前で",
  "学校の裏庭で", "友達からのLINEで", "親から", "お風呂で",
];
let dayList = [
  "褒められる", "叱られる", "笑われる", "勝つ", "慰められる", "いいことばかり",
  "お小遣いをもらう", "いじられる", "おごってもらう", "興奮する", "事件が起きる",
  "遅刻する", "疑われる", "約束させられる", "追いかけられる", "早退する", "100円を拾う",
  "落とし物をする", "癒される", "自信を失う", "フラれる", "告白される", "炎上する",
  "サインを求められる", "声をかけられる", "逆転する", "手を握られる",
  "写真を撮る", "歌を歌う", "すっ転ぶ","忘れられる",
];

//Processing Java
String[] monthList = new String[]{
  "国語の先生に", "保健室に行ったら", "給食の時に", "クラスの女子に",
  "隣のクラスの先生と", "ドッジボールで", "テストの時に", "校門の前で",
  "学校の裏庭で", "友達からのLINEで", "親から", "お風呂で",
};
String[] dayList = new String[]{
  "褒められる", "叱られる", "笑われる", "勝つ", "慰められる", "いいことばかり",
  "お小遣いをもらう", "いじられる", "おごってもらう", "興奮する", "事件が起きる",
  "遅刻する", "疑われる", "約束させられる", "追いかけられる", "早退する", "100円を拾う",
  "落とし物をする", "癒される", "自信を失う", "フラれる", "告白される", "炎上する",
  "サインを求められる", "声をかけられる", "逆転する", "手を握られる",
  "写真を撮る", "歌を歌う", "すっ転ぶ","忘れられる",
};

■月のリストをランダムシャッフルする

rouletteMonthListというオリジナル命令を定義し、drawの中で呼び出すことで1秒間に60回シャッフルさせます。


■マウスクリックでシャッフルを止める

フラグを用意し、フラグが立っていたらシャッフルを止めるように制御します。


ここから先は図解くんはありません。
自分で頭を整理して課題に取り組んでみてください。

■(★★☆)課題1. 日のリストもシャッフルするようにしましょう

月のリストしかシャッフルしていませんでした。
日のリストもシャッフルするように、rouletteDayList命令を作りましょう。

■(★☆☆)課題2.もう一度クリックで再度シャッフルされるようにしましょう

フラグを0にするだけでシャッフルし始めますね。

■(★★☆)課題3.自分の誕生日をハイライトしましょう

自分の誕生日がわかりやすくなるよう、色を変えてハイライトをしましょう。

■(★★★)課題4. シャッフルを共通化しよう

rouletteMonthListとrouletteDayListは処理が非常に似ています。
こういう似た処理は引数を使うことで処理を抽象化し、共通化することができます。
以下はrouletteCommonとして、引数にmonthListやdayList、その他どんな配列でも渡せば、いい感じにシャッフルしてくれるオリジナル命令です。

-ヒント-
プログラミングのウデマエは「抽象化」で決まると言っても過言ではありません。
具体的なプログラミングは仕様変更やメンテナンス性に欠けますが、抽象化しておくことで仕様変更やコードの資産化にグッと強くなります。

■オリジナルの占いに仕上げよう

リストの中を変えるだけでもオリジナリティを出せるはずです。
また、テーマ性を持たせることでまとまりもできるはずです。今回は学校をテーマに持たせてみましたが、例えば、運動会占い、恋愛占い、クラスメート占い、晩御飯のおかず占い、などテーマ性で面白さがぐっと引き立つはずです。

(有料)完成コード

let monthList = [
  "国語の先生に", "保健室に行ったら", "給食の時に", "クラスの女子に",
  "隣のクラスの先生と", "ドッジボールで", "テストの時に", "校門の前で",
  "学校の裏庭で", "友達からのLINEで", "親から", "お風呂で",
];
let dayList = [
  "褒められる", "叱られる", "笑われる", "勝つ", "慰められる", "いいことばかり",
  "お小遣いをもらう", "いじられる", "おごってもらう", "興奮する", "事件が起きる",
  "遅刻する", "疑われる", "約束させられる", "追いかけられる", "早退する", "100円を拾う",
  "落とし物をする", "癒される", "自信を失う", "フラれる", "告白される", "炎上する",
  "サインを求められる", "声をかけられる", "逆転する", "手を握られる",
  "写真を撮る", "歌を歌う", "すっ転ぶ","忘れられる",
];
let flag = 0;
function setup() {
	createCanvas(600, 400);
}

function draw() {
	background(255, 200, 0);
	if(flag == 0){
		rouletteCommon(monthList);
		rouletteCommon(dayList);
	}
	for(let i=0; i<12; i++){
		let x = 60;
		let y = 20 + i * 30;
		fill(255, 100, 0);
		if(i == 6){
			fill(255, 20, 0);
		}
		rect(x, y, 150, 30);
		textAlign(RIGHT, CENTER);
		textSize(12);
		fill(255);
		text(i + 1 + "月", x + 30, y + 15);
		textAlign(LEFT, CENTER);
		text(monthList[i], x + 35, y + 15);
	}
	for(let i=0; i<31; i++){
		let x = 240 + int(i / 18) * 150;
		let y = 20 + i % 18 * 20;
		fill(0, 200, 200);
		if(i == 6){
			fill(0, 100, 100);
		}
		rect(x, y, 150, 20);
		textAlign(RIGHT, CENTER);
		textSize(10);
		fill(255);
		text(i + 1 + "日", x + 30, y + 10);
		textAlign(LEFT, CENTER);
		text(dayList[i], x + 35, y + 10);
	}
}

function mousePressed(){
	if(flag == 0){
		flag = 1;
	}else{
		flag = 0;
	}
}

function rouletteCommon(targetList){
	let count = targetList.length;
	for(let i=0; i<count; i++){
		let from = int(random(0, count));
		let to = int(random(0, count));
		let cache = targetList[from];
		targetList[from] = targetList[to];
		targetList[to] = cache;
	}
}









いいなと思ったら応援しよう!