2011-06-05 239 views
17

我嘗試用HTML5 Canvas,JavaScript(也使用John Resig簡單繼承庫)和Node.js與Socket.IO創建簡單多人遊戲。 我的客戶端代碼:多人遊戲HTML5,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(){ 

    }) 

}); 

當我運行兩個客戶端與第一個客戶,我可以移動第二個客戶端矩形,並與第二客戶端移動第一客戶端正確,而且喜歡的東西第三個客戶可以移動第一個和第二個客戶矩形。

我有問題如何創建真正的多人?如: 打開三個客戶端和第一個客戶端獲得rect1,第二個rect2和最後一個rect3。第一個客戶端只能移動rect1,第三個客戶端只能移動rect3。

也許任何人有想法?我在谷歌搜索,但沒有找到答案。

對不起,我的英文。

回答

14

,先看看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

+1

超級瀏覽器2 turbo高清再混合介紹HTML5遊戲開發真棒! 感謝您的回答!我嘗試了你的模式化的客戶端/服務器代碼,但對我來說不行。 但謝謝你幫我理解多人遊戲! – rhavd 2011-06-07 14:42:07

+1

我沒有測試我的修改後的代碼,所以可能存在一些錯誤,但是您明白了這個問題^ _^ – generalhenry 2011-06-07 15:35:32

+1

所有鏈接目前都已經不在此答案中。 – 2015-03-25 03:31:51

0

如果有人像我剛纔那樣絆倒了這個問題,我想添加this link as an example

我幾個月前就跟隨op一樣的路徑,閱讀了關於權威服務器模型(包括@Epeli答案中引用的一篇文章)的每篇文章,以及如何使用nodejs/socketio 。

我的研究結果表明自己在上面提供的鏈接(也有一個現場演示)的github項目中。希望這可以幫助某人。

0

現在有一個開源的多人實時JavaScript的服務器(和客戶端庫)稱爲Lance.gg,它提供了,就像你說的, 一個真正的多人遊戲體驗

它處理客戶端預測,一步漂移,彎曲和基本物理學。

聲明:我是撰稿人之一