Многопользовательский HTML5, Node.js, Socket.IO

Я пытался создать простой мультиплеер с HTML5 Canvas, JavaScript(тоже с использованием простой библиотеки наследования Джона Резига) и Node.js с Socket.IO. Мой код клиента:

var canvas  = document.getElementById('game');
var context = canvas.getContext('2d');
var socket  = new io.Socket('127.0.0.1', {port: 8080});

var player = null;

var UP    = 'UP',
    LEFT  = 'LEFT',
    DOWN  = 'DOWN',
    RIGHT = 'RIGHT';

socket.connect();

socket.on('connect', function() {socket.send();
    console.log('Connected!');
    player = new Player(50, 50);
});

socket.on('message', function(msg) {
    if(msg == 'UP') {
        player.moveUP();
    } else if(msg == 'LEFT') {
        player.moveLEFT();
    } else if(msg == 'DOWN') {
        player.moveDOWN();
    } else if(msg == 'RIGHT') {
        player.moveRIGHT();
    } else {

    }
});

socket.on('disconnect', function() {
    console.log('Disconnected!');
});

var Player = Class.extend({
    init : function(x, y) {
        this.x = x;
        this.y = y;
    },
    setX : function(x){
        this.x = x;
    },
    getX : function(){
        return this.x;
    },
    setY : function(y){
        this.y = y;
    },
    getY : function(){
        return this.y;
    },
    draw : function(){
        context.clearRect(0, 0, 350, 150);
        context.fillRect(this.x, this.y, 15, 15);
    },
    move : function() {
        this.x += 1;
        this.y += 1;
    },
    moveUP : function() {
        this.y--;
    },
    moveLEFT : function() {
        this.x--;
    },
    moveDOWN : function() {
        this.y++;
    },
    moveRIGHT : function() {
        this.x++;
    }
});

function checkKeyCode(event) {
    var keyCode;
    if(event == null) {
        keyCode = window.event.keyCode;
    } else {
        keyCode = event.keyCode;
    }

    switch(keyCode) {
        case 38: // UP
            player.moveUP();
            socket.send(UP);
        break;
        case 37: // LEFT
            player.moveLEFT();
            socket.send(LEFT);
        break;
        case 40: //DOWN
            player.moveDOWN();
            socket.send(DOWN);
        break;
        case 39: // RIGHT
            player.moveRIGHT();
            socket.send(RIGHT);
        break;
        default:
        break;

    }

}

function update() {
    player.draw();
}

var FPS = 30;
setInterval(function() {
    update();
    player.draw();
}, 1000/FPS);

function init() {
    document.onkeydown = checkKeyCode;
}

init();

И код сервера:

var http = require('http'),
io = require('socket.io'),
buffer = new Array(),

server = http.createServer(function(req, res){
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.end('<h1>Hello world</h1>');
});
server.listen(8080);

var socket = io.listen(server);

socket.on('connection', function(client){

    client.on('message', function(message){
        console.log(message);
        client.broadcast(message);
    })
    client.on('disconnect', function(){

    })

});

И когда я запускаю два клиента, я с первым клиентом могу переместить второй клиент Rect, а со вторым клиентом переместить первый клиент прямоугольник, и что-то подобное с третьим клиентом может переместить первый и второй клиент прямоугольник.

У меня есть вопрос, как создать настоящий Multi-Player? что-то вроде: Откройте три клиента, и первый клиент получит rect1, второй rect2 и последний rect3. Первый клиент может перемещать только rect1, третий клиент может перемещать только rect3.

Может у кого есть идеи? Я ищу в Google, но не могу найти ответ.

Извините за мой английский язык.

4 ответа

Решение

Сначала ознакомьтесь с http://www.google.com/events/io/2011/sessions/super-browser-2-turbo-hd-remix-introduction-to-html5-game-development.html

это объясняет, как использовать requestAnimationFrame среди прочего.

Во-вторых, игровое состояние должно существовать на сервере и отражаться на клиентах.

Когда игрок нажимает вниз, клиент должен только отправить сообщение. Затем сервер должен отправить сообщение всем клиентам, включая клиента, который предпринял действие.

Каждый игрок должен существовать как объект на сервере. Когда игрок входит в систему, он должен быть в курсе статуса каждого игрока, уже находящегося на сервере.

модифицированный код клиента: http://codr.cc/s/d0154536/js

модифицированный код сервера: http://codr.cc/s/f96ce1d2/js

Статья Гленна Фидлера (Glenn Fiedler). Что нужно знать каждому программисту об игровой сети - статья полезна для всех, кто хочет войти в игровую сеть. Он объясняет основы на очень высоком уровне, поэтому его можно адаптировать для JS и Socket.io.

В настоящее время существует многопользовательский javascript-сервер с открытым исходным кодом (и клиентская библиотека) под названием Lance.gg, который обеспечивает, как вы говорите,настоящий многопользовательский опыт.

Он обрабатывает предсказания на стороне клиента, смещение шага, изгиб и базовую физику.

Отказ от ответственности: я один из участников

В случае, если кто-нибудь наткнется на этот вопрос, как я только что, я хотел бы добавить эту ссылку в качестве примера.

Несколько месяцев назад я следовал по тому же пути, что и операционная система, и прочитал каждую статью, которую смог найти в модели авторитетного сервера (включая ту, на которую ссылается @Epeli), и как ее реализовать с помощью nodejs/socketio.

Результат моего исследования проявился в проекте github, расположенном по ссылке, указанной выше (также есть живая демонстрация). Надеюсь, это кому-нибудь поможет.

Другие вопросы по тегам