Skip to content

Instantly share code, notes, and snippets.

@kittinan
Last active September 17, 2024 17:00
Show Gist options
  • Save kittinan/2cd744b56613e57d3506b39a8f877596 to your computer and use it in GitHub Desktop.
Save kittinan/2cd744b56613e57d3506b39a8f877596 to your computer and use it in GitHub Desktop.
hippo game by ChatGPT o1-preview use wsad to control
<!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