3000ms で、800pixcel を水平移動する。その4
昨日のプログラムを見て、整理しようと思った。
「余りを次の処理に繰り越す」という考えを、apos さんの説明は、理解しやすくするために、余りを整数で例えている。
実際に自分のプログラムは変数 err に少数部分を誤差として代入している。もしゲームならスピード優先。整数で考えるべきだ。
その考えの前に、「遅延が発生した場合、補正が必要だ」ということは理解した。本来、移動するプログラムが個々に遅延を考慮するべきなのだろうか?そこで強引ではあるが、遅延を補間するようなコードの下で走らせてはどうか?と考えた。
遅延がある程度解消されるまでコールバック関数を数回呼び出す。
そしてインターバルのタイミングを1ドット移動するための時間とする。
さすれば加算値は整数になる。
<!DOCTYPE html> <title>遅延時間を考えて移動する</title> <meta charset="UTF-8"> <style> #invader { list-style : none; position: absolute; margin : 0; padding: 0; top : 0px; left: 3px; } #invader li { margin : 0; padding : 0; display : none; } </style> <ol id ="invader"> <li class="type1 v"> <img id ="inv3" alt="インベーダ" src="data:image/gif;base64, R0lGODlhMAAYAIAAAP8ntf///yH5BAEAAAEALAAAAAAwABgAAAJijI95wO2sopzqWUCzXtft 34Vi8yHjeZUcymJgC3tZTLtUHWth9fDp3PGREjvgz9QjBo04lK7JekJPKkMReaxiLcKkdutd cb+BMdgmhlTNabQ1/JKdu24VW3L/5unkOVNNUQAAOw=="> <li class="type2"> <img id="inv3o" alt="インベーダ" src="data:image/gif;base64, R0lGODlhMAAYAIAAAP8ntf///yH5BAEAAAEALAAAAAAwABgAAAJmjI95wO2sopzqWUCzXtft 34Vi8yHjeZUcymJgC3tZTLtUHWth9fDp3PGREjvgz9QjBo04lK7JekJPKqUMea3ektihdps1 WL6SMRNCXnkn5nSgzeaW4NZ1HQ22d/FCfll+Z9MnaFAAADs="> </ol> <canvas id="hoge" width="800" height="200"></canvas> <p>時間:<input type="text" value="0" id="fuga"></p> <script> var changePattern = (function () { var pattern = document.querySelectorAll ('#invader > li'); var state = 0; var max = 2; Array.prototype.forEach.call ( pattern, function (e) { e.style.display = 'none'; } ); function change () { pattern[state].style.display = 'none'; state = (state + 1) % max; pattern[state].style.display = 'inline'; } change (); return change; }) (); setInterval (changePattern, 200); //_______________ (function () { function IntervalCompletion (cbFunc, interval, maxCompletion) { this.cbFunc = cbFunc; this.interval = interval; this.maxCompletion = maxCompletion; this.startTime = null; this.count = null; } var loop = (function () { var now = (new Date).getTime (); var delay = (now - this.startTime) - this.interval * this.count; var completion = 0; var result; if (0 < delay) { completion = Math.floor (delay / this.interval); if (this.maxCompletion < completion) { completion = this.maxCompletion; } } do { result = this.cbFunc ((new Date).getTime ()); this.count++; if (! result) break; } while (completion--); if (result) setTimeout (loop.bind (this), this.interval); }); IntervalCompletion.prototype.start = (function () { this.startTime = (new Date).getTime (); this.count = 0; loop.call (this); }); IntervalCompletion.create = (function (cbFunc, interval) { if (1 > arguments.length) throw new Error; return new IntervalCompletion (cbFunc, interval); }); this.IntervalCompletion = IntervalCompletion; }) (); //_______________ var moveInvader = (function (time, distance) { var style = document.querySelector ('#invader').style; var x = 0; var y = 30; var step = 1; var t = +new Date;//debug function move () { x += step; if (distance < x) return false; document.getElementById('fuga').value=+(new Date)-t;//debug setPosition (); return true; } function setPosition () { style.left = x + 'px'; style.top = y + 'px'; } return move; }) (3000, 800); var obj = new IntervalCompletion (moveInvader, 3000/800, 4); obj.start(); </script>