HTML5でパズルゲームの作り方を現役エンジニアが解説【初心者向け】

初心者向けにHTML5でパズルゲームの作り方について解説しています。ここではJavaScriptを使ってスライドパズルを作成する例を紹介します。動作の流れと、CSSでスタイルを指定する方法についても見ていきましょう。

TechAcademyマガジンは受講者数No.1のオンラインプログラミングスクールTechAcademy [テックアカデミー]が運営。初心者向けに解説した記事を公開中。現役エンジニアの方はこちらをご覧ください。

HTML5でパズルゲームの作り方について、TechAcademyのメンター(現役エンジニア)が実際のコードを使用して初心者向けに解説します。

そもそも、HTMLの記述方法がわからない場合は、HTMLの書き方について解説した記事を読むとさらに理解が深まります。

 

なお本記事は、TechAcademyのオンラインブートキャンプ、Webデザイン講座のHTMLカリキュラムをもとに執筆しています。

 

田島悠介

今回は、HTMLに関する内容だね!

大石ゆかり

どういう内容でしょうか?

田島悠介

パズルゲームの作り方について詳しく説明していくね!

大石ゆかり

お願いします!

 

目次

 

HTMLゲームについて

ブラウザでゲームを実行するときはHTML上で動くように開発する必要があります。ここでは、ブラウザ上で動作するゲームを全般的にHTMLゲームとします。昔はFlashで開発したゲームがWeb上で公開されていました。しかし、Flashには脆弱性があることなどから2020年末にサポートが終了します。

その一方でFlashに代わる技術としてJavaScriptのSDKが充実したり、HTML5の登場によりJavaScriptで様々なゲームを開発できるようになりました。

 

[PR] HTML/CSSで挫折しない学習方法を動画で公開中

パズルゲームについて

パズルゲームには様々な種類が存在します。最近ではスマホゲームでもパズル要素を取り入れたゲームが多く存在します。ここではHTMLで作られたパズルゲームをいくつか紹介します。

テトリス

パズルゲームの中で有名なものがテトリスです。落ち物パズルの代表でブロックを組み合わせて列を揃えて消すというルールです。テトリスはオンライン上で色んなサイトが公開しています。

https://tetris.com/play-tetris

ケスケス

こちらはスマホゲームによくあるパターンのゲームです。同じ色のブロックを小さい数字から順に消していくルールのゲームです。遊んでいくうちに時間が忘れていきそうです。

https://www.afsgames.com/del.htm

スライドパズル

縁日や駄菓子屋さんでよく見かける15パズルです。4×4の盤面に15個ある数字のピースをスライドさせて順番に並び替えるゲームです。パズルゲームの定番であり、少ない手数でクリアさせるためにはとても頭を使います。

 

https://www.afsgames.com/15puzzle.htm

 

パズルゲームを作ってみよう

それでは、実際にパズルゲームを作ってみましょう。パズルゲームはアルゴリズムが複雑でコード量が多くなりますが、今回は比較的シンプルなスライドパズルを作ります。作るものは先程紹介した15パズルをよりシンプルにした8パズルです。

今回はJavaScriptのコード量が多いため、ファイルを分けて紹介します。まずはHTMLを用意します。以下のソースコードをコピーして以下のディレクトリに保存します。

<!DOCTYPE html>

<html>

    <head>

        <title>サンプルパズル</title>

        <meta charset="utf-8">

        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">]

        <link rel="stylesheet" href="layout.css">

        <script type="text/javascript" src="puzzle.js"></script>

    </head>

    <body>

        <center>

            <h1>8パズル</h1>

            <div id="puzzle">

                <button id="t0" class="btn btn-secondary tile" onclick="pushed(this.id)" > </button> <button id="t1" class="btn btn-secondary tile" onclick="pushed(this.id)" >1</button> <button id="t2" class="btn btn-secondary tile" onclick="pushed(this.id)" >2</button><br />

                <button id="t3" class="btn btn-secondary tile" onclick="pushed(this.id)" >3</button> <button id="t4" class="btn btn-secondary tile" onclick="pushed(this.id)" >4</button> <button id="t5" class="btn btn-secondary tile" onclick="pushed(this.id)" >5</button><br />

                <button id="t6" class="btn btn-secondary tile" onclick="pushed(this.id)" >6</button> <button id="t7"  class="btn btn-secondary tile" onclick="pushed(this.id)" >7</button> <button id="t8" class="btn btn-secondary tile" onclick="pushed(this.id)" >8</button>

            </div>

            <br>

            <button class="btn btn-primary" onclick="randomTaslar()">シャッフル</button>

        </center>

    </body>

