Last active
September 17, 2024 17:00
-
-
Save kittinan/2cd744b56613e57d3506b39a8f877596 to your computer and use it in GitHub Desktop.
hippo game by ChatGPT o1-preview use wsad to control
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Baby Pygmy Hippopotamus Game</title> | |
<style> | |
body { margin: 0; overflow: hidden; } | |
canvas { display: block; } | |
#score { | |
position: absolute; | |
top: 10px; | |
right: 60px; | |
font-size: 24px; | |
color: #fff; | |
font-family: Arial, sans-serif; | |
text-shadow: 1px 1px 2px #000; | |
} | |
#music-icon { | |
position: absolute; | |
top: 10px; | |
right: 20px; | |
width: 32px; | |
height: 32px; | |
background-image: url('data:image/svg+xml;utf8,<svg fill="%23fff" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 3v10.55A4 4 0 1014 17V7h4V3h-6z"/></svg>'); | |
cursor: pointer; | |
} | |
#music-icon.paused { | |
background-image: url('data:image/svg+xml;utf8,<svg fill="%23fff" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>'); | |
} | |
#start-message { | |
position: absolute; | |
top: 50%; | |
left: 50%; | |
transform: translate(-50%, -50%); | |
font-size: 36px; | |
color: #fff; | |
font-family: Arial, sans-serif; | |
text-shadow: 1px 1px 2px #000; | |
display: none; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="score">Score: 0</div> | |
<div id="music-icon" class="paused"></div> | |
<div id="start-message">Press Enter to Start Game</div> | |
<!-- Include Three.js library --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> | |
<!-- Include Tween.js for animation --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/18.6.4/tween.umd.js"></script> | |
<script> | |
// Scene, Camera, Renderer | |
var scene = new THREE.Scene(); | |
var camera = new THREE.PerspectiveCamera( | |
75, | |
window.innerWidth / window.innerHeight, | |
0.1, | |
1000 | |
); | |
var renderer = new THREE.WebGLRenderer({ antialias: true }); | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
document.body.appendChild(renderer.domElement); | |
// Score display and start message | |
var score = 0; | |
var scoreElement = document.getElementById('score'); | |
var startMessage = document.getElementById('start-message'); | |
startMessage.style.display = 'block'; // Show the start message initially | |
// Background Music Control | |
var musicIcon = document.getElementById('music-icon'); | |
var backgroundMusic = new Audio('https://www.bensound.com/bensound-music/bensound-littleidea.mp3'); | |
backgroundMusic.loop = true; | |
backgroundMusic.volume = 0.5; // Adjust volume as needed | |
musicIcon.addEventListener('click', function() { | |
if (backgroundMusic.paused) { | |
backgroundMusic.play(); | |
musicIcon.classList.remove('paused'); | |
} else { | |
backgroundMusic.pause(); | |
musicIcon.classList.add('paused'); | |
} | |
}); | |
// Background color (Savanna sky) | |
scene.background = new THREE.Color(0x87CEEB); | |
// Ground (Savanna ground) | |
var groundGeometry = new THREE.PlaneGeometry(1000, 1000); | |
var groundMaterial = new THREE.MeshLambertMaterial({ color: 0xC2B280 }); | |
var ground = new THREE.Mesh(groundGeometry, groundMaterial); | |
ground.rotation.x = -Math.PI / 2; | |
scene.add(ground); | |
// Lighting | |
var ambientLight = new THREE.AmbientLight(0x404040); | |
scene.add(ambientLight); | |
var sun = new THREE.DirectionalLight(0xffffff, 1); | |
sun.position.set(100, 100, 50); | |
scene.add(sun); | |
// Hippopotamus | |
var hippo = new THREE.Group(); | |
// Body | |
var bodyGeometry = new THREE.SphereGeometry(1, 32, 32); | |
var bodyMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 }); | |
var body = new THREE.Mesh(bodyGeometry, bodyMaterial); | |
body.scale.set(1.5, 1, 1); | |
hippo.add(body); | |
// Head | |
var headGeometry = new THREE.SphereGeometry(0.5, 32, 32); | |
var head = new THREE.Mesh(headGeometry, bodyMaterial); | |
head.position.set(1.5, 0.3, 0); | |
hippo.add(head); | |
// Face features | |
// Eyes | |
function createEye(x, y, z) { | |
var eyeWhiteGeometry = new THREE.SphereGeometry(0.06, 16, 16); | |
var eyeWhiteMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff }); | |
var eyeWhite = new THREE.Mesh(eyeWhiteGeometry, eyeWhiteMaterial); | |
eyeWhite.position.set(x, y, z); | |
head.add(eyeWhite); | |
var pupilGeometry = new THREE.SphereGeometry(0.03, 16, 16); | |
var pupilMaterial = new THREE.MeshLambertMaterial({ color: 0x000000 }); | |
var pupil = new THREE.Mesh(pupilGeometry, pupilMaterial); | |
pupil.position.set(0, 0, 0.05); | |
eyeWhite.add(pupil); | |
} | |
createEye(0.2, 0.15, 0.15); // Left eye | |
createEye(0.2, 0.15, -0.15); // Right eye | |
// Nostrils | |
var nostrilGeometry = new THREE.SphereGeometry(0.05, 16, 16); | |
var nostrilMaterial = new THREE.MeshLambertMaterial({ color: 0x000000 }); | |
var leftNostril = new THREE.Mesh(nostrilGeometry, nostrilMaterial); | |
leftNostril.position.set(0.4, -0.05, 0.08); | |
head.add(leftNostril); | |
var rightNostril = leftNostril.clone(); | |
rightNostril.position.z = -0.08; | |
head.add(rightNostril); | |
// Ears | |
var earGeometry = new THREE.SphereGeometry(0.1, 16, 16); | |
var earMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 }); | |
var leftEar = new THREE.Mesh(earGeometry, earMaterial); | |
leftEar.position.set(0, 0.35, 0.2); | |
head.add(leftEar); | |
var rightEar = leftEar.clone(); | |
rightEar.position.z = -0.2; | |
head.add(rightEar); | |
// Legs (with joints for animation) | |
var legMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 }); | |
var legs = []; | |
function createLeg(xOffset, zOffset) { | |
var upperLegGeometry = new THREE.CylinderGeometry(0.2, 0.2, 0.5, 16); | |
var lowerLegGeometry = new THREE.CylinderGeometry(0.15, 0.15, 0.5, 16); | |
var footGeometry = new THREE.BoxGeometry(0.3, 0.1, 0.2); | |
var upperLeg = new THREE.Mesh(upperLegGeometry, legMaterial); | |
var lowerLeg = new THREE.Mesh(lowerLegGeometry, legMaterial); | |
var foot = new THREE.Mesh(footGeometry, legMaterial); | |
upperLeg.position.set(xOffset, -0.25, zOffset); | |
upperLeg.rotation.z = 0; | |
hippo.add(upperLeg); | |
lowerLeg.position.set(0, -0.5, 0); | |
lowerLeg.rotation.z = 0; | |
upperLeg.add(lowerLeg); | |
foot.position.set(0, -0.3, 0); | |
lowerLeg.add(foot); | |
legs.push({ upperLeg: upperLeg, lowerLeg: lowerLeg }); | |
} | |
// Front Left Leg | |
createLeg(0.7, 0.4); | |
// Front Right Leg | |
createLeg(0.7, -0.4); | |
// Back Left Leg | |
createLeg(-0.7, 0.4); | |
// Back Right Leg | |
createLeg(-0.7, -0.4); | |
// Position hippo | |
hippo.position.y = 1; | |
scene.add(hippo); | |
// Camera position | |
camera.position.set(0, 5, 10); | |
camera.lookAt(hippo.position); | |
// Controls | |
var keys = {}; | |
var gameRunning = false; | |
document.addEventListener('keydown', function (event) { | |
keys[event.code] = true; | |
if (event.code === 'Enter') { | |
startMessage.style.display = 'none'; // Hide start message when the game starts | |
gameRunning = !gameRunning; | |
// Play the background music when the game starts | |
if (gameRunning && backgroundMusic.paused) { | |
backgroundMusic.play(); | |
musicIcon.classList.remove('paused'); | |
} | |
} | |
if (event.code === 'Space') { | |
roar(); | |
} | |
}); | |
document.addEventListener('keyup', function (event) { | |
keys[event.code] = false; | |
}); | |
function roar() { | |
// Animate the head to simulate roaring | |
var roarDuration = 0.5; // seconds | |
var roarStart = Date.now(); | |
function animateRoar() { | |
var elapsed = (Date.now() - roarStart) / 1000; | |
if (elapsed < roarDuration) { | |
head.rotation.x = Math.sin(elapsed * Math.PI * 4) * 0.4; | |
requestAnimationFrame(animateRoar); | |
} else { | |
head.rotation.x = 0; | |
} | |
} | |
animateRoar(); | |
} | |
// Trees (Savanna environment) | |
var trees = []; | |
function addTree(x, z) { | |
var treeType = Math.floor(Math.random() * 3); // 0, 1, or 2 | |
var trunkMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 }); | |
var leavesMaterial = new THREE.MeshLambertMaterial({ color: 0x228B22 }); | |
var trunk, leaves; | |
if (treeType === 0) { | |
// Type 1: Classic tree | |
var trunkGeometry = new THREE.CylinderGeometry(0.2, 0.2, 2); | |
trunk = new THREE.Mesh(trunkGeometry, trunkMaterial); | |
trunk.position.set(x, 1, z); | |
var leavesGeometry = new THREE.SphereGeometry(1, 16, 16); | |
leaves = new THREE.Mesh(leavesGeometry, leavesMaterial); | |
leaves.position.set(0, 1.5, 0); | |
trunk.add(leaves); | |
} else if (treeType === 1) { | |
// Type 2: Tall palm-like tree | |
var trunkGeometry = new THREE.CylinderGeometry(0.1, 0.2, 3); | |
trunk = new THREE.Mesh(trunkGeometry, trunkMaterial); | |
trunk.position.set(x, 1.5, z); | |
var leavesGeometry = new THREE.ConeGeometry(0.5, 1, 8); | |
leaves = new THREE.Mesh(leavesGeometry, leavesMaterial); | |
leaves.position.set(0, 2, 0); | |
trunk.add(leaves); | |
} else { | |
// Type 3: Short bush | |
var bushGeometry = new THREE.SphereGeometry(0.8, 16, 16); | |
var bushMaterial = new THREE.MeshLambertMaterial({ color: 0x228B22 }); | |
trunk = new THREE.Mesh(bushGeometry, bushMaterial); | |
trunk.position.set(x, 0.8, z); | |
} | |
trunk.userData.isTree = true; // Mark this object as a tree | |
trees.push(trunk); | |
scene.add(trunk); | |
} | |
// Add initial trees | |
for (var i = 0; i < 50; i++) { | |
var x = Math.random() * 100 - 50; | |
var z = Math.random() * 100 - 50; | |
addTree(x, z); | |
} | |
// Function to grow trees randomly during gameplay | |
function growTrees() { | |
if (gameRunning) { | |
var x = hippo.position.x + (Math.random() * 100 - 50); | |
var z = hippo.position.z + (Math.random() * 100 - 50); | |
addTree(x, z); | |
} | |
setTimeout(growTrees, Math.random() * 5000 + 5000); // Grow a tree every 5-10 seconds | |
} | |
growTrees(); | |
// Animation variables | |
var clock = new THREE.Clock(); | |
var legSwing = 0; | |
var legSpeed = 5; | |
// Animation loop | |
function animate() { | |
requestAnimationFrame(animate); | |
var delta = clock.getDelta(); | |
if (gameRunning) { | |
var speed = 0.1; | |
var direction = new THREE.Vector3(); | |
if (keys['KeyW']) { | |
direction.z -= 1; | |
} | |
if (keys['KeyS']) { | |
direction.z += 1; | |
} | |
if (keys['KeyA']) { | |
direction.x -= 1; | |
} | |
if (keys['KeyD']) { | |
direction.x += 1; | |
} | |
direction.normalize(); | |
if (direction.length() > 0) { | |
hippo.position.add(direction.multiplyScalar(speed)); | |
hippo.rotation.y = Math.atan2(direction.x, direction.z); | |
// Animate legs | |
legSwing += delta * legSpeed; | |
legs.forEach(function (leg, index) { | |
var phase = (index % 2 === 0) ? 0 : Math.PI; | |
leg.upperLeg.rotation.x = Math.sin(legSwing + phase) * 0.5; | |
leg.lowerLeg.rotation.x = Math.cos(legSwing + phase) * 0.5; | |
}); | |
} else { | |
// Reset leg positions when not moving | |
legs.forEach(function (leg) { | |
leg.upperLeg.rotation.x = 0; | |
leg.lowerLeg.rotation.x = 0; | |
}); | |
} | |
checkCollisions(); | |
updateCamera(); | |
} | |
TWEEN.update(); | |
renderer.render(scene, camera); | |
} | |
// Camera follow | |
var cameraOffset = new THREE.Vector3(0, 5, 10); | |
function updateCamera() { | |
var desiredPosition = hippo.position.clone().add(cameraOffset); | |
camera.position.lerp(desiredPosition, 0.1); | |
camera.lookAt(hippo.position); | |
} | |
// Handle window resize | |
window.addEventListener('resize', onWindowResize, false); | |
function onWindowResize() { | |
camera.aspect = window.innerWidth / window.innerHeight; | |
camera.updateProjectionMatrix(); | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
} | |
// Collision detection | |
function checkCollisions() { | |
var hippoBox = new THREE.Box3().setFromObject(hippo); | |
for (var i = 0; i < trees.length; i++) { | |
var tree = trees[i]; | |
if (!tree.userData.collected) { | |
var treeBox = new THREE.Box3().setFromObject(tree); | |
if (hippoBox.intersectsBox(treeBox)) { | |
tree.userData.collected = true; | |
scene.remove(tree); // Remove the tree from the scene | |
score += 1; | |
updateScore(); | |
} | |
} | |
} | |
} | |
function updateScore() { | |
scoreElement.textContent = 'Score: ' + score; | |
} | |
// Start animation | |
animate(); | |
</script> | |
</body> | |
</html> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment