You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js与PHP多人游戏中立方体定位异常问题求助

问题分析与修复建议

核心问题定位

红立方体位置被绿立方体覆盖的本质是位置更新/读取逻辑出现了字段混淆——要么是PHP后端错误地将红玩家的位置写入了绿玩家的数据库字段,要么是客户端错误地将绿玩家的位置赋值给了红立方体,或是身份判断逻辑导致更新分支错误。

具体排查步骤

1. 验证PHP后端的更新分支与参数绑定

  • 检查身份判断逻辑:在game.php中添加日志,打印每次请求的$_SESSION['username']和$_POST['player']值,确认红玩家操作时是否进入了正确的else分支(更新player2的位置字段):

    // 加入日志,查看服务器错误日志(如Apache的error.log)
    error_log("Session User: " . $_SESSION['username'] . ", POST Player: " . $_POST['player']);
    
    if ($_SESSION['username'] == $_POST['player']) { 
      error_log("Updating Player1 position");
      $query = "UPDATE fight SET player1_position_x=?, player1_position_y=?, player1_position_z=? WHERE id=?"; 
    } 
    else { 
      error_log("Updating Player2 position");
      $query = "UPDATE fight SET player2_position_x=?, player2_position_y=?, player2_position_z=? WHERE id=?"; 
    }
    

    如果红玩家操作时日志显示Updating Player1 position,说明身份判断逻辑错误,导致更新了绿玩家的字段。

  • 检查参数绑定的正确性:确认分支对应的位置参数是否正确绑定,避免无论哪个分支都复用同一组变量的错误:

    // 正确示例:绑定当前请求的位置参数(从POST获取)
    $x = $_POST['x'];
    $y = $_POST['y'];
    $z = $_POST['z'];
    $stmt->bind_param("dddi", $x, $y, $z, $fight_id);
    

2. 排查客户端AJAX请求参数

在浏览器Network面板查看红玩家移动时发送的POST请求,确认:

  • player参数是红玩家的用户名,而非绿玩家的
  • x/y/z参数是红立方体的当前位置,不是绿立方体的
  • fight_id参数与当前战斗ID一致,没有串号

3. 验证客户端位置读取逻辑

检查拉取位置的代码,确认红立方体读取的是player2_position_*字段,绿立方体读取player1_position_*字段,不要搞混:

// 正确示例
greenCube.position.set(data.player1_position_x, data.player1_position_y, data.player1_position_z);
redCube.position.set(data.player2_position_x, data.player2_position_y, data.player2_position_z);

4. 确认Session隔离性

测试时使用不同浏览器/隐私窗口登录不同玩家账号,避免Session共享导致身份判断混乱(比如两个浏览器用了同一个登录Session,后端误判都是绿玩家)。

修复方案

1. 优化后端身份判断逻辑(推荐)

不要依赖$_POST['player']参数判断更新字段,直接从数据库获取当前战斗的玩家分配关系,确保每个用户只能更新自己对应的位置字段:

$fight_id = $_GET['fight_id'];
// 先获取当前战斗的玩家信息
$stmt = $conn->prepare("SELECT player1_username, player2_username FROM fight WHERE id=?");
$stmt->bind_param("i", $fight_id);
$stmt->execute();
$result = $stmt->get_result();
$fight = $result->fetch_assoc();

// 根据Session用户判断更新哪个字段
$current_user = $_SESSION['username'];
if ($current_user == $fight['player1_username']) {
    $query = "UPDATE fight SET player1_position_x=?, player1_position_y=?, player1_position_z=? WHERE id=?";
} elseif ($current_user == $fight['player2_username']) {
    $query = "UPDATE fight SET player2_position_x=?, player2_position_y=?, player2_position_z=? WHERE id=?";
} else {
    http_response_code(403);
    exit("Unauthorized access");
}

// 绑定参数并执行
$x = $_POST['x'];
$y = $_POST['y'];
$z = $_POST['z'];
$stmt = $conn->prepare($query);
$stmt->bind_param("dddi", $x, $y, $z, $fight_id);
$stmt->execute();

2. 客户端增加参数校验

发送AJAX请求时,强制player参数为当前登录用户的用户名,避免参数错误:

function updateCubePosition(x, y, z) {
  // 假设当前登录用户名存在全局变量currentUser中
  const player = currentUser;
  const xhr = new XMLHttpRequest();
  xhr.open('POST', `game.php?fight_id=<?php echo $fightId; ?>`, true);
  xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhr.send(`player=${encodeURIComponent(player)}&x=${x}&y=${y}&z=${z}`);
}

3. 增加数据库字段约束

在fight表中确保player1_username和player2_username不为空,且唯一对应每个战斗,避免身份判断时出现歧义。

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 15:11:00