「毎日Unity」の技術ブログ

開発で役立つ情報を発信する

オンラインブラウザゲームの作成方法(1)

今回の記事ではローカル環境で動作確認するまでのやり方を解説しています。

[ 環境構築 ]

Node.jsのインストール

下記にアクセスします。
nodejs.org
「Download Node.js (LTS)」をクリックして「Node.js」をダウンロードします。

ダウンロードが完了したらダウンロードフォルダ内にある「node-v20.12.1-x64.msi」を起動します。

「Next」をクリックします。

「I accept the terms in the License Agreement」にチェックを入れて「Next」をクリックします。

「Node.js」のインストール先を指定して「Next」をクリックします。

「Next」をクリックします。

「Next」をクリックします。

「Install」をクリックします。

下記のウィンドウが表示されたらインストール完了です。

コマンドプロンプトで「node -v」を実行して「Node.js」のバージョンが表示されれば「Node.js」はインストールされています。

Microsoft Windows [Version 10.0.19045.4170]
(c) Microsoft Corporation. All rights reserved.

C:\Users\EDunity>node -v
v20.12.1

C:\Users\EDunity>

Expressのインストール

コマンドプロンプトで「npm install express」を実行して「Express」をインストールします。

Microsoft Windows [Version 10.0.19045.4170]
(c) Microsoft Corporation. All rights reserved.

C:\Users\EDunity>npm install express

up to date, audited 97 packages in 1s

15 packages are looking for funding
  run `npm fund` for details

3 moderate severity vulnerabilities

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

C:\Users\EDunity>

コマンドプロンプトで「npm list express」を実行して「Express」のバージョンが表示されれば「Express」はインストールされています。

Microsoft Windows [Version 10.0.19045.4170]
(c) Microsoft Corporation. All rights reserved.

C:\Users\EDunity>npm list express
EDunity@ C:\Users\EDunity
`-- express@4.19.2


C:\Users\EDunity>

Socket.ioのインストール

コマンドプロンプトで「npm install socket.io」を実行して「Socket.io」をインストールします。

Microsoft Windows [Version 10.0.19045.4170]
(c) Microsoft Corporation. All rights reserved.

C:\Users\EDunity>npm install socket.io

added 23 packages, and audited 120 packages in 2s

15 packages are looking for funding
  run `npm fund` for details

3 moderate severity vulnerabilities

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

C:\Users\EDunity>

コマンドプロンプトで「npm list socket.io」を実行して「Socket.io」のバージョンが表示されれば「Socket.io」はインストールされています。

Microsoft Windows [Version 10.0.19045.4170]
(c) Microsoft Corporation. All rights reserved.

C:\Users\EDunity>npm list socket.io
EDunity@ C:\Users\EDunity
`-- socket.io@4.7.5


C:\Users\EDunity>

Webpackのインストール

コマンドプロンプトで次のコマンドを順番に実行します。
「cd desktop」「mkdir tmp」「cd tmp」「npm init -y」「npm install webpack webpack-cli --save-dev」
これらのコマンドはデスクトップに「tmp」フォルダを作成してその中に「Webpack」をインストールするコマンドです。

Microsoft Windows [Version 10.0.19045.4170]
(c) Microsoft Corporation. All rights reserved.

C:\Users\EDunity>cd desktop

C:\Users\EDunity\Desktop>mkdir tmp

C:\Users\EDunity\Desktop>cd tmp

C:\Users\EDunity\Desktop\tmp>npm init -y
Wrote to C:\Users\EDunity\Desktop\tmp\package.json:

{
  "name": "tmp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}



C:\Users\EDunity\Desktop\tmp>npm install webpack webpack-cli --save-dev

added 119 packages, and audited 120 packages in 7s

16 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

C:\Users\EDunity\Desktop\tmp>

この時点で「tmp」の中身は下記のようになっているはずです。

tmp
  ├ node_modules
  │  └ ...
  ├ package.json
  └ package-lock.json

「tmp」フォルダ内にある「package.json」ファイルの「"main"」と「"scripts"」を下記のように書き換えます。
「〇〇〇」の部分はそれぞれのバージョンにします。

{
  "name": "tmp",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": 
  {
    "start": "node server.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^〇〇〇",
    "webpack-cli": "^〇〇〇"
  }
}

雛形作成

「tmp」フォルダ内に「server.js」ファイルを作成して中身は下記のようにします。

const Express = require("express");
const Http = require("http");
const Path = require("path");
const SocketIO = require("socket.io");

const App = Express();
const Server = Http.Server(App);
const IO = SocketIO(Server);

class Player
{
    constructor(_ID, _Name, _PosX, _PosY)
    {
        this.ID = _ID;
        this.Name = _Name;
        this.Width = 64;
        this.Height = 64;
        this.PosX = _PosX;
        this.PosY = _PosY;
        this.Movement = {};
    }
};

const Port = process.env.PORT || 3000;
const FrameRate = 60;

const Players = {};

IO.on("connection", function(_Socket) 
{
    _Socket.on("Setup", function(_Name, _PosX, _PosY) 
    {
        if(_Name != null)
        {
            Players[_Socket.id] = new Player(_Socket.id, _Name, _PosX, _PosY);
        }
    });
    
    _Socket.on("Movement", function(_Movement) 
    {
        if(_Socket.id in Players)
        {
            Players[_Socket.id].Movement = _Movement;
        }
    });

    _Socket.on("disconnect", () =>
    {
        if(_Socket.id in Players)
        {
            delete Players[_Socket.id];
        }
    });
});

setInterval(function() 
{
    for(const i in Players) 
    {
        if(Players[i].Movement["w"])
        {
            Players[i].PosY -= 5;
        }
        if(Players[i].Movement["s"])
        {
            Players[i].PosY += 5;
        }
        if(Players[i].Movement["d"])
        {
            Players[i].PosX += 5;
        }
        if(Players[i].Movement["a"])
        {
            Players[i].PosX -= 5;
        }
    }

    IO.sockets.emit("Draw", Players);

}, 1000 / FrameRate);

App.use("/public", Express.static(__dirname + "/public"));

App.get("/", (_Request, _Response) => 
{
    _Response.sendFile(Path.join(__dirname, "/public/index.html"));
});

Server.listen(Port, function() 
{
    console.log("Starting Server on port " + Port + ".");
});

「tmp」フォルダの中に「public」フォルダを作成します。この時点で「tmp」の中身は下記のようになっているはずです。

tmp
 ├ node_modules
 │  └ ...
 ├ public
 ├ package-lock.json
 ├ package.json
 └ server.js

「public」フォルダ内に「index.html」ファイルを作成して中身は下記のようにします。

<html lang="ja">

<head>
    <title>tmp</title>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/p5@1.4.0/lib/p5.js"></script>
    <script type="text/javascript" src="/socket.io/socket.io.js"></script>
    <script type="text/javascript" src="/public/game.js"></script>
    <link type="text/css" rel="stylesheet" href="/public/style.css">
</head>

<body>
    <hr>
    <div class="Parent">
        <div id="Parent">
        </div>
    </div>
    <hr>
</body>

</html>

「public」フォルダ内に「style.css」ファイルを作成し、中身は下記のようにします。

.Parent
{
    display:block;
    text-align:center;
}

「public」フォルダ内に「game.js」ファイルを作成して中身は下記のようにします。

const Socket = io();

let Canvas_Sketch;
const Width_Sketch = 600;
const Height_Sketch = 600;  

const Keys = ["w", "s", "d", "a"];
const Movement = {};

function setup() 
{
    Canvas_Sketch = createCanvas(Width_Sketch, Height_Sketch);
    Canvas_Sketch.parent("Parent");

    background(225);

    Socket.on("connect", function()
    {
        Socket.emit("Setup", prompt("Please enter your name."), Math.random() * Width_Sketch, Math.random() * Height_Sketch);
    });
}
function draw(){
}
function keyPressed() {
    if(Keys.includes(key))
    {
        Movement[key] = true;

        Socket.emit("Movement", Movement);
    }
}
function keyReleased() {
    if(Keys.includes(key))
    {
        Movement[key] = false;

        Socket.emit("Movement", Movement);
    }
}

Socket.on("Draw", function(_Players)
{
    background(225);

    for(const i in _Players) 
    {
        text(_Players[i].Name + "#" + _Players[i].ID, _Players[i].PosX + 15, _Players[i].PosY - 15);
        ellipse(_Players[i].PosX, _Players[i].PosY, 30, 30);
    }
});

この時点で「tmp」の中身は下記のようになっているはずです。

tmp
 ├ node_modules
 │  └ ...
 ├ public
 │  ├ index.html
 │  ├ style.css
 │  └ game.js
 ├ package.json
 ├ package-lock.json
 └ server.js

[ 動作確認 ]

コマンドプロンプトで「node desktop/tmp/server.js」を実行してサーバーを起動します。

Microsoft Windows [Version 10.0.19045.4170]
(c) Microsoft Corporation. All rights reserved.

C:\Users\EDunity>cd desktop

C:\Users\EDunity\Desktop>cd tmp

C:\Users\EDunity\Desktop\tmp>node server.js
Starting Server on port 3000.

下記にアクセスします。
http://localhost:3000/
アクセスすると白い円が表示されるはずです。WASDで白い円は操作できます。

[ 参考文献 ]

paiza.hatenablog.com