<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ウォータースライザーゲーム</title>
<style>
body { margin: 0; overflow: hidden; }
canvas { display: block; }
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/curves/CatmullRomCurve3.js"></script>
<script>
let scene, camera, renderer, tube, curve, clock;
function init() {
// シーンの作成
scene = new THREE.Scene();
// カメラの作成
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 1000);
camera.position.z = 5;
// レンダラーの作成
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// ライトの作成
const light = new THREE.PointLight(0xffffff);
light.position.set(10, 10, 10);
scene.add(light);
// 曲線を定義(チューブの軌道)
curve = new THREE.CatmullRomCurve3([
new THREE.Vector3(-10, 0, -10),
new THREE.Vector3(-5, 5, 0),
new THREE.Vector3(0, 0, 10),
new THREE.Vector3(5, -5, 0),
new THREE.Vector3(10, 0, -10)
], true);
// チューブのジオメトリを作成
const tubeGeometry = new THREE.TubeGeometry(curve, 100, 2, 8, true);
const tubeMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true });
tube = new THREE.Mesh(tubeGeometry, tubeMaterial);
scene.add(tube);
// クロックの作成(時間を計測)
clock = new THREE.Clock();
animate();
}
function animate() {
requestAnimationFrame(animate);
const time = clock.getElapsedTime();
const looptime = 20; // ループ時間
const t = (time % looptime) / looptime;
// 曲線に沿ってカメラを移動
const pos = curve.getPointAt(t);
const tangent = curve.getTangentAt(t);
camera.position.copy(pos);
camera.lookAt(pos.clone().add(tangent));
renderer.render(scene, camera);
}
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
init();
</script>
</body>
</html>