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
所以我在 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