JavaScriptでスロットゲームのプログラムを解説【JQuery】

JavaScriptのJQueryでスロットゲームをプログラミングしたサンプルコードの解説です。
この記事を書いている僕は、プログラミング歴10年以上のプログラマーです。
詳細:プログラミング未経験の新卒が10年間プログラマーとして仕事して思うこと
JavaScriptでスロットゲームをプログラム解説
JavaScriptのJQueryでスロットゲームをプログラミングしたサンプルコードを解説します。

スロットは、アニメーションでリールを回転する処理がポイントです。
ぜひチャレンジしてみてください。
※今回はHTMLタグの追加などを簡単に行えるように「JQuery」も使っています。
サンプルコード
JavaScriptのJQueryでプログラミングしたスロットゲームのサンプルコードを紹介します。
(基本的に画像以外はコピペで動くと思います)
<html>
<head>
<meta charset="UTF-8">
<title>JavaScriptでスロットゲームを作成</title>
<style>
body {
text-align: center;
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
.slot {
width: 90%;
height: 500px;
overflow: hidden;
margin: auto;
border : solid 1px #333 ;
}
.slot-frame {
height: 500px;
position: relative;
overflow: hidden;
border : solid 1px #333 ;
}
.reels {
width: 31%;
position: absolute;
}
.reels:nth-child(1) {
left: 0;
}
.reels:nth-child(2) {
left: 33%;
}
.reels:nth-child(3) {
right: 0;
}
.reel {
height: 270px;
}
.reel img {
display: block;
width: 89%;
margin: auto;
}
</style>
</head>
<body>
<h1>JavaScriptでスロットゲームを作成</h1>
<div class="slot">
<div class="slot-frame">
<ul class="reels">
<li class="reel"><img src="/slot/img/slot1.jpg"></li>
<li class="reel"><img src="/slot/img/slot2.jpg"></li>
<li class="reel"><img src="/slot/img/slot1.jpg"></li>
<li class="reel"><img src="/slot/img/slot3.jpg"></li>
<li class="reel"><img src="/slot/img/slot4.jpg"></li>
<li class="reel"><img src="/slot/img/slot5.jpg"></li>
<li class="reel"><img src="/slot/img/slot1.jpg"></li>
<li class="reel"><img src="/slot/img/slot2.jpg"></li>
</ul>
<ul class="reels">
<li class="reel"><img src="/slot/img/slot5.jpg"></li>
<li class="reel"><img src="/slot/img/slot2.jpg"></li>
<li class="reel"><img src="/slot/img/slot4.jpg"></li>
<li class="reel"><img src="/slot/img/slot1.jpg"></li>
<li class="reel"><img src="/slot/img/slot3.jpg"></li>
<li class="reel"><img src="/slot/img/slot4.jpg"></li>
<li class="reel"><img src="/slot/img/slot5.jpg"></li>
<li class="reel"><img src="/slot/img/slot2.jpg"></li>
</ul>
<ul class="reels">
<li class="reel"><img src="/slot/img/slot3.jpg"></li>
<li class="reel"><img src="/slot/img/slot2.jpg"></li>
<li class="reel"><img src="/slot/img/slot5.jpg"></li>
<li class="reel"><img src="/slot/img/slot1.jpg"></li>
<li class="reel"><img src="/slot/img/slot4.jpg"></li>
<li class="reel"><img src="/slot/img/slot5.jpg"></li>
<li class="reel"><img src="/slot/img/slot3.jpg"></li>
<li class="reel"><img src="/slot/img/slot2.jpg"></li>
</ul>
</div>
</div>
<div>
<button type="button" class="btn-start">start</button>
<button type="button" class="btn-reset" disabled="true">reset</button>
</div>
<div>
<button type="button" class="btn-stop" data-val="0" disabled="true">stop 0</button>
<button type="button" class="btn-stop" data-val="1" disabled="true">stop 1</button>
<button type="button" class="btn-stop" data-val="2" disabled="true">stop 2</button>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
(function (global) {
"use strict";
/*
* スロットのリール回転速度(実行毎秒数)
*/
var sec = 100;
/*
* スロットのリール情報
* ・スロットのリールelement
* ・スロットのリール停止フラグ
* ・スロットのリール回転数
*/
var $reels = [],
stopReelFlag = [],
reelCounts = [];
/*
* 位置情報
*/
var slotFrameHeight = 0,
slotReelsHeight = 0,
slotReelItemHeight = 0,
slotReelStart = 0,
slotReelStartHeight = 0;
/**
* スロット
*/
var Slot = {
/**
* 初期化処理
*/
init: function init() {
$reels[0] = $reels[1] = $reels[2] = null;
stopReelFlag[0] = stopReelFlag[1] = stopReelFlag[2] = false;
reelCounts[0] = reelCounts[1] = reelCounts[2] = 0;
},
/**
* スタートボタンのクリックイベント
*/
start: function () {
for (var index = 0; index<3; index++) {
Slot.animation(index);
}
},
/**
* ストップボタンのクリックイベント
*/
stop: function (index) {
stopReelFlag[index] = true;
if (stopReelFlag[0] && stopReelFlag[1] && stopReelFlag[2]) {
// 全リール停止したらリセットボタンを押下できるようにする
$('.btn-reset').attr('disabled', false);
}
},
/**
* 位置情報の初期化処理
*/
resetLocationInfo: function () {
slotFrameHeight = $('.slot-frame').outerHeight();
slotReelsHeight = $('.reels').eq(0).outerHeight();
slotReelItemHeight = $('.reel').eq(0).outerHeight();
slotReelStart = 5 - 2;
// リールの上下は、半分だけ表示させるための位置調整
slotReelStartHeight = -slotReelsHeight;
slotReelStartHeight = slotReelStartHeight + slotFrameHeight + ((slotReelItemHeight * 3 / 2) - (slotFrameHeight / 2));
$('.reels').css({
'top':slotReelStartHeight
});
},
/**
* スロットの回転アニメーション
*/
animation: function (index) {
console.log('アニメーション', '開始', index);
if (reelCounts[index] >= 5) {
reelCounts[index] = 0;
}
console.log('slotReelStartHeight', slotReelStartHeight);
console.log('reelCounts[index]', reelCounts[index]);
console.log('slotReelsHeight', slotReelsHeight);
console.log('top', slotReelStartHeight + (reelCounts[index] * slotReelItemHeight));
$('.reels').eq(index).animate({
'top': slotReelStartHeight + (reelCounts[index] * slotReelItemHeight)
}, {
duration: sec,
easing: 'linear',
complete: function () {
console.log('アニメーション', '完了', index, reelCounts[index]);
if (stopReelFlag[index]) {
console.log('アニメーション', 'ストップ', index, reelCounts[index]);
return ;
}
// 移動階数をカウント
reelCounts[index]++;
// スロット回転のアニメーションを実行する
Slot.animation(index);
}
});
},
};
global.Slot = Slot;
})((this || 0).self || global);
/**
* 読み込み後
*/
$(document).ready(function () {
/*
* スロットの初期化処理を実行
*/
Slot.init();
Slot.resetLocationInfo();
/**
* スタートボタンのクリックイベント
*/
$('.btn-start').click(function () {
// スタートボタンを押せないようにする
$(this).attr('disabled', true);
// スロットの回転を開始
Slot.start();
// ストップボタンを押せるようにする
$('.btn-stop').attr('disabled', false);
});
/**
* リセットボタンのクリックイベント
*/
$('.btn-reset').click(function () {
// リセットボタンを押せないようにする
$(this).attr('disabled', true);
// スタートボタンを押せるようにする
$('.btn-start').attr('disabled', false);
// ストップボタンを押せないようにする
$('.btn-stop').attr('disabled', true);
// スロットのリール情報を初期化
Slot.init();
});
/**
* ストップボタンのクリックイベント
*/
$('.btn-stop').click(function () {
// ストップボタンを押せないようにする
$(this).attr('disabled', true);
// レールの回転を停止
Slot.stop($(this).attr('data-val'));
});
});
</script>
</body>
</html>
CODEPEN
See the Pen [sample code]javascript slot by UTのCodePen (@ut_1029) on CodePen.
HTML部分の解説
JavaScriptのJQueryでプログラミングしたスロットゲームのサンプルコードのHTML部分から解説します。

細かく解説していきます!
文字コードを指定
HTMLのheadタグ内にmetaタグでcharset(文字コード)をUTF-8に指定します。
<meta charset="UTF-8">
metaタグでcharset(文字コード)を指定しないとWebページが文字化けする原因となります。
スロットのリールを作成
<ul>タグを3つ用意してリールを3列作成します。そして、<li>タグで1列のリールのコマを作成します。
<div class="slot">
<div class="slot-frame">
<ul class="reels">
<li class="reel"><img src="/slot/img/slot1.jpg"></li>
各種ボタンを用意
<button>タグで各種ボタンを用意します。
<button type="button" class="btn-start">start</button>
<button type="button" class="btn-reset" disabled="true">reset</button>
<button type="button" class="btn-stop" data-val="0" disabled="true">stop 0</button>
<button type="button" class="btn-stop" data-val="1" disabled="true">stop 1</button>
<button type="button" class="btn-stop" data-val="2" disabled="true">stop 2</button>
- class="btn-start"
- スロットの回転をスタートするボタン
- class="btn-stop"
- 回転したスロットのリールをストップするボタン
- class="btn-reset"
- スロットのリールの3列ストップした時にリセットするボタン
※クラス名は任意ですが、今回は"btn-start"、"btn-stop"、"btn-reset"としてJavaScriptでボタンのクリックイベントを定義しています。
JQueryをCDNで読み込む
JavaScriptでHTMLタグの追加を簡単に行えるようにJQueryをCDNで読み込みます。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Content Delivery Networkの略です。
リソース(CSSやJQueryなど)を自サーバへ用意せず、外部サーバから取得する仕組みです。リソースを配信する外部サーバは、最適化されたネットワークでリソースを配信します。
簡単にいうと「高速にリソース(CSSやJQuery)を外部サーバから取得できる」って感じです。
CSS部分の解説
JavaScriptのJQueryでプログラミングしたスロットゲームのサンプルコードのCSS部分を解説します。

スロットのスタイル部分についてポイントを解説します。
スロットのスタイルを調整

スロット枠のスタイル
クラス名が"slot"へoverflowでスロット枠からはみ出したリールを表示しないようにします。
.slot {
width: 90%;
height: 500px;
overflow: hidden;
margin: auto;
border : solid 1px #333 ;
}
スロットのリール枠のスタイル
クラス名が"slot-frame"へpositionでリールの表示位置を調整しています。
.slot-frame {
height: 500px;
position: relative;
overflow: hidden;
border : solid 1px #333 ;
}
スロットのルールのスタイル
クラス名が"reels"へpositionで表示位置を調整します。
.reels {
width: 31%;
position: absolute;
}
JavaScript部分の解説
JavaScriptのJQueryでプログラミングしたスロットゲームのサンプルコードのJavaScript部分を解説します。

スロットのリールを回転する部分についてポイントを解説します。
リールの開始位置を調整
画面ロード時にリールの開始位置をJavaScriptで調整します。
/**
* 位置情報の初期化処理
*/
resetLocationInfo: function () {
slotFrameHeight = $('.slot-frame').outerHeight();
slotReelsHeight = $('.reels').eq(0).outerHeight();
slotReelItemHeight = $('.reel').eq(0).outerHeight();
slotReelStart = 5 - 2;
// リールの上下は、半分だけ表示させるための位置調整
slotReelStartHeight = -slotReelsHeight;
slotReelStartHeight = slotReelStartHeight + slotFrameHeight + ((slotReelItemHeight * 3 / 2) - (slotFrameHeight / 2));
$('.reels').css({
'top':slotReelStartHeight
});
},

上記コードを細かく解説します。
リールの開始位置をリセットする関数を定義
resetLocationInfo: function () {
},
スロット枠などの高さ(height)値を取得
slotFrameHeight = $('.slot-frame').outerHeight();
slotReelsHeight = $('.reels').eq(0).outerHeight();
slotReelItemHeight = $('.reel').eq(0).outerHeight();
スロットの開始位置を計算
このコードでスロットのリール開始位置を上下に1マス半だけ表示するなどを制御しています。
slotReelStartHeight = -slotReelsHeight;
slotReelStartHeight = slotReelStartHeight + slotFrameHeight + ((slotReelItemHeight * 3 / 2) - (slotFrameHeight / 2));
スロットの開始位置を適用
$('.reels').css({
'top':slotReelStartHeight
});
スロットのリール回転アニメーション
スロットのリールを回転させるアニメーション処理を実装します。
/**
* スロットの回転アニメーション
*/
animation: function (index) {
console.log('アニメーション', '開始', index);
if (reelCounts[index] >= 5) {
reelCounts[index] = 0;
}
console.log('slotReelStartHeight', slotReelStartHeight);
console.log('reelCounts[index]', reelCounts[index]);
console.log('slotReelsHeight', slotReelsHeight);
console.log('top', slotReelStartHeight + (reelCounts[index] * slotReelItemHeight));
$('.reels').eq(index).animate({
'top': slotReelStartHeight + (reelCounts[index] * slotReelItemHeight)
}, {
duration: sec,
easing: 'linear',
complete: function () {
console.log('アニメーション', '完了', index, reelCounts[index]);
if (stopReelFlag[index]) {
console.log('アニメーション', 'ストップ', index, reelCounts[index]);
return ;
}
// 移動階数をカウント
reelCounts[index]++;
// スロット回転のアニメーションを実行する
Slot.animation(index);
}
});
},

上記コードを細かく解説します。
スロットのリールを回転させるアニメーションの関数を定義
animation: function (index) {
},
リールの回転数を初期化
今回は1リールに8つコマがあります。なので上下1コマの2コマを除いた6コマ目まで回転したら0コマ目へカウンター変数を初期化するようにします。
if (reelCounts[index] >= 5) {
reelCounts[index] = 0;
}
リールの回転アニメーションを定義
$('.reels').eq(index).animate({
'top': slotReelStartHeight + (reelCounts[index] * slotReelItemHeight)
},{
duration: sec,
easing: 'linear',
complete: function () {
if (stopReelFlag[index]) {
return ;
}
// 移動階数をカウント
reelCounts[index]++;
// スロット回転のアニメーションを実行する
Slot.animation(index);
}
}
ポイントとしては
- リールのタグを下方向へアニメーションして移動させている。
- 最終地点に到達したら開始位置へ戻している。
といった処理に注意が必要です。
まとめ:JavaScriptでスロットゲームをプログラム解説
今回はJavaScriptのJQueryでスロットゲームをプログラムしたサンプルコードを解説しました。

JavaScriptを使ったゲームを作る上ではアニメーションの制御が重要になってきます。
余談
このサンプルのスロットですが、リールが最後のマスまで回転すると開始位置へ戻るようにしているので、回転がガクガクして滑らかじゃないのでいずれ変更したいと思っています。
最後まで見ていただきありがとうございました。
ディスカッション
コメント一覧
JavaScriptでスロットゲームを参考にさせて頂いています。リールが止まった時の各リールの画像名を拾得したいのですが、どうしたらよろしいですか?
コメントありがとうございます。
停止したときのリール画像を取得する方法ですが、サンプルプログラムの192行目に以下のような追記したプログラムへ置き換えると確認できると思います。
if (stopReelFlag[index]) {
console.log('アニメーション', 'ストップ', index, reelCounts[index], $reels[index]);
// ↓ 追記
// レールにある画像枚数を取得(サンプルでは8枚)
var reelAllCount = $('.reels').eq(index).find('.reel').length;
// 停止している画像のインデックスを計算
// (reelAllCount - 1)
// →配列が0始まりなので画像枚数8枚から-1する。
// (reelCounts[index] + 1)
// →一番下の画像には止まらないので移動しているリールのカウント数に+1している。
var reelIndex = (reelAllCount - 1) - (reelCounts[index] + 1);
// 停止した画像のパスを表示
console.log($('.reels').eq(index).find('.reel').eq(reelIndex).find('img').attr('src'));
// ↑ 追記