いんわんの研究ブログ

INWAN'S LABO

ライツアウトは5×5などで構成されたマス(ライト)を全部消すゲームです。

スマホ以降のカジュアルゲームかと思いきやウィキペディアによると意外と古いゲームらしいです。

ゲームとしては非常にシンプルなのでプログラミング初心者向けの題材としてよく使われてる気がします。

 

今回はそのライツアウトを素のJavaScriptだけで作ります。

サンプルはCodePenに公開しています。CodePen上で編集できるのでご自由に改造して遊んでください。

See the Pen
ライツアウトのゲーム作ったよ
by いんわん (@inwan78)
on CodePen.

ゲームエンジン的な部分のCoreオブジェクトについてはこっちの記事を参照してください。

ではプログラムをさっくりと解説します。

 

データは配列で管理

ライツアウトは5×5のマスを使うのでこのデータを配列を使って管理します。

table配列はゲーム開始時のライトの状態が入っています。0が消灯で1が点灯です。

ここの0、1を入れ替えるとゲーム開始時のライトのつき方が変わります。

 

マスの作成

マスはCORE.engine()内で作成しています。tilesという配列にTileというクラスを作って入れています。

Tileクラス本体はプログラムの一番最後にあります。

Tileクラスは座標とマス内の位置を示すrow、colというプロパティを持っています。

draw()はマスを描画するメソッドで点灯なら赤、消灯なら青色に描画します。

色の指定は#000088みたいな感じで指定します。これはcssの色の指定と同じです。他の色を指定したい場合はこちらのサイトが便利です ▷ カラーコード一覧表

 

タッチ処理

タッチ処理は

CORE.canvas.addEventListener("pointerdown", (e) => { });

の部分で行っています。

引数の「e」にタッチした座標などが入っているんですが、どのタイルをタッチしたのかはタイルの座標と比較しないとわかりません。

なのでcheckTiles(e)で調べています。

 

checkTiles()の最初の部分

const x = e.offsetX / CORE.resolutionRatio;
const y = e.offsetY / CORE.resolutionRatio;

これはタッチした座標とゲーム内の座標が違うのを直しています。

表示されている画面はウィンドウのサイズに合うように変更されています。そのためe.offsetX(e.offsetY)の値とはズレています。そのためゲーム内の座標と合うようにリサイズの時に計算している解像度の比率で割っています。

 

タッチした位置のタイルは色を反転し対応するtable配列のデータも上書きします。

 

relateTileChek()

ライツアウトは押したマスとその上下左右のマスが反転します。その処理をrelateTileChek()でしています。

posはtable配列上の位置(一つ上や一つ右など)となるような数字を入れています(コメントアウトしてるのは斜めの位置になるバージョン)。

これをfor文内でチェックします。

 

if( r < 0 || r >= tiles.length || c < 0 || c >= tiles[0].length)continue;

この部分でおかしな位置になる場合を取り除いています。

 

クリアのチェック

isClear()はクリアしたかどうかのチェックです。

全部のマスが消灯したらクリアなのでtable配列のデータが全部0ならクリアです。

一つでも1があればクリアではありません。

 

おしまい

かなりさっくりですがライツアウトの作り方でした。

プログラムは自由に改造してもらって構わないのであちこちいじって遊んでください。

問題増やしてステージ制にしてみたり色々してみてください。