- ベストアンサー
javascriptでスロットゲームを作ろうとしています
- javascriptを使用して、スロットゲームを作成する方法について質問です。
- スロットゲームの絵柄がランダムでなく順番に回転するようにする方法について教えてください。
- すべての絵柄が止まっていないのに、大当たりの背景色変化が起こらないようにする方法について教えてください。
- みんなの回答 (15)
- 専門家の回答
質問者が選んだベストアンサー
#1です。 #2に回答がでているので、#3様にならってオブジェクト的になもの(?)を練習で作ってみました。(prototype使うの慣れてないので、要領悪いかも…) <div class="dram">となっている要素の中に、ドラムが作成されます。 とりあえず、imgではなくtextで代用していますが、ドラムを生成する時にTextNodeの代わりにimg要素を入れるようにすれば、表示をそのまま画像に替えられるはず。 stopボタンを押してから空回りして止まるようにしています。その変化をintervalとstepを変えることで行なっているので、数値を変えると止まるまでの時間や回り方も変わります。 最後に止まるときに、どちら側で止まるのか逆転させたりして、ややアナログ的な雰囲気にしたつもり。 ご愛嬌ですが、ご参考まで… <html> <head> <title>test</title> <style type="text/css"> .dram { margin:0; padding:0; text-align:center; float:left; width:50px; } .dram div { height:48px; _height:52px; overflow:hidden; background-color:#fff; border:4px ridge #fff; margin-bottom:8px; } .dram div span { font-size:30px; font-weight:bold; line-height:46px; position:relative; } .clr { clear:both; } </style> </head> <body> <div class="dram">dram1</div> <div class="dram">dram2</div> <div class="dram">dram3</div> <div class="dram">dram4</div> <div class="dram">dram5</div> <div class="dram">dram6</div> <div class="dram">dram7</div> <hr class="clr"> <input type="button" value="start" id="starter"> <script type="text/javascript"> window.onload = function(){ slot.init(); }; // *** スロット全体 *** var slot = { item : [], //スロットの初期設定 init : function() { var param = { height : 46, // 1コマの高さ(px) interval : [30, 30, 40, 36, 40, 30, 50, 80], // 速度(msec) step : [10, 8, 6, 4, 2, 1, 1, 1], // 1回の送り量(px) point : [10, 30, 70, 100, 140, 160, 180, 'end'] //速度切替えポイント }; var letter = '9876543210'; // 表示用文字列(仮設定) var i = 0, e, tmp; var m = letter.split(''), n = m.length; var div = document.getElementsByTagName('DIV'); while (e = div[i++]) if (e.className == 'dram') { tmp = new dram(param); tmp.create(e, m, n); this.item[this.item.length] = tmp; } document.getElementById('starter').onclick = function() { slot.starter(); }; }, //スタートボタンを押したとき starter : function() { var i = 0, e; while (e = this.item[i++]) e.start(); }, //ドラムが止まったときの結果判定 result : function() { var i = 0, e, f = true, result = ''; while (e = this.item[i++]) { if (e.status.tid) { f = false; break; } result += (e.status.number - e.status.value - 1) + ' '; } if (f) alert(result); } } // *** ドラムの定義 *** var dram = function (p) { //this.type = 'dram'; this.status = {tid:null, counter:0, pointer:0, value:0}; this.param = p; } //ドラムを停止 dram.prototype.stop = function() { var s = this.status; s.counter = 1; s.element.parentNode.style.backgroundColor = ''; } //ドラムをスタート dram.prototype.start = function() { var p = this.param, s = this.status; if (s.tid) clearTimeout(s.tid); s.interval = p.interval[0]; s.step = p.step[0]; s.counter = 0, s.pointer = 0; this.roll(); s.element.parentNode.style.backgroundColor = '#ffd'; } //ドラムを回転させる(速度調整含む) dram.prototype.roll = function() { var f = true, p = this.param, s = this.status; var tmp = s.top + s.step; tmp -= (tmp<0)?0:s.max; s.element.style.top = tmp + 'px'; s.top = tmp, s.value = Math.round(-tmp / p.height) % s.number; if (s.counter) { tmp = p.point[s.pointer]; if (tmp == 'end') { tmp = s.top / p.height; s.step = tmp - Math.round(tmp)>0?-1:1; f = !!(s.top % p.height); } else { if (++s.counter > tmp) { s.interval = p.interval[++s.pointer]; s.step = p.step[s.pointer]; } } } if (f) { s.tid = setTimeout((function(obj) { return function(){obj.roll();} })(this), s.interval); } else { s.tid = null; slot.result(); } } //ドラムを作成する dram.prototype.create = function(e, m, n) { var d, sp, j, h = this.param.height, s = this.status; sp = document.createElement('span'); d = document.createElement('div'); while (e.firstChild) e.removeChild(e.firstChild); for (j=0; j<m.length; j++) { sp.appendChild(document.createTextNode(m[j])); sp.appendChild(document.createElement('br')); } sp.appendChild(document.createTextNode(m[0])); d.appendChild(sp); e.appendChild(d); s.element = sp; s.number = n; s.max = h * n; j = -Math.floor(Math.random() * n) * h; s.top = j, sp.style.top = j + 'px'; sp = document.createElement('input'); sp.type = 'button'; sp.value = 'stop'; e.appendChild(sp); sp.onclick = (function(obj) { return function(){obj.stop();} })(this); } </script> </body> </html>
その他の回答 (14)
- babu_baboo
- ベストアンサー率51% (268/525)
やっぱり、自信がないんだよね~。>メモリーリークパターン http://www.tagindex.com/cgi-lib/bbs/patio.cgi?mode=view&no=146&p=2 とか、ここの検索で、このキーワードで調べてみて~! あなたなら判る!俺は無理。 イベントはバブルするから大元でチェックすれば充分。ってのが見つかるはず。 ここの受け売りみたいで申し訳ない。
- fujillin
- ベストアンサー率61% (1594/2576)
>メモリーリーク よくわかってないので、なんとも言えませんが… sp.onclick = (function(obj) { return function(){obj.stop();} })(this); thisはDOMオブジェクトではないので、かってにならないだろうと思っていたんだけど… >回避策とかありますか? とりあえず、 sp.onclick = set(this); function set(t) { return function() { t.stop(); } } みたいにするとかではダメ?
- babu_baboo
- ベストアンサー率51% (268/525)
//その6 var images = ImageLoader( image_base64_number, 'data:image/gif;base64' );//画像の先読みっぽい? var dram0 = new Drum( 's0', images ); var dram1 = new Drum( 's1', images ); var dram2 = new Drum( 's2', images ); var dram3 = new Drum( 's3', images ); var dram4 = new Drum( 's4', images );//回転ドラムを3個つくる new Slot( 'swStart', [ 'sw0', dram0 ], [ 'sw1', dram1 ], [ 'sw2', dram2 ], [ 'sw3', dram3 ], [ 'sw4', dram4 ] );//スイッチとセットでスロットを作る </script> 以上で~~す! 1つ手前の投稿は、画像データです。そのうち閲覧可能になるでしょう~~!
- babu_baboo
- ベストアンサー率51% (268/525)
//その5 var image_base64_number = [ 'R0lGODlhEAAYAKIAAP///+7u7tTU1LCwsHZ2dkFBQRkZGQAAACwAAAAAEAAYAAADXXi63P4wPkNGqQSSAIYpnNcUQGkoRDk0QwksaVkshvui7oq7sBv0vJ1J0QoeYjKiDZg8FEtMwMy5FEqt0axQQKseXZnFk3micQDlYphREAAElNLacfkQypK8ft9IAAA7', 'R0lGODlhEAAYAKIAAP///+7u7rCwsHZ2dkFBQRkZGQAAAAAAACwAAAAAEAAYAAADN2i63P4wxkKGIHEEwAGGhNB5kiFyX3SS0ppCbhm33fvMai3rNLr7PdajoOkIBpDBqFNqOp/QRQIAOw==', 'R0lGODlhEAAYAKIAAP///+7u7tTU1LCwsHZ2dkFBQRkZGQAAACwAAAAAEAAYAAADZHi63P4wOkPGOJYYVwIQBQYAQbgY3rcdI7keRAsQikwrcXvLl4KOgRWPQdEoCraIQSAzTZg6SAEKGDgbuYExYrlGCuCGYfCaygRaAtO0lLlHi9y71YOVDhSqSlIgELwSgYKDBwkAOw==', 'R0lGODlhEAAYAKIAAP///+7u7tTU1LCwsHZ2dkFBQRkZGQAAACwAAAAAEAAYAAADY3i63P4wvkKGqaQ8AgAxhdBZDDcqRgcIzKAC2vESi6vG81KorJLrhA9KFTBECjZPJCmIQS4iQMD5JBoVyAFt8TsEVFuZaoB9kX3jchrdCduKaun1cBldvgBS4/IJCiWAgYINCQA7', 'R0lGODlhEAAYAKIAAP///+7u7tTU1LCwsHZ2dkFBQRkZGQAAACwAAAAAEAAYAAADTni63P4wSkUGmacAcKURWxcRG+eR4Uig5lMEayky33Cw8zIExi07pALlx3iJcI0BYMCMbQQWXYnD2tggSEn2YSCAnoSeQzPdCDHotHqSAAA7', 'R0lGODlhEAAYAKIAAP///+7u7tTU1LCwsHZ2dkFBQRkZGQAAACwAAAAAEAAYAAADYXi63P4wNlOKmaURwLsQwKB1JJcxWwkEhFMQcGw9lcQMhEFUOzQMIBiH5RiETqmQpsUAcZgRI0fAKPxOBylnUSCdtIBFEsDUUhXjcgdqcIoOhsB0YmQVnDna7pW3+f+ACgkAOw==', 'R0lGODlhEAAYAKIAAP///+7u7tTU1LCwsHZ2dkFBQRkZGQAAACwAAAAAEAAYAAADZXi63P4wQjJIGdU4I0AoBgEAQtEMI6GI48AUI6AeaMzUsoILTBDPhc5nYYjlFqaX0VITzBSwH8Xogi6tP2xqsVtcdcZFZwu2rbJlEhFNYx9Y1cNYoGGwCIbaoN4IgQh4EoKDhA4JADs=', 'R0lGODlhEAAYAKIAAP///+7u7tTU1LCwsHZ2dkFBQRkZGQAAACwAAAAAEAAYAAADTHi63P4wtmLKuMQsqgoYQCgKBFh0YqpqhycMgRoOCwGwRRkHBFNKwFaABrQFWBEboCdRHiWG2KcoYkYEVWBKoE2drt7mKJjLBM/odAIAOw==', 'R0lGODlhEAAYAKIAAP///+7u7tTU1LCwsHZ2dkFBQRkZGQAAACwAAAAAEAAYAAADaHi63P4wPkMGKcM+AoAoVPcxXEcsnWcsQnoqKfAe8VwvgYvqysDTqZXC0PKASjJHaVAQFRoGHyBAiHYCzwXSdhUabjBe8xcbKMamXcesyKXD78N2mAoIFQR3tch0GAoEVYFZEoWGhwwJADs=', 'R0lGODlhEAAYAKIAAP///+7u7tTU1LCwsHZ2dkFBQRkZGQAAACwAAAAAEAAYAAADY3i63P4wPjJGoeQZAYAwRPc1XGcoITAwabe0xTJ0Lkqvyky/dCDTAB7tdGgFbbTYwRCgZYpAZbHpNEqXlAEBFGURpEZWEulhAHGtp+JMJubGB51aYdAJLp05A7S9uCWAgYIMCQA7' ];
- babu_baboo
- ベストアンサー率51% (268/525)
//その4 Slot.prototype.idCheck = (function ( ) { return function ( id ) { var obj; if( obj = this.buf[ id ] ) { obj.stop( (function ( that, id ) { return function ( num ) { that.nums[ id ] = num; that.numsCheck(); };})( this, id ) ); } else this.start(); };})(); Slot.prototype.numsCheck = (function ( ) { return function ( ) { var nums = '', k; for( k in this.nums ) { if( this.nums.hasOwnProperty( k ) ) { if( this.nums[ k ] === false ) return false; nums += this.nums[ k ]; } } alert(nums);//結果は文字列 return nums; };})(); //何が押されたか Slot.handler = function ( evt ) { var e = evt./*@if( @_jscript ) srcElement @else@*/ target /*@end@*/; var o; e && ( o = Slot.buffer[ e.id ] ) && o.idCheck( e.id ); }; //クリックされたら (function ( ) { document./*@if( @_jscript ) attachEvent( 'on' + @else@*/ addEventListener( /*@end@*/ 'click', Slot.handler, false ); })(); //画像データ
- babu_baboo
- ベストアンサー率51% (268/525)
//その3 //呼ばれるたびドラムを回転 Drum.prototype.roll = (function ( int ) { return function ( ) { if( this.f ) { //加速 this.step = Math.min( this.step + this.ac, 15 ); } else { //減速 this.step = Math.max( this.step - this.ac, 1 ); if( 1 == this.step && int( this.angle % this.n ) == 0) { clearInterval( this.tmid ); this.tmid = null; if( 'function' === typeof this.cbFunc ) { this.cbFunc( this.getNumber() ); } } } this.angle += this.step; this.view(); }; })( Math.floor ); Drum.prototype.start = (function ( ) { return function ( ) { if( !this.tmid ) { this.f = true; this.step = 0; this.tmid = setInterval( (function ( that ) { return function ( ) { that.roll( ); }; })( this ), 30); } };})(); Drum.prototype.stop = (function ( ) { return function ( cbFunc ) { this.cbFunc = cbFunc; this.f = false; };})(); Drum.prototype.getNumber = (function ( ) { return function ( ) { return this.tmid ? false: Math.floor( ( this.angle % 360 ) / this.n ); };})(); //スロットを定義 var Slot = function ( ) { this.init.apply( this, arguments ); }; Slot.buffer = [ ];//clickでidをキーとして、オブジェクトを調べるため Slot.prototype.init = (function ( ) { return function ( tgsw /*, [ swid, dramObj ], [ ] */ ) { this.name = 'Slot'; this.buf = [ ]; this.nums = [ ]; var cnt = 1; var ary, id, drum; Slot.buffer[ tgsw ] = this; while( ary = arguments[ cnt++ ] ) { id = ary[0], drum = ary[1]; this.buf[ id ] = drum; Slot.buffer[ id ] = this; } };})(); Slot.prototype.start = (function ( ) { return function ( ) { for( var k in this.buf ) if( this.buf.hasOwnProperty( k ) ) { this.nums[ k ] = false; this.buf[ k ].start(); } };})();
- babu_baboo
- ベストアンサー率51% (268/525)
//その2 var Drum = function ( ) { this.init.apply( this, arguments ); }; //ドラムの初期化 Drum.prototype.init = function ( id, images, setNo, ac ) { var cnt = 0; var pnt = document.getElementById( id ); var img, newImg; this.imgs = [ ]; while( img = images[ cnt++ ] ) { newImg = document.createElement( 'img' ); newImg.src = img.src; newImg.alt = img.alt; with( newImg.style ) position = 'absolute',top = left = '0px'; this.imgs.push( pnt.appendChild( newImg ) ); } this.name = 'Drum'; this.max = --cnt; this.radius = newImg.offsetHeight / (2 * Math.tan( Math.PI / cnt ) );//半径 this.center = Math.floor( pnt.offsetHeight / 2 );//中心 this.n = 360 / cnt; //n角形 this.angle = setNo || Math.floor( Math.random( ) * cnt ) * this.n; //ドラムの回転角度 this.step = 0; //回転量(加速量) this.ac = ac || .2;//加速度 this.f = false;//true:加速 false:減速 this.tmid = null; this.view(); }; //ドラムの絵柄表示 Drum.prototype.view = (function ( int, deg, sin ) { return function ( ) { var cnt = 0; var sa = this.angle + this.n / 2; var py0, py1, img, style; py0 = int( this.center + sin( sa * deg ) * this.radius ); while( img = this.imgs[ cnt++ ] ) { style = img.style; sa -= this.n; py1 = int( this.center + sin( sa * deg ) * this.radius ); if( py0 > py1 ) { style.top = py1 + 'px'; style.height = py0 - py1 + 'px'; style.display = 'inline'; } else { style.display = 'none'; } py0 = py1; } }; })( Math.floor, Math.PI / 180, Math.sin );
- babu_baboo
- ベストアンサー率51% (268/525)
長いので分割してアップします。全角空白は、全て半角空白になおしてください その1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <title>スロットゲーム</title> <style type="text/css"> #slot div { height: 240px; width : 60px; overflow: hidden; position: relative; border: 1px #888 solid; float:left; z-index: 0; margin:1px; } #slot div img { height: 80px; width: 60px; } #button { clear:both; } #button input { width: 60px; } </style> <div id="slot"> <div id="s0"> </div> <div id="s1"> </div> <div id="s2"> </div> <div id="s3"> </div> <div id="s4"> </div> </div> <p id="button"> <input type="button" value="Stop" id="sw0"> <input type="button" value="Stop" id="sw1"> <input type="button" value="Stop" id="sw2"> <input type="button" value="Stop" id="sw3"> <input type="button" value="Stop" id="sw4"> <input type="button" value="Start" id="swStart"> </p> <script type="text/javascript"> //@cc_on //画像の先読み var ImageLoader = function ( srcList, header ) { var rst = [ ]; var cnt = 0; var max = srcList.length; while( cnt < max ) { rst[ cnt ] = new Image; rst[ cnt ].src = ( header ? header + ',': '' ) + srcList[ cnt ]; rst[ cnt ].alt = cnt + ''; cnt++; } return rst; };
- babu_baboo
- ベストアンサー率51% (268/525)
おぅ~がっつり書きましたね~。まってました!>fujillin さん ここでは、がっつんと指摘する人が少ないので、やんわりと・・・。 最後の方の sp.onclick = (function(obj) { return function(){obj.stop();} })(this); とかって、メモリーリークだと思ってる。 回避策とかありますか? いまだに、自分も悩みます。 OKWaveからだと、文字数制限があって、一度にアップできなくて、分割するのが面倒です。^^;
- babu_baboo
- ベストアンサー率51% (268/525)
まちがえた //cc_on を //@cc_on に あぁ~今年こそ無駄な回答をしないようにと、思ってたのに・・・。
- 1
- 2
お礼
babu_babooさん 丁寧なプログラムありがとうございます。 また わからないことがあったら教えてください。