- ベストアンサー
画像の座標位置取得方法とシューティングゲームの連射アルゴリズムについて
- javascriptの勉強を始めたばかりで、画像の座標位置取得方法がわからないので質問します。
- ブロック内の座標をevent.offsetで取得するための方法を教えてください。
- シューティングゲームの連射アルゴリズムがわからないので助けてください。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
かいせつかぁ~。 へんなかきかただものね~。 >var FEND = true; この変数は、ゲームのループを終了させるために使っている。 たとえば if (FEND == true) { setTimeout(LOOP,10) } と書けばよいのだけど if (FEND) setTimeout(LOOP,10); これも同じ。さらに FEND && setTimeout( LOOP, 10); これも同じ。 >var Pmouse = {x:240, y:600}; は、マウスの座標の初期値として利用している 例えば、 Pmouse = [240,600]; とすると、600の値を取得するのに Pmouse[1]としなければならない。これだと可読性が悪い! (ってこんなコードを書いてるのに可読性とはおかしいね) Pmouse.y とすると 600が取得できる >document.getElementById('waku').onmousemove = function (evt) { >evt = evt ? evt: window.event; これは、このマウスオーバーしたときのイベントを取得するため 残念ながら、IEではevtにイベントが代入されない。なので evt が何も無かったら window.event を代入している。 三項演算子っていったかな? evt = evt ? evt: window.event; を普通に書くと if (evt == undefined) evt = window.event; else evt = evt; FEND = teki.y < 600; は、teki.y < 600 を評価して、条件が満たされれば、trueがFENDに代入される つまり敵のY座標が600より小さければ、ゲームを継続する。 これも普通に書けば、 if (teki<600) { FEND = true; } と同じ。 >FEND && setTimeout(LOOP1, 20); //これはclearTimeoutはする必要はないのでしょうか? setTimeoutは一度しか使われないので、実行されればそれで終わり。 >jiki.x += (Pmouse.x < jiki.x -8 ) * -4 + (Pmouse.x > jiki.x +8) *4; これを普通に書けば、 if (Pmouse.x < (jiki.x - 8)) jiki.x = jiki.x -4; if (Pmouse.x > (jiki.x + 8)) jiki.x = jiki.x +4; となる。 例えば a = (何かの条件式) * 4; の場合、条件が成立すると、trueなんだけど、掛け算するときは、数値の1と解釈できる!と 覚えておけばいいのかも? ちなみに±8は、マウスのマージンね。止めたいときに、判定を甘くしてる。 >FEND && setTimeout(LOOP2, 60); >第二引数の数字が敵か自機かなどによって数字が違うのもどうしてでしょうか? ゲームを作るうえで、キャラクターの動き、つまりバランスは非常に大事。 第二引数で、キャラクターの速度の調節が簡単にできる。 早く動かそうとして、4ドットを8ドットづつにするのは、好きじゃない。 >cloneNode(false); 今回は、画像の'TAMA'に利用しているけど、これは画面上に何個出現するかわからない 玉にたいして、画像をたくさん用意するより、1つ隠しておいて、それをコピーして 使っている。appendChildは、コピーしたものを出現させる!という意味かな? appendChildすると HTML上は <div id="waku"> <img src="jiki.png" width="20" height="20" alt="自機" id="JIKI"> <img src="teki.png" width="20" height="20" alt="敵機" id="TEKI"> <img src="tama0.png" width="20" height="20" alt="玉" id="TAMA"> <img src="tama0.png" width="20" height="20" alt="玉"> <img src="tama0.png" width="20" height="20" alt="玉"> <img src="tama0.png" width="20" height="20" alt="玉"> <img src="tama0.png" width="20" height="20" alt="玉"> <img src="tama0.png" width="20" height="20" alt="玉"> <img src="tama0.png" width="20" height="20" alt="玉"> <img src="tama0.png" width="20" height="20" alt="玉"> </div> なふうになっていると思う。 >if (y>4) setTimeout(LOOP3, 20); else { >document.getElementById('waku').removeChild(e); >}//自分でしらべたところ、appendChildとcloneNodeはわかったのですが(なんとなく…)、 >removeChildがどういうことがよくわかりませんでした。 これは、玉が一番上までいったら、必要ないので消している。と考えてね。 HTML内から外す。という意味で。 function getPosition(node) { var x = 0, y = x; do x += node.offsetLeft, y += node.offsetTop; while (node = node.offsetParent) return {x: x, y:y}; } は、あなたが求めていた >画像の座標をどうやって取得すればいいのかがわかりません。(マウスはevent.offsetで取得してるのでそれに合わせたい) の、回答に近いものです。nodeで指定された要素、つまり今回はid="waku"が、ページ上どこの座標にあるか求めるために あります。 これで得られた値を、基準としてマウスの座標と引き算すれば、waku内でのマウスの位置がわかります さて、これでしつもんにぜんぶこたえたかな? ばぶばぶばぶぅ~!
その他の回答 (5)
- babu_baboo
- ベストアンサー率51% (268/525)
こーどのみやすさかだとか、そくどだとか、いろいろかんがえると おもしろいよ!これは、おくがふか~い。 ぷろぐらむをかくことで、じぶんが、べんきょうしているからね~。 くろーじゃーだとか、おぶじぇくとしこう、だとか まだまだいっぱいあるじょ! http://okwave.jp/qa5001540.html のかいとうも、なにかのさんこうになるかも? かうんたーなのだけど、すうじがすろっとましーんのようにかいてんして へんかするじょ! げーむのとくてんなんかにつかえるかもよ! やっぱりさいごは、ばぶぅ~! そうそう、ぽいんとは10000ぽいんとくらいでいいじょ!^^;
- babu_baboo
- ベストアンサー率51% (268/525)
解説の訂正 if (teki<600) { FEND = true; } は、 if (teki<600) { FEND = true; } else { FEND = false; }
- babu_baboo
- ベストアンサー率51% (268/525)
れんしゃするこーどを、おうようして、てきもふやしてみたじょ! もうこうなれば、あたりはんていは、まっぷつくってやるしかないかなぁ~。 きゃらくたーは、あにめーしょんGIFがたのしいかも。 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <title>Game</title> <style type="text/css"> #waku { width:480px; height:640px; border :2px #888 inset; position:relative;background-color:black} #waku img { position:absolute; } #TAMA, #TEKI { display:none; } </style> <body> <div id="waku"> <img src="./img/4.gif" width="20" height="20" alt="自機" id="JIKI"> <img src="./img/8.gif" width="20" height="20" alt="敵機" id="TEKI"> <img src="./img/1.gif" width="20" height="20" alt="玉" id="TAMA"> </div> <script type="text/Javascript"> var offset = getPosition(document.getElementById('waku')); var jiki = {x: 240, y: 600, e: document.getElementById('JIKI') }; var tama = {x: 0, y:0 , e: document.getElementById('TAMA') }; var FEND = true; var Pmouse = {x:240, y:600}; var LR = 4; var LASTE; var LASTF = 0; document.getElementById('waku').onmousemove = function (evt) { evt = evt ? evt: window.event; Pmouse.x = evt.clientX - offset.x; Pmouse.y = evt.clientY - offset.y; } document.getElementById('waku').onclick = function (evt) { start_tama();return false; // return evt ? evt.preventDefault(): event.returnValue = false; }; start = function LOOP () { //ここに何か書く? FEND && setTimeout( LOOP, 10); }; start_teki = function (x, y) { var e = document.getElementById('TEKI').cloneNode(false); var memory_down = LR; e.id = null; document.getElementById('waku').appendChild(e); e.style.display = 'inline'; LASTE = e; var P = function LOOP1 () { if (memory_down != LR) { memory_down = LR; y += 20; } else { x += memory_down; e.style.top = y + 'px'; e.style.left = x + 'px'; if (x < 0 || x > 460) LASTF = 1; } if (e == LASTE && LASTF == 1) LASTF = 0, LR*=-1; FEND = FEND && y < 600; FEND && setTimeout(LOOP1, 80); }; P(); }; start_jiki = function LOOP2 () { jiki.x += (Pmouse.x < jiki.x -8) * -4 + (Pmouse.x > jiki.x + 8) *4; jiki.e.style.left = jiki.x + 'px'; jiki.e.style.top = jiki.y + 'px'; FEND && setTimeout(LOOP2, 30); }; start_tama = function () { var x = jiki.x; var y = jiki.y; var e = document.getElementById('TAMA').cloneNode(false); e.id = null; document.getElementById('waku').appendChild(e); e.style.display = 'inline'; var P = function LOOP3 () { y-= 8; e.style.left = x + 'px'; e.style.top = y + 'px'; if (y>4) setTimeout(LOOP3, 20); else { document.getElementById('waku').removeChild(e); } }; P(); }; function getPosition(node) { var x = 0, y = x; do x += node.offsetLeft, y += node.offsetTop; while (node = node.offsetParent) return {x: x, y:y}; } start(); for(var i=70; i<200; i+=30) { for(var j=10; j<300; j+=30) { start_teki(j,i); } } start_jiki(); </script>
補足
まずはno2の回答から自分のものにしたいと思います! 回答を締め切るときには必ず良回答をつけさせていただきたいと思います。
- babu_baboo
- ベストアンサー率51% (268/525)
どっかにかいたことがあったんだけど、えほんのなかから みつけられなかった。なのでかいたじょ。ばぶ。 こんな、ぐろーばるへんすうのつかいかただと、みんなにわらわれるか?! きもちよく、れんしゃしてくれ! もちろん、あたりはんてい、などない! ぜんかくはくうはくは、ていきとうになおしてね! けんとうをいのる。 ばぶぅ~! <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <title>Game</title> <style type="text/css"> #waku { width:480px; height:640px; border :2px #888 inset; position:relative;} #waku img { position:absolute; } #TAMA { display:none; } </style> <body> <div id="waku"> <img src="jiki.png" width="20" height="20" alt="自機" id="JIKI"> <img src="teki.png" width="20" height="20" alt="敵機" id="TEKI"> <img src="tama0.png" width="20" height="20" alt="玉" id="TAMA"> </div> <script type="text/Javascript"> var offset = getPosition(document.getElementById('waku')); var teki = {x: 0, y: 0, m: 4, e: document.getElementById('TEKI') }; var jiki = {x: 240, y: 600, e: document.getElementById('JIKI') }; var tama = {x: 0, y:0 , e: document.getElementById('TAMA') }; var FEND = true; var Pmouse = {x:240, y:600}; document.getElementById('waku').onmousemove = function (evt) { evt = evt ? evt: window.event; Pmouse.x = evt.clientX - offset.x; Pmouse.y = evt.clientY - offset.y; } document.getElementById('waku').onclick = function (evt) { start_tama(); return evt ? evt.preventDefault(): event.returnValue = false; }; start = function LOOP () { //ここに何か書く? FEND && setTimeout( LOOP, 10); }; start_teki = function LOOP1 () { teki.x += teki.m; if (teki.x < 0 || teki.x > 460) teki.m *=-1, teki.y += 20; teki.e.style.top = teki.y + 'px'; teki.e.style.left = teki.x + 'px'; FEND = teki.y < 600; FEND && setTimeout(LOOP1, 20); }; start_jiki = function LOOP2 () { jiki.x += (Pmouse.x < jiki.x -8 ) * -4 + (Pmouse.x > jiki.x +8) *4; jiki.e.style.left = jiki.x + 'px'; jiki.e.style.top = jiki.y + 'px'; FEND && setTimeout(LOOP2, 60); }; start_tama = function () { var x = jiki.x; var y = jiki.y; var e = document.getElementById('TAMA').cloneNode(false); e.id = null; e.style.display = 'inline'; document.getElementById('waku').appendChild(e); var P = function LOOP3 () { y-= 8; e.style.left = x + 'px'; e.style.top = y + 'px'; if (y>4) setTimeout(LOOP3, 20); else { document.getElementById('waku').removeChild(e); } }; P(); }; function getPosition(node) { var x = 0, y = x; do x += node.offsetLeft, y += node.offsetTop; while (node = node.offsetParent) return {x: x, y:y}; } start(); start_teki(); start_jiki(); </script>
補足
具体的には… var FEND = true; var Pmouse = {x:240, y:600}; と、 document.getElementById('waku').onmousemove = function (evt) { evt = evt ? evt: window.event; //←この関数の中では特にここ Pmouse.x = evt.clientX - offset.x; Pmouse.y = evt.clientY - offset.y; } と、 FEND = teki.y < 600; FEND && setTimeout(LOOP1, 20); //これはclearTimeoutはする必要はないのでしょうか? と、 jiki.x += (Pmouse.x < jiki.x -8 ) * -4 + (Pmouse.x > jiki.x +8) *4; //(Pmouse.x < jiki.x -8 ) * -4も、(Pmouse.x > jiki.x +8) *4も、どういう演算なのでしょうか?()の中は、比較演算子なのに、それに-4や+4をかけるということがよく理解できません…。 と、 FEND && setTimeout(LOOP2, 60); //FENDにどういう意味があるのかもわかりません。第二引数の数字が敵か自機かなどによって数字が違うのもどうしてでしょうか? と、 cloneNode(false); と、 appendChild(e); と、 if (y>4) setTimeout(LOOP3, 20); else { document.getElementById('waku').removeChild(e); } //自分でしらべたところ、appendChildとcloneNodeはわかったのですが(なんとなく…)、removeChildがどういうことがよくわかりませんでした。 function getPosition(node) { var x = 0, y = x; do x += node.offsetLeft, y += node.offsetTop; while (node = node.offsetParent) return {x: x, y:y}; } です… こんなに沢山わかりません…。 もしご迷惑でなければご教授お願いできますでしょうか…?
- babu_baboo
- ベストアンサー率51% (268/525)
このままだと、けっしておぎょうぎがよくないじょ。 ちゃんとできたら、おもしろそうだね。がんばれ~! yのあたいが、ちいさいままだったじょ。 たいまーも、いちどくりあーする・・・。 せっといんたーばるに、もじれつでかんすうしきをわたすのは、 ふるいというか、こてんというか、かいしゃくにじかんかかるじょ! げーむは、すぴーどが、いのち? <script language="JavaScript"><!-- var y = 450; var interval = 20; var timerId; function moveBall(){ y = y - interval; document.getElementById("ball").style.pixelLeft = getlyrleft("ber") + 24; document.getElementById("ball").style.pixelTop = y; document.getElementById("ball").style.visibility = "visible"; if( (y < 10) ){ document.getElementById("ball").style.visibility = "hidden"; document.getElementById("ball").style.pixelTop = getlyrtop("ber"); clearInterval(timerId); return 0; } } function getlyrtop(lyr){ return(parseInt(document.getElementById(lyr).style.pixelTop)); } function getlyrleft(lyr){ return(parseInt(document.getElementById(lyr).style.pixelLeft)); } // --></script> </head> <body onclick="y=450;timerId = setInterval(moveBall,1)"> <img src="bb01.gif" id="ball" style="position:absolute; visibility:hidden" left:0px;top:16px;"> <img src="bb03.gif" id="ber" style="position:absolute; left:445px; top:459px;"/>
補足
何度もありがとうございます!返事が遅くなってしまいすみません。 NO2の回答をずっと考えてました。まだまだ初心者なのでNO2の時点でちょっと難解です…;
お礼
丁寧にありがとうございます!この解説を参考に自分の力でも組めるようにがんばってみます!あまり何度も質問してしまっても迷惑だと思うので、またなにか解決できない疑問にぶちあたったら新しい質問を投稿することにします。 本当にありがとうございました!感謝感激です! ポイントは1000000ポイントくらいあげたいところですけど…gooがそんなに沢山良回答をつけさせてくれません…! どうもありがとうございました!