function animate(time: number) {
animationId = requestAnimationFrame(animate);
if (previousTime != null) {
const elapsedTime = time - previousTime;
accumulatedTime = Math.min(accumulatedTime + elapsedTime, maxAccumulatedTime);
}
previousTime = time;
const ticks = Math.floor(accumulatedTime / clientTickDuration);
accumulatedTime -= ticks * clientTickDuration;
if (pub != null && pub.match == null) {
sceneAngleY += Math.PI / 640;
} else {
if (Math.abs(sceneAngleY) > 0.1) sceneAngleY = lerp(sceneAngleY, 0, 0.15);
else sceneAngleY = 0;
}
if (sceneAngleY > Math.PI) sceneAngleY -= Math.PI * 2;
scene.setRotationFromEuler(tmpEuler.set(0, sceneAngleY, 0));
let width = canvas.parentElement.clientWidth;
let height = canvas.parentElement.clientHeight;
if (width > height * 4 / 3) width = height * 4 / 3;
if (height > width * 3 / 4) height = width * 3 / 4;
canvas.width = width;
canvas.height = height;
camera.updateProjectionMatrix();
threeRenderer.setSize(canvas.width, canvas.height, false);
threeRenderer.render(scene, camera);
input.gather();
if (input.hasJustPressedLeftTrigger) { socket.emit("throwBall"); }
for (const playerId in modelsById) {
const model = modelsById[playerId];
const { avatar } = players.byId[playerId];
const hasBall = pub.ball.playerId === playerId;
model.nametag.setRotationFromEuler(tmpEuler.set(0, -sceneAngleY, 0));
if (playerId === myPlayerId) {
for (let i = 0; i < ticks; i++) input.predict(pub.match != null, pub.ball.playerId === myPlayerId, ballThrownTimer > 0);
model.root.position.set(input.prediction.x, 0, input.prediction.z);
model.body.setRotationFromEuler(tmpEuler.set(0, -input.prediction.angleY, 0));
model.shoulders.setRotationFromEuler(tmpEuler.set(0, 0, input.prediction.catching || hasBall ? input.prediction.angleX : -Math.PI * 0.4));
} else {
// TODO: Lerp between previous and current!
model.root.position.set(avatar.x, 0, avatar.z);
model.body.setRotationFromEuler(tmpEuler.set(0, -avatar.angleY, 0));
model.shoulders.setRotationFromEuler(tmpEuler.set(0, 0, avatar.catching || hasBall ? avatar.angleX : -Math.PI * 0.4));
}
model.root.position.y = shared.getAvatarY(avatar.jump);
}
if (pub != null && pub.ball.playerId == null) {
ballModel.position.set(pub.ball.x, pub.ball.y, pub.ball.z);
ballMarker.position.set(pub.ball.x, 0.01, pub.ball.z);
}
}
请发表评论