1999.04.18 改

実践練習 − スロットマシーン
◆このページでは、実際のプログラムを作りながら、オブジェクト操作や構文の使い方、 そして1つのまとまったプログラム作りを学んでもらえればと思います。
このページは 初心者ページに目を通している方、あるいはその程度の知識がある方を対象にしています。
実際に使うオブジェクト操作は 画像、フォーム、ウィンドウオブジェクトです。
構文は、if文と for文 程度です。
古い方法ではありますが、JavaScriptの基礎の部分だけでできています。 まだ難しいと思う人はスルーで。


プランニング
◆まず練習ですからプランを立てる所から始めしょう。
と言っても、私が一方的に考えて作って行きますが・・・・。

◆どんな仕組みにする?
スロットと言うと、バナナやりんごのフルーツと ラッキー7 等ですが とりあえず簡単に画像を作れる数字のみの物にします。 ここでは、数字は0〜9の10枚用意します。
フォームと文字を使っても良いのですが画像のコントロールも覚えられますので画像にします。
スロットは何枚かの絵柄が揃うと『当たり』になるわけです。 5個も窓があると、スロットが難しくなりますから オーソドックスに 窓は3つにします。

◆あと必要な物は?
操作に必要なボタンが要ります。 窓3ヶ所の画像をストップさせるボタン、 ゲームをスタートさせるボタンと、プログラム自体をリセットするボタンも必要ですね。
あと次の動作を教えたり、当たりを知らせるテキストボックスも一応必要ですね。

システム的には、bet (掛点)をどうするか? 当たりをどう設定するか?
betは 今回は簡単に 一口10点 で 好きなだけ掛けられるようにします。 当たりは 数字が3つ揃うと10倍、7が3つ揃うと 20倍 とします。 最初の持ち点は 200点とします。

これで必要な事は決まりました。


ゲームフォームを作る
先ほどまでに決まった事をまずhtmlファイルにしてみます。まだ、何も動きません。
画像は私のスロットで使っている10枚を使います。
用意する画像は必ず、すべて同じ大きさにします。

<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript">

//ここにスクリプトを書きます

</SCRIPT>
</HEAD>
<BODY BGCOLOR="#000000" TEXT="#FFFFFF">

<FORM NAME="SLOT">
<TABLE CELLSPACING=0>

<TR><TD COLSPAN=3 ALIGN="center">
<INPUT NAME="mes" TYPE="text" VALUE="PUSH START !!" SIZE=30>
</TD></TR>

<TR><TD COLSPAN=3 ALIGN="center">TOTAL
<INPUT NAME="total" TYPE="text" VALUE="200" SIZE=10></TD></TR>

<TR BGCOLOR="#000000">
<TD>
<IMG NAME="CELL1" SRC="./img7.gif" WIDTH="50" HEIGHT="76"></TD>
<TD>
<IMG NAME="CELL2" SRC="./img7.gif" WIDTH="50" HEIGHT="76"></TD>
<TD>
<IMG NAME="CELL3" SRC="./img7.gif" WIDTH="50" HEIGHT="76"></TD>
</TR>

<TR>
<TD>
<INPUT NAME="btn1" TYPE="button" VALUE="STOP"></TD>
<TD>
<INPUT NAME="btn2" TYPE="button" VALUE="STOP"></TD>
<TD>
<INPUT NAME="btn3" TYPE="button" VALUE="STOP"></TD>
</TR>

<TR><TD COLSPAN=3 ALIGN="center">
<INPUT NAME="start" TYPE="Button" VALUE="START"></TD></TR>

<TR><TD COLSPAN=3 ALIGN="center">BET
<INPUT NAME="bet" TYPE="text" SIZE=5 VALUE="10"></TD></TR>

<TR><TD COLSPAN=3 ALIGN="center">
<INPUT NAME="down" TYPE="button" VALUE="−">
<INPUT NAME="up" TYPE="button" VALUE="+">
</TD></TR>

<TR><TD COLSPAN=3 ALIGN="center">
<INPUT NAME="clear" TYPE="Button" VALUE="RESET"></TD></TR>

</TABLE>
</FORM>

</BODY>
</HTML>
こんな感じになります。
TOTAL
BET
◆オブジェクト名
・フォーム全体は SLOT
・メッセージエリアは mes
・合計点枠 は total
・掛け点枠 は bet
・画像は 左から CELL1、CELL2、CELL3
・STOPボタンは 左から btn1、btn2、btn3
・− ボタンは down
・+ ボタンは up
・STARTボタンは start
・RESETボタンは clear

・画像名 0〜9 が img0.gif 〜 img9.gif

0 1 2 3 4 5 6 7 8 9
私が自分のスロットを作る時の過程がこんな感じでした。
初心者の方でもここまでは簡単に作れますよね? 必要な物のみ HTMLで作り上げるだけですから。


STEP 1 画像配列
スロットでは、画像が回転します。ここでは 画像を0〜9 まですりかえます。 すりかえる度に読み込んでいては、時間がかかりますので ダミーのImageオブジェクトを作り必要な画像10枚を 先に読み込んでしまいます。 画像置換えの基本的なテクニックです。
ダミー画像オブジェクトを数値で呼び出しできるように配列にします。 配列にすれば 配列のインデックス 0,1,2・・・ と言う番号で呼び出せます。

