• 締切済み

ボタンでjsの動きを制御する

Html,css,jsの3種類を使い、"play"ボタンでjsの動きを制御したいと思っています。 基本的にやりたいことは、jsでキャラクターを動かすということです。 矢印ボタンを押せばキャラックターが右や左に動くということはできそうですが、矢印ボタンを押した瞬時にキャラクターが動くのではなく、"play"ボタンを押した時に動作するようにしたいです。 例えば↑←↓↓と↓ボタンを順番に押して、その後"play"ボタンを押すとキャラクターが動き始めるといったプログラムです。 参考動画をyoutubeで見つけましたので、リンクを貼っておきます。 youtubeの動画のようにしたいです。 https://youtu.be/PR4d-j3gGps?t=1m54s なにかアイディアやアドバイスがあればよろしくお願いします。

みんなの回答

回答No.4

連投で申し訳ないね >css = 'background-image: url("../img/ApplicationIcon.png")') 単純に最後の")"が余計だけど、本質は違うのだろうと思う。 エスパーとしては、"../" これが示すディレクトリが違う。 また書き直した。Buffder が無限?にpushできたので制限追加。 回答にレスがつくと思わなかったから適当に書いてみたけど、 キャラクターの表現をバックグランドで行うのはだめだな。 なので、背景マップを作って表を作成することにした。 キャラクターは、どうしているか見ればわかるよね。

回答No.3

まじ文字数が。。。 <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>

回答No.2

#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');

shiro857
質問者

補足

回答ありがとうございます。 無事に確認することができました。 もう一つ質問なのですが、Playerの背景が赤いところを画像に差し替えたいのですが、 css = 'background:red'のところを css = 'background-image: url("../img/ApplicationIcon.png")') に変えたのですがうまくいきません。なにか間違っているのでしょうか。

回答No.1

文字数制限で解説なしです。見直すとちょっと汚い。 <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>

関連するQ&A