three.js socket.io多人系统

three.js socket.io multiplayer system

所以我在 three.js 中构建了一个简单的场景,玩起来真的很酷,但我想从 socket.io 服务器添加一些多人游戏功能 运行 所以我添加这样的玩家

var username = prompt("whats yo name")

然后我在加载所有模型后执行此操作

socket.emit('addPlayer', username)

然后在我的服务器端发生这种情况

socket.on('addPlayer', function(username) {
    players.push(username)
    console.log(username + " joined")
    console.log("online Users " + players)
    socket.broadcast.emit('syncPlayers', players)
    socket.emit('syncPlayers', players)
})

所有这些都完全符合我的计划

所以当在所有客户端上调用 syncPlayers

socket.on('syncPlayers', function(players) {
    players.forEach(function(value) {
        if (value == username) {
            console.log("not adding " + value + " thats you ")
        } else {
            console.log("player Online " + value);
            newplayer = value;

            addPlayer(newplayer)
        }
    });
})

然后当然调用 addPlayer 传递 var new player

function addPlayer() {
    console.log("adding " + newplayer)
    charObjectName = newplayer + "Char"
    console.log("added" + charObjectName)
    charObjectName = new THREE.Mesh(
        new THREE.BoxGeometry(3, 3, 3),
        new THREE.MeshPhongMaterial({
            color: 0xffffff,
            map: crateTexture,
            bumpMap: crateBumpMap,
            normalMap: crateNormalMap
        })

    );
    scene.add(charObjectName)
    charObjectName.position.set(10, 10, 10)
}

现在我让每个新玩家都成为一个立方体,因为当我尝试加载一个已加载的模型时它一直说未定义或其他什么,但那是另一次

但我认为我的问题可能出在这一行

charObjectName = newplayer + "Char"

可能它没有设置正确,所以我在控制台记录了它,这是我预期的值

但是当我尝试将玩家立方体的位置更新到这样的位置时

    if (keyboard[87]) { // W key
        camera.position.x -= Math.sin(camera.rotation.y) * player.speed;
        camera.position.z -= -Math.cos(camera.rotation.y) * player.speed;
        socket.emit('updateXZPos', username, camera.position.x, camera.position.z)
    }
    if (keyboard[83]) { // S key
        camera.position.x += Math.sin(camera.rotation.y) * player.speed;
        camera.position.z += -Math.cos(camera.rotation.y) * player.speed;
        socket.emit('updateXZPos', username, camera.position.x, camera.position.z)
    }
    if (keyboard[65]) { // A key
        camera.position.x += Math.sin(camera.rotation.y + Math.PI / 2) * player.speed;
        camera.position.z += -Math.cos(camera.rotation.y + Math.PI / 2) * player.speed;
        socket.emit('updateXZPos', username, camera.position.x, camera.position.z)
    }
    if (keyboard[68]) { // D key
        camera.position.x += Math.sin(camera.rotation.y - Math.PI / 2) * player.speed;
        camera.position.z += -Math.cos(camera.rotation.y - Math.PI / 2) * player.speed;
        socket.emit('updateXZPos', username, camera.position.x, camera.position.z)
    }

这就是它在服务器端所做的事情

socket.on('updateXZPos', function(username, pos1, pos2) {

    console.log(username + ' x-' + pos1 + '-   y-' + pos2)
    socket.broadcast.emit('updateZPos', username, pos1, pos2)
})

我让控制台完美记录事情

然后在客户端调用 updateZPos 函数时

socket.on('updateZPos', function(username, pos1, pos2) {
    console.log(pos1 + pos2)
    toMove = username + "Char"
    console.log(toMove)
    toMove.position.x = pos2, toMove.position.z = pos2
})

显然我无法将 x 属性 设置为未定义,所以 var toMove 可能不正确?

抱歉,如果这是一个很长的问题,但它确实困扰着我

创建 THREEJS 框时,您这样做:

charObjectName = newplayer + "Char"
charObjectName = new THREE.Mesh(...);

这实际上意味着“将字符串放入变量 charObjectName,然后用对三网格的引用覆盖该字符串。”

然后您尝试使用

检索相同的对象
toMove = username + "Char"
toMove.position.x = pos2, toMove.position.z = pos2

意思是“将一个字符串放入变量toMove,然后尝试在对象position中更新toMove对象中的属性x

但是如您所见,toMove 包含一个字符串而不是对三网格的引用。

您可能想尝试将所有相关引用保存在一个对象中。像这样:

var threeObjects = {};

// setting
function addPlayer(playerName) {
    var charObjectName = playerName + "Char"
    var threeObject = new THREE.Mesh(
        new THREE.BoxGeometry(3, 3, 3),
        new THREE.MeshPhongMaterial({
            color: 0xffffff,
            map: crateTexture,
            bumpMap: crateBumpMap,
            normalMap: crateNormalMap
        })

    );
    scene.add(threeObject)
    threeObject.position.set(10, 10, 10)
    // set reference
    threeObjects[charObjectName] =  threeObject;
}

// retrieving
socket.on('updateZPos', function(username, pos1, pos2) {
    toMove = threeObjects[username + "Char"]
    toMove.position.x = pos1;
    toMove.position.z = pos2;
})

多人游戏,尤其是网络上的多人游戏是一个非常微妙的话题。如果您有兴趣阅读更多相关信息,可以在这个开源库中找到一个很好的资源 - lance