☆まず配列を作ります
配列定義の説明が面倒なので、組み込みオブジェクト Array() を使います
この為 基本的に NN3、IE4以上の動作となります。
var $imgs = new Array(10);  // 10は要素の個数

次にこの各配列要素 $imgs[0]〜$imgs[9] を Imageオブジェクト にします。
for(i=0; i<10; i++){
    $imgs[i] = new Image(); //配列の要素は画像オブジェクト
    $imgs[i].src = "./img" + i + ".gif"; //そのsrcプロパティに画像のURLをセット
}
これはわかりますね?
iが0 なら $imgs[0] = new Image() となります。次の行は
$imgs[0].src = "./img" + 0 + ".gif"; となります。
左:画像オブジェクトのSRCプロパティ
右:文字列連結 "./img0.gif" になりますね? ( 0 はその時の i の値)
これをi=9 まで繰り返します。
これで配列のindex番号と 画像の数字 が同じになります。
と言うより同じになるように画像を作り名前を付けます。
$imgs[3] なら img3.gif で画像は 3の表示。

わからないなら次のように書きます。
$imgs[0] = new Image();
$imgs[0].src = "./img0.gif"
$imgs[1] = new Image();
$imgs[1].src = "./img1.gif"
	・
	・
	・
$imgs[9] = new Image();
$imgs[9].src = "./img9.gif"
これを SCRIPTタグ内に むき出しで書く事で ページが読み込まれると同時に 0〜9 の画像がJavaScript内で読み込まれます。
すりかえる画像の用意は整ったわけです。


STEP 2 画像をまわす
ではスロットの基本、画像を回転させてみましょう。 プログラムで順番にすでに読み込んでいる画像をすりかえるだけです。 回転させるに当たって、いつまでも回りつづけるとサンプル上も困るので STARTを押したら回る、STOPを押すとそのドラム(セル)が止まると言う所までやりましょう。
ここからは、イベントハンドラ以外はSCRIPTタグエリア内に記述して行きます。

◆STARTを押すとゲーム開始ですから、ゲーム開始の関数 GetStart() を作り それを呼び出します。GetStart()では、各セルをまわすそれぞれの関数を呼び出します。 回転用関数は1つにしてもいいのですが、わかりやすく3つにします。 また、STOPボタンを押すと、回転を止めますので 回転を止める関数 StopRoll()を作り STOPボタンから呼び出します。

◆HTML エレメント
☆STARTボタンに onClick="GetStart()"をつけます
<INPUT NAME="start" TYPE="button" VALUR="START" onClick="GetStart()">
☆STOPボタンに onClick="StopRoll(引数)"をつけます。
引数は どのボタンを押したかわかるようにする値を入れます。
<INPUT NAME="btn1" TYPE="button" VALUR="STOP" onClick="StopRoll(1)">
<INPUT NAME="btn2" TYPE="button" VALUR="STOP" onClick="StopRoll(2)">
<INPUT NAME="btn3" TYPE="button" VALUR="STOP" onClick="StopRoll(3)">

◆SCRIPTタグ内
☆回転状態を示す変数を インデックスで呼び出せるように
配列変数として、作ります。都合上 1〜3 を使います。
回転中 true、停止中 false ( この値をfalseにすると回転が止まる)
var $DR = new Array();
$DR[1] = $DR[2] = $DR[3] = false;

☆ゲーム開始関数を作ります
全ドラムが止まっている事を確認してゲームに入ります。
最初に動作中として $DR[] を trueにします。
次に、回転用関数を呼び出します。
動いている(ゲーム中の)場合は 警告を出します。
function GetStart(){
    if(!$DR[1] && !$DR[2] && !$DR[3]){
        $DR[1] = $DR[2] = $DR[3] = true;
        DoRoll1();
        DoRoll2();
        DoRoll3();
    }else{ alert('ゲーム中です'); }
}

☆ 0〜9 まで変化しますので現在の値を入れる変数を作ります
初期値は一番最初に表示している画像と同じ値 7 にして置きます。
var $cl1 = $cl2 = $cl3 = 7;
☆回転速度を決めます(1/1000秒単位)
var $speed = 100;
☆ 回転用関数 1,2,3 を作ります
function DoRoll1(){

}
function DoRoll2(){

}
function DoRoll3(){

}

☆停止用関数を作ります
停止用関数はこれ一つで済ませる為、引数でどのボタンかをチェックします。
function StopRoll( _n ){

}
◆回転用・停止用 関数を詳しく説明しながら作ります

☆回転用
var $cl1 = $cl2 = $cl3 = 7;
var $speed = 50;
function DoRoll1(){
    if($DR[1]){ // #0
        $cl1++; // #1
        if($cl1 >= 10){ $cl1 = 0;} // #2
        document.images["CELL1"].src = $imgs[$cl1].src; // #3
        $Timer1 = setTimeout("DoRoll1()",$speed); // #4
    }
}
# $DR[1]が true の場合のみ 以下のステートメントを実行
#1 回転関数が呼び出されると、現在の値 $cl1 をインクリメントします。
#2 $cl1が 10 になると元に戻って 0 になるようにします。(0〜9なので)
#3 ページ内のCELL1と言う画像オブジェクトのSRCの値をすでに読み込んだ
ダミー画像オブジェクト $imgs[$cl1]のSRCの値に取り替えます。
$cl1は0〜9の数字ですよね? 8なら $imgs[8].src となるわけです。
#4 再帰法 自分自身の関数をまた呼び出します。
あとで、JavaScriptから中止できるように、変数値にしておきます。