</html>
続いてJavaScriptを用意します。以下のソースコードを先程用意したHTMLと同じフォルダに保存してください。ファイル名はpuzzle.jsとします。
let taslar = ["t0","t1","t2","t3","t4","t5","t6","t7","t8"]

function tasBul(val){

    for (i = 0; i < taslar.length; i++) { 

            if(document.getElementById(taslar[i]).firstChild.data == val){

                return(taslar[i])

            }

        }

}

function degisme(id, bosTasId){

    let yakinlar = []

    if([2,5,8].includes(parseInt(bosTasId[1]))){

        yakinlar = [+3,-3,-1]

    }else if([0,3,6].includes(parseInt(bosTasId[1]))){

        yakinlar = [+3,+1,-3]

    }else{

        yakinlar = [+3,+1,-3,-1]

    }

    for(i = 0; i < taslar.length; i++){

        if(parseInt(bosTasId[1])+parseInt(yakinlar[i]) == parseInt(id[1])){

            return(true);

        }

    }

    return(false)

}

function pushed(id){

    var btn = document.getElementById(id);

    if (btn.firstChild.data!=" "){

        bosTasId = tasBul(" ") 

        if(degisme(id, bosTasId) == false) return;

        document.getElementById(bosTasId).firstChild.data = btn.firstChild.data;

        btn.firstChild.data = " "

    }

}

function solvable(rndList){

    var count = 0;

    for(i=0;i<rndList.length-1;i++){

        if(rndList[i] == 0){

            continue;

        }

        for(j=i+1;j<rndList.length;j++){

            if(rndList[j] == 0){

                continue;

            }else if(rndList[i]>rndList[j]){

                count++;

            }

        }

    }

    

    if(count%2 == 0){

        return(true);

    }else{

        return(false);

    }

}

function randomTaslar(){

    var rndList = []

    while(true){

        rndList = []

        while(rndList.length < 9){

            var randomnumber = Math.ceil(Math.random()*9)-1

            if(rndList.indexOf(randomnumber) > -1) continue;

            rndList[rndList.length] = randomnumber;

        }

        if(solvable(rndList)){

            break;

        }

    }

    for (i = 0; i < taslar.length; i++) {

        if(rndList[i] == 0){

            val = " "

        }else{

            val = rndList[i].toString()

        }

        document.getElementById(taslar[i]).firstChild.data = val

    }

}
ここまででゲームは動きますが、パズルのパネルの見た目を整えるためにCSSを入れます。以下のソースコードをコピーして、HTMLと同じフォルダに保存します。ファイル名はlayout.cssとします。
.tile {

    width:100px; 

    height:100px;

    font-family:arial black;

    font-size: x-large;

  }
これでHTMLファイルをブラウザ上で立ち上げて、以下のようにゲーム画面が表示されたら問題ないです。画面にあるシャッフルボタンを押すとパネルがシャッフルされてゲームをできます。空白の隣りにある数字パネルをクリックすると空白の方向に数字パネルが動いて遊べるようになります。

 

監修してくれたメンター

メンター 三浦

モバイルゲームを運用している会社のエンジニアをしています。趣味でWEB開発やクラウドコンピューティングもやっており、ソフトもハードもなんでもやります。

TechAcademyジュニアではPythonロボティクスコースを担当しています。好きな言語はpython, Node.js

 

大石ゆかり

内容分かりやすくて良かったです!

田島悠介

ゆかりちゃんも分からないことがあったら質問してね!

大石ゆかり

分かりました。ありがとうございます!

TechAcademyでは初心者でも、オリジナルWebサイトを公開できる、オンラインブートキャンプを開催しています。

また、現役エンジニアから学べる無料体験も実施しているので、ぜひ参加してみてください。