Untitled
unknown
plain_text
9 months ago
26 kB
12
Indexable
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cupcake Clicker</title>
<style>
body {
font-family: 'Comic Sans MS', cursive;
background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 50%, #fecfef 100%);
margin: 0;
padding: 20px;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
}
.game-container {
max-width: 1200px;
width: 100%;
display: grid;
grid-template-columns: 1fr 350px;
gap: 20px;
}
.main-game {
background: rgba(255, 255, 255, 0.9);
border-radius: 20px;
padding: 30px;
text-align: center;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
}
.shop {
background: rgba(255, 255, 255, 0.9);
border-radius: 20px;
padding: 20px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
max-height: 700px;
overflow-y: auto;
}
h1 {
color: #d63384;
font-size: 2.5em;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
}
.stats {
font-size: 1.2em;
margin-bottom: 20px;
color: #6f42c1;
}
.cupcake {
font-size: 8em;
cursor: pointer;
transition: transform 0.1s;
user-select: none;
margin: 20px 0;
display: inline-block;
}
.cupcake:hover {
transform: scale(1.1);
}
.cupcake:active {
transform: scale(0.95);
}
.click-animation {
animation: bounce 0.3s ease-out;
}
@keyframes bounce {
0% { transform: scale(1); }
50% { transform: scale(1.2); }
100% { transform: scale(1); }
}
.shop-section {
margin-bottom: 25px;
}
.shop h2, .shop h3 {
color: #d63384;
text-align: center;
margin-bottom: 15px;
border-bottom: 2px solid #fecfef;
padding-bottom: 10px;
}
.shop h3 {
font-size: 1.3em;
color: #6f42c1;
}
.shop-item {
background: #fff;
border: 2px solid #e9ecef;
border-radius: 10px;
padding: 12px;
margin-bottom: 8px;
cursor: pointer;
transition: all 0.3s;
position: relative;
}
.shop-item:hover {
border-color: #d63384;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.shop-item.affordable {
border-color: #28a745;
background: #f8fff9;
}
.shop-item.unaffordable {
opacity: 0.6;
cursor: not-allowed;
}
.shop-item.click-upgrade {
border-left: 4px solid #ff6b6b;
}
.shop-item.passive-upgrade {
border-left: 4px solid #4ecdc4;
}
.item-name {
font-weight: bold;
color: #d63384;
font-size: 1em;
}
.item-description {
font-size: 0.85em;
color: #666;
margin: 5px 0;
}
.item-cost {
font-weight: bold;
color: #28a745;
font-size: 0.9em;
}
.item-owned {
float: right;
background: #6f42c1;
color: white;
padding: 2px 6px;
border-radius: 10px;
font-size: 0.75em;
}
.floating-number {
position: absolute;
font-weight: bold;
color: #d63384;
font-size: 1.5em;
pointer-events: none;
animation: float-up 1s ease-out forwards;
}
@keyframes float-up {
0% {
opacity: 1;
transform: translateY(0);
}
100% {
opacity: 0;
transform: translateY(-100px);
}
}
.achievements {
margin-top: 20px;
text-align: left;
}
.achievement {
background: #fff3cd;
border: 1px solid #ffeaa7;
border-radius: 5px;
padding: 8px;
margin: 5px 0;
font-size: 0.8em;
}
.achievement.unlocked {
background: #d4edda;
border-color: #c3e6cb;
}
.critical-hit {
color: #ff6b6b !important;
font-size: 2em !important;
text-shadow: 0 0 10px #ff6b6b;
}
@media (max-width: 768px) {
.game-container {
grid-template-columns: 1fr;
}
.cupcake {
font-size: 6em;
}
}
</style>
</head>
<body>
<div class="game-container">
<div class="main-game">
<h1>🧁 Cupcake Clicker 🧁</h1>
<div class="stats">
<div>Cupcakes: <span id="cupcakeCount">0</span></div>
<div>Per Second: <span id="cupcakesPerSecond">0</span></div>
<div>Per Click: <span id="cupcakesPerClick">1</span></div>
<div>Critical Chance: <span id="criticalChance">0</span>%</div>
</div>
<div class="cupcake" id="mainCupcake" onclick="clickCupcake()">🧁</div>
<div>Click the cupcake to start baking!</div>
</div>
<div class="shop">
<h2>🛒 Bakery Shop</h2>
<div class="shop-section">
<h3>👆 Click Upgrades</h3>
<div id="clickUpgrades"></div>
</div>
<div class="shop-section">
<h3>🏭 Passive Income</h3>
<div id="passiveUpgrades"></div>
</div>
<div class="achievements">
<h3>🏆 Achievements</h3>
<div id="achievements"></div>
</div>
</div>
</div>
<script>
// Game state
let gameState = {
cupcakes: 0,
cupcakesPerSecond: 0,
cupcakesPerClick: 1,
totalCupcakesBaked: 0,
totalClicks: 0,
criticalChance: 0,
criticalMultiplier: 2,
clickMultiplier: 1
};
// Click upgrades
const clickUpgrades = [
{
id: 'cursor',
name: '👆 Extra Finger',
description: '+1 cupcake per click',
baseCost: 15,
cost: 15,
owned: 0,
effect: () => gameState.cupcakesPerClick += 1
},
{
id: 'reinforced_finger',
name: '💪 Reinforced Finger',
description: '+2 cupcakes per click',
baseCost: 100,
cost: 100,
owned: 0,
effect: () => gameState.cupcakesPerClick += 2
},
{
id: 'golden_touch',
name: '✨ Golden Touch',
description: '+5 cupcakes per click',
baseCost: 500,
cost: 500,
owned: 0,
effect: () => gameState.cupcakesPerClick += 5
},
{
id: 'click_frenzy',
name: '⚡ Click Frenzy',
description: '+10 cupcakes per click',
baseCost: 2500,
cost: 2500,
owned: 0,
effect: () => gameState.cupcakesPerClick += 10
},
{
id: 'sugar_rush',
name: '🍭 Sugar Rush',
description: '+25 cupcakes per click',
baseCost: 10000,
cost: 10000,
owned: 0,
effect: () => gameState.cupcakesPerClick += 25
},
{
id: 'mega_click',
name: '💥 Mega Click',
description: '+50 cupcakes per click',
baseCost: 50000,
cost: 50000,
owned: 0,
effect: () => gameState.cupcakesPerClick += 50
},
{
id: 'ultra_click',
name: '🚀 Ultra Click',
description: '+100 cupcakes per click',
baseCost: 250000,
cost: 250000,
owned: 0,
effect: () => gameState.cupcakesPerClick += 100
},
{
id: 'divine_click',
name: '👼 Divine Click',
description: '+250 cupcakes per click',
baseCost: 1000000,
cost: 1000000,
owned: 0,
effect: () => gameState.cupcakesPerClick += 250
},
{
id: 'lucky_finger',
name: '🍀 Lucky Finger',
description: '+2% critical hit chance',
baseCost: 1000,
cost: 1000,
owned: 0,
effect: () => gameState.criticalChance += 2
},
{
id: 'fortune_touch',
name: '🎰 Fortune Touch',
description: '+3% critical hit chance',
baseCost: 5000,
cost: 5000,
owned: 0,
effect: () => gameState.criticalChance += 3
},
{
id: 'blessed_hands',
name: '🙏 Blessed Hands',
description: '+5% critical hit chance',
baseCost: 25000,
cost: 25000,
owned: 0,
effect: () => gameState.criticalChance += 5
},
{
id: 'critical_master',
name: '⭐ Critical Master',
description: 'Critical hits do 3x damage instead of 2x',
baseCost: 100000,
cost: 100000,
owned: 0,
maxOwned: 1,
effect: () => gameState.criticalMultiplier = 3
},
{
id: 'double_tap',
name: '👆👆 Double Tap',
description: 'Each click counts as 2 clicks',
baseCost: 75000,
cost: 75000,
owned: 0,
maxOwned: 1,
effect: () => gameState.clickMultiplier = 2
},
{
id: 'triple_tap',
name: '👆👆👆 Triple Tap',
description: 'Each click counts as 3 clicks (replaces Double Tap)',
baseCost: 500000,
cost: 500000,
owned: 0,
maxOwned: 1,
effect: () => gameState.clickMultiplier = 3
},
{
id: 'click_storm',
name: '🌪️ Click Storm',
description: 'Clicks have 10% chance to trigger 5 extra clicks',
baseCost: 200000,
cost: 200000,
owned: 0,
maxOwned: 1,
effect: () => {} // Special effect handled in click function
}
];
// Passive upgrades
const passiveUpgrades = [
{
id: 'grandma',
name: '👵 Grandma Baker',
description: '+1 cupcake per second',
baseCost: 100,
cost: 100,
owned: 0,
effect: () => gameState.cupcakesPerSecond += 1
},
{
id: 'oven',
name: '🔥 Magic Oven',
description: '+5 cupcakes per second',
baseCost: 500,
cost: 500,
owned: 0,
effect: () => gameState.cupcakesPerSecond += 5
},
{
id: 'bakery',
name: '🏪 Cupcake Bakery',
description: '+20 cupcakes per second',
baseCost: 2000,
cost: 2000,
owned: 0,
effect: () => gameState.cupcakesPerSecond += 20
},
{
id: 'factory',
name: '🏭 Cupcake Factory',
description: '+100 cupcakes per second',
baseCost: 10000,
cost: 10000,
owned: 0,
effect: () => gameState.cupcakesPerSecond += 100
},
{
id: 'wizard',
name: '🧙♂️ Cupcake Wizard',
description: '+500 cupcakes per second',
baseCost: 50000,
cost: 50000,
owned: 0,
effect: () => gameState.cupcakesPerSecond += 500
},
{
id: 'portal',
name: '🌀 Cupcake Portal',
description: '+2000 cupcakes per second',
baseCost: 200000,
cost: 200000,
owned: 0,
effect: () => gameState.cupcakesPerSecond += 2000
},
{
id: 'time_machine',
name: '⏰ Time Machine',
description: '+10000 cupcakes per second',
baseCost: 1000000,
cost: 1000000,
owned: 0,
effect: () => gameState.cupcakesPerSecond += 10000
}
];
// Achievements
const achievements = [
{ id: 'first_click', name: 'First Bite', description: 'Click your first cupcake', condition: () => gameState.totalClicks >= 1, unlocked: false },
{ id: 'hundred_cupcakes', name: 'Sweet Tooth', description: 'Bake 100 cupcakes', condition: () => gameState.totalCupcakesBaked >= 100, unlocked: false },
{ id: 'thousand_cupcakes', name: 'Cupcake Lover', description: 'Bake 1,000 cupcakes', condition: () => gameState.totalCupcakesBaked >= 1000, unlocked: false },
{ id: 'first_grandma', name: 'Grandma\'s Helper', description: 'Buy your first Grandma Baker', condition: () => passiveUpgrades.find(item => item.id === 'grandma').owned >= 1, unlocked: false },
{ id: 'ten_thousand_cupcakes', name: 'Cupcake Master', description: 'Bake 10,000 cupcakes', condition: () => gameState.totalCupcakesBaked >= 10000, unlocked: false },
{ id: 'hundred_clicks', name: 'Click Master', description: 'Click 100 times', condition: () => gameState.totalClicks >= 100, unlocked: false },
{ id: 'first_critical', name: 'Lucky Strike', description: 'Get your first critical hit upgrade', condition: () => clickUpgrades.find(item => item.id === 'lucky_finger').owned >= 1, unlocked: false },
{ id: 'million_cupcakes', name: 'Cupcake Millionaire', description: 'Bake 1,000,000 cupcakes', condition: () => gameState.totalCupcakesBaked >= 1000000, unlocked: false },
{ id: 'thousand_clicks', name: 'Click Legend', description: 'Click 1,000 times', condition: () => gameState.totalClicks >= 1000, unlocked: false },
{ id: 'max_critical', name: 'Critical Expert', description: 'Reach 25% critical chance', condition: () => gameState.criticalChance >= 25, unlocked: false }
];
function clickCupcake() {
let totalCupcakesEarned = 0;
let clicksToProcess = gameState.clickMultiplier;
let isCritical = false;
// Process each click (for double/triple tap)
for (let i = 0; i < clicksToProcess; i++) {
let cupcakesThisClick = gameState.cupcakesPerClick;
// Check for critical hit
if (Math.random() * 100 < gameState.criticalChance) {
cupcakesThisClick *= gameState.criticalMultiplier;
isCritical = true;
}
totalCupcakesEarned += cupcakesThisClick;
}
// Check for click storm
const clickStorm = clickUpgrades.find(item => item.id === 'click_storm');
if (clickStorm && clickStorm.owned > 0 && Math.random() < 0.1) {
// Trigger 5 extra clicks
for (let i = 0; i < 5; i++) {
let bonusClick = gameState.cupcakesPerClick;
if (Math.random() * 100 < gameState.criticalChance) {
bonusClick *= gameState.criticalMultiplier;
isCritical = true;
}
totalCupcakesEarned += bonusClick;
}
}
gameState.cupcakes += totalCupcakesEarned;
gameState.totalCupcakesBaked += totalCupcakesEarned;
gameState.totalClicks++;
// Animation
const cupcake = document.getElementById('mainCupcake');
cupcake.classList.add('click-animation');
setTimeout(() => cupcake.classList.remove('click-animation'), 300);
// Floating number animation
showFloatingNumber(totalCupcakesEarned, isCritical);
updateDisplay();
checkAchievements();
}
function showFloatingNumber(amount, isCritical = false) {
const cupcake = document.getElementById('mainCupcake');
const rect = cupcake.getBoundingClientRect();
const floatingNumber = document.createElement('div');
floatingNumber.className = 'floating-number';
if (isCritical) {
floatingNumber.classList.add('critical-hit');
floatingNumber.textContent = `CRIT! +${Math.floor(amount)}`;
} else {
floatingNumber.textContent = `+${Math.floor(amount)}`;
}
floatingNumber.style.left = (rect.left + rect.width / 2 + (Math.random() - 0.5) * 100) + 'px';
floatingNumber.style.top = rect.top + 'px';
floatingNumber.style.position = 'fixed';
document.body.appendChild(floatingNumber);
setTimeout(() => {
if (document.body.contains(floatingNumber)) {
document.body.removeChild(floatingNumber);
}
}, 1000);
}
function buyItem(itemId, isClickUpgrade = true) {
const items = isClickUpgrade ? clickUpgrades : passiveUpgrades;
const item = items.find(i => i.id === itemId);
if (gameState.cupcakes >= item.cost && (!item.maxOwned || item.owned < item.maxOwned)) {
gameState.cupcakes -= item.cost;
item.owned++;
item.effect();
if (!item.maxOwned || item.owned < item.maxOwned) {
item.cost = Math.ceil(item.baseCost * Math.pow(1.15, item.owned));
}
updateDisplay();
checkAchievements();
}
}
function updateDisplay() {
document.getElementById('cupcakeCount').textContent = Math.floor(gameState.cupcakes).toLocaleString();
document.getElementById('cupcakesPerSecond').textContent = gameState.cupcakesPerSecond.toLocaleString();
document.getElementById('cupcakesPerClick').textContent = Math.floor(gameState.cupcakesPerClick).toLocaleString();
document.getElementById('criticalChance').textContent = Math.min(gameState.criticalChance, 100).toFixed(1);
// Update click upgrades
updateShopSection('clickUpgrades', clickUpgrades, true);
// Update passive upgrades
updateShopSection('passiveUpgrades', passiveUpgrades, false);
}
function updateShopSection(containerId, items, isClickUpgrade) {
const container = document.getElementById(containerId);
container.innerHTML = '';
items.forEach(item => {
const itemElement = document.createElement('div');
itemElement.className = `shop-item ${isClickUpgrade ? 'click-upgrade' : 'passive-upgrade'}`;
const canAfford = gameState.cupcakes >= item.cost;
const maxedOut = item.maxOwned && item.owned >= item.maxOwned;
if (canAfford && !maxedOut) {
itemElement.classList.add('affordable');
} else {
itemElement.classList.add('unaffordable');
}
let costText = maxedOut ? 'MAX' : `${item.cost.toLocaleString()} cupcakes`;
itemElement.innerHTML = `
<div class="item-name">${item.name} <span class="item-owned">${item.owned}${item.maxOwned ? `/${item.maxOwned}` : ''}</span></div>
<div class="item-description">${item.description}</div>
<div class="item-cost">Cost: ${costText}</div>
`;
if (!maxedOut) {
itemElement.onclick = () => buyItem(item.id, isClickUpgrade);
}
container.appendChild(itemElement);
});
}
function checkAchievements() {
const achievementContainer = document.getElementById('achievements');
achievementContainer.innerHTML = '';
achievements.forEach(achievement => {
if (!achievement.unlocked && achievement.condition()) {
achievement.unlocked = true;
showAchievementNotification(achievement);
}
const achievementElement = document.createElement('div');
achievementElement.className = `achievement ${achievement.unlocked ? 'unlocked' : ''}`;
achievementElement.innerHTML = `
<strong>${achievement.name}</strong><br>
${achievement.description}
`;
achievementContainer.appendChild(achievementElement);
});
}
function showAchievementNotification(achievement) {
setTimeout(() => {
alert(`🏆 Achievement Unlocked: ${achievement.name}!\n${achievement.description}`);
}, 100);
}
// Game loop for passive income
setInterval(() => {
if (gameState.cupcakesPerSecond > 0) {
const cupcakesEarned = gameState.cupcakesPerSecond / 10;
gameState.cupcakes += cupcakesEarned;
gameState.totalCupcakesBaked += cupcakesEarned;
updateDisplay();
}
}, 100);
setInterval(checkAchievements, 1000);
// Save game
setInterval(() => {
localStorage.setItem('cupcakeClickerSave', JSON.stringify({
gameState,
clickUpgrades: clickUpgrades.map(item => ({ id: item.id, owned: item.owned, cost: item.cost })),
passiveUpgrades: passiveUpgrades.map(item => ({ id: item.id, owned: item.owned, cost: item.cost })),
achievements: achievements.map(ach => ({ id: ach.id, unlocked: ach.unlocked }))
}));
}, 5000);
// Load game
window.addEventListener('load', () => {
const savedGame = localStorage.getItem('cupcakeClickerSave');
if (savedGame) {
try {
const save = JSON.parse(savedGame);
gameState = { ...gameState, ...save.gameState };
if (save.clickUpgrades) {
save.clickUpgrades.forEach(savedItem => {
const item = clickUpgrades.find(i => i.id === savedItem.id);
if (item) {
item.owned = savedItem.owned;
item.cost = savedItem.cost;
}
});
}
if (save.passiveUpgrades) {
save.passiveUpgrades.forEach(savedItem => {
const item = passiveUpgrades.find(i => i.id === savedItem.id);
if (item) {
item.owned = savedItem.owned;
item.cost = savedItem.cost;
}
});
}
if (save.achievements) {
save.achievements.forEach(savedAch => {
const ach = achievements.find(a => a.id === savedAch.id);
if (ach) {
ach.unlocked = savedAch.unlocked;
}
});
}
updateDisplay();
checkAchievements();
} catch (e) {
console.log('Could not load save game');
}
}
});
// Initialize
updateDisplay();
checkAchievements();
</script>
</body>
</html>
Editor is loading...
Leave a Comment