[ブラウザゲームの作り方] Number-Place(数独)#8「同じ数値を見やすくする処理」

2023年5月27日

ゲーム プログラミング

eyecatch 一通りのゲーム機能が搭載できたところで、もう少しいろいろな機能を追加してゲームクオリティをアップさせたいと思います。 ていうか、今の段階では、遊びづらいと思うので、ユーザーインターフェイスを考慮する必要があります。 ゲーム作りに限らず、プログラミングで何かのアプリやサービスを作った時に、この思考は非常に重要です。 ということで、今回は入力してある数字にカーソルがマウスオーバーした時に、表示されている同じ数字の色を変更して、ナンプレのゲームをやり安いようにしてみたいと思います。 ただし、気づいた人もいるかもしれませんが、これはパソコンの操作限定になります。 スマートフォンでのユーザーインターフェイスは今回棚上げです。

ソースコード

[追加] css/table.css

※下のコードをファイルに追加 #NumberPlace td[data-same-number='1']{ color:red; }

[一部修正] js/input.js

※mousemove()関数を下記に書き換え mousemove(e){ if(this.data){ const size = Math.abs(e.pageX - this.data.pos.x) if(size < Main.interval_px){return} const num = this.pos2num(size) this.data.cell.textContent = num || '' this.data.num = num this.data.move_flg = true } else{ // same-number this.check_same_number(e) } }

[追加] js/input.js

※下記の関数(2つ)を追加 check_same_number(e){ const current_cell = e.target.closest('#NumberPlace td') if(current_cell && this.current_cell !== current_cell){ this.current_cell = current_cell const current_num = Number(current_cell.textContent || 0) this.set_same_number(current_num) } else if(!current_cell && this.current_cell){ this.set_same_number() delete this.current_cell } } set_same_number(current_num){ const cell_all = document.querySelectorAll('#NumberPlace td') for(const cell of cell_all){ const num = Number(cell.textContent || 0) if(!current_num || current_num !== num){ if(cell.hasAttribute('data-same-number')){ cell.removeAttribute('data-same-number') } } else if(current_num === num){ cell.setAttribute('data-same-number' , 1) } } }

結果表示

上記の様に、入力されている数字の上にマウスカーソルを乗せると、同じ数字の色が赤色に変わります。 これで、同じ数字のカブりチェックがしやすくなると思います。

解説とポイント

今回は比較的簡単な処理で、次のようなフローで考えました。
1. マウス移動のmousemoveイベントで、tableのcellで数字があるマス目に乗った時に、table内の同じ数字の書かれているcellに、data-same-number='1'という属性を追加。 2. cssで、"#NumberPlace td[data-same-number='1']" というセレクターに文字色を変更する処理を書く。 3. 対象の数値が変わった場合は、変わる前の数値の属性を削除する。
比較的シンプルで、コードも少なくて理解しやすいかと思います。 主にjs/input.jsでの処理のみで行っていて、mousemoveイベントの箇所に処理を追加(少し変更)して、新たに2つの関数を追加してそこで、カーソルのhoverされている数字判定と、属性を付ける処理をしています。

今回のポイント

マウスイベントで使っている、js/input.js内のthis.dataという変数の判定には関係なく処理をしたいので、mousemove()関数のthis.dataが存在しなければ、処理をしないという処理判定を変更しています。 あと、同じセルは処理しないという判定を入れないと、mousemove()は、ピクセル単位で判定がされてしまうため、マウスが移動するたびに繰り返しの処理をどんどん実行されてしまいます。 処理を行ったセルをthis.current_cellという変数に格納して、同じセルの場合は判定をしないというif文を書いています。 一方、this.current_cellが格納されている時に、別のセルの上に乗っていない場合は、全ての属性を削除する処理をいれないと、赤い文字がずっと残り続けてしまうことになっているので、数字なし判定をして、this.current_cell変数を削除しています。 この辺の一時保存して削除するやり方は、設計者によってやり方が様々あるので、自分なりのやりやすい方式を見つけておくと同時に、他の人がどういうプログラムで書いているかを知っておくのも重要だと思います。

あとがき

ナンプレが少し遊びやすくなってきたと思いますが、もっと便利に遊べるようにするために、どんな機能を追加したらいいか、自分で考えて、機能追加をしてみるのもいいかもしれません。 でも、この講座が終わるまでは、独自のプログラムは追加しないようにしてください。 gitが分かる人は、別ブランチでどんどん改修してもらってもいいですよ。