$DR[1]が falseになると、回転をやめます。
$speed で全ドラムのスピードを決めています。これを替えれば
全体の回転速度を簡単に変えられます。

DoRoll1()〜DoRoll3()は対象となるセル CELL1〜3 が違います。
また現在の値を示す $cl1〜$cl3 、状態の$DR[1]〜$DR[3]

☆停止用
function StopRoll( _n ){
    $DR[_n] = false;
    if(!$DR[1] && !$DR[2] && !$DR[3]){
	//全部が止まったら、値の判定へ
    }
}
押されたボタンに対応する回転関数を止める為に
その関数用の状態を示す $DR[_n] を false にします。
_n は引数で ボタンに付けたイベントハンドラから値をもらいます。
$DR[_n] が falseであれば、回転関数で自分を呼び出すのをやめますね?

$DR[1]〜[3] が全部 false なら 全部のドラムが止まった事になります。
全部が止まった場合は、数値が揃ったかを判定する事になり
判定する為の関数へ処理を移行します。次の説明で行います。

ここまでの注意点は、ゲームに入る時と全部止まった時に使っている
!$DR[1] && !$DR[2] && !$DR[3] の部分です。
この部分は、$DR[] が 全部 false なら、と言う意味です。
ここを
$DR[1] == $DR[2] == $DR[3] == false の様に書かないでください。
例えば A == B == false と書くと
A == B が falseなら、つまり AとBが Notイコールならと言う意味になります。
!$DR[1] && !$DR[2] && !$DR[3]は、!演算子を使わないなら
($DR[1] == false) && ($DR[2] == false) && ($DR[3] == false)ですね。	
さて、ここまでで回転のSTARとSTOPができました。 どうしても、それぞれの関数が お互いの関わり合いがあるので 一気に説明してしまいました。 出来上がりソースを次に書きます。 次のソースの他に START、STOPボタンにイベントハンドラも忘れずに。

var $imgs = new Array(10);
for(i=0; i<10; i++){
    $imgs[i] = new Image();
    $imgs[i].src = "./img" + i + ".gif";
}

var $DR = new Array();
$DR[1] = $DR[2] = $DR[3] = false;
function GetStart(){
    if(!$DR[1] && !$DR[2] && !$DR[3]){
        $DR[1] = $DR[2] = $DR[3] = true;
        DoRoll1();
        DoRoll2();
        DoRoll3();
    }else{ alert('ゲーム中です'); }
}

var $cl1 = $cl2 = $cl3 = 7;
var $speed = 50;
function DoRoll1(){
    if($DR[1]){
        $cl1++;
        if($cl1 >= 10){ $cl1 = 0;}
        document.images["CELL1"].src = $imgs[$cl1].src;
        $Timer1 = setTimeout("DoRoll1()",$speed);
    }
}
function DoRoll2(){
    if($DR[2]){
        $cl2++;
        if($cl2 >= 10){ $cl2 = 0;}
        document.images["CELL2"].src = $imgs[$cl2].src;
        $Timer2 = setTimeout("DoRoll2()",$speed);
    }
}
function DoRoll3(){
    if($DR[3]){
        $cl3++;
        if($cl3 >= 10){ $cl3 = 0;}
        document.images["CELL3"].src = $imgs[$cl3].src;
        $Timer3 = setTimeout("DoRoll3()",$speed);
    }
}

function StopRoll( _n ){
    $DR[_n] = false;
    if(!$DR[1] && !$DR[2] && !$DR[3]){
        alert('全部止まりました'); //とりあえず
    }
}
初めてのゲームではドラムは 3ヶ所とも同じ数字から始まりますので 同じ回転をします。2回目以降は、止まった数字からになります。 これで、ゲームの本体は80%完成?みたいなのもです。 後は点数関係と、細部を仕上げればOK。


STEP 3 点数関連
次に、持ち点、掛け点、当たりの処理、はずれの処理も等の 点数に関してのスクリプトを付け加えて行きましょう。
・最初の持ち点 200 点
・掛け点 単位10点
・777 掛け点×20倍
・それ以外 掛け点×10倍
・最初はベース単位の10点、手動で 増減可能。 一度掛け点を替えたら次のSTARTもそのままの掛け点。 例えば、20点ずつ掛け続ける時に毎回替えなくて済むように。 毎回 ベース10点に戻すと、毎回 BET指定が必要なので。


◆まず 点数のBET の 増減コントロール
関数 BetCTRL() を作り +ボタン −ボタン から呼び出します。
☆HTML エレメント
<INPUT NAME="down" TYPE="button" VALUE="−" onClick()="BetCTRL(0)">
<INPUT NAME="up" TYPE="button" VALUE="+" onClick()="BetCTRL(1)">
ベットUPの場合は 1、downの場合は 0 を引数として渡します。

☆SCRIPTタグ内
// TotalポイントとBetポイントをグローバル変数で管理します
var $t_point = 200; // total デフォルト
var $b_point = 10; // bet デフォルト
// Bet(+,-)ボタン が押された時の処理
function BetCTRL(_n){
if(!$DR[1] && !$DR[2] && !$DR[3]){ //動作チェック
    if(_n == 1){  // ☆UPの場合
        if(($t_point - $b_point) >= 10){
            $b_point += 10;
            document.SLOT.bet.value = $b_point;
        }else{ alert('手持ち不足\n これ以上BetUpできません。'); }
    }else{  // ☆DOWNの場合
        if($b_point >= 20){
            $b_point -= 10;
            document.SLOT.bet.value = $b_point;
        }else{ alert('最低Bet は 10point です。'); }
    }
}else{ alert('ゲーム中にBETできません');}
}
まず、この関数が呼び出されると最初に現在ゲーム中かを調べます。 !$DR[1] && !$DR[2] && !$DR[3]であればゲーム中ではありません。 ゲームが始まってからBetできない様にする為です。

Betボタンによる Betポイントのコントロールです。
Betポイントと totalポイントは基本的に グローバル変数で全て管理します。 毎回 ポイントのフォームを参照してそこから現在のポイントを取り出しても良いのですが IEでは対処方法はあるものの、Netscapeでは フォームを手動で好きなように書きかえれてしまいます。 従って、フォームから値を得ると『いかさま』ができてしまいますので グローバル変数を使って、内部でポイントを管理します。

☆UP の場合
まず、手持ちポイント($t_point)とベットポイント($b_point)の差をチェックします。 これが10以上あればまだUPする事ができますね?。 その場合、$b_point に 10 を加算します。 差が少なければ、手持ち金はもう余裕がありません。警告を出します。

☆Down の場合
Betポイント($b_point)が 20以上であれば、まだ下げられます。 従って、$b_point から 10 減算します。 しかし、20未満の場合(事実上10のみ)は もう下げられません。警告を出します。

