3d_snake_test / index.html
broadfield-dev's picture
Update index.html
31119d6 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Sphere Snake Game</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>
let camera, scene, renderer;
let snake, food;
let angle = 0;
function init() {
// Camera setup
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// Scene setup
scene = new THREE.Scene();
// Sphere (world)
const geometry = new THREE.SphereGeometry(2, 32, 32);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true });
scene.add(new THREE.Mesh(geometry, material));
// Snake setup
snake = [];
for (let i = 0; i < 3; i++) {
const snakePart = new THREE.Mesh(new THREE.SphereGeometry(0.1), new THREE.MeshBasicMaterial({ color: 0xff0000 }));
snakePart.position.set(0, 0, i * 0.2 - 0.4);
snake.push(snakePart);
scene.add(snakePart);
}
// Food setup
food = new THREE.Mesh(new THREE.SphereGeometry(0.1), new THREE.MeshBasicMaterial({ color: 0x0000ff }));
setRandomFoodPosition();
scene.add(food);
// Renderer setup
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Event listeners for rotation
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('touchmove', onTouchMove, { passive: false });
}
function setRandomFoodPosition() {
const radius = 1.9;
const phi = Math.acos(2 * Math.random() - 1);
const theta = 2 * Math.PI * Math.random();
food.position.x = radius * Math.sin(phi) * Math.cos(theta);
food.position.y = radius * Math.sin(phi) * Math.sin(theta);
food.position.z = radius * Math.cos(phi);
}
function onMouseMove(e) {
angle -= e.movementX * 0.001;
}
function onTouchMove(e) {
e.preventDefault();
const touch = e.touches[0];
if (touch) {
angle -= touch.movementX * 0.001;
}
}
function update() {
// Move snake
for (let i = snake.length - 1; i > 0; i--) {
snake[i].position.copy(snake[i - 1].position);
}
// Move head in direction (simple forward movement here)
const head = snake[0];
const direction = head.position.clone().normalize().multiplyScalar(0.05);
head.position.add(direction);
// Check for food
if (head.position.distanceTo(food.position) < 0.2) {
const newPart = new THREE.Mesh(new THREE.SphereGeometry(0.1), new THREE.MeshBasicMaterial({ color: 0xff0000 }));
newPart.position.copy(snake[snake.length - 1].position);
snake.push(newPart);
scene.add(newPart);
setRandomFoodPosition();
}
// Keep snake on sphere surface
head.position.normalize().multiplyScalar(1.9);
}
function animate() {
requestAnimationFrame(animate);
// Rotate the scene for interaction
scene.rotation.y = angle;
update();
renderer.render(scene, camera);
}
init();
animate();
// Resize handling
window.addEventListener('resize', onWindowResize, false);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
</script>
</body>
</html>