如何在html 5多人游戏中使用socket.io移动对象

时间:2014-10-02 10:43:08

标签: node.js socket.io

我试图使用Quintus HTML5游戏引擎和node.js和socket.io来构建一个多人纸牌游戏,直到现在我已经创建了mainLevel场景并将一些卡片对象插入到这个场景中,卡片可以通过mose触摸并拖动玩家放开它去卡片中心的卡片并制作这个游戏多人游戏我使用socket.io来做到这一点,但我有点丢失没有任何文档或资源如何建立游戏与套接字。 io但是我现在用套接字做了什么,当新客户进入游戏的索引页面时,他自动连接到名为Lobby的房间,当卡片播放(移动)时,这个房间里的所有其他玩家都知道卡片正在移动但我不能实际上弄清楚如何移动一个玩家在另一个玩家场景中玩过的牌。

所以我现在所做的是:

server.js:

    var express = require('express'),
    app = express(),
    server = require('http').createServer(app),
    io = require('socket.io').listen(server);

//_______________________________________________

app.get('/',function(req,res) {
    res.sendfile(__dirname + '/index.html');
});

app.use(express.static(__dirname + '/static'));

//_______________________________________________

var port = process.env.PORT || 3000;

server.listen(port);
console.log('Listening on port ' + port + '...');
//_______________________________________________

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

    console.log('a user connected\n');//log test

//on socket connection serever add user to lobby room   
 socket.on('adduser', function() {
        socket.room = 'Lobby';//set the socket.room to Lobby room when first connect by Defults
        socket.join('Lobby');//let the client sockt join the Lobby room by Defult when firts connect to server 
    });

socket.on('tellothers', function(data) {
        socket.broadcast.to(socket.room).emit('cardmove', data);
    });
});

game.js:

var Q = window.Q = Quintus().include("Sprites, Scenes, Input, Touch");
Q.setup("myGame").touch(Q.SPRITE_ALL);

var socket = io.connect('http://localhost:3000');

socket.on('connect',function(){
  console.log('user connect');
});

socket.emit('adduser');

socket.on('cardmove',function(data){
   console.log('Card Name : '+ data.cardName + ' x :' + data.x + ' y : ' + data.y);
});

//Define Card object
Q.Sprite.extend("Card", {

    init: function (p) {

        this._super(p)

        this.on("drag");
        this.on("touchEnd");

    },

    drag: function (touch) {    

        this.p.dragging = true;
        this.p.x = touch.origX + touch.dx;
        this.p.y = touch.origY + touch.dy;

    },

    touchEnd: function (touch) {

        // put a line on the screen if the card pass it put the card in the new position if not put the card in the orginal(old) postion 
        if (touch.origY + touch.dy > touch.origY - ((10/100)*Q.el.height)) { //define the line that the card should pass if the amount of draged > the screen line in Q.el.height - 200

            // put the card in the same old postion if is not pass the line
            this.p.x = touch.origX;
            this.p.y = touch.origY;

        } else {
            // put the card if it pass the line in the new postion  
            this.p.x = ((50/100)*Q.el.width);
            this.p.y = Q.el.height - ((50/100)*Q.el.height);
            //end the drag and touch after one time the object has been draged 

            touch.obj.off('drag'); 
            touch.obj.off('touchEnd');

            socket.emit('tellothers',{cardName: this.p.name ,x: this.p.x , y: this.p.y});
        }
    },
});

//___________________________________________________________________

//drwa objects in canvace
Q.scene("mainLevel", function(stage){
    Q.gravity = 0;
    stage.insert(new Q.Sprite({ asset: "Card_Table.png", x:Q.el.width / 2, y: Q.el.height / 2, type: Q.SPRITE_NON }));

  stage.insert(new Q.Card({name:'Card_1',asset: "Queen_OF_Hearts.png", scale: 0.60, x: Q.el.width / 2, y: Q.el.height - ((15/100)*Q.el.height) }));

  stage.insert(new Q.Card({name:'Card_2',asset:'Queen_OF_Hearts.png', scale: 0.50, x: ((20/100)*Q.el.width), y: Q.el.height - ((50/100)*Q.el.height)}));

  stage.insert(new Q.Card({name:'Card_3',asset:'Queen_OF_Hearts.png', scale: 0.80, x: ((80/100)*Q.el.width), y: Q.el.height - ((50/100)*Q.el.height)}));

  stage.insert(new Q.Card({name:'Card_4',asset:'Queen_OF_Hearts.png', x: ((50/100)*Q.el.width), y: Q.el.height - ((80/100)*Q.el.height)}));

});

 //___________________________________________________________________

