WGGの活動log

都内でゲーム開発だったりVRだったりをしてるかもしれないエンジニアです. WGGは「ワグ」と読みます

p5.jsでプロ生ちゃんのスライドパズルアプリを作った話

少し前に,プロ生ちゃんのスライドパズル(15パズル)が遊べるブラウザゲームを作って公開しました

難易度は一般的な4x4だけでなく,3x3やもっと大きな分割まで用意しているので,こんな事もできます
時間がかかるので自分で解いていませんが...
f:id:wgg00sh:20180825000727p:plain


今回はこれを作った手法とかについて書いていきます.
ソースコードは全てgithubにあげていますので,よければそちらも見てみてください
github.com

開発環境

今回,ブラウザゲームということで一応PCでもスマートフォンでも動作するように多少注意を払って作りました.
とはいえ自分の持っている環境が,「WindowsPC」「iPhone」の2種類なので,Android端末や,Macは未確認です.
開発に使用したソフトなんかをいくつか書いていきます.

VSCode

code.visualstudio.com

テキストエディタです
p5.js を書くのに適した拡張機能がいくつかあったのと,それ以外でも普段からよく使っているので採用しました.
f:id:wgg00sh:20180824225859p:plain

拡張機能

この辺は昨日書いた記事とちょっと内容が被っています.
wgg.hatenablog.jp

p5js snippets

marketplace.visualstudio.com
p5用のスニペットで,コーディングがしやすくなります.

Live Server

marketplace.visualstudio.com
ローカルのWebサーバを立ち上げて編集中のファイルをアップロードできる拡張機能です.
これを用いるとスマホで動作確認するためにどこかWeb上にアップロードしたりする必要がなくなり,非常に手間が省けました

ios-webkit-debug-proxy

github.com
iOSSafariで開いているWebページのコンソールをPCに表示するアプリです
PCでは動作するのに,スマホだとクラッシュする事が時々あり,その原因を調べるのに使用しました.
iPhoneとPCをLightningケーブルで繋ぐだけでiOSSafariで開いているページのログをPCのブラウザで表示できます.

p5.jsの始め方

一番始めはとりあえず3つのファイルが有れば大丈夫です.
Webページ本体となるindex.html, p5のコードを書く Main.js, p5のライブラリであるp5.js(公式サイトからダウンロードします)
p5js.org

<!-- index.html -->

<!doctype html>
<html lang="ja">
<head>
  <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1" />
  <meta charset="UTF-8">
  <title>タイトル</title>
  <script src="js/p5.js"></script>
  <script src="js/Main.js"></script>
</head>
<body>
</body>
</html>
//Main.js

function setup() {
  // キャンバスの作成
  createCanvas(windowWidth, windowHeight);
}

// メインループ
function draw() {
}

Main.jsにプログラムを追加していきます.
ソースコードを複数ファイルに分割する場合は,それらを全てindex.htmlに記述します.
今回作成したスライドパズルは8つのファイルからできています.

  1. アクセスポイント(Main.js)
  2. ゲームの状態管理などを行うクラス(Game.js)
  3. 画像データなどの読み込みを行うクラス(Resource.js)
  4. マウスや画面タップなどの情報を保持するクラス(Input.js)
  5. 各シーンのクラス(Title.js, ImageSelect.js, Puzzle.js)
  6. その他自作の汎用関数をまとめたファイル(Util.js)

一応クラスと書いていますが,これを作った当初はJavascriptのクラスについて十分に理解していなかったため,言語仕様的にはかなり問題のある書き方をしているかも知れません()

全画面表示の仕方

次のようなコードを動かしてみます.

function setup() {
  createCanvas(windowWidth, windowHeight);
}

function draw() {
  background(0);
}

想定した挙動は,画面全体が真っ黒になるはずなのですが実際は↓のようになります
f:id:wgg00sh:20180824233237p:plain
f:id:wgg00sh:20180824233437p:plain

PC,スマートフォン共に,周りにわずかに白い領域ができ,特にPCではスクロールバーまで表示されてしまっています.
この問題はcssを弄ることで解決しました.
p5に限らずWebページを作る時によくある奴です

index.htmlに以下のcssを直接記述するか,cssファイルを読み込むことで解決します.

*{
  padding: 0;
  margin: 0;
}

スマホで画面がスクロールしてしまう.

(これは今回のスライドパズルを作った後に解決した内容です)
開発中に,このような問題に遭遇しました

Twitterでこちらの記事を教えていただき,解決することができました
qiita.com

スマホとPC両方でのレイアウト調整

ここが結構難しかったです.

PC版
f:id:wgg00sh:20180824234618p:plain
f:id:wgg00sh:20180824234630p:plain
f:id:wgg00sh:20180824234640p:plain

スマートフォン
f:id:wgg00sh:20180824234728p:plain
f:id:wgg00sh:20180824234734p:plain
f:id:wgg00sh:20180824234741p:plain

基本的には,「メインコンテンツを大きく表示し」「その他UIは扱いづらいサイズ感にならないように」しようとしています.


p5.jsでは画像などを描画する場合に,基本は座標を入力するのですが,画面サイズが環境によって異なることを考えると,この入力方法は扱いづらいです.そこで,画面の比率を用いて座標を設定する関数を自作してそちらを利用するようにしました

// Util.js

// 横幅の比率に対する座標を取得
var widthScale = function (val) {
  return windowWidth* val;
}

// 縦幅の比率に対する座標を取得
var heightScale = function (val) {
  return windowHeight * val;
}

この2つの関数は,引数に0~1の値を渡すと,0(左端,上端)から,最大値(右端,下端)までの比率で座標値を取得してくれます.

画面のレイアウト

先に「メインコンテンツを大きく表示する」事を意識していると書いたように,このゲームでは環境によって画像などの配置の仕方を変えています.
メインのパズルシーンのレイアウトについて説明します

f:id:wgg00sh:20180824235618p:plain
f:id:wgg00sh:20180824235729p:plain

ボタンなどのUIを設置するスペースを画面の下端に設けて,残りのスペースが縦長か,横長かで処理を分けています.
スマホのように,縦長の場合は,画像全体が画面の横幅を埋め尽くすように配置し,PCのように,横長の画面では,画像全体が,レイアウト用に確保したスペースを除いて縦幅を埋め尽くすように配置しています.
このようにすることで,ゲーム画面とボタンなどのUIを様々な環境で(一応は...)共存させています.

終わりに

こんな感じで,javascriptもp5もほとんど初めてだったのですが,3日程かけて1つのゲームを作ってみました.
お盆休みで久しぶりに趣味でコードを書ける時間が確保できたので楽しかったです.
良ければ遊んでみてください^^