At the end of the working day on Friday, while thinking about the current task, the thought suddenly appeared in the fevered brain - would you try to write my game server?
In my thoughts we skipped pictures one more beautiful than the other, the mechanics of the future game, special effects were invented. In my head, the game was almost ready, nothing was left to prepare a concept, to begin work on a design document, to find artists, scriptwriters, sound engineers, programmers ... With a sigh, he sighed again and sent the idea to the dump.
But apparently, the thorn firmly stuck in my head, so when I woke up on Saturday, I began to create.
')
Firstly, I had to choose the technologies with which to implement my plans. Having said decisively, there is no experience that I used to say that I need to use technologies familiar to me, such as java.nio for the server and cocos2d for the client, the following technology stack was chosen: javascript + node.js + socket.io + html canvas.
Considering that all these technologies are a wonder for me, the pessimist in me thought, okay, play around a bit, it will not work out quickly anyway.
To begin with, it was necessary to install node.js, on a poppy this was resolved quite simply using ports:
sudo port install nodejs
sudo port install npm
npm install socket.io
On this preparations were completed.
Having briskly started the work, quickly got stuck for some time in the syntax of javascript, but in the end sketched the backbone of the application. And what is most surprising, it worked!
Here is the code:
SERVER
var io = require('socket.io').listen(80); io.sockets.on('connection', function (socket) { socket.on('message', function () { }); socket.on('disconnect', function () { }); });
CLIENT
<script> var socket = io.connect('http://localhost/'); socket.on('connect', function () { socket.send('hi'); socket.on('message', function (msg) {
Which I shamelessly took from here
socket.io/#how-to-useHowever, the code quickly changed:
CLIENT
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);
SERVER
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);
The deme provides for the management of one of the actors (greenbacks), when you click to a certain place on the canvas, the actor teleports there and changes its direction and speed to random ones.
Game cycle implemented in the class Game, behavior in the class Actor. All logic is calculated on the server and sends the coordinates to the client who draws the circles (of our actors) in the required coordinates. The construction of a reliable physical model was not the goal of this experiment, so I just realized the “rebound” of the balls from the walls. In general, everything turned out pretty simple, the code on the server was surprised to understand that everything was working and unexpectedly smoothly.
At first I wanted to make the common Base classes Game and Actor for the server and the client, but I decided not to fool myself and people and wrote the code twice for the client and the server.
As a result, I got acquainted with technologies unfamiliar to me until now, I felt fully that all the same technologies are not standing still and that the node.js platform in particular deserves attention in order to take a closer look at it more closely.
Stress testing is not conducted, so I can not say anything about performance. Subjective sensations should be “not very”, but I can’t confirm yet.
For those who want to try, here is a
link (not the fastest virtual machine is used as a server, so anything can happen).
If someone has a desire to get acquainted with the source code, please
come here .