ゲームを作って公開してみたのですが、そこでこんなリクエストが…。
プレイヤー名と効果音のボリュームをそのつど設定するのは面倒なので保存できないか?
そこで今回はcookieに設定を保存する方法を考えます。
JavaScriptでcookieに値を保存するには、document.cookieを使用します。ここへ任意の名前と値をセットすることで設定が保存されます。デフォルトではセットした名前と値はブラウザを終了した時点で消去されます。
document.cookie = “任意の名前=任意の値”;
これだとセットした名前と値はブラウザを終了した時点で消去されてしまうので、次回アクセスしたときに使えるようにするには以下のようにします。
1 2 3 |
let expire = new Date(); expire.setTime( expire.getTime() + 1000 * 3600 * 24 * 14); // 2週間 document.cookie = "任意の名前=任意の値; Expires=" + expire.toUTCString(); |
それからcookieはブラウザの設定で使用不可にできるため、まずcookieが使用できるか確認する必要があります。またcookieには”=”、”;”などの記号や日本語文字を保存することができません。そこでこれらの文字列がある可能性があるのであればencodeURIComponentを使ってエンコードした値をセットします。エンコードした値はdecodeURIComponentで元に戻すことができます。
これはcookieに値を保存してそれを表示させるコードです。保存する名前と値のなかにエスケープが必要な文字列はないのですが、'<‘ と ‘>’ をエスケープする処理を入れています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>cookieに値を保存し読み出すテスト</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <style> td { border: 1px solid #777; padding: 4px 20px 4px 20px; } </style> <div id = "result"></div> <script> if (navigator.cookieEnabled) { //cookieが使えるか確認 document.cookie = "key=" + encodeURIComponent("abc"); document.cookie = "name=" + encodeURIComponent("太郎"); document.cookie = "value=" + encodeURIComponent("111"); let arr = document.cookie.split(' '); let cookie = arr.join(''); arr = cookie.split(';'); let text = ''; text += '<table>'; for(let i = 0; i < arr.length; i++) { let arr2 = arr[i].split('='); // 見えてしまうといけないものもあるので表示されるものを'key''name''value'に限定する let name = decodeURIComponent(arr2[0]); if(name != 'key' && name != 'name' && name != 'value') continue; text += `<tr> <td>${decodeURIComponent(arr2[0]).split('<').join('<').split('>').join('>')}</td> <td>${decodeURIComponent(arr2[1]).split('<').join('<').split('>').join('>')}</td> </tr>`; // '<' と '>' をエスケープしている } text += '</table>'; document.getElementById('result').innerHTML = text; } </script> </body> </html> |
設定を保存するコードを示します。名前を保存をクリックするとテキストボックス内の文字列をcookieに保存します。そして次回アクセスしたときに保存した文字列がテキストボックス内に表示されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>テキストを保存する</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <input type="text" id="name"><button onclick="save()">名前を保存</button> <script> function save(){ if (navigator.cookieEnabled) { //cookieが使えるか確認 var expire = new Date(); expire.setTime( expire.getTime() + 1000 * 3600 * 24 * 14); // 2週間 document.cookie = "your-name=" + encodeURIComponent(document.getElementById('name').value) + '; Expires='+ expire.toUTCString(); } } window.onload = (ev) => { if (navigator.cookieEnabled) { //cookieが使えるか確認 let arr = document.cookie.split(' '); let cookie = arr.join(''); arr = cookie.split(';'); for(let i = 0; i < arr.length; i++) { let arr2 = arr[i].split('='); if(arr2[0] == 'your-name') document.getElementById('name').value = decodeURIComponent(arr2[1]); } } } </script> </body> </html> |
ボリュームコントロールの表示と設定の保存・読み出し
最初の課題であるプレイヤー名と効果音のボリュームを保存するコードを示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>ゲームの設定を保存する</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <label>ハンドルネーム</label> <input type="text" id="name" maxlength='16' /><br> <input type="checkbox" id="checkbox" />チェックボックス <p>音量: <input type="range" id="volume" min="0" max="1" step="0.01"> <span id="vol_range"></span> </p> <button onclick="playSound()">音を鳴らす</button> <button onclick="save()">cookieに設定を保存する</button> <script> let $playerName = document.getElementById('name'); let $checkbox = document.getElementById('checkbox'); // ボリューム設定 let $elemVolume = document.getElementById("volume"); let $elemRange = document.getElementById("vol_range"); let $sound = new Audio('./sound.mp3'); function playSound() { $sound.currentTime = 0; $sound.play(); } function save(){ if (navigator.cookieEnabled) { //cookieが使えるか確認 var expire = new Date(); expire.setTime( expire.getTime() + 1000 * 3600 * 24 * 14); // 2週間 document.cookie = "your-name=" + encodeURIComponent($playerName.value) + '; Expires='+ expire.toUTCString(); let checked = $checkbox.checked ? 'true' : 'false'; document.cookie = "checked=" + checked + '; Expires='+ expire.toUTCString(); document.cookie = "volume=" + $elemVolume.value + '; Expires='+ expire.toUTCString(); } } window.onload = (ev) => { let playerName = '名無しのゴンベ'; let volume = 0.03; let isChecked = false; if (navigator.cookieEnabled) { //cookieが使えるか確認 let arr = document.cookie.split(' '); let cookie = arr.join(''); arr = cookie.split(';'); for(let i = 0; i < arr.length; i++) { let arr2 = arr[i].split('='); if(arr2[0] == 'your-name') playerName = decodeURIComponent(arr2[1]); if(arr2[0] == 'volume') volume = Number(arr2[1]); if(arr2[0] == 'checked'){ isChecked = arr2[1] == 'true' ? true : false; } } } $playerName.value = playerName; $checkbox.checked = isChecked; $elemVolume.value = volume; $elemRange.textContent = volume; $sound.volume = volume; // ボリューム変更時 $elemVolume.addEventListener("change", function(){ $elemRange.textContent = $elemVolume.value; $sound.volume = $elemVolume.value; }, false); } </script> </body> </html> |
それからこんなゲームもあるのでよろしければ是非遊んでみてください。
1980年、任天堂のシューティングゲーム・レーダースコープを模してつくったゲームです。疑似3Dシューティングゲームのような、当時としては斬新なグラフィックで人気となりました。敵は時折、機雷を投下して攻撃する。自機の下方は味方の基地になっており、機雷を撃ちもらすとダメージを受けてしまいます。自機だけでなく下方の基地も守らなければならない点や近くまで接近してきた敵が斜めに弾丸を発射するなど緊張感があるゲームです。