![見出し画像](https://assets.st-note.com/production/uploads/images/82592960/rectangle_large_type_2_6e5d64f7be7a694b549134c86bec1e4d.png?width=800)
合わせて10を作れ!配置系パズルゲームを作ろう!クミタテ式プログラミングドリル(p5JavaScript / Processing)
-王道のパズル操作
今回作るのはパネル配置系パズルゲームです。
数字パネルを配置して、上下合わせて10の数を作りましょう。
パネル配置はパズルゲームの王道です。また、数字パズルはゲームルールに落とし込みやすい側面もあります。
技術的にも、ゲームルール的にも参考になる教材です。
![](https://assets.st-note.com/production/uploads/images/82592334/picture_pc_135710b4008974a4419163459d9cb9ef.gif?width=800)
デモアプリはこちらから。https://openprocessing.org/sketch/1613498
- クミタテ式プログラミングドリルとは?
クミタテ式は英語のp5JavaScriptのコードを、日本語で書かれた図解(通称、図解くん)を使って解説し、プラモデルのように図解通りにコードを組み立てていきながら学習する、テキスト教材型のプログラミング教材です。
![](https://assets.st-note.com/img/1657714288874-seSZ8dNI8B.png?width=800)
- 動画を見ながら学習する
テキスト教材の補助として動画を作成しています。クミタテ式が初めての方は動画と一緒に学習すると良いでしょう。
動画とこのテキスト教材は期間限定で無料公開しています。たくさんのゲームジャンルのプログラミング方法をお伝えしているのでチャンネル登録もよろしくお願いします。
- 開発環境
OpenProcessingを使ったp5js、Processingを環境を前提としています。
■[ここからスタート!]画面のサイズを決める
画面サイズを600x400の固定サイズにしましょう。
![](https://assets.st-note.com/img/1657714151457-ymZTieJAAn.png?width=800)
■背景を黄色で塗りつぶし続ける
drawの中で背景を黄色で塗りつぶし続けましょう。drawの中で毎回背景を塗りつぶすことでアニメーションが実現できます。
![](https://assets.st-note.com/img/1657714162034-q5nlgLdFng.png?width=800)
■四角形のマスを1つ表示する
固定の位置座標(160, 50)の位置に四角形を表示します。
![](https://assets.st-note.com/img/1657714151393-16HDfGdUVL.png?width=800)
■繰り返し処理で49個のマスを、とりあえず重ねて表示する
四角形のマスを49個表示していきます。
繰り返し処理forを使い、49回ループさせることで49個の四角形を表示します。
ここではとりあえず、同じ場所に重ねて49個の四角形を表示します。
![](https://assets.st-note.com/img/1657714151609-DX3MPB6qmy.png?width=800)
■49個の四角形を敷き詰める
同じ箇所に表示されてしまった四角形マスをきれいに敷き詰めていきましょう。
横に7回敷き詰めたら折り返すようにアルゴリズムを組みます。
![](https://assets.st-note.com/img/1657714152271-vk3cPlVZGZ.png?width=800)
■マス情報を配列で管理する
49個の四角形マスに情報を与えていきます。
49個の変数を用意するのは大変なので、ここで配列に登場してもらいます。
「99」のマスは外枠の壁として灰色で表示してみます。
配列は以下をサンプルとしてお使いください。
//p5.js
let slotList = [
99, 99, 99, 99, 99, 99, 99,
99, 0, 0, 0, 0, 0, 99,
99, 0, 0, 0, 0, 0, 99,
99, 0, 0, 9, 0, 0, 99,
99, 0, 0, 0, 0, 0, 99,
99, 0, 0, 0, 0, 0, 99,
99, 99, 99, 99, 99, 99, 99,
];
// Processing Java
int[] slotList = new int[]{
99, 99, 99, 99, 99, 99, 99,
99, 0, 0, 0, 0, 0, 99,
99, 0, 0, 0, 0, 0, 99,
99, 0, 0, 9, 0, 0, 99,
99, 0, 0, 0, 0, 0, 99,
99, 0, 0, 0, 0, 0, 99,
99, 99, 99, 99, 99, 99, 99,
};
![](https://assets.st-note.com/img/1657714151489-v0GbPJRzHI.png?width=800)
■マス情報を文字で表示する
49個のマス情報を、四角形マスの上にテキスト表示していきます。
![](https://assets.st-note.com/img/1657714151803-SOwuMYIAG8.png?width=800)
■0と99は文字を表示しない
文字だらけで見づらいですね。
0はパネルなし、99は壁なので、文字は表示しないようにしましょう。
![](https://assets.st-note.com/img/1657714152024-AYqTfVxtGc.png?width=800)
■手札パネルを表示する
盤上に配置していく、手札パネルを表示します。
ここでは仮に、手札のパネルを1としました。
![](https://assets.st-note.com/img/1657714152446-eRvhiEN9RL.png?width=800)
■手札パネルをマウスでドラッグする
手札パネルを動かせるようにしていきます。
マウスが離されたら手札を元の位置に戻します。
![](https://assets.st-note.com/img/1657714152997-5uM9RlYN19.png?width=800)
■手札パネルを配置する
マウスが離されたときに、マウスの座標から盤上の位置を特定し、
マス情報に手札情報を載せ替えます。
![](https://assets.st-note.com/img/1657714153121-TXylXAjLSR.png?width=800)
ここから先は図解くんはありません。
自分で頭を整理して課題に取り組んでみてください。
■課題1. 新しい手札を配布する
手札パネルを置いても、手札は1のままです。
新しい手札を配布しましょう。とりあえずランダムで良いでしょう。
■課題2. パネル配置時、合計10かをチェックする
配置したパネルの、上下左右のパネル情報を足し算して、合計10かをチェックしましょう。
なお、壁の値99を足し算しないよう注意しましょう。
できれば、オリジナル関数「is10(p1)」命令を作りましょう。
-ヒント-
右隣は+1番目、左隣は-1番目、上は-7番目、下は+7番目ですね。
■課題3.合計10になったパネルを消去する
上下左右のパネルを消去し、0に戻しましょう。
できれば、オリジナル関数「removeAround(p1)」命令を作りましょう。
■課題4.バランス調整する
手札がどの数字の範囲で、どの程度配布すればいいかでバランスが決定します。
排出する手札を調整してみましょう。
なお、デモアプリでは、ランダムな数字が偏らないように、デッキから1枚ずつ抜き出していくデッキ方式を採用しています。
■オリジナルゲームに仕上げよう
今回は足し算して10でしたが、足し算して20でも良いでしょうし、
配置したパネルの上下左右が割り算した商でも面白いと思います。
数字はアルゴリズムとして成立しやすいため、どういうアルゴリズムがゲームとして成立しやすいか、試行錯誤してみましょう。
■完成コード
//p5.js
let slotList = [
99, 99, 99, 99, 99, 99, 99,
99, 0, 0, 0, 0, 0, 99,
99, 0, 0, 0, 0, 0, 99,
99, 0, 0, 9, 0, 0, 99,
99, 0, 0, 0, 0, 0, 99,
99, 0, 0, 0, 0, 0, 99,
99, 99, 99, 99, 99, 99, 99,
];
let hand_number = 1;
let drag_flag = 0;
function setup() {
createCanvas(600, 400);
}
function draw() {
background(255, 200, 0);
for(let i=0; i<49; i++){
let x = 160 + i % 7 * 40;
let y = 50 + int(i / 7) * 40;
fill(255, 255, 255);
if(slotList[i] == 99){
fill(100, 100, 100);
}
rect(x, y, 40, 40);
if(slotList[i] > 0 && slotList[i] < 99){
textAlign(CENTER, CENTER);
textSize(32);
fill(30, 30, 30);
text(slotList[i], x + 20, y + 20);
}
}
let hand_x = 280;
let hand_y = 350;
if(drag_flag == 1){
hand_x = mouseX - 25;
hand_y = mouseY - 25;
}
fill(255, 255, 255);
rect(hand_x, hand_y, 40, 40);
textAlign(CENTER, CENTER);
textSize(32);
fill(30, 30, 30);
text(hand_number, hand_x + 20, hand_y + 20);
}
function mousePressed(){
drag_flag = 1;
}
function mouseReleased(){
drag_flag = 0;
for(let i=0; i<49; i++){
let x = 160 + i % 7 * 40;
let y = 50 + int(i / 7) * 40;
if(mouseX > x && mouseX < x + 40){
if(mouseY > y && mouseY < y + 40){
slotList[i] = hand_number;
if(is10(i) == 1){
removeAround(i);
}
hand_number = int(random(1, 4));
}
}
}
}
function removeAround(p1){
slotList[p1] = 0;
if(slotList[p1 + 1] < 99){
slotList[p1 + 1] = 0;
}
if(slotList[p1 - 1] < 99){
slotList[p1 - 1] = 0;
}
if(slotList[p1 - 7] < 99){
slotList[p1 - 7] = 0;
}
if(slotList[p1 + 7] < 99){
slotList[p1 + 7] = 0;
}
}
function is10(p1){
let sum = 0;
sum = sum + slotList[p1];
if(slotList[p1 + 1] < 99){
sum = sum + slotList[p1 + 1];
}
if(slotList[p1 - 1] < 99){
sum = sum + slotList[p1 - 1];
}
if(slotList[p1 - 7] < 99){
sum = sum + slotList[p1 - 7];
}
if(slotList[p1 + 7] < 99){
sum = sum + slotList[p1 + 7];
}
if(sum == 10){
return 1;
}
return 0;
}
この記事が気に入ったらサポートをしてみませんか?