Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Hugs Clicker - Get Virtual Hugs!</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/> | |
<style> | |
.hugger { | |
transition: all 0.1s ease; | |
cursor: pointer; | |
} | |
.hugger:active { | |
transform: scale(0.95); | |
} | |
.floating-hug { | |
position: absolute; | |
pointer-events: none; | |
animation: floatUp 2s forwards; | |
opacity: 0.8; | |
} | |
@keyframes floatUp { | |
0% { | |
transform: translateY(0) rotate(0deg); | |
opacity: 1; | |
} | |
100% { | |
transform: translateY(-100px) rotate(10deg); | |
opacity: 0; | |
} | |
} | |
.progress-bar { | |
transition: width 0.3s ease; | |
} | |
.unlock-notification { | |
animation: bounce 0.5s ease; | |
} | |
@keyframes bounce { | |
0%, 100% { transform: scale(1); } | |
50% { transform: scale(1.1); } | |
} | |
</style> | |
</head> | |
<body class="bg-gradient-to-b from-pink-100 to-purple-100 min-h-screen font-sans"> | |
<div class="container mx-auto px-4 py-8"> | |
<header class="text-center mb-8"> | |
<h1 class="text-4xl md:text-5xl font-bold text-purple-800 mb-2">Hugs Clicker</h1> | |
<p class="text-lg text-purple-600">Spread love one hug at a time!</p> | |
</header> | |
<div class="flex flex-col lg:flex-row gap-8"> | |
<!-- Main hugger section --> | |
<div class="flex-1 flex flex-col items-center"> | |
<div class="relative mb-4"> | |
<div id="hug-counter" class="text-3xl font-bold text-purple-700 mb-4 text-center">0 Hugs</div> | |
<div id="hugger" class="hugger w-64 h-64 md:w-80 md:h-80 bg-white rounded-full shadow-xl flex items-center justify-center overflow-hidden"> | |
<img id="hugger-image" src="https://em-content.zobj.net/source/microsoft-teams/363/hugging-face_1f917.png" alt="Hugging face" class="w-full h-full object-contain p-6"> | |
</div> | |
<div id="hug-effects" class="absolute inset-0 pointer-events-none"></div> | |
</div> | |
<div class="text-center text-purple-600 mb-6"> | |
<p id="hugs-per-second" class="text-lg">0 hugs per second</p> | |
</div> | |
<div class="w-full max-w-md bg-white bg-opacity-70 rounded-lg p-4 shadow-md mb-6"> | |
<h3 class="text-xl font-semibold text-purple-800 mb-2">Hug Power</h3> | |
<div class="h-4 bg-purple-200 rounded-full mb-2"> | |
<div id="power-bar" class="h-full bg-purple-500 rounded-full progress-bar" style="width: 0%"></div> | |
</div> | |
<p id="power-text" class="text-sm text-purple-600">Click faster to increase your hug power!</p> | |
</div> | |
</div> | |
<!-- Upgrades section --> | |
<div class="flex-1 bg-white bg-opacity-80 rounded-xl p-6 shadow-lg"> | |
<h2 class="text-2xl font-bold text-purple-800 mb-4 border-b-2 border-purple-100 pb-2">Hug Upgrades</h2> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<div class="upgrade-card" data-cost="20" data-id="auto-hugger" data-cps="1"> | |
<div class="flex items-center gap-3"> | |
<img src="https://em-content.zobj.net/source/microsoft-teams/363/smiling-face-with-hearts_1f970.png" alt="Auto hugger" class="w-12 h-12"> | |
<div> | |
<h3 class="font-semibold text-purple-700">Auto Hugger</h3> | |
<p class="text-sm text-purple-600">Gives 1 hug per second</p> | |
</div> | |
</div> | |
<div class="ml-auto text-right"> | |
<p class="cost text-lg font-bold text-purple-800">20 Hugs</p> | |
<p class="owned text-xs text-purple-600">Owned: 0</p> | |
</div> | |
</div> | |
<div class="upgrade-card" data-cost="100" data-id="hug-buddy" data-cps="5"> | |
<div class="flex items-center gap-3"> | |
<img src="https://em-content.zobj.net/source/microsoft-teams/363/smiling-face-with-smiling-eyes_1f60a.png" alt="Hug buddy" class="w-12 h-12"> | |
<div> | |
<h3 class="font-semibold text-purple-700">Hug Buddy</h3> | |
<p class="text-sm text-purple-600">Gives 5 hugs per second</p> | |
</div> | |
</div> | |
<div class="ml-auto text-right"> | |
<p class="cost text-lg font-bold text-purple-800">100 Hugs</p> | |
<p class="owned text-xs text-purple-600">Owned: 0</p> | |
</div> | |
</div> | |
<div class="upgrade-card" data-cost="500" data-id="hug-team" data-cps="10"> | |
<div class="flex items-center gap-3"> | |
<img src="https://em-content.zobj.net/source/microsoft-teams/363/smiling-face-with-heart-eyes_1f60d.png" alt="Hug team" class="w-12 h-12"> | |
<div> | |
<h3 class="font-semibold text-purple-700">Hug Team</h3> | |
<p class="text-sm text-purple-600">Gives 10 hugs per second</p> | |
</div> | |
</div> | |
<div class="ml-auto text-right"> | |
<p class="cost text-lg font-bold text-purple-800">500 Hugs</p> | |
<p class="owned text-xs text-purple-600">Owned: 0</p> | |
</div> | |
</div> | |
<div class="upgrade-card" data-cost="2000" data-id="hug-factory" data-cps="50"> | |
<div class="flex items-center gap-3"> | |
<img src="https://em-content.zobj.net/source/microsoft-teams/363/star-struck_1f929.png" alt="Hug factory" class="w-12 h-12"> | |
<div> | |
<h3 class="font-semibold text-purple-700">Hug Factory</h3> | |
<p class="text-sm text-purple-600">Gives 50 hugs per second</p> | |
</div> | |
</div> | |
<div class="ml-auto text-right"> | |
<p class="cost text-lg font-bold text-purple-800">2000 Hugs</p> | |
<p class="owned text-xs text-purple-600">Owned: 0</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Achievements section --> | |
<div class="mt-8 bg-white bg-opacity-80 rounded-xl p-6 shadow-lg"> | |
<h2 class="text-2xl font-bold text-purple-800 mb-4 border-b-2 border-purple-100 pb-2">Hug Achievements</h2> | |
<div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4"> | |
<div class="achievement" data-threshold="10"> | |
<div class="achievement-icon bg-purple-200 rounded-full w-16 h-16 flex items-center justify-center mx-auto mb-2"> | |
<img src="https://em-content.zobj.net/source/microsoft-teams/363/smiling-face_263a-fe0f.png" alt="First Hugs" class="w-10 h-10"> | |
</div> | |
<p class="text-center text-sm font-medium text-purple-700">First Hugs</p> | |
<p class="text-center text-xs text-purple-500">10 hugs</p> | |
</div> | |
<div class="achievement" data-threshold="50"> | |
<div class="achievement-icon bg-purple-200 rounded-full w-16 h-16 flex items-center justify-center mx-auto mb-2"> | |
<img src="https://em-content.zobj.net/source/microsoft-teams/363/smiling-face-with-halo_1f607.png" alt="Hug Apprentice" class="w-10 h-10"> | |
</div> | |
<p class="text-center text-sm font-medium text-purple-700">Hug Apprentice</p> | |
<p class="text-center text-xs text-purple-500">50 hugs</p> | |
</div> | |
<div class="achievement" data-threshold="100"> | |
<div class="achievement-icon bg-purple-200 rounded-full w-16 h-16 flex items-center justify-center mx-auto mb-2"> | |
<img src="https://em-content.zobj.net/source/microsoft-teams/363/smiling-face-with-sunglasses_1f60e.png" alt="Hug Expert" class="w-10 h-10"> | |
</div> | |
<p class="text-center text-sm font-medium text-purple-700">Hug Expert</p> | |
<p class="text-center text-xs text-purple-500">100 hugs</p> | |
</div> | |
<div class="achievement" data-threshold="500"> | |
<div class="achievement-icon bg-purple-200 rounded-full w-16 h-16 flex items-center justify-center mx-auto mb-2"> | |
<img src="https://em-content.zobj.net/source/microsoft-teams/363/partying-face_1f973.png" alt="Hug Master" class="w-10 h-10"> | |
</div> | |
<p class="text-center text-sm font-medium text-purple-700">Hug Master</p> | |
<p class="text-center text-xs text-purple-500">500 hugs</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Unlock notification --> | |
<div id="unlock-notification" class="fixed top-4 left-1/2 transform -translate-x-1/2 bg-purple-600 text-white px-6 py-3 rounded-full shadow-lg hidden unlock-notification"> | |
New hugger unlocked! | |
</div> | |
<script> | |
// Game state | |
let hugs = 0; | |
let hugsPerSecond = 0; | |
let clickPower = 1; | |
let powerLevel = 0; | |
let maxPower = 100; | |
let powerDecayRate = 0.5; | |
// Upgrades data | |
const upgrades = { | |
'auto-hugger': { cost: 20, cps: 1, owned: 0 }, | |
'hug-buddy': { cost: 100, cps: 5, owned: 0 }, | |
'hug-team': { cost: 500, cps: 10, owned: 0 }, | |
'hug-factory': { cost: 2000, cps: 50, owned: 0 } | |
}; | |
// Achievements data | |
const achievements = { | |
10: { unlocked: false, name: "First Hugs" }, | |
50: { unlocked: false, name: "Hug Apprentice" }, | |
100: { unlocked: false, name: "Hug Expert" }, | |
500: { unlocked: false, name: "Hug Master" } | |
}; | |
// Different hugger images | |
const huggerImages = [ | |
'https://em-content.zobj.net/source/microsoft-teams/363/hugging-face_1f917.png', | |
'https://em-content.zobj.net/source/microsoft-teams/363/smiling-face-with-hearts_1f970.png', | |
'https://em-content.zobj.net/source/microsoft-teams/363/smiling-face-with-smiling-eyes_1f60a.png', | |
'https://em-content.zobj.net/source/microsoft-teams/363/smiling-face-with-heart-eyes_1f60d.png', | |
'https://em-content.zobj.net/source/microsoft-teams/363/star-struck_1f929.png' | |
]; | |
let currentHuggerIndex = 0; | |
// DOM elements | |
const hugCounter = document.getElementById('hug-counter'); | |
const hugsPerSecondDisplay = document.getElementById('hugs-per-second'); | |
const hugger = document.getElementById('hugger'); | |
const hugEffects = document.getElementById('hug-effects'); | |
const powerBar = document.getElementById('power-bar'); | |
const powerText = document.getElementById('power-text'); | |
const upgradeCards = document.querySelectorAll('.upgrade-card'); | |
const achievementElements = document.querySelectorAll('.achievement'); | |
const unlockNotification = document.getElementById('unlock-notification'); | |
// Initialize the game | |
function init() { | |
loadGame(); | |
updateDisplay(); | |
setupEventListeners(); | |
startGameLoop(); | |
} | |
// Set up event listeners | |
function setupEventListeners() { | |
// Click on hugger | |
hugger.addEventListener('click', () => { | |
addHugs(clickPower); | |
powerLevel = Math.min(powerLevel + 2, maxPower); | |
updatePower(); | |
createClickEffect(event); | |
// Random chance to change hugger image | |
if (Math.random() < 0.05 && currentHuggerIndex < huggerImages.length - 1) { | |
currentHuggerIndex++; | |
document.getElementById('hugger-image').src = huggerImages[currentHuggerIndex]; | |
showUnlockNotification(); | |
} | |
}); | |
// Buy upgrades | |
upgradeCards.forEach(card => { | |
card.addEventListener('click', () => { | |
const upgradeId = card.dataset.id; | |
buyUpgrade(upgradeId); | |
}); | |
}); | |
} | |
// Game loop | |
function startGameLoop() { | |
setInterval(() => { | |
// Add passive hugs | |
if (hugsPerSecond > 0) { | |
addHugs(hugsPerSecond / 10); | |
} | |
// Power decay | |
if (powerLevel > 0) { | |
powerLevel = Math.max(0, powerLevel - powerDecayRate); | |
updatePower(); | |
} | |
// Check achievements | |
checkAchievements(); | |
// Save game every 5 seconds | |
if (Date.now() % 5000 < 50) { | |
saveGame(); | |
} | |
}, 100); | |
} | |
// Add hugs to the total | |
function addHugs(amount) { | |
hugs += amount; | |
updateDisplay(); | |
} | |
// Buy an upgrade | |
function buyUpgrade(upgradeId) { | |
const upgrade = upgrades[upgradeId]; | |
if (hugs >= upgrade.cost) { | |
hugs -= upgrade.cost; | |
upgrade.owned++; | |
hugsPerSecond += upgrade.cps; | |
// Increase cost for next purchase | |
upgrade.cost = Math.floor(upgrade.cost * 1.15); | |
updateDisplay(); | |
updateUpgradeCards(); | |
} | |
} | |
// Check for unlocked achievements | |
function checkAchievements() { | |
for (const threshold in achievements) { | |
if (!achievements[threshold].unlocked && hugs >= parseInt(threshold)) { | |
achievements[threshold].unlocked = true; | |
showAchievement(threshold); | |
} | |
} | |
} | |
// Show achievement notification | |
function showAchievement(threshold) { | |
const achievement = achievements[threshold]; | |
const achievementElements = document.querySelectorAll(`.achievement[data-threshold="${threshold}"]`); | |
achievementElements.forEach(el => { | |
el.classList.add('animate__animated', 'animate__bounce'); | |
setTimeout(() => { | |
el.classList.remove('animate__animated', 'animate__bounce'); | |
}, 1000); | |
// Change style to show it's unlocked | |
const icon = el.querySelector('.achievement-icon'); | |
icon.classList.remove('bg-purple-200'); | |
icon.classList.add('bg-purple-400', 'shadow-md'); | |
}); | |
} | |
// Show unlock notification | |
function showUnlockNotification() { | |
unlockNotification.classList.remove('hidden'); | |
unlockNotification.classList.add('animate__animated', 'animate__bounce'); | |
setTimeout(() => { | |
unlockNotification.classList.add('hidden'); | |
unlockNotification.classList.remove('animate__animated', 'animate__bounce'); | |
}, 2000); | |
} | |
// Create visual effect when clicking | |
function createClickEffect(event) { | |
const effect = document.createElement('div'); | |
effect.className = 'floating-hug'; | |
// Random hug emoji | |
const hugEmojis = ['❤️', '🤗', '🫂', '💕', '😊']; | |
const randomEmoji = hugEmojis[Math.floor(Math.random() * hugEmojis.length)]; | |
effect.textContent = `+${clickPower} ${randomEmoji}`; | |
effect.style.left = `${event.clientX - 20}px`; | |
effect.style.top = `${event.clientY - 20}px`; | |
effect.style.color = ['#8b5cf6', '#ec4899', '#6366f1', '#f43f5e'][Math.floor(Math.random() * 4)]; | |
effect.style.fontSize = `${14 + Math.random() * 10}px`; | |
hugEffects.appendChild(effect); | |
// Remove after animation | |
setTimeout(() => { | |
effect.remove(); | |
}, 2000); | |
} | |
// Update power display | |
function updatePower() { | |
const percentage = (powerLevel / maxPower) * 100; | |
powerBar.style.width = `${percentage}%`; | |
// Update click power based on power level | |
clickPower = 1 + Math.floor(powerLevel / 20); | |
powerText.textContent = powerLevel > 0 | |
? `Hug Power: ${clickPower}x (${Math.floor(powerLevel)}%)` | |
: 'Click faster to increase your hug power!'; | |
} | |
// Update all displays | |
function updateDisplay() { | |
// Update hug counter | |
hugCounter.textContent = `${Math.floor(hugs)} Hug${hugs !== 1 ? 's' : ''}`; | |
// Update HPS display | |
hugsPerSecondDisplay.textContent = `${hugsPerSecond.toFixed(1)} hugs per second`; | |
// Update upgrade cards | |
updateUpgradeCards(); | |
} | |
// Update upgrade cards state | |
function updateUpgradeCards() { | |
upgradeCards.forEach(card => { | |
const upgradeId = card.dataset.id; | |
const upgrade = upgrades[upgradeId]; | |
// Update cost display | |
card.querySelector('.cost').textContent = `${Math.floor(upgrade.cost)} Hugs`; | |
// Update owned count | |
card.querySelector('.owned').textContent = `Owned: ${upgrade.owned}`; | |
// Disable if can't afford | |
if (hugs < upgrade.cost) { | |
card.classList.add('opacity-50'); | |
} else { | |
card.classList.remove('opacity-50'); | |
} | |
}); | |
} | |
// Save game to localStorage | |
function saveGame() { | |
const gameData = { | |
hugs, | |
hugsPerSecond, | |
upgrades, | |
achievements, | |
currentHuggerIndex, | |
lastSave: Date.now() | |
}; | |
localStorage.setItem('hugsClickerSave', JSON.stringify(gameData)); | |
} | |
// Load game from localStorage | |
function loadGame() { | |
const savedData = localStorage.getItem('hugsClickerSave'); | |
if (savedData) { | |
const gameData = JSON.parse(savedData); | |
hugs = gameData.hugs || 0; | |
hugsPerSecond = gameData.hugsPerSecond || 0; | |
// Merge upgrades | |
for (const id in gameData.upgrades) { | |
if (upgrades[id]) { | |
upgrades[id].cost = gameData.upgrades[id].cost; | |
upgrades[id].owned = gameData.upgrades[id].owned; | |
} | |
} | |
// Merge achievements | |
for (const threshold in gameData.achievements) { | |
if (achievements[threshold]) { | |
achievements[threshold].unlocked = gameData.achievements[threshold].unlocked; | |
} | |
} | |
currentHuggerIndex = gameData.currentHuggerIndex || 0; | |
document.getElementById('hugger-image').src = huggerImages[currentHuggerIndex]; | |
// Calculate offline progress (up to 24 hours) | |
if (gameData.lastSave) { | |
const offlineTime = Math.min(Date.now() - gameData.lastSave, 86400000); // Max 24 hours | |
const offlineHugs = (hugsPerSecond * offlineTime) / 1000; | |
if (offlineHugs > 0) { | |
addHugs(offlineHugs); | |
alert(`Welcome back! You earned ${Math.floor(offlineHugs)} hugs while you were away!`); | |
} | |
} | |
// Update achievements display | |
for (const threshold in achievements) { | |
if (achievements[threshold].unlocked) { | |
const achievementElements = document.querySelectorAll(`.achievement[data-threshold="${threshold}"]`); | |
achievementElements.forEach(el => { | |
const icon = el.querySelector('.achievement-icon'); | |
icon.classList.remove('bg-purple-200'); | |
icon.classList.add('bg-purple-400', 'shadow-md'); | |
}); | |
} | |
} | |
} | |
} | |
// Start the game | |
init(); | |
</script> | |
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=FranckAbgrall/hugging-clicker" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
</html> |