◆次に、当たり、はずれ 処理です
すでに作ってある function StopRoll( _n ){ $DR[_n] = false; if(!$DR[1] && !$DR[2] && !$DR[3]){ alert('全部止まりました'); //とりあえず } } で、全てのドラムが止まったか?をチェックしています。 とまると、とりあえず alert() にしてありますが、 判定用関数を作り、呼び出すようにします。 function StopRoll( _n ){ $DR[_n] = false; if(!$DR[1] && !$DR[2] && !$DR[3]){ ResultCheck(); } } で、ResultCheck()関数を作ります。 function ResultCheck(){ $t_point -= $b_point; if(($cl1 == $cl2) && ($cl2 == $cl3 )){ if($cl1 == 7 ){ $t_poinnt += $b_point*20; }else{ $t_point += $b_point*10; } } document.SLOT.total.value = $t_point; }
ResultCheck()関数では、まず呼び出されると最初に 持ち点から掛け点を引きます。 これで持ち点が、正確になります。 次に、当たり判定です。
($cl1 == $cl2) && ($cl2 == $cl3 ) の状態は 現在の各ドラムの値を示す変数が 全部同じなら? を意味します。 全部同じであれば、表示されている画像 $imgs[変数].src;も同じ物ですので 『あたり』となります。
あたりの場合2種類あります。この変数の1つが 7であれば全部7ですね? この場合はラッキー7で、20倍です。 7以外であれば、ゾロメで、10倍となります。 それぞれBetポイントに 倍数を掛けた値を、$t_pointに 追加加算します。
最後に、当たりも外れも含めて、totalポイントの表示フォームに 現在の トータルポイントを表示します。

この ResultChekc()関数にもう一つ付け足す物がありました。
もしこの結果の時点で、totalポイントが10未満(事実上は0)になっていたら ゲームオーバーになると言う処理です。

if($t_point <10){ alert('ゲームオーバー'); }
を付け足します。ゲームオーバー後の処理として ゲームを続けられない様にする為に、ゲームオーバー変数を作り その変数を true(どちらでもいいが) にしましょう。
$gameover = true;
これで、リセットボタンを押すとこれを falseにするようにして true の場合はStartボタンを無効にします。

☆ 判定用関数
$gameover = false;
function ResultCheck(){
    $t_point -= $b_point;
    if(($cl1 == $cl2) && ($cl2 == $cl3 )){
        if($cl1 == 7 ){
            $t_poinnt += $b_point*20;
        }else{ $t_point += $b_point*10; }
    }
    document.SLOT.total.value = $t_point;
    if($t_point < 10){ $gameover = true; alert('ゲームオーバー')}
}

☆ ゲーム開始関数
function GetStart(){
    if(!$DR[1] && !$DR[2] && !$DR[3] && !$gameover){
        $DR[1] = $DR[2] = $DR[3] = true;
        DoRoll1();
        DoRoll2();
        DoRoll3();
    }else{
        if(!$gameover){ alert('ゲーム中です');}
        else{ alert('ゲームオーバーです。リセットしてください'); }
    }
}
!$gaemover ( $gameover が falseなら)を付け足しています。
開始条件が整わないけれども $gameover が falseと言う場合は この場合はゲーム中と言いう事とです。 開始条件が整わない場合で $gameoverが trueなら ゲームオーバーですのでその警告を出します。

もう少しで仮完成です。


STEP 4 リセット処理
ゲームオーバー後などのリセット処理です。
基本的にはフォームをリセットする事で、表示上での トータルポイントや ベットポイント、メッセージ等を 初期値に戻せます。 しかし、JavaScript内部での変数値や、表示画像などは共に戻りません。 ページのリロードを行う方法では、フォームの値が元に戻らない事もあります。 全てをきちんと、プログラムを使って処理してみましょう。

☆HTMLエレメント
リセットボタンを押すと、リセット関数 ClearAll() を呼び出します。
<INPUT NAME="clear" TYPE="Button" VALUE="RESET" onClick="ClearAll()">

☆SCRIPT内
// ゲームオーバーではない場合、リセットしていいか尋ねる
function ClearAll(){
    if($gameover){
        ResetAll();
    }else{
        if(confirm('ゲーム続行可能です\n 最初からやり直しますか?'))
        { ResetAll();}
    }
}

// リセット処理
var $Timer1,$Timer2,$Timer3;
function ResetAll(){
	// タイマーを停止
	if($Timer1){ clearTimeout($Timer1); }
	if($Timer2){ clearTimeout($Timer2); }
	if($Timer3){ clearTimeout($Timer3); }
    //フォーム値をリセット
    document.SLOT.reset();
    // 画像を全部 7 に
    document.images["CELL1"].src = $imgs[7].src; ;
    document.images["CELL2"].src = $imgs[7].src; ;
    document.images["CELL3"].src = $imgs[7].src; ;
	// ドラムの画像値を示す値を 7に
	$cl1 = $cl2 = $cl3 = 7;
	//ゲームオーバーを falseに
	$gameover = false;
	//ドラム回転状況を falseに
	$DR[1] = $DR[2] = $DR[3] = false;
	// JavaScript内ポイントを初期値に
	$t_point = 200;
	$b_point = 10;
}
ClearAll()では、まだゲーム続行可能な状態なのか? ゲームーバーなのか?を チェックして、続行可能な場合は confirmで質問を出します。 ゲームオーバーの場合と、「はい」 ボタンを押した場合は ResetAll() 関数へ行きます。 これは、間違って Resetボタンを押してしまった場合を考えての処理です。

ResetAll()関数では、フォームのリセット、もし動いている場合のドラムのタイマーのクリア、 その他、初期設定のある全ての変数の初期化、画像の初期化を行っています。 他に方法が無くはないのですが、とりあえず、自分で設定した変数ですから ここできちんと把握して、全てを初期化した方が確実です。

また、ゲームが始まっていない時点でリセットされると $Timer数字 という変数がまだ存在しないので clearTimer()でエラーになりますし、if($Timer)でも参照できません。 その為プログラムが読み込まれた時点で、var $Timer1,$Timer2,$Timer3; として変数が存在する事だけは宣言しておきます。


STEP 5 メッセージの表示
ほぼ完成していますが、メッセージ表示フォームをまだ何もしていません。 また、後1つ大事な処理が残っています。

◆Betポイントが totalポイントを上回る場合
10ポイントずつ掛けていれば、Totalポイントが 0 になって時点でゲームオーバーになり Startを押せません。では 20ポイントずつ掛けていた場合はどうなるでしょう? Totalポイントが 残10 では ゲームオーバーにはなっていませんが、20ポイントは掛けられません。 でも Bet+-ボタンを押さないで前回から連続の場合は、このままゲームが始まってしまいます。 そこで ゲーム開始関数で、Betポイントが Total残ポイントを上回っていないか?をチェックしなければなりません。 上回っている場合には、強制的に 現在 掛けられる最高ポイントに修正してメッセージを出します。

☆ ゲーム開始関数
function GetStart(){
    if(!$DR[1] && !$DR[2] && !$DR[3] && !$gameover){
        if(($t_point - $b_point) < 0){
			$b_point = $t_point;
            alert("掛金が手持ちを上回っていますので\n自動的に$t_pontに変更します。\n STARTボタンを押してください。");
            document.SLOT.bet.value = $b_point;
        }else{
            $DR[1] = $DR[2] = $DR[3] = true;
            DoRoll1();
            DoRoll2();
            DoRoll3();
        }
    }else{
        if(!$gameover){ alert('ゲーム中です');}
        else{ alert('ゲームオーバーです。リセットしてください'); }
    }
}
トータルポイント−ベットポイントが マイナスになるようであれば
現在の最高額 トータルポイントにベットポイントを合わせて
警告を出します。

次に様々な状況での メッセージの表示です。今まで、アラートにしていた部分も、
とくに アラートである必要が無ければメッセージにします。
個々をここには書きません、95%できあがりスクリプトを見てチェックしてください。
一応、内容だけ
デフォルト:STARTボタンを押してください。
ゲーム開始後:STOPを押してください。
3つともSTOP:当たり、はずれの結果。
ゲームオーバー:リセットしてください
ベットポイント不足:不足しています
等々です。
フォームにメッセージを表示するには
document.SLOT.mes.value = "メッセージ";


STEP 6 仮完成
HTMLまで含めて95%完成のソースを書きます。
今後の説明は各部署の名前に対して、付け加えや改造として解説します。

<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript">
<!--
/* -------------------------------------------
配列要素を、画像オブジェクト化して先読込み
-------------------------------------------- */
var $imgs = new Array(10);
for(i=0; i<10; i++){
    $imgs[i] = new Image();
	$imgs[i].src = "./img" + i + ".gif";
}
/* -------------------------------------------
点初期値変数 と 掛け点の増減用関数
-------------------------------------------- */
var $t_point = 200; // 手持 初期値
var $b_point = 10;  // 掛け 初期値
function BetCTRL(_n){
    if(!$DR[1] && !$DR[2] && !$DR[3]){
        if(_n == 1){
            if(($t_point - $b_point) >= 10){
                $b_point += 10;
                document.SLOT.bet.value = $b_point;
            }else{ alert('手持ち不足\n これ以上BetUpできません。'); }
        }else{
            if($b_point >= 20){
                $b_point -= 10;
                document.SLOT.bet.value = $b_point;
            }else{ alert('最低Bet は 10point です。'); }
        }
    }else{ alert('ゲーム中にBETできません');}
}
/* ------------------------------------------
ドラムの状態を示す 変数配列
-------------------------------------------- */
var $DR = new Array();
$DR[1] = $DR[2] = $DR[3] = false;
/* ------------------------------------------
ゲーム開始関数 状況把握とゲーム開始
-------------------------------------------- */
function GetStart(){
    if(!$DR[1] && !$DR[2] && !$DR[3] && !$gameover){
        if(($t_point - $b_point) < 0){
            $b_point = $t_point;
            document.SLOT.mes.value = "ALERT !!!";
            alert("掛金が手持ちを上回っていますので\n自動的に$t_pontに変更します。\n STARTボタンを押してください。");
            document.SLOT.bet.value = $b_point;
        }else{
            $DR[1] = $DR[2] = $DR[3] = true;
            document.SLOT.mes.value = "PUSH STOP Button!!";
            DoRoll1();
            DoRoll2();
            DoRoll3();
        }
    }else{
        if(!$gameover){ alert('ゲーム中です');}
        else{ alert('ゲームオーバーです。リセットしてください'); }
    }
}
/* ------------------------------------------
ドラム回転関数 ドラム画像の初期値、速度
-------------------------------------------- */
var $cl1 = $cl2 = $cl3 = 7;
var $speed = 50;
function DoRoll1(){
    if($DR[1]){
        $cl1++;
        if($cl1 >= 10){ $cl1 = 0;}
        document.images["CELL1"].src = $imgs[$cl1].src;
        $Timer1 = setTimeout("DoRoll1()",$speed);
    }
}
function DoRoll2(){
    if($DR[2]){
        $cl2++;
        if($cl2 >= 10){ $cl2 = 0;}
        document.images["CELL2"].src = $imgs[$cl2].src;
        $Timer2 = setTimeout("DoRoll2()",$speed);
    }
}
function DoRoll3(){
    if($DR[3]){
        $cl3++;
        if($cl3 >= 10){ $cl3 = 0;}
        document.images["CELL3"].src = $imgs[$cl3].src;
        $Timer3 = setTimeout("DoRoll3()",$speed);
    }
}
/* ------------------------------------------
ドラム停止関数・全停止→判定処理呼出し
-------------------------------------------- */
function StopRoll( _n ){
    $DR[_n] = false;
    if(!$DR[1] && !$DR[2] && !$DR[3]){
        ResultCheck();
    }
}
/* ------------------------------------------
判定関数
-------------------------------------------- */
$gameover = false;
function ResultCheck(){
    $t_point -= $b_point;
    if(($cl1 == $cl2) && ($cl2 == $cl3 )){
        if($cl1 == 7 ){
            document.SLOT.mes.value = "Lucky7!! ×20";
            $t_poinnt += $b_point*20;
        }else{
            document.SLOT.mes.value = "Bingo!! ×10";
            $t_point += $b_point*10;
        }
    }else{ document.SLOT.mes.value = "NextGame"; }
    document.SLOT.total.value = $t_point;
    if($t_point < 10){
        $gameover = true;
        document.SLOT.mes.value = "Game Over!!";
    }
}
/* ------------------------------------------
リセット・状況チェック関数
-------------------------------------------- */
function ClearAll(){
    if($gameover){
        ResetAll();
    }else{
        if(confirm('ゲーム続行可能です\n 最初からやり直しますか?')){ ResetAll();}
    }
}
/* ------------------------------------------
リセット・初期化関数
-------------------------------------------- */
var $Timer1,$Timer2,$Timer3;
function ResetAll(){
    // タイマーを停止
    if($Timer1){ clearTimeout($Timer1); }
    if($Timer2){ clearTimeout($Timer2); }
    if($Timer3){ clearTimeout($Timer3); }
    document.SLOT.reset();
    document.images["CELL1"].src = $imgs[7].src; ;
    document.images["CELL2"].src = $imgs[7].src; ;
    document.images["CELL3"].src = $imgs[7].src; ;
    $cl1 = $cl2 = $cl3 = 7;
    $gameover = false;
    $DR[1] = $DR[2] = $DR[3] = false;
    $t_point = 200;
    $b_point = 10;
}
//-->
</SCRIPT>
</HEAD>
<BODY BGCOLOR="#000000" TEXT="#FFFFFF">

<FORM NAME="SLOT">
<TABLE CELLSPACING=0>

<TR><TD COLSPAN=3 ALIGN="center">
<INPUT NAME="mes" TYPE="text" VALUE="PUSH START !!" SIZE=30>
</TD></TR>

<TR><TD COLSPAN=3 ALIGN="center">TOTAL
<INPUT NAME="total" TYPE="text" VALUE="200" SIZE=10></TD></TR>

<TR BGCOLOR="#000000">
<TD>
<IMG NAME="CELL1" SRC="./img7.gif" WIDTH="50" HEIGHT="76"></TD>
<TD>
<IMG NAME="CELL2" SRC="./img7.gif" WIDTH="50" HEIGHT="76"></TD>
<TD>
<IMG NAME="CELL3" SRC="./img7.gif" WIDTH="50" HEIGHT="76"></TD>
</TR>

<TR>
<TD>
<INPUT NAME="btn1" TYPE="button" VALUE="STOP" onClick="StopRoll(1)"></TD>
<TD>
<INPUT NAME="btn2" TYPE="button" VALUE="STOP" onClick="StopRoll(2)"></TD>
<TD>
<INPUT NAME="btn3" TYPE="button" VALUE="STOP" onClick="StopRoll(3)"></TD>
</TR>

<TR><TD COLSPAN=3 ALIGN="center">
<INPUT NAME="Start" TYPE="Button" VALUE="START" onClick="GetStart()"></TD></TR>

<TR><TD COLSPAN=3 ALIGN="center">BET
<INPUT NAME="bet" TYPE="text" SIZE=5 VALUE="10"></TD></TR>

<TR><TD COLSPAN=3 ALIGN="center">
<INPUT NAME="down" TYPE="button" VALUE="−" onClick="BetCTRL(0)">
<INPUT NAME="up" TYPE="button" VALUE="+" onClick="BetCTRL(1)">
</TD></TR>

<TR><TD COLSPAN=3 ALIGN="center">
<INPUT NAME="clear" TYPE="Button" VALUE="RESET" onClick="ClearAll()"></TD></TR>

</TABLE>
</FORM>

</BODY>
</HTML>
小さなバグはあるかもしれませんが、これで一応のゲームとして
スロットマシーンを楽しめると思います。


STEP 7 完成度を高めて100%に
ここまでの完成で十分ゲームとして動作します。
JavaScriptを学ぶと言う点でもう少し付け足して、より便利にしてみます。

◆ ENTERキー で操作可能にする
JavaScriptでは、フォームの部品やWindowにフォーカスを当てる事ができます。 フォーカスを当てるとは、その部品に焦点が合っている状態です。 選択されている、あるいは選択・クリックの準備状態にある事です。 ボタンなどにフォーカスが当たっていると、ENTERキーを押すとそのボタンを押す事ができます。 まず、最初は STARTボタン、STARTすると STOPボタン、全停止すると STARTボタン ゲームオーバーで、RESETボタンにフォーカスが当たるようにします。

★ゲーム開始関数
// STOPボタン1に フォーカスを移します
function GetStart(){
    if(!$DR[1] && !$DR[2] && !$DR[3] && !$gameover){
        if(($t_point - $b_point) < 0){
            $b_point = $t_point;
            document.SLOT.mes.value = "ALERT !!!";
            alert("掛金が手持ちを上回っていますので\n自動的に$t_pontに変更します。\n STARTボタンを押してください。");
            document.SLOT.bet.value = $b_point;
        }else{
            $DR[1] = $DR[2] = $DR[3] = true;
            document.SLOT.mes.value = "PUSH STOP Button!!";
            document.SLOT.btn1.focus();
            DoRoll1();
            DoRoll2();
            DoRoll3();
        }
    }else{
        if(!$gameover){ alert('ゲーム中です');}
        else{ alert('ゲームオーバーです。リセットしてください'); }
    }
}
★ ドラム停止関数
// 全部止まっていなければ、まだ止まっていないボタンにフォーカス
function StopRoll( _n ){
    $DR[_n] = false;
    if(!$DR[1] && !$DR[2] && !$DR[3]){
        ResultCheck();
    }else{
        if($DR[1]){ document.SLOT.btn1.focus();
        }else{ if($DR[2]){ document.SLOT.btn2.focus();
               }else{ if($DR[3]){ document.SLOT.btn3.focus();}}
        }
    }
}

★ 結果判定関数
// ゲームオーバーの場合 RESETボタンにフォーカス
// それ以外は STARTにフォーカス
$gameover = false;
function ResultCheck(){
    $t_point -= $b_point;
    if(($cl1 == $cl2) && ($cl2 == $cl3 )){
        if($cl1 == 7 ){
            document.SLOT.mes.value = "Lucky7!! ×20";
            $t_poinnt += $b_point*20;
        }else{
            document.SLOT.mes.value = "Bingo!! ×5";
            $t_point += $b_point*5;
        }
    }else{ document.SLOT.mes.value = "NextGame"; }
    document.SLOT.total.value = $t_point;
    if($t_point < 10){
        $gameover = true;
        document.SLOT.mes.value = "Game Over!!";
        document.SLOT.clear.focus();
    }else{ document.SLOT.start.focus();}
}

★ リセット初期化関数
// リセットボタンが押されると STARTボタンにフォーカスします
var $Timer1,$Timer2,$Timer3;
function ResetAll(){
    // タイマーを停止
    if($Timer1){ clearTimeout($Timer1); }
    if($Timer2){ clearTimeout($Timer2); }
    if($Timer3){ clearTimeout($Timer3); }
    document.SLOT.reset();
    document.images["CELL1"].src = $imgs[7].src; ;
    document.images["CELL2"].src = $imgs[7].src; ;
    document.images["CELL3"].src = $imgs[7].src; ;
    $cl1 = $cl2 = $cl3 = 7;
    $gameover = false;
    $DR[1] = $DR[2] = $DR[3] = false;
    $t_point = 200;
    $b_point = 10;
    document.SLOT.start.focus();
}
Netscape3では、フォーカスしてENTERボタンで動作しません。NN4、IE4から使えます。
IE4では ENTERを押しっぱなしにすると、どんどん進んでしまいます。
ゲームの面白味が無くなるかもしれません。

★ブラウザ判別で NN3以上、IE4以上のみにする
組み込みオブジェクト Array()の使用などで、正常な動作が得られないであろう
NN3未満、IE4未満 (両方Mozilla/3互換未満)の場合、ゲームができない様にします。
また、ページを表示した時点で、警告を出します。
その後も使いますので毎回関数を呼び出す作業を省く為
使用可能なら true 不可能なら false を $navi 変数に入れ込みます。

★HTML
BODYタグに onLoad="GetNavi();" を書き込みます。

★スクリプト

☆新規関数作成
/* ------------------------------------------
ブラウザ判別関数
-------------------------------------------- */
$navi = true;
function GetNavi(){
$agent = navigator.userAgent.charAt(8);
    if($agent < 3){
        alert('このゲームはNN3、IE4以上で動作します');
        $navi = false;
    }
}

☆ゲーム開始関数
function GetStart(){
    if($navi && !$DR[1] && !$DR[2] && !$DR[3] && !$gameover){
        if(($t_point - $b_point) < 0){
            $b_point = $t_point;
            document.SLOT.mes.value = "ALERT !!!";
            alert("掛金が手持ちを上回っていますので\n自動的に$t_pontに変更します。\n STARTボタンを押してください。");
            document.SLOT.bet.value = $b_point;
        }else{
            $DR[1] = $DR[2] = $DR[3] = true;
            document.SLOT.mes.value = "PUSH STOP Button!!";
            document.SLOT.btn1.focus();
            DoRoll1();
            DoRoll2();
            DoRoll3();
        }
    }else{
        if(!$navi){ alert('このブラウザではゲームができません');
        }else{
            if(!$gameover){ alert('ゲーム中です');}
            else{ alert('ゲームオーバーです。リセットしてください'); }
        }
    }
}
とりあえずこれで完成です。

完成品を テキストファイルにしてあります。
ダウンロード用 テキスト完成品:SLOT.txt
文字コードをセットしていませんのでブラウザで開く場合文字コードをShift_JISに。


あとがき 様々なアイデア
◆いかがでしたでしょうか? 初心者にとっては説明の仕方がちょっと難しかったかもしれません。 でも、プログラム自体は簡単なはずです。
画像のコントロールとフォームのコントロール、それぞれのパートを受け持つ関数を作って 条件によって満たされると次へ移ります。これだけの事です。 初めて自分で考えながら作る時は、まず基本的な動作を作り、それに色々付け加えて行きながら 完成度を高めるようにしてください。 たとえば、『全部止まっていれば STARTボタンを押せる』と言う部分は 最初は付けなくて結構ですし、『ゲーム中にBetボタンや、リセットボタン』を押した場合等の 処理も後で付け足せば良い事です。また、focus() でENTERボタンでの操作ができるようにするのも 付加価値でしかありません。付加価値と言えば、これは基本なので余計な物は付けていませんが 例えば 当たりの時は 3つの画像(画像のみ)を入れ替えて、当たりマーク画像を表示するとか ぞろ目でなくても、2つ揃えば 5倍ポイントを上げるとか、工夫の余地はまだまだあります。 是非、自分で改造を繰り返しながら面白い物を作ってみてください。

私は 配布しているSLOT(ほとんどこれと同じ)をJavaScriptを覚え始めて2週間くらいで作りました。 JavaScriptを学ぶ時にただ読んでいても何も覚えません。画像とフォーム、時間差ができる事を知った時点で スロットが作れると思い、作りながらJavaScriptの扱い方を実践で覚える事にしました。 実践・実験がもっとも早く覚える方法でもあります。 また、完成度を高めながら、ユーザーはこちらの思った通りのボタンを押すとは限らないと言う事もつくづく思いました。 これらの事はページに埋め込むJavaScriptに対しても言えるのではないでしょうか? ビジターが 何をしてもこちらでそれに対処できるように、思い込みではなく客観的に想像をしながら 組み上げて行く事が必要になります。

ある程度理解ができたら、このページを見ずに0から作ってみてください。
決して遠い道のりではないと思います。

←前



専用ページから申し込むと
So-netより高い3万円CB

案ずるより産むが易し
使ってみれば疑問も解決

XREA+ (plus) 206円/月
( お試し7日間 )

CORE SERVER 428円/月
( お試し15日間 )

ロリポップ 270円/月
( お試し期間10日間 )

ヘテムル 1620円/月
( お試し期間15日間 )

さくら 129円/月
( お試し期間2週間 )

無駄な高額ドメイン管理料金払ってませんか?

バリュードメイン
ムームードメイン

2010年で第二世代携帯がサービス終了。ソフトバンクに乗り換えて安くなった人が7割以上います!