hamstagotchi / index.html
Remsky's picture
Update index.html
00619ac verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pixel Hamster Care</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
@keyframes hamsterWalk {
0%, 100% { transform: translateX(0) rotate(0deg); }
25% { transform: translateX(5px) rotate(5deg); }
75% { transform: translateX(-5px) rotate(-5deg); }
}
@keyframes hamsterEat {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05) translateY(-3px); }
}
@keyframes hamsterClean {
0%, 100% { transform: rotate(0deg); }
25% { transform: rotate(15deg); }
75% { transform: rotate(-15deg); }
}
@keyframes hamsterHappy {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-5px); }
}
.hamster-animation-walk {
animation: hamsterWalk 0.8s infinite;
}
.hamster-animation-eat {
animation: hamsterEat 0.5s infinite;
}
.hamster-animation-clean {
animation: hamsterClean 0.6s infinite;
}
.hamster-animation-happy {
animation: hamsterHappy 0.7s infinite;
}
.pixel-art {
image-rendering: pixelated;
image-rendering: -moz-crisp-edges;
image-rendering: crisp-edges;
}
.progress-bar {
transition: width 0.5s ease-in-out;
}
.action-button:hover {
transform: translateY(-2px);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.action-button:active {
transform: translateY(0);
}
.notification {
animation: fadeInOut 2s ease-in-out;
opacity: 0;
}
@keyframes fadeInOut {
0%, 100% { opacity: 0; transform: translateY(10px); }
20%, 80% { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body class="bg-amber-50 min-h-screen flex flex-col items-center justify-center p-4">
<div class="max-w-md w-full bg-amber-100 rounded-2xl shadow-xl overflow-hidden border-4 border-amber-300">
<div class="bg-amber-300 p-4 flex justify-between items-center">
<h1 class="text-2xl font-bold text-amber-800">Pixel Hamster Care</h1>
<div class="text-amber-700 font-mono">Day: <span id="day-counter">1</span></div>
</div>
<div class="p-6 flex flex-col items-center">
<!-- Status bars -->
<div class="w-full mb-6 space-y-2">
<div class="flex items-center">
<span class="w-20 text-amber-900 font-medium">Hunger:</span>
<div class="flex-1 h-4 bg-amber-200 rounded-full overflow-hidden">
<div id="hunger-bar" class="h-full bg-red-500 progress-bar" style="width: 100%"></div>
</div>
</div>
<div class="flex items-center">
<span class="w-20 text-amber-900 font-medium">Happiness:</span>
<div class="flex-1 h-4 bg-amber-200 rounded-full overflow-hidden">
<div id="happiness-bar" class="h-full bg-green-500 progress-bar" style="width: 100%"></div>
</div>
</div>
<div class="flex items-center">
<span class="w-20 text-amber-900 font-medium">Cleanliness:</span>
<div class="flex-1 h-4 bg-amber-200 rounded-full overflow-hidden">
<div id="clean-bar" class="h-full bg-blue-500 progress-bar" style="width: 100%"></div>
</div>
</div>
</div>
<!-- Hamster display -->
<div class="relative w-48 h-48 bg-amber-200 rounded-xl border-2 border-amber-300 flex items-center justify-center mb-6">
<div id="hamster-container" class="hamster-animation-walk">
<!-- Pixel art hamster SVG -->
<svg id="hamster" class="pixel-art" width="120" height="120" viewBox="0 0 120 120">
<!-- Body -->
<rect x="40" y="50" width="40" height="30" fill="#D1A684" />
<rect x="35" y="45" width="10" height="10" fill="#D1A684" />
<rect x="75" y="45" width="10" height="10" fill="#D1A684" />
<!-- Head -->
<rect x="45" y="35" width="30" height="20" fill="#D1A684" />
<!-- Ears -->
<rect x="40" y="30" width="10" height="10" fill="#D1A684" />
<rect x="70" y="30" width="10" height="10" fill="#D1A684" />
<rect x="42" y="32" width="6" height="6" fill="#F5D5B9" />
<rect x="72" y="32" width="6" height="6" fill="#F5D5B9" />
<!-- Eyes -->
<rect x="50" y="40" width="5" height="5" fill="#333" />
<rect x="65" y="40" width="5" height="5" fill="#333" />
<!-- Nose -->
<rect x="45" y="45" width="5" height="5" fill="#333" />
<rect x="70" y="45" width="5" height="5" fill="#333" />
<!-- Cheeks -->
<rect x="45" y="50" width="10" height="5" fill="#F5A9A9" />
<rect x="65" y="50" width="10" height="5" fill="#F5A9A9" />
<!-- Mouth -->
<rect x="55" y="50" width="10" height="5" fill="#333" />
<!-- Arms -->
<rect x="35" y="55" width="5" height="15" fill="#D1A684" />
<rect x="80" y="55" width="5" height="15" fill="#D1A684" />
<!-- Legs -->
<rect x="45" y="80" width="10" height="5" fill="#D1A684" />
<rect x="65" y="80" width="10" height="5" fill="#D1A684" />
<!-- Tail -->
<rect x="30" y="55" width="10" height="5" fill="#D1A684" />
</svg>
</div>
<!-- Cage elements -->
<div class="absolute bottom-2 left-2 w-16 h-8 bg-amber-400 rounded"></div>
<div class="absolute top-2 right-2 w-12 h-6 bg-amber-500 rounded"></div>
<!-- Notification -->
<div id="notification" class="notification absolute top-0 left-0 right-0 bg-amber-400 text-amber-900 text-center py-1 font-medium hidden"></div>
</div>
<!-- Action buttons -->
<div class="grid grid-cols-3 gap-4 w-full">
<button id="feed-btn" class="action-button bg-red-400 hover:bg-red-500 text-white font-bold py-3 px-4 rounded-lg transition-all flex flex-col items-center">
<svg class="w-8 h-8 mb-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
Feed
</button>
<button id="play-btn" class="action-button bg-green-400 hover:bg-green-500 text-white font-bold py-3 px-4 rounded-lg transition-all flex flex-col items-center">
<svg class="w-8 h-8 mb-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"></path>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
Play
</button>
<button id="clean-btn" class="action-button bg-blue-400 hover:bg-blue-500 text-white font-bold py-3 px-4 rounded-lg transition-all flex flex-col items-center">
<svg class="w-8 h-8 mb-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"></path>
</svg>
Clean
</button>
</div>
</div>
<div class="bg-amber-200 p-4 text-center text-amber-800">
<p id="hamster-message">Hello! I'm your new hamster friend!</p>
</div>
</div>
<script>
// Game state
const state = {
hunger: 100,
happiness: 100,
cleanliness: 100,
day: 1,
isSleeping: false,
currentAnimation: 'walk',
messages: [
"Hello! I'm your new hamster friend!",
"I'm getting hungry...",
"Play with me!",
"My cage is getting dirty...",
"I love you!",
"Zzz... zzz...",
"That was fun!",
"Yummy!",
"Ahh, so clean now!",
"I'm bored...",
"Wheel time!"
]
};
// DOM elements
const hungerBar = document.getElementById('hunger-bar');
const happinessBar = document.getElementById('happiness-bar');
const cleanBar = document.getElementById('clean-bar');
const dayCounter = document.getElementById('day-counter');
const hamsterContainer = document.getElementById('hamster-container');
const hamsterMessage = document.getElementById('hamster-message');
const notification = document.getElementById('notification');
const feedBtn = document.getElementById('feed-btn');
const playBtn = document.getElementById('play-btn');
const cleanBtn = document.getElementById('clean-btn');
// Game loop
let gameLoop = setInterval(() => {
// Decrease stats over time
state.hunger = Math.max(0, state.hunger - 1);
state.happiness = Math.max(0, state.happiness - 0.8);
state.cleanliness = Math.max(0, state.cleanliness - 0.5);
// Update UI
updateBars();
// Random hamster actions
if (Math.random() < 0.1) {
randomHamsterAction();
}
// Check for day change
if (state.hunger <= 0 || state.happiness <= 0 || state.cleanliness <= 0) {
showNotification("Your hamster ran away! Starting new day...");
resetDay();
}
// Random messages
if (Math.random() < 0.2) {
showRandomMessage();
}
}, 2000);
// Update status bars
function updateBars() {
hungerBar.style.width = `${state.hunger}%`;
happinessBar.style.width = `${state.happiness}%`;
cleanBar.style.width = `${state.cleanliness}%`;
// Change colors based on level
hungerBar.className = `h-full progress-bar ${state.hunger > 50 ? 'bg-red-500' : state.hunger > 20 ? 'bg-orange-500' : 'bg-yellow-300'}`;
happinessBar.className = `h-full progress-bar ${state.happiness > 50 ? 'bg-green-500' : state.happiness > 20 ? 'bg-yellow-500' : 'bg-red-400'}`;
cleanBar.className = `h-full progress-bar ${state.cleanliness > 50 ? 'bg-blue-500' : state.cleanliness > 20 ? 'bg-purple-400' : 'bg-gray-400'}`;
}
// Random hamster animation
function randomHamsterAction() {
const actions = ['walk', 'sleep', 'happy'];
const randomAction = actions[Math.floor(Math.random() * actions.length)];
changeAnimation(randomAction);
if (randomAction === 'sleep') {
hamsterMessage.textContent = "Zzz... zzz...";
}
}
// Change hamster animation
function changeAnimation(animation) {
hamsterContainer.classList.remove(
'hamster-animation-walk',
'hamster-animation-eat',
'hamster-animation-clean',
'hamster-animation-happy'
);
state.currentAnimation = animation;
switch(animation) {
case 'walk':
hamsterContainer.classList.add('hamster-animation-walk');
break;
case 'eat':
hamsterContainer.classList.add('hamster-animation-eat');
break;
case 'clean':
hamsterContainer.classList.add('hamster-animation-clean');
break;
case 'happy':
hamsterContainer.classList.add('hamster-animation-happy');
break;
case 'sleep':
// No animation for sleep, just static
break;
}
}
// Show random message
function showRandomMessage() {
if (state.hunger < 30) {
hamsterMessage.textContent = "I'm so hungry!";
} else if (state.happiness < 30) {
hamsterMessage.textContent = "I'm bored... play with me!";
} else if (state.cleanliness < 30) {
hamsterMessage.textContent = "My cage is dirty!";
} else {
const randomIndex = Math.floor(Math.random() * state.messages.length);
hamsterMessage.textContent = state.messages[randomIndex];
}
}
// Show notification
function showNotification(message) {
notification.textContent = message;
notification.classList.remove('hidden');
notification.style.animation = 'none';
void notification.offsetWidth; // Trigger reflow
notification.style.animation = 'fadeInOut 2s ease-in-out';
setTimeout(() => {
notification.classList.add('hidden');
}, 2000);
}
// Reset day
function resetDay() {
state.hunger = 100;
state.happiness = 100;
state.cleanliness = 100;
state.day++;
dayCounter.textContent = state.day;
updateBars();
changeAnimation('happy');
hamsterMessage.textContent = "Yay! A new day!";
}
// Event listeners
feedBtn.addEventListener('click', () => {
state.hunger = Math.min(100, state.hunger + 25);
updateBars();
changeAnimation('eat');
showNotification("Nom nom nom!");
setTimeout(() => changeAnimation('happy'), 1500);
});
playBtn.addEventListener('click', () => {
state.happiness = Math.min(100, state.happiness + 25);
updateBars();
changeAnimation('happy');
showNotification("Wheee! So fun!");
});
cleanBtn.addEventListener('click', () => {
state.cleanliness = Math.min(100, state.cleanliness + 25);
updateBars();
changeAnimation('clean');
showNotification("Ahh, so fresh!");
setTimeout(() => changeAnimation('happy'), 1500);
});
// Initial setup
updateBars();
</script>
</body>
</html>