WEBで出来るスロット作成

# はじめに

高校生を卒業した私達は18歳。もうりっぱな成人ですね。18歳になると解禁されるものといえば...?
そう！パチンコなんですねぇ！でもパチンコはお金もかかるし、どうにかして気分だけでも味わえないものか..
じゃあ、自分で作ればいいじゃん。ということで今回は、Web上で動かせるスロットを作ってみました。

<a id="#html"></a>
# HTML 
~~~html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="sr.css">
</head>

<body>
    <h1>スロット</h1>
    <p>画像をうまく揃えられるように頑張って</p>
		<div class="slot">
			<div class="slot-frame">
				<ul class="reels">
					<li class="reel"><img src="./images/slot01.png"></li>
					<li class="reel"><img src="./images/slot02.png"></li>
					<li class="reel"><img src="./images/slot01.png"></li>
					<li class="reel"><img src="./images/slot03.png"></li>
					<li class="reel"><img src="./images/slot04.png"></li>
					<li class="reel"><img src="./images/slot05.png"></li>
					<li class="reel"><img src="./images/slot01.png"></li>
					<li class="reel"><img src="./images/slot02.png"></li>
                    <li class="reel"><img src="./images/slot05.png"></li>
				</ul>
				<ul class="reels">
					<li class="reel"><img src="./images/slot05.png"></li>
					<li class="reel"><img src="./images/slot02.png"></li>
					<li class="reel"><img src="./images/slot04.png"></li>
					<li class="reel"><img src="./images/slot01.png"></li>
					<li class="reel"><img src="./images/slot03.png"></li>
					<li class="reel"><img src="./images/slot04.png"></li>
					<li class="reel"><img src="./images/slot05.png"></li>
					<li class="reel"><img src="./images/slot02.png"></li>
                    <li class="reel"><img src="./images/slot04.png"></li>
				</ul>
				<ul class="reels">
					<li class="reel"><img src="./images/slot03.png"></li>
					<li class="reel"><img src="./images/slot02.png"></li>
					<li class="reel"><img src="./images/slot05.png"></li>
					<li class="reel"><img src="./images/slot01.png"></li>
					<li class="reel"><img src="./images/slot04.png"></li>
					<li class="reel"><img src="./images/slot05.png"></li>
					<li class="reel"><img src="./images/slot03.png"></li>
					<li class="reel"><img src="./images/slot02.png"></li>
                    <li class="reel"><img src="./images/slot01.png"></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 src="sr.js"></script>
</body>

</html>
~~~


<a id="#css"></a>
# CSS
~~~css
body {
    text-align: center;
    padding: 0;
    margin: 0;
    background-color: aliceblue;
}
body h1 {
    background-color: rgb(255, 238, 0);
    padding-bottom: 0.5%;
}
ul {
    list-style: none;
}
.slot {
    width: 30%;
    height: 500px;
    overflow: hidden;
    margin: auto;
    border : solid 3px #333 ;
    background-color: burlywood;
}
.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;
}
.btn-start {
    margin-left: 3%;
    margin-top: 2%;
    font-size: 30px;
}
.btn-reset {
    margin-left: 6%;
    margin-top: 2%;
    font-size: 30px;
}
.btn-stop {
    margin-top: 3%;
    margin-right: 1%;
    margin-left: 4%;
    font-size: 30px;
}
p {
    font-size: 20px;
}
~~~
<a id="#javascript"></a>
# JS
~~~js
(function (global) {
    "use strict";

    /*
     * スロットのリール回転速度(実行毎秒数)
     */
    var sec = 50;

    /*
     * スロットのリール情報
     * ・スロットのリール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'));
    });

});
~~~
<a id="#reference"></a>

<a id="#kekka"></a>
# 結果
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3630872/e9dc3c07-e1bb-5e34-e5f9-6996b0a698d1.png)



<a id="#matome"></a>
# まとめ

今回スロットを作成してみましたが、やっぱり僕にはゲームで遊ぶのがちょうどいいのかなと感じました。
コード的には、画像をy軸で移動させて途中で初期化することであたかも回っているかのように見せるという所が一番難しい場所だったとおもいます。もし皆さんがパチンコをする際は、ぜひ計画的に遊ぶことをお勧めします。

# 参考サイト
- [Javascriptでスロットを作成](https://uteee.com/system/program/2975/)
- [[Javascript]スロットの作り方](https://balance.bz/magazine/category/design-dev/slotgame/)