Node.js + Socket.ioで1日でゲームサーバー

金曜日の作業日の終わりに、現在のタスクを熟考して、思考が頭の痛いところに突然現れました-私は自分のゲームサーバーを書こうとするべきですか?



私の考えでは、写真は他のものよりも美しい写真をスキップしました。未来のゲームの仕組み、特殊効果が発明されました。 ゲームは頭の中でほとんど準備ができていて、何もする必要がありませんでした。コンセプトを準備し、デザインドキュメントの作業を開始し、アーティスト、脚本家、サウンドエンジニア、プログラマーを見つけました。



しかし、どうやら、とげは頭にしっかりと刺さっていたので、土曜日に目が覚めたとき、私は創造し始めました。



まず、計画を実施するためのテクノロジーを選択する必要がありました。 サーバーにはjava.nio、クライアントにはcocos2dなど、私にとって馴染みのあるテクノロジーを使用する必要があると断言した経験はないので、次のテクノロジースタックが選択されました:javascript + node.js + socket.io + html canvas。



これらのテクノロジーはすべて私にとって好奇心であると考えると、私の悲観主義者は、少しでも同じようにプレイしても、すぐにはうまくいかないと思いました。



まず第一に、node.jsをインストールする必要がありました。ポピーでは、ポートを使用して簡単に解決できました。

sudo port install nodejs

sudo port install npm

npm install socket.io



これで準備が完了しました。



元気に作業を始めて、私はすぐにJavaScriptシンタックスにすぐに行き詰まりましたが、最終的にはアプリケーションのバックボーンをスケッチしました。 そして、最も驚くべきことに、うまくいきました!



コードは次のとおりです。



サーバー

var io = require('socket.io').listen(80); io.sockets.on('connection', function (socket) { socket.on('message', function () { }); socket.on('disconnect', function () { }); });
      
      





クライアント

 <script> var socket = io.connect('http://localhost/'); socket.on('connect', function () { socket.send('hi'); socket.on('message', function (msg) { // my msg }); }); </script>
      
      







socket.io/#how-to-useから私はここから恥知らずに取った



ただし、コードはすぐに変更されました。



クライアント

 var URL = 'http://localhost:9090'; var Network = function(url) { this.url = url; this.pingTime = 0; this.actorId = 0; this.sendingPing = false; } Network.prototype.ping = function() { if(this.sendingPing) { return; } this.sendingPing = true; this.startDate = new Date(); this.socket.send("hi"); } Network.prototype.start = function(game) { var socket = io.connect(this.url); this.socket = socket; socket.on('connect', function () { socket.on('message', function () { var now = new Date(); network.pingTime = (now.getTime()-network.startDate.getTime()); network.sendingPing = false; }); socket.on('actorId', function (id) { network.actorId = id; }); socket.on('gameInfo', function (msg) { game.networkUpdate(msg); }); network.ping(); game.active = true; }); socket.on('disconnect', function () { network.start(game); }); } Network.prototype.update = function() { this.ping(); } Network.prototype.sendInput = function(pos) { this.socket.emit('input', pos); } var network = new Network(URL); network.start(game);
      
      







サーバー

 var io = require('socket.io').listen(9090); var clients = []; io.sockets.on('connection', function (socket) { var client = new Client(socket); clients.push(client); game.active = clients.length != 0; socket.on('message', function (msg) { client.onMessage(msg); }); socket.on('input', function (pos) { client.onInput(pos); }); socket.on('disconnect', function () { var index = clients.indexOf(client); if(index != -1) { clients.splice(index); } game.active = clients.length != 0; client.onDisconnect(); }); }); console.log("Server started.."); setInterval(function() { if(!game.active) { return; } game.update(TICK_TIME); var gameInfo = game.gameInfo(); for(var i=0;i<clients.length;i++) { var client = clients[i]; client.update(gameInfo); } }, TICK_TIME);
      
      







デムは、キャンバスの特定の場所(緑)をクリックすると、俳優がテレポートし、方向と速度をランダムに変更します。



Gameクラスに実装されたゲームループ、Actorクラスの動作。 すべてのロジックはサーバー上で計算され、座標をクライアントに渡します。クライアントは、目的の座標に(俳優の)円を描きます。 信頼性の高い物理モデルの構築はこの実験の目的ではなかったため、壁からのボールの「リバウンド」を実感しました。 一般に、すべてが非常に単純であることが判明し、サーバーにコードを驚くほどアップロードすると、すべてが正常に機能し、予期せずスムーズに動作することがわかりました。



最初は、サーバーとクライアントに共通のゲームとアクターの基本クラスを作成したかったのですが、自分と人をだますことはせず、クライアントとサーバーに2回コードを書きました。



その結果、今まで馴染みのないテクノロジーに出会い、まったく同じテクノロジーが静止しているわけではなく、特にnode.jsプラットフォームに注目する価値があると十分に感じました。



私はストレステストを実施しなかったため、パフォーマンスについては何も言えません。 主観的な感情によると、それは「それほどではない」はずですが、まだ確認できません。



試してみたい人のために、ここにリンクがあります (最速の仮想マシンがサーバーとして使用されるわけではないため、何でも可能です)。

誰かがソースコードを知りたいという願望を持っているなら、 ここに来てください



All Articles