九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、このところElectron
開発が楽しいのでそちら関連の記事が多くなっていますが、やはりたまにはその他の話題も、ということで今回はVue.jsを使った開発のご紹介です。
テーマは、「反射神経ゲーム」です。
というのも、このブログではできるだけビギナーの方にもわかりやすく、興味をもてる話題を提供したいので、今回はいつものような業務感をなくしてゲームのつくり方を記事にしてみます。
では、今回も最後に教材ソースコードを用意しましたので、ぜひスキルアップに役立ててくださいね。
開発環境: Vue 2.5、Google Chrome 70
目次
やりたいこと
まず丸い形をしたボタンを25個用意します。
そのボタンはランダムで1個だけ色が変わるので挑戦者はこの赤丸をクリックしていきます。
そして、赤丸を10個クリックするとゲーム終了。要するに最短時間を目指すゲームです。(ちなみに間違ったボタンをクリックした場合は+10秒ペナルティを加算します)
レイアウトをつくる
では、まずはレイアウトをつくりましょう。
実際のHTMLコードです。
<html> <head> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"> <style> body { padding: 15px; } .circle-button { margin: 10px; text-align: center; vertical-align: middle; height: 75px; width: 75px; border-radius: 50%; color: #999999; border: 4px solid #CCCCCC; background: #fff; outline: none !important; } .current-button { color: #f44336; border: 4px solid #f44336; } </style> </head> <body> <div id="app"> <h1>Vueで反射神経ゲーム!</h1> <hr> <button class="circle-button"></button> <button class="circle-button"></button> <button class="circle-button"></button> <button class="circle-button"></button> <button class="circle-button"></button> <br> <button class="circle-button"></button> <button class="circle-button"></button> <button class="circle-button"></button> <button class="circle-button"></button> <button class="circle-button"></button> <br> <button class="circle-button"></button> <button class="circle-button current-button"></button> <button class="circle-button"></button> <button class="circle-button"></button> <button class="circle-button"></button> <br> <button class="circle-button"></button> <button class="circle-button"></button> <button class="circle-button"></button> <button class="circle-button"></button> <button class="circle-button"></button> <br> <button class="circle-button"></button> <button class="circle-button"></button> <button class="circle-button"></button> <button class="circle-button"></button> <button class="circle-button"></button> <br> <br> <h4>00:00:00 秒</h4> <button class="btn btn-lg btn-dark">スタート</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js"></script> <script> new Vue({ el: '#app' }); </script> </body> </html>
これを実行したものがこちらです。
では、このレイアウトを使ってJavaScriptのコードを書いていきましょう!
JavaScriptのコードをつくる
丸ボタン部分をつくる
まずは丸ボタンをvueで表示する部分を作っていきます。
<span v-for="buttonNumber in 25"> <button class="circle-button" @click="onClick()"></button> <br v-if="buttonNumber%5 == 0"> </span>
使うのはv-for
です。v-for
は配列やオブジェクトのループによく使われますが、このように数字でも利用することができます。(ただし、数字は0
ではなく1
から始まります)
また、v-if
を使って、buttonNumber÷5
がゼロになる、つまり5の倍数のときだけ<br>
で開業するようにしています。そのため、ボタンが5つずつ上からならんで5列、合計25個のボタンが作成されることになります。
実際に実行したものがこちら。
※ ボタンをクリックしたときの挙動は後でつくります。
経過時間の部分をつくる
まずは、経過時間(秒)を格納する変数seconds
を登録します。
そして、キャッシュがきくcomputed
にsecondsInHMS
という名前の秒を「時:分:秒」表記に変換する疑似変数をつくります。
methods: { strPad(number) { let str = number.toString(); if(str.toString().length == 1) { str = '0'+ str; } return str; } }, computed: { secondsInHMS() { const hours = Math.floor(this.seconds / 3600); const minutes = Math.floor(this.seconds % 3600 / 60); const seconds = Math.floor(this.seconds % 3600 % 60); return this.strPad(hours) +':' + this.strPad(minutes) +':' + this.strPad(seconds) } }
なお、数字がひと桁の場合はゼロを足して「05」としたいのでmethods
にstrPad()
も追加しています。
では、HTMLへ設置しましょう。
<h4>{{ secondsInHMS }} 秒</h4>
そして、テストで4000秒経過したものとして実行したものがこちらです。
スタートボタンをつくる
では、スタートボタンをクリックした時のコードをつくります。
まずは時間のタイマーが格納される変数timer
を登録。
data: { seconds: 0, timer: null },
そして、@click
でstart()
が実行されるようにします。
<button class="btn btn-lg btn-dark" @click="start()">スタート</button>
start()の中身はこうなります。
methods: { start() { this.seconds = 0; if(this.timer != null) { clearInterval(this.timer); } this.timer = setInterval(() => { this.seconds++; }, 1000); }, // 省略 },
まずは始めにtimer
がnull
かどうかをチェックし、もしすでに時間タイマーが実行されているなら、clearInterval()
でこれをクリアします。
そして、setInterval()
で、1秒(1000ミリ秒)ごとに変数seconds
を1ずつ足していきます。
これで時間が経つにつれて秒数が1ずつ増えるようになりました。
赤い丸をランダムで表示する部分をつくる
では、赤い丸をランダムで表示して、それがクリックされたら成功カウントを追加していく部分をつくっていきましょう。
まずは変数です。
data: { seconds: 0, timer: null, count: 0, currentNumer: 0 },
赤丸のクリックが成功したら、このcount
を増やしていきます。
また、currentNumber
は、現在表示されている赤丸の番号、つまり答えです。
では、次に1〜25
の25個の数字をランダムにつくってcurrentNumber
を更新するメソッドsetRandomNumber()
をつくります。
methods: { // 省略 setRandomNumber() { this.currentNumber = Math.floor((Math.random() * 25) + 1); }, // 省略 },
そして、このsetRandomNumber()
はstart()
の一番最後の部分と1秒毎に実行されるsetInterval()
の中の2ヶ所で実行するようにしましょう。(つまり、1秒毎にクリックすべき場所が変わります)
また、成功カウントが分かるcount
もゲームがスタートしたらすぐに初期化するようにします。
start() { // 省略 this.count = 0; // 省略 this.timer = setInterval(() => { this.setRandomNumber(); this.seconds++; }, 1000); this.setRandomNumber(); },
次に、CSSで実際に赤丸を表示する部分です。
まず、class
をメソッドで作成するよう:class
へ変更しbuttonClass()
を登録します。
<span v-for="buttonNumber in 25"> <button :class="buttonClass(buttonNumber)"></button> <br v-if="buttonNumber%5 == 0"> </span>
buttonClass()
の中身はこうなります。
buttonClass(number) { let classNames = ['circle-button']; if(number == this.currentNumber) { classNames.push('current-button'); } return classNames; }
やっているのは、ランダムにつくられた番号と現在の番号が同じ場合に赤丸のクラス、current-button
を追加しているだけです。
これで赤丸がランダムに表示されるようになりました。
テストで実行してみましょう。
丸ボタンをクリックしたときのコードをつくる
では、最後に丸ボタンがクリックされたときのコードです。
<button :class="buttonClass(buttonNumber)" @click="answer(buttonNumber)"></button>
まず丸ボタンをクリックしたときにanswer()
が実行されるようにします。
methods: { answer(number) { if(number == this.currentNumber) { this.count++; if(this.count == 10) { clearInterval(this.timer); alert("ゴール!\n結果は、「"+ this.secondsInHMS +"」でした。"); } this.setRandomNumber(); } else { // ペナルティ this.seconds += 10; } }, // 省略
answer()
の中では、クリックされたボタン番号とランダム番号が同じかをチェックして、もし同じ(正解)ならcount
を1増やします。そして、もし成功カウントが10
になったらタイマーを止め、ゲーム完了のアラートを表示します。
逆に間違ったボタンをクリックした場合は+10秒のペナルティです。
デモを用意しました
今回開発した反射神経ゲームは以下から体験できます。
※ なおIEは対応してません。(ゴメンナサイ…IEはもう見限ったんですT^T)
教材ソースコードをダウンロード
今回実際に開発したソースコード一式を以下からダウンロードすることができます。cdn
を使っているので、展開してindex.html
を開くだけで実行できますよ!