如何在p5.js WEBGL中实现相机围绕目标点旋转?
解决p5.js WEBGL中第三人称相机围绕目标旋转的问题
要实现相机围绕玩家(立方体)旋转,核心是通过极坐标转换计算相机位置,而非直接旋转玩家模型。以下是修正后的完整方案:
关键调整点
- 添加相机旋转角度与距离变量,控制相机的相对位置
- 使用鼠标拖动事件控制旋转,限制垂直旋转范围避免异常视角
- 基于相机视角调整玩家移动方向(不再沿世界坐标轴移动)
- 修复重力逻辑的错误,确保玩家正常落地
修正后的完整代码
let x = 0; let y = 1; let z = 0; let dy = 0; // 垂直速度(用于跳跃和重力) let speed = 2; let cam; let jumpHeight = 0.5; let grav = 0.02; // 相机旋转与距离参数 let camYaw = 0; // 水平旋转角(绕Y轴) let camPitch = -0.3; // 垂直旋转角(绕X轴),初始值让相机稍微俯视玩家 let camDistance = 250; // 相机到玩家的固定距离 function setup() { createCanvas(windowWidth, windowHeight, WEBGL); background(100); debugMode(); cam = createCamera(); } function draw() { background(100); controller(); gravity(); // 通过极坐标计算相机相对于玩家的位置 let camX = x + camDistance * sin(camYaw) * cos(camPitch); let camY = y + camDistance * sin(camPitch); let camZ = z + camDistance * cos(camYaw) * cos(camPitch); // 设置相机位置并始终看向玩家 cam.setPosition(camX, camY, camZ); cam.lookAt(x, y, z); // 绘制玩家立方体 push(); translate(x, y, z); box(20); pop(); } function controller() { let moveSpeed = speed; // 获取相机旋转矩阵,提取前向和右向向量(用于基于视角的移动) let camMatrix = cam.getMatrix(); let forward = createVector(-camMatrix[8], -camMatrix[9], -camMatrix[10]).normalize(); let right = createVector(camMatrix[0], camMatrix[1], camMatrix[2]).normalize(); // W/S:沿相机前向/后向移动 if (keyIsDown(87)) { x += forward.x * moveSpeed; z += forward.z * moveSpeed; } if (keyIsDown(83)) { x -= forward.x * moveSpeed; z -= forward.z * moveSpeed; } // A/D:沿相机左向/右向移动 if (keyIsDown(65)) { x -= right.x * moveSpeed; z -= right.z * moveSpeed; } if (keyIsDown(68)) { x += right.x * moveSpeed; z += right.z * moveSpeed; } } function keyPressed() { // 空格跳跃,仅当玩家在地面时生效 if (keyCode == 32 && y <= 0.1) { dy = -jumpHeight; } } function gravity() { y += dy; dy += grav; // 持续施加重力加速度 // 落地检测,重置位置与垂直速度 if (y <= 0) { y = 0; dy = 0; } } function mouseDragged() { // 根据鼠标位移更新相机旋转角度 camYaw += mouseX - pmouseX; camPitch += mouseY - pmouseY; // 限制垂直旋转范围,避免相机翻转到异常角度 camPitch = constrain(camPitch, -PI/2 + 0.1, PI/2 - 0.1); }
核心代码解释
相机位置计算:
利用三角函数将极坐标(角度+距离)转换为笛卡尔坐标,确保相机始终围绕玩家旋转,同时保持固定距离。camYaw控制水平旋转,camPitch控制垂直旋转。基于视角的移动:
通过cam.getMatrix()获取相机的旋转矩阵,从中提取前向和右向向量,让玩家的WASD移动始终跟随相机视角方向,符合第三人称控制器的常规逻辑。鼠标旋转控制:
使用mouseDragged事件捕捉鼠标位移,实时更新旋转角度,并通过constrain限制垂直旋转范围,防止相机过度上下翻转导致视角异常。重力修复:
修正原代码中错误的落地逻辑,当玩家接触地面时重置垂直位置和速度,确保跳跃和重力表现正常。
内容的提问来源于stack exchange,提问作者CoderGuy
相关产品推荐
相关产品推荐