Q.debug = true;
Q.debugFill = true;

//load assets
Q.load(["Card_Table.png","Queen_OF_Hearts.png"], function(){
    Q.stageScene("mainLevel");
});

 //___________________________________________________________________

var currentObj = null;

     Q.el.addEventListener('mousemove',function(e) {
        var x = e.offsetX || e.layerX,
            y = e.offsetY || e.layerY,
            stage = Q.stage();

        var stageX = Q.canvasToStageX(x, stage),
            stageY = Q.canvasToStageY(y, stage);

        var obj = stage.locate(stageX,stageY);

        if(currentObj) { currentObj.p.over = false; }
            if(obj) {
              currentObj = obj;
              obj.p.over = true;
            }
  });

index.html

<!DOCTYPE html>

<html>

<head>
    <title>Card Game</title>
    <link rel="stylesheet" type="text/css" href="bootstrap-3.2.0-dist/css/bootstrap.min.css">
</head>

<body>  
    <canvas id='myGame' width= "640" height="603" class="img-responsive"></canvas>
    <script src="/JS/jquery-2.1.1.min.js" type="text/javascript"></script>
    <script src="/JS/socket.io.js" type="text/javascript"></script>
    <script src="/JS/quintus-all.min.js" type="text/javascript"></script>

    <script src="/JS/Game.js" type="text/javascript"></script> 
</body>

</html>

所以请任何关于如何使一个玩家玩的牌在游戏中的其他玩家中移动的任何帮助。

更新

link to download source code

1 个答案:

答案 0 :(得分:1)

我成功地在游戏中的所有连接用户中移动了相同的对象,所以我做了什么

第一:
我默认将对象数组var cards = [];添加为空,以便以后用于将所有卡放入(推入)并更新移动的对象。

第二:
我改变了
socket.emit('tellothers',{cardName: this.p.name ,x: this.p.x , y: this.p.y});

socket.emit('tellothers',{cardName:this.p.name, cardAsset:this.p.asset, cardScale:this.p.scale, cardX:this.p.x, cardY:this.p.y});
我传递了移动卡的所有参数供以后使用,以便让其他客户知道移动的卡是什么。

第三:
然后在插入卡后的mainLevel场景中,我已将所有卡推送到var cards = [];

cards.push({name:'Card_1',asset: "Queen_OF_Hearts.png", scale: 0.60, x: Q.el.width / 2, y: Q.el.height - ((15/100)*Q.el.height) });
cards.push({name:'Card_2',asset:'Queen_OF_Hearts.png', scale: 0.50, x: ((20/100)*Q.el.width), y: Q.el.height - ((50/100)*Q.el.height)});
cards.push({name:'Card_3',asset:'Queen_OF_Hearts.png', scale: 0.80, x: ((80/100)*Q.el.width), y: Q.el.height - ((50/100)*Q.el.height)});
cards.push({name:'Card_4',asset:'Queen_OF_Hearts.png', scale:0.00 ,x: ((50/100)*Q.el.width), y: Q.el.height - ((80/100)*Q.el.height)});

第四:
我已经创建了新的updateLevel场景,以便以后用于更新所有客户端的场景,使用已在所有客户端中移动的卡,甚至是移动卡的客户端场景。

Q.scene("updateLevel", function(stage){
  Q.gravity = 0;

  stage.insert(new Q.Sprite({ asset: "Card_Table.png", x:Q.el.width / 2, y: Q.el.height / 2, type: Q.SPRITE_NON }));

  for(sub in cards){
    stage.insert(new Q.Card({name:cards[sub].name, asset:cards[sub].asset, scale:cards[sub].scale, x:cards[sub].x, y:cards[sub].y}));
  }

});

第五: 我创建了一些功能,可以在场景更新时调用他

var UpdateCards = function(){
    Q.clearStages();
    Q.stageScene('updateLevel');
}

然后: 何时cardmove

  socket.on('cardmove',function(data){

     data.cardX = ((50/100)*Q.el.width);
     data.cardY = Q.el.height - ((50/100)*Q.el.height);

  cards = cards.filter(function(obj) {
    return obj.name !== data.cardName;
});

  cards.push({name:data.cardName, asset:data.cardAsset, scale:data.cardScale, x:data.cardX, y:data.cardY});

  UpdateCards();
});

并在服务器端: 我改变了

socket.on('tellothers', function(data) {
        socket.broadcast.to(socket.room).emit('cardmove', data);
    });


socket.on('tellothers', function(data) {
        io.sockets["in"](socket.room).emit('cardmove', data);
    }); 

我更新问题并将新的源代码和链接下载,如果你想试试它:D。