- 締切済み
ボタンでjsの動きを制御する
Html,css,jsの3種類を使い、"play"ボタンでjsの動きを制御したいと思っています。 基本的にやりたいことは、jsでキャラクターを動かすということです。 矢印ボタンを押せばキャラックターが右や左に動くということはできそうですが、矢印ボタンを押した瞬時にキャラクターが動くのではなく、"play"ボタンを押した時に動作するようにしたいです。 例えば↑←↓↓と↓ボタンを順番に押して、その後"play"ボタンを押すとキャラクターが動き始めるといったプログラムです。 参考動画をyoutubeで見つけましたので、リンクを貼っておきます。 youtubeの動画のようにしたいです。 https://youtu.be/PR4d-j3gGps?t=1m54s なにかアイディアやアドバイスがあればよろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- babu_baboo
- ベストアンサー率51% (268/525)
連投で申し訳ないね >css = 'background-image: url("../img/ApplicationIcon.png")') 単純に最後の")"が余計だけど、本質は違うのだろうと思う。 エスパーとしては、"../" これが示すディレクトリが違う。 また書き直した。Buffder が無限?にpushできたので制限追加。 回答にレスがつくと思わなかったから適当に書いてみたけど、 キャラクターの表現をバックグランドで行うのはだめだな。 なので、背景マップを作って表を作成することにした。 キャラクターは、どうしているか見ればわかるよね。
- babu_baboo
- ベストアンサー率51% (268/525)
まじ文字数が。。。 <html lang="ja"> <head> <meta charset="utf-8"> <title>これがGame?</title> <style> #f { border-collapse: collapse; border-spacing: 0;} td, td img { width: 40px; height: 40px } .direction { display: inline-block; text-align: center;} .direction td { width: 30px; height: 30px;} .f0 { background: #0ff; } .f1 { background: #0c0; } .f2 { background: #a64; } .f3 { background: #eee; } .charactor { display: none; } </style> <body> <p class="player"> Command: <input type="button" value="↑"> <input type="button" value="→"> <input type="button" value="↓"> <input type="button" value="←"> <input type="button" value="Start"><br> Direction: <table border="1" class="direction"><tr><td><td><td><td><td><td></table> </p> <table id="f"> </table> <p class="charactor"> <img src="data:image/gif;base64,R0lGODlhDAAIAIAAAP///wAAACwAAAAADAAIAAACEoQRGWfqip6Esc1pV9S1p85YBQA7"> </p> <script> { class Buffer { constructor (buf) { this.td = Array.from (buf.querySelectorAll ('td')); this.max = this.td.length; this.clear (); } clear () { this.ary = []; this.disp (); } push (vec) { this.ary.push (vec); if (this.max < this.ary.length) this.ary.shift (); this.disp (); } shift () { let rst = this.ary.shift (); this.disp (); return rst; } disp () { this.td.forEach ((e, i) => e.textContent = this.ary[i] || ''); } } const field = document.querySelector('table#f'), direction = { '↑': {x: 0, y:-1}, '→': {x: 1, y:0}, '↓': {x: 0, y:1}, '←': {x: -1, y:0} }, fmap = [ [0,0,0,1,1,1,2,3,2,1,1,1,1,0,0], [0,0,0,1,1,1,1,2,2,1,1,1,1,1,0], [0,0,1,1,1,1,2,2,2,1,1,1,1,1,0], [0,1,1,0,0,1,2,2,2,2,1,1,1,1,1], [0,0,0,0,0,1,1,2,3,2,2,1,1,1,1], [0,0,0,1,1,1,2,3,3,3,2,2,1,1,1], [0,0,1,1,2,2,3,3,0,3,2,2,2,1,1], [0,1,1,1,1,2,3,3,3,3,2,2,2,2,1], [0,1,1,1,1,1,2,2,2,2,2,2,1,1,1], [0,1,1,1,1,1,1,1,2,2,2,1,1,1,0], [0,0,0,1,1,1,1,2,2,2,2,1,1,0,0], [0,0,0,0,0,1,2,1,1,1,1,1,1,0,0], [0,0,0,1,1,1,2,2,2,1,1,1,1,1,0], [0,0,1,1,2,2,3,3,2,2,1,1,1,0,0], [0,1,1,2,3,3,3,3,3,2,2,1,1,0,0] ], speed = 1000, //ms locate = function (x, y, img) { if (y < 0 || field.rows.length <= y || x < 0 || field.rows[y].cells.length <= x || !fmap[y][x]) return true; field.rows[y].cells[x].appendChild (img); }, createTD = function (no) { this.insertCell (-1).className = 'f' + no; }, createTR = function (row) { row.forEach (createTD, this.insertRow (-1)); }; //__________________ fmap.forEach (createTR, field); class Player { constructor (controller, x = 0, y = 0, img) { this.ctrl = controller; this.x = x; this.y = y; this.img = img; this.buffer = new Buffer (controller.querySelector ('table.direction')); this.setPoistion (); this.disabled = this.toDisable (); controller.addEventListener ('click', this, false); } handleEvent ({target:{type, value}}) { if (! this.disabled) if ('button' === type) switch (value) { case '↑': case '→': case '↓' : case '←' : this.buffer.push (value); break; case 'Start' : this.disabled = this.toDisable (1); this.move (); break; } } setPoistion (vec) { if (vec) { let {x, y} = direction[vec], mx = this.x + x, my = this.y + y; if (! locate (mx, my, this.img)) { this.x = mx; this.y = my; } } else locate (this.x, this.y, this.img) } move () { let vec = this.buffer.shift (); if (vec) { this.setPoistion (vec); setTimeout (this.move.bind (this), speed); } else this.disabled = this.toDisable (); } toDisable (f = false) { f = !!f; Array.from (this.ctrl.querySelectorAll ('input[type="button"]')) .forEach (e => e.disabled = f); return f; } } this.Player = Player; } let p = new Player (document.querySelector ('p.player'), 7, 0, document.querySelector ('p.charactor img')); </script>
- babu_baboo
- ベストアンサー率51% (268/525)
#1です スクリプトを修正します。 Buffer 部分の見直し。 ついでに移動中はコマンドの入力禁止を追加。 -- { class Buffer { constructor (buf) { this.td = Array.from (buf.querySelectorAll ('td')); this.clear (); } clear () { this.ary = []; this.disp (); } push (vec) { this.ary.push (vec); this.disp (); } shift () { let rst = this.ary.shift (); this.disp (); return rst; } disp () { this.td.forEach ((e, i) => e.textContent = this.ary[i] || ''); } } const field = document.querySelector('table#f'), direction = { '↑': {x: 0, y:-1}, '→': {x: 1, y:0}, '↓': {x: 0, y:1}, '←': {x: -1, y:0} }, speed = 1000, //ms locate = function (x = 0, y = 0, css = '') { if (css) if (y < 0 || field.rows.length <= y || x < 0 || field.rows[y].cells.length <= x) return true; field.rows[y].cells[x].style.cssText = css; }; class Player { constructor (controller, x = 0, y = 0, css = 'background:red') { this.ctrl = controller; this.x = x; this.y = y; this.css = css; this.buffer = new Buffer (controller.querySelector ('table.direction')); this.setPoistion (); this.disabled = this.toDisable (); controller.addEventListener ('click', this, false); } handleEvent ({target:{type, value}}) { if (! this.disabled) if ('button' === type) switch (value) { case '↑': case '→': case '↓' : case '←' : this.buffer.push (value); break; case 'Start' : this.disabled = this.toDisable (1); this.move (); break; } } setPoistion (vec) { if (vec) { let {x, y} = direction[vec], mx = this.x + x, my = this.y + y, rst = locate (mx, my, this.css); if (! rst) { locate (this.x, this.y); this.x = mx; this.y = my; } } else locate (this.x, this.y, this.css); } move () { let vec = this.buffer.shift (); if (vec) { this.setPoistion (vec); setTimeout (this.move.bind (this), speed); } else this.disabled = this.toDisable (); } toDisable (f = false) { f = !!f; Array.from (this.ctrl.querySelectorAll ('input[type="button"]')) .forEach (e => e.disabled = f); return f; } } this.Player = Player; } //------------------- let [ctrl_A, ctrl_B] = document.querySelectorAll ('p.player'); let p1 = new Player (ctrl_A); let p2 = new Player (ctrl_B, 9, 9,'background: blue');
- babu_baboo
- ベストアンサー率51% (268/525)
文字数制限で解説なしです。見直すとちょっと汚い。 <html lang="ja"> <head> <meta charset="utf-8"> <title>これがGame?</title> <style> td { width: 40px; height: 40px } .direction { display: inline-block; text-align: center;} .direction td { width: 30px; height: 30px;} </style> <body> <p class="player"> Command: <input type="button" value="↑"> <input type="button" value="→"> <input type="button" value="↓"> <input type="button" value="←"> <input type="button" value="Start"><br> Direction: <table border="1" class="direction"><tr><td><td><td><td><td><td></table> </p> <table border="1" id="f"> <tr><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td> </table> <p class="player"> Command: <input type="button" value="↑"> <input type="button" value="→"> <input type="button" value="↓"> <input type="button" value="←"> <input type="button" value="Start"><br> Direction: <table border="1" class="direction"><tr><td><td><td><td><td><td></table> </p> <script> { class Buffer { constructor (buf) { this.buf = buf; this.td = Array.from (buf.querySelectorAll ('td')); this.max = this.td.length; this.clear (); } clear () { this.index = 0; this.td.forEach (e => e.textContent = ''); } push (vec) { let i = this.index; i < this.max ? ++this.index: this.shift (i = --this.index); this.td[i].textContent = vec; } shift () { if (0 < this.index) { let td = this.td.shift (), vec = td.textContent; td.textContent = ''; td.parentNode.appendChild (td); this.td.push (td); this.index--; return vec; } return null; } } const field = document.querySelector('table#f'), direction = { '↑': {x: 0, y:-1}, '→': {x: 1, y:0}, '↓': {x: 0, y:1}, '←': {x: -1, y:0} }, speed = 1000, //ms locate = function (x = 0, y = 0, css = '') { console.log(x,y); if (css) if (y < 0 || field.rows.length < y || x < 0 || field.rows[y].cells.length < x) return true; field.rows[y].cells[x].style.cssText = css; }; class Player { constructor (controller, x = 0, y = 0, css = 'background:red') { this.ctrl = controller; this.x = x; this.y = y; this.css = css; this.buffer = new Buffer (controller.querySelector ('table.direction')); this.setPoistion (); controller.addEventListener ('click', this, false); } handleEvent ({target}) { let { type, value } = target; if ('button' === type) switch (value) { case '↑': case '→': case '↓' : case '←' : this.buffer.push (value); break; case 'Start' : this.move (); break; } } setPoistion (vec) { if (vec) { let {x, y} = direction[vec], mx = this.x + x, my = this.y + y, rst = locate (mx, my, this.css); if (! rst) { locate (this.x, this.y); this.x = mx; this.y = my; } } else locate (this.x, this.y, this.css); } move () { let vec = this.buffer.shift (); if (vec) { this.setPoistion (vec); setTimeout (this.move.bind (this), speed); } } } this.Player = Player; } //------------------- let p = document.querySelectorAll ('p.player'); let p1 = new Player (p[0]); let p2 = new Player (p[1], 9, 9,'background: blue'); </script>
補足
回答ありがとうございます。 無事に確認することができました。 もう一つ質問なのですが、Playerの背景が赤いところを画像に差し替えたいのですが、 css = 'background:red'のところを css = 'background-image: url("../img/ApplicationIcon.png")') に変えたのですがうまくいきません。なにか間違っているのでしょうか。