|
|
<!DOCTYPE html> |
|
|
<html lang="en"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>Clone Evolution - The Consumption Game</title> |
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
|
<style> |
|
|
* { |
|
|
margin: 0; |
|
|
padding: 0; |
|
|
box-sizing: border-box; |
|
|
} |
|
|
|
|
|
:root { |
|
|
--primary-color: #6c5ce7; |
|
|
--secondary-color: #a29bfe; |
|
|
--accent-color: #00cec9; |
|
|
--danger-color: #ff7675; |
|
|
--success-color: #00b894; |
|
|
--dark-bg: #0a0a1a; |
|
|
--card-bg: rgba(255, 255, 255, 0.05); |
|
|
} |
|
|
|
|
|
body { |
|
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; |
|
|
background: var(--dark-bg); |
|
|
min-height: 100vh; |
|
|
color: white; |
|
|
overflow-x: hidden; |
|
|
} |
|
|
|
|
|
header { |
|
|
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); |
|
|
padding: 1rem 2rem; |
|
|
display: flex; |
|
|
justify-content: space-between; |
|
|
align-items: center; |
|
|
flex-wrap: wrap; |
|
|
gap: 1rem; |
|
|
box-shadow: 0 4px 20px rgba(108, 92, 231, 0.3); |
|
|
} |
|
|
|
|
|
.logo { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 0.5rem; |
|
|
font-size: 1.5rem; |
|
|
font-weight: bold; |
|
|
} |
|
|
|
|
|
.logo i { |
|
|
animation: pulse 2s infinite; |
|
|
} |
|
|
|
|
|
@keyframes pulse { |
|
|
0%, 100% { transform: scale(1); } |
|
|
50% { transform: scale(1.2); } |
|
|
} |
|
|
|
|
|
.built-with { |
|
|
font-size: 0.9rem; |
|
|
opacity: 0.9; |
|
|
} |
|
|
|
|
|
.built-with a { |
|
|
color: white; |
|
|
text-decoration: none; |
|
|
font-weight: bold; |
|
|
transition: all 0.3s; |
|
|
} |
|
|
|
|
|
.built-with a:hover { |
|
|
text-shadow: 0 0 10px white; |
|
|
} |
|
|
|
|
|
.stats-bar { |
|
|
display: flex; |
|
|
gap: 2rem; |
|
|
padding: 1rem 2rem; |
|
|
background: var(--card-bg); |
|
|
backdrop-filter: blur(10px); |
|
|
flex-wrap: wrap; |
|
|
justify-content: center; |
|
|
} |
|
|
|
|
|
.stat { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
align-items: center; |
|
|
min-width: 100px; |
|
|
} |
|
|
|
|
|
.stat-label { |
|
|
font-size: 0.8rem; |
|
|
opacity: 0.7; |
|
|
text-transform: uppercase; |
|
|
} |
|
|
|
|
|
.stat-value { |
|
|
font-size: 1.5rem; |
|
|
font-weight: bold; |
|
|
color: var(--accent-color); |
|
|
} |
|
|
|
|
|
.game-container { |
|
|
display: grid; |
|
|
grid-template-columns: 1fr 2fr 1fr; |
|
|
gap: 1rem; |
|
|
padding: 1rem; |
|
|
max-width: 1600px; |
|
|
margin: 0 auto; |
|
|
} |
|
|
|
|
|
@media (max-width: 1200px) { |
|
|
.game-container { |
|
|
grid-template-columns: 1fr 1fr; |
|
|
} |
|
|
} |
|
|
|
|
|
@media (max-width: 768px) { |
|
|
.game-container { |
|
|
grid-template-columns: 1fr; |
|
|
} |
|
|
} |
|
|
|
|
|
.panel { |
|
|
background: var(--card-bg); |
|
|
border-radius: 15px; |
|
|
padding: 1.5rem; |
|
|
backdrop-filter: blur(10px); |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
} |
|
|
|
|
|
.panel-title { |
|
|
font-size: 1.2rem; |
|
|
margin-bottom: 1rem; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 0.5rem; |
|
|
color: var(--secondary-color); |
|
|
} |
|
|
|
|
|
.game-arena { |
|
|
min-height: 500px; |
|
|
position: relative; |
|
|
background: linear-gradient(180deg, #1a1a2e 0%, #16213e 100%); |
|
|
border-radius: 15px; |
|
|
overflow: hidden; |
|
|
} |
|
|
|
|
|
.arena-floor { |
|
|
position: absolute; |
|
|
bottom: 0; |
|
|
width: 100%; |
|
|
height: 100px; |
|
|
background: linear-gradient(180deg, #2d3436 0%, #1a1a2e 100%); |
|
|
} |
|
|
|
|
|
.player { |
|
|
position: absolute; |
|
|
bottom: 100px; |
|
|
left: 50%; |
|
|
transform: translateX(-50%); |
|
|
width: 60px; |
|
|
height: 80px; |
|
|
background: linear-gradient(180deg, var(--primary-color), var(--secondary-color)); |
|
|
border-radius: 30px 30px 20px 20px; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
box-shadow: 0 0 30px var(--primary-color); |
|
|
transition: all 0.3s; |
|
|
z-index: 10; |
|
|
} |
|
|
|
|
|
.player.evolved-1 { |
|
|
box-shadow: 0 0 40px var(--accent-color); |
|
|
background: linear-gradient(180deg, var(--accent-color), #00b894); |
|
|
} |
|
|
|
|
|
.player.evolved-2 { |
|
|
box-shadow: 0 0 50px #fd79a8; |
|
|
background: linear-gradient(180deg, #fd79a8, #e84393); |
|
|
} |
|
|
|
|
|
.player.evolved-3 { |
|
|
box-shadow: 0 0 60px #ffeaa7; |
|
|
background: linear-gradient(180deg, #ffeaa7, #fdcb6e); |
|
|
} |
|
|
|
|
|
.player-face { |
|
|
width: 40px; |
|
|
height: 25px; |
|
|
background: rgba(255, 255, 255, 0.9); |
|
|
border-radius: 50%; |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
gap: 8px; |
|
|
} |
|
|
|
|
|
.eye { |
|
|
width: 8px; |
|
|
height: 8px; |
|
|
background: #2d3436; |
|
|
border-radius: 50%; |
|
|
animation: blink 3s infinite; |
|
|
} |
|
|
|
|
|
@keyframes blink { |
|
|
0%, 90%, 100% { transform: scaleY(1); } |
|
|
95% { transform: scaleY(0.1); } |
|
|
} |
|
|
|
|
|
.clone { |
|
|
position: absolute; |
|
|
bottom: 100px; |
|
|
width: 40px; |
|
|
height: 55px; |
|
|
border-radius: 20px 20px 15px 15px; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
opacity: 0.8; |
|
|
transition: all 0.5s; |
|
|
animation: cloneSpawn 0.5s ease-out; |
|
|
} |
|
|
|
|
|
@keyframes cloneSpawn { |
|
|
0% { transform: scale(0); opacity: 0; } |
|
|
50% { transform: scale(1.2); } |
|
|
100% { transform: scale(1); opacity: 0.8; } |
|
|
} |
|
|
|
|
|
.clone-face { |
|
|
width: 25px; |
|
|
height: 15px; |
|
|
background: rgba(255, 255, 255, 0.9); |
|
|
border-radius: 50%; |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
gap: 5px; |
|
|
} |
|
|
|
|
|
.clone .eye { |
|
|
width: 5px; |
|
|
height: 5px; |
|
|
} |
|
|
|
|
|
.consumable { |
|
|
position: absolute; |
|
|
cursor: pointer; |
|
|
transition: all 0.3s; |
|
|
animation: float 2s ease-in-out infinite; |
|
|
z-index: 5; |
|
|
} |
|
|
|
|
|
.consumable:hover { |
|
|
transform: scale(1.2); |
|
|
filter: brightness(1.3); |
|
|
} |
|
|
|
|
|
@keyframes float { |
|
|
0%, 100% { transform: translateY(0); } |
|
|
50% { transform: translateY(-10px); } |
|
|
} |
|
|
|
|
|
.consumable-icon { |
|
|
font-size: 2rem; |
|
|
filter: drop-shadow(0 0 10px currentColor); |
|
|
} |
|
|
|
|
|
.items-grid { |
|
|
display: grid; |
|
|
grid-template-columns: repeat(2, 1fr); |
|
|
gap: 0.5rem; |
|
|
} |
|
|
|
|
|
.item-card { |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
border-radius: 10px; |
|
|
padding: 0.8rem; |
|
|
text-align: center; |
|
|
cursor: pointer; |
|
|
transition: all 0.3s; |
|
|
border: 2px solid transparent; |
|
|
} |
|
|
|
|
|
.item-card:hover { |
|
|
background: rgba(255, 255, 255, 0.1); |
|
|
border-color: var(--accent-color); |
|
|
transform: translateY(-3px); |
|
|
} |
|
|
|
|
|
.item-card.locked { |
|
|
opacity: 0.5; |
|
|
cursor: not-allowed; |
|
|
} |
|
|
|
|
|
.item-icon { |
|
|
font-size: 2rem; |
|
|
margin-bottom: 0.5rem; |
|
|
} |
|
|
|
|
|
.item-name { |
|
|
font-size: 0.8rem; |
|
|
margin-bottom: 0.3rem; |
|
|
} |
|
|
|
|
|
.item-effect { |
|
|
font-size: 0.7rem; |
|
|
opacity: 0.7; |
|
|
} |
|
|
|
|
|
.item-cost { |
|
|
font-size: 0.8rem; |
|
|
color: var(--accent-color); |
|
|
margin-top: 0.3rem; |
|
|
} |
|
|
|
|
|
.evolution-track { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
gap: 1rem; |
|
|
} |
|
|
|
|
|
.evolution-stage { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 1rem; |
|
|
padding: 1rem; |
|
|
background: rgba(255, 255, 255, 0.03); |
|
|
border-radius: 10px; |
|
|
border-left: 4px solid var(--primary-color); |
|
|
transition: all 0.3s; |
|
|
} |
|
|
|
|
|
.evolution-stage.active { |
|
|
border-left-color: var(--success-color); |
|
|
background: rgba(0, 184, 148, 0.1); |
|
|
} |
|
|
|
|
|
.evolution-stage.locked { |
|
|
opacity: 0.5; |
|
|
} |
|
|
|
|
|
.evolution-icon { |
|
|
font-size: 2rem; |
|
|
} |
|
|
|
|
|
.evolution-info h4 { |
|
|
margin-bottom: 0.3rem; |
|
|
} |
|
|
|
|
|
.evolution-info p { |
|
|
font-size: 0.8rem; |
|
|
opacity: 0.7; |
|
|
} |
|
|
|
|
|
.progress-bar { |
|
|
width: 100%; |
|
|
height: 8px; |
|
|
background: rgba(255, 255, 255, 0.1); |
|
|
border-radius: 4px; |
|
|
overflow: hidden; |
|
|
margin-top: 0.5rem; |
|
|
} |
|
|
|
|
|
.progress-fill { |
|
|
height: 100%; |
|
|
background: linear-gradient(90deg, var(--primary-color), var(--accent-color)); |
|
|
transition: width 0.5s; |
|
|
border-radius: 4px; |
|
|
} |
|
|
|
|
|
.abilities-list { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
gap: 0.5rem; |
|
|
} |
|
|
|
|
|
.ability { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 0.5rem; |
|
|
padding: 0.8rem; |
|
|
background: rgba(255, 255, 255, 0.03); |
|
|
border-radius: 8px; |
|
|
cursor: pointer; |
|
|
transition: all 0.3s; |
|
|
} |
|
|
|
|
|
.ability:hover:not(.locked) { |
|
|
background: rgba(255, 255, 255, 0.1); |
|
|
} |
|
|
|
|
|
.ability.locked { |
|
|
opacity: 0.5; |
|
|
cursor: not-allowed; |
|
|
} |
|
|
|
|
|
.ability-icon { |
|
|
font-size: 1.5rem; |
|
|
} |
|
|
|
|
|
.ability-info { |
|
|
flex: 1; |
|
|
} |
|
|
|
|
|
.ability-name { |
|
|
font-size: 0.9rem; |
|
|
font-weight: bold; |
|
|
} |
|
|
|
|
|
.ability-desc { |
|
|
font-size: 0.7rem; |
|
|
opacity: 0.7; |
|
|
} |
|
|
|
|
|
.ability-cooldown { |
|
|
font-size: 0.8rem; |
|
|
color: var(--danger-color); |
|
|
} |
|
|
|
|
|
.controls { |
|
|
position: fixed; |
|
|
bottom: 1rem; |
|
|
left: 50%; |
|
|
transform: translateX(-50%); |
|
|
display: flex; |
|
|
gap: 1rem; |
|
|
background: var(--card-bg); |
|
|
padding: 1rem; |
|
|
border-radius: 50px; |
|
|
backdrop-filter: blur(10px); |
|
|
} |
|
|
|
|
|
.control-btn { |
|
|
width: 50px; |
|
|
height: 50px; |
|
|
border-radius: 50%; |
|
|
border: none; |
|
|
background: var(--primary-color); |
|
|
color: white; |
|
|
font-size: 1.2rem; |
|
|
cursor: pointer; |
|
|
transition: all 0.3s; |
|
|
} |
|
|
|
|
|
.control-btn:hover { |
|
|
transform: scale(1.1); |
|
|
box-shadow: 0 0 20px var(--primary-color); |
|
|
} |
|
|
|
|
|
.control-btn:active { |
|
|
transform: scale(0.95); |
|
|
} |
|
|
|
|
|
.notification { |
|
|
position: fixed; |
|
|
top: 100px; |
|
|
left: 50%; |
|
|
transform: translateX(-50%); |
|
|
background: var(--success-color); |
|
|
color: white; |
|
|
padding: 1rem 2rem; |
|
|
border-radius: 10px; |
|
|
font-weight: bold; |
|
|
opacity: 0; |
|
|
transition: all 0.5s; |
|
|
z-index: 100; |
|
|
} |
|
|
|
|
|
.notification.show { |
|
|
opacity: 1; |
|
|
animation: slideDown 0.5s ease-out; |
|
|
} |
|
|
|
|
|
@keyframes slideDown { |
|
|
0% { transform: translateX(-50%) translateY(-20px); } |
|
|
100% { transform: translateX(-50%) translateY(0); } |
|
|
} |
|
|
|
|
|
.clone-counter { |
|
|
position: absolute; |
|
|
top: 10px; |
|
|
right: 10px; |
|
|
background: var(--primary-color); |
|
|
padding: 0.5rem 1rem; |
|
|
border-radius: 20px; |
|
|
font-weight: bold; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 0.5rem; |
|
|
} |
|
|
|
|
|
.enemy { |
|
|
position: absolute; |
|
|
width: 50px; |
|
|
height: 60px; |
|
|
background: linear-gradient(180deg, #e74c3c, #c0392b); |
|
|
border-radius: 10px; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
box-shadow: 0 0 20px rgba(231, 76, 60, 0.5); |
|
|
animation: enemyMove 3s ease-in-out infinite; |
|
|
} |
|
|
|
|
|
@keyframes enemyMove { |
|
|
0%, 100% { transform: translateX(0); } |
|
|
50% { transform: translateX(20px); } |
|
|
} |
|
|
|
|
|
.enemy-face { |
|
|
width: 30px; |
|
|
height: 20px; |
|
|
background: rgba(255, 255, 255, 0.9); |
|
|
border-radius: 50%; |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
gap: 5px; |
|
|
} |
|
|
|
|
|
.enemy .eye { |
|
|
background: #c0392b; |
|
|
} |
|
|
|
|
|
.hp-bar { |
|
|
width: 40px; |
|
|
height: 5px; |
|
|
background: rgba(0, 0, 0, 0.3); |
|
|
border-radius: 3px; |
|
|
margin-top: 5px; |
|
|
overflow: hidden; |
|
|
} |
|
|
|
|
|
.hp-fill { |
|
|
height: 100%; |
|
|
background: #2ecc71; |
|
|
transition: width 0.3s; |
|
|
} |
|
|
|
|
|
.score-popup { |
|
|
position: absolute; |
|
|
color: #ffd700; |
|
|
font-weight: bold; |
|
|
font-size: 1.2rem; |
|
|
pointer-events: none; |
|
|
animation: scoreFloat 1s ease-out forwards; |
|
|
} |
|
|
|
|
|
@keyframes scoreFloat { |
|
|
0% { opacity: 1; transform: translateY(0); } |
|
|
100% { opacity: 0; transform: translateY(-50px); } |
|
|
} |
|
|
|
|
|
.modal { |
|
|
position: fixed; |
|
|
top: 0; |
|
|
left: 0; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
background: rgba(0, 0, 0, 0.8); |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
z-index: 1000; |
|
|
opacity: 0; |
|
|
visibility: hidden; |
|
|
transition: all 0.3s; |
|
|
} |
|
|
|
|
|
.modal.show { |
|
|
opacity: 1; |
|
|
visibility: visible; |
|
|
} |
|
|
|
|
|
.modal-content { |
|
|
background: var(--dark-bg); |
|
|
padding: 2rem; |
|
|
border-radius: 20px; |
|
|
max-width: 500px; |
|
|
width: 90%; |
|
|
text-align: center; |
|
|
border: 2px solid var(--primary-color); |
|
|
animation: modalPop 0.3s ease-out; |
|
|
} |
|
|
|
|
|
@keyframes modalPop { |
|
|
0% { transform: scale(0.8); } |
|
|
100% { transform: scale(1); } |
|
|
} |
|
|
|
|
|
.modal h2 { |
|
|
margin-bottom: 1rem; |
|
|
color: var(--accent-color); |
|
|
} |
|
|
|
|
|
.modal p { |
|
|
margin-bottom: 1.5rem; |
|
|
opacity: 0.8; |
|
|
} |
|
|
|
|
|
.modal-btn { |
|
|
padding: 1rem 2rem; |
|
|
border: none; |
|
|
border-radius: 10px; |
|
|
background: var(--primary-color); |
|
|
color: white; |
|
|
font-size: 1rem; |
|
|
cursor: pointer; |
|
|
transition: all 0.3s; |
|
|
} |
|
|
|
|
|
.modal-btn:hover { |
|
|
transform: scale(1.05); |
|
|
box-shadow: 0 0 20px var(--primary-color); |
|
|
} |
|
|
|
|
|
.tutorial-tip { |
|
|
position: absolute; |
|
|
background: var(--accent-color); |
|
|
color: white; |
|
|
padding: 0.5rem 1rem; |
|
|
border-radius: 10px; |
|
|
font-size: 0.8rem; |
|
|
z-index: 50; |
|
|
animation: bounce 1s infinite; |
|
|
} |
|
|
|
|
|
@keyframes bounce { |
|
|
0%, 100% { transform: translateY(0); } |
|
|
50% { transform: translateY(-5px); } |
|
|
} |
|
|
|
|
|
.xp-bar-container { |
|
|
width: 100%; |
|
|
margin-top: 1rem; |
|
|
} |
|
|
|
|
|
.xp-label { |
|
|
display: flex; |
|
|
justify-content: space-between; |
|
|
font-size: 0.8rem; |
|
|
margin-bottom: 0.3rem; |
|
|
} |
|
|
|
|
|
.special-effect { |
|
|
position: absolute; |
|
|
pointer-events: none; |
|
|
z-index: 20; |
|
|
} |
|
|
|
|
|
.particle { |
|
|
position: absolute; |
|
|
width: 10px; |
|
|
height: 10px; |
|
|
border-radius: 50%; |
|
|
animation: particleExplode 1s ease-out forwards; |
|
|
} |
|
|
|
|
|
@keyframes particleExplode { |
|
|
0% { transform: translate(0, 0) scale(1); opacity: 1; } |
|
|
100% { transform: translate(var(--tx), var(--ty)) scale(0); opacity: 0; } |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body> |
|
|
<header> |
|
|
<div class="logo"> |
|
|
<i class="fas fa-dna"></i> |
|
|
Clone Evolution |
|
|
</div> |
|
|
<div class="built-with"> |
|
|
Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">anycoder</a> |
|
|
</div> |
|
|
</header> |
|
|
|
|
|
<div class="stats-bar"> |
|
|
<div class="stat"> |
|
|
<span class="stat-label">Level</span> |
|
|
<span class="stat-value" id="level">1</span> |
|
|
</div> |
|
|
<div class="stat"> |
|
|
<span class="stat-label">Score</span> |
|
|
<span class="stat-value" id="score">0</span> |
|
|
</div> |
|
|
<div class="stat"> |
|
|
<span class="stat-label">Clones</span> |
|
|
<span class="stat-value" id="cloneCount">0</span> |
|
|
</div> |
|
|
<div class="stat"> |
|
|
<span class="stat-label">Energy</span> |
|
|
<span class="stat-value" id="energy">100</span> |
|
|
</div> |
|
|
<div class="stat"> |
|
|
<span class="stat-label">Evolution</span> |
|
|
<span class="stat-value" id="evolutionStage">Base</span> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="game-container"> |
|
|
<div class="panel"> |
|
|
<h3 class="panel-title"><i class="fas fa-flask"></i> Consumables</h3> |
|
|
<div class="items-grid" id="consumablesGrid"> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="panel game-arena" id="gameArena"> |
|
|
<div class="clone-counter"> |
|
|
<i class="fas fa-users"></i> |
|
|
<span id="arenaCloneCount">0</span> |
|
|
</div> |
|
|
<div class="arena-floor"></div> |
|
|
<div class="player" id="player"> |
|
|
<div class="player-face"> |
|
|
<div class="eye"></div> |
|
|
<div class="eye"></div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="panel"> |
|
|
<h3 class="panel-title"><i class="fas fa-chart-line"></i> Evolution Track</h3> |
|
|
<div class="evolution-track" id="evolutionTrack"> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="xp-bar-container"> |
|
|
<div class="xp-label"> |
|
|
<span>XP</span> |
|
|
<span id="xpText">0 / 100</span> |
|
|
</div> |
|
|
<div class="progress-bar"> |
|
|
<div class="progress-fill" id="xpBar" style="width: 0%"></div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<h3 class="panel-title" style="margin-top: 1.5rem;"><i class="fas fa-bolt"></i> Abilities</h3> |
|
|
<div class="abilities-list" id="abilitiesList"> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="controls"> |
|
|
<button class="control-btn" id="moveLeft" title="Move Left"> |
|
|
<i class="fas fa-arrow-left"></i> |
|
|
</button> |
|
|
<button class="control-btn" id="spawnClone" title="Spawn Clone (Cost: 20 Energy)"> |
|
|
<i class="fas fa-plus"></i> |
|
|
</button> |
|
|
<button class="control-btn" id="attack" title="Attack"> |
|
|
<i class="fas fa-fist-raised"></i> |
|
|
</button> |
|
|
<button class="control-btn" id="moveRight" title="Move Right"> |
|
|
<i class="fas fa-arrow-right"></i> |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<div class="notification" id="notification"></div> |
|
|
|
|
|
<div class="modal" id="welcomeModal"> |
|
|
<div class="modal-content"> |
|
|
<h2><i class="fas fa-dna"></i> Welcome to Clone Evolution!</h2> |
|
|
<p>You are a unique being with the power to create clones by consuming special items. Collect consumables to gain energy, spawn clones, defeat enemies, and evolve into more powerful forms!</p> |
|
|
<ul style="text-align: left; margin-bottom: 1.5rem; opacity: 0.8;"> |
|
|
<li>🍎 Collect consumables for energy & clone power</li> |
|
|
<li>👥 Spawn clones to help you fight</li> |
|
|
<li>⚔️ Defeat enemies to gain XP</li> |
|
|
<li>🧬 Evolve to unlock new abilities</li> |
|
|
</ul> |
|
|
<button class="modal-btn" onclick="startGame()">Start Game</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="modal" id="evolutionModal"> |
|
|
<div class="modal-content"> |
|
|
<h2 id="evolutionTitle"><i class="fas fa-star"></i> Evolution!</h2> |
|
|
<p id="evolutionDesc">You have evolved into a new form!</p> |
|
|
<button class="modal-btn" onclick="closeEvolutionModal()">Continue</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
|
|
|
const gameState = { |
|
|
level: 1, |
|
|
score: 0, |
|
|
clones: [], |
|
|
energy: 100, |
|
|
maxEnergy: 100, |
|
|
xp: 0, |
|
|
xpToNext: 100, |
|
|
evolutionStage: 0, |
|
|
playerPosition: 50, |
|
|
enemies: [], |
|
|
consumables: [], |
|
|
abilities: [], |
|
|
unlockedAbilities: [0], |
|
|
cooldowns: {}, |
|
|
gameStarted: false |
|
|
}; |
|
|
|
|
|
|
|
|
const consumablesData = [ |
|
|
{ id: 1, name: 'Energy Orb', icon: '🔮', color: '#a29bfe', energy: 20, clonePower: 1, cost: 0 }, |
|
|
{ id: 2, name: 'Power Crystal', icon: '💎', color: '#00cec9', energy: 30, clonePower: 2, cost: 50 }, |
|
|
{ id: 3, name: 'Soul Essence', icon: '👻', color: '#fd79a8', energy: 40, clonePower: 3, cost: 100 }, |
|
|
{ id: 4, name: 'Dragon Heart', icon: '🔥', color: '#e17055', energy: 50, clonePower: 4, cost: 200 }, |
|
|
{ id: 5, name: 'Star Fragment', icon: '⭐', color: '#ffeaa7', energy: 60, clonePower: 5, cost: 350 }, |
|
|
{ id: 6, name: 'Void Shard', icon: '🌑', color: '#636e72', energy: 80, clonePower: 7, cost: 500 } |
|
|
]; |
|
|
|
|
|
|
|
|
const evolutionStages = [ |
|
|
{ name: 'Base Form', icon: '🧬', requirement: 0, bonus: 'Start your journey', class: '' }, |
|
|
{ name: 'Enhanced', icon: '💫', requirement: 100, bonus: '+25% Clone Power', class: 'evolved-1' }, |
|
|
{ name: 'Ascended', icon: '🌟', requirement: 300, bonus: '+50% Clone Power, Heal Ability', class: 'evolved-2' }, |
|
|
{ name: 'Transcendent', icon: '👑', requirement: 600, bonus: '+100% Clone Power, All Abilities', class: 'evolved-3' } |
|
|
]; |
|
|
|
|
|
|
|
|
const abilitiesData = [ |
|
|
{ id: 0, name: 'Clone Rush', icon: '⚡', desc: 'All clones attack at once', cooldown: 10, unlockLevel: 1 }, |
|
|
{ id: 1, name: 'Energy Shield', icon: '🛡️', desc: 'Protect from damage', cooldown: 15, unlockLevel: 2 }, |
|
|
{ id: 2, name: 'Clone Fusion', icon: '🔄', desc: 'Merge 2 clones into 1 powerful clone', cooldown: 20, unlockLevel: 3 }, |
|
|
{ id: 3, name: 'Mass Production', icon: '🏭', desc: 'Spawn 3 clones at once', cooldown: 25, unlockLevel: 4 } |
|
|
]; |
|
|
|
|
|
|
|
|
const player = document.getElementById('player'); |
|
|
const gameArena = document.getElementById('gameArena'); |
|
|
const notification = document.getElementById('notification'); |
|
|
|
|
|
|
|
|
function initGame() { |
|
|
renderConsumables(); |
|
|
renderEvolutionTrack(); |
|
|
renderAbilities(); |
|
|
document.getElementById('welcomeModal').classList.add('show'); |
|
|
} |
|
|
|
|
|
function startGame() { |
|
|
document.getElementById('welcomeModal').classList.remove('show'); |
|
|
gameState.gameStarted = true; |
|
|
spawnConsumables(); |
|
|
spawnEnemy(); |
|
|
gameLoop(); |
|
|
} |
|
|
|
|
|
function renderConsumables() { |
|
|
const grid = document.getElementById('consumablesGrid'); |
|
|
grid.innerHTML = consumablesData.map(item => ` |
|
|
<div class="item-card ${gameState.score < item.cost ? 'locked' : ''}" |
|
|
onclick="buyConsumable(${item.id})" |
|
|
data-id="${item.id}"> |
|
|
<div class="item-icon">${item.icon}</div> |
|
|
<div class="item-name">${item.name}</div> |
|
|
<div class="item-effect">+${item.energy} Energy, +${item.clonePower} Clone Power</div> |
|
|
<div class="item-cost">${item.cost === 0 ? 'Free' : item.cost + ' pts'}</div> |
|
|
</div> |
|
|
`).join(''); |
|
|
} |
|
|
|
|
|
function renderEvolutionTrack() { |
|
|
const track = document.getElementById('evolutionTrack'); |
|
|
track.innerHTML = evolutionStages.map((stage, index) => ` |
|
|
<div class="evolution-stage ${index === gameState.evolutionStage ? 'active' : ''} ${index > gameState.evolutionStage ? 'locked' : ''}"> |
|
|
<div class="evolution-icon">${stage.icon}</div> |
|
|
<div class="evolution-info"> |
|
|
<h4>${stage.name}</h4> |
|
|
<p>${stage.bonus}</p> |
|
|
<p style="color: var(--accent-color);">Requires: ${stage.requirement} XP</p> |
|
|
</div> |
|
|
</div> |
|
|
`).join(''); |
|
|
} |
|
|
|
|
|
function renderAbilities() { |
|
|
const list = document.getElementById('abilitiesList'); |
|
|
list.innerHTML = abilitiesData.map(ability => { |
|
|
const unlocked = gameState.level >= ability.unlockLevel; |
|
|
const onCooldown = gameState.cooldowns[ability.id] > 0; |
|
|
return ` |
|
|
<div class="ability ${!unlocked ? 'locked' : ''}" |
|
|
onclick="useAbility(${ability.id})" |
|
|
data-id="${ability.id}"> |
|
|
<div class="ability-icon">${ability.icon}</div> |
|
|
<div class="ability-info"> |
|
|
<div class="ability-name">${ability.name}</div> |
|
|
<div class="ability-desc">${ability.desc}</div> |
|
|
</div> |
|
|
<div class="ability-cooldown"> |
|
|
${onCooldown ? gameState.cooldowns[ability.id] + 's' : (unlocked ? 'Ready' : 'Lvl ' + ability.unlockLevel)} |
|
|
</div> |
|
|
</div> |
|
|
`; |
|
|
}).join(''); |
|
|
} |
|
|
|
|
|
function buyConsumable(id) { |
|
|
const item = consumablesData.find(c => c.id === id); |
|
|
if (gameState.score >= item.cost) { |
|
|
gameState.score -= item.cost; |
|
|
gameState.energy = Math.min(gameState.maxEnergy, gameState.energy + item.energy); |
|
|
showNotification(`Consumed ${item.name}! +${item.energy} Energy`); |
|
|
|
|
|
|
|
|
spawnConsumableInArena(item); |
|
|
updateStats(); |
|
|
renderConsumables(); |
|
|
} else { |
|
|
showNotification('Not enough points!', 'error'); |
|
|
} |
|
|
} |
|
|
|
|
|
function spawnConsumableInArena(item) { |
|
|
const consumable = document.createElement('div'); |
|
|
consumable.className = 'consumable'; |
|
|
consumable.style.left = Math.random() * 80 + 10 + '%'; |
|
|
consumable.style.top = Math.random() * 50 + 20 + '%'; |
|
|
consumable.style.color = item.color; |
|
|
consumable.innerHTML = `<span class="consumable-icon">${item.icon}</span>`; |
|
|
consumable.dataset.id = item.id; |
|
|
consumable.dataset.power = item.clonePower; |
|
|
|
|
|
consumable.onclick = () => collectConsumable(consumable, item); |
|
|
|
|
|
gameArena.appendChild(consumable); |
|
|
gameState.consumables.push(consumable); |
|
|
} |
|
|
|
|
|
function spawnConsumables() { |
|
|
const randomItems = consumablesData.filter(i => i.cost === 0); |
|
|
for (let i = 0; i < 3; i++) { |
|
|
const item = randomItems[Math.floor(Math.random() * randomItems.length)]; |
|
|
spawnConsumableInArena(item); |
|
|
} |
|
|
} |
|
|
|
|
|
function collectConsumable(element, item) { |
|
|
gameState.energy = Math.min(gameState.maxEnergy, gameState.energy + item.energy); |
|
|
gameState.score += 10; |
|
|
gameState.xp += 5; |
|
|
|
|
|
createParticles(element.offsetLeft, element.offsetTop, item.color); |
|
|
showScorePopup(element.offsetLeft, element.offsetTop, '+10'); |
|
|
|
|
|
element.remove(); |
|
|
gameState.consumables = gameState.consumables.filter(c => c !== element); |
|
|
|
|
|
checkEvolution(); |
|
|
updateStats(); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
if (gameState.gameStarted) { |
|
|
const randomItem = consumablesData[Math.floor(Math.random() * consumablesData.length)]; |
|
|
spawnConsumableInArena(randomItem); |
|
|
} |
|
|
}, 3000); |
|
|
} |
|
|
|
|
|
function spawnClone() { |
|
|
if (gameState.energy >= 20) { |
|
|
gameState.energy -= 20; |
|
|
|
|
|
const evolutionMultiplier = 1 + (gameState.evolutionStage * 0.25); |
|
|
const clonePower = Math.floor(10 * evolutionMultiplier); |
|
|
|
|
|
const clone = document.createElement('div'); |
|
|
clone.className = 'clone'; |
|
|
|
|
|
const colors = ['#6c5ce7', '#00cec9', '#fd79a8', '#ffeaa7', '#00b894']; |
|
|
const color = colors[gameState.clones.length % colors.length]; |
|
|
clone.style.background = `linear-gradient(180deg, ${color}, ${adjustColor(color, -30)})`; |
|
|
clone.style.boxShadow = `0 0 15px ${color}`; |
|
|
|
|
|
const offset = (gameState.clones.length - Math.floor(gameState.clones.length / 2)) * 50; |
|
|
clone.style.left = `calc(50% + ${offset}px)`; |
|
|
clone.style.transform = 'translateX(-50%)'; |
|
|
|
|
|
clone.innerHTML = ` |
|
|
<div class="clone-face"> |
|
|
<div class="eye"></div> |
|
|
<div class="eye"></div> |
|
|
</div> |
|
|
`; |
|
|
|
|
|
clone.dataset.power = clonePower; |
|
|
clone.dataset.hp = 50; |
|
|
|
|
|
gameArena.appendChild(clone); |
|
|
gameState.clones.push(clone); |
|
|
|
|
|
showNotification(`Clone spawned! Power: ${clonePower}`); |
|
|
updateStats(); |
|
|
} else { |
|
|
showNotification('Not enough energy!', 'error'); |
|
|
} |
|
|
} |
|
|
|
|
|
function spawnEnemy() { |
|
|
const enemy = document.createElement('div'); |
|
|
enemy.className = 'enemy'; |
|
|
enemy.style.left = Math.random() > 0.5 ? '10%' : '80%'; |
|
|
enemy.style.bottom = '100px'; |
|
|
|
|
|
const hp = 50 + (gameState.level * 20); |
|
|
enemy.dataset.hp = hp; |
|
|
enemy.dataset.maxHp = hp; |
|
|
|
|
|
enemy.innerHTML = ` |
|
|
<div class="enemy-face"> |
|
|
<div class="eye"></div> |
|
|
<div class="eye"></div> |
|
|
</div> |
|
|
<div class="hp-bar"> |
|
|
<div class="hp-fill" style="width: 100%"></div> |
|
|
</div> |
|
|
`; |
|
|
|
|
|
gameArena.appendChild(enemy); |
|
|
gameState.enemies.push(enemy); |
|
|
} |
|
|
|
|
|
function attack() { |
|
|
if (gameState.enemies.length === 0) return; |
|
|
|
|
|
const totalPower = gameState.clones.reduce((sum, clone) => { |
|
|
return sum + parseInt(clone.dataset.power || 10); |
|
|
}, 10); |
|
|
|
|
|
gameState.enemies.forEach(enemy => { |
|
|
const currentHp = parseInt(enemy.dataset.hp); |
|
|
const newHp = currentHp - totalPower; |
|
|
enemy.dataset.hp = newHp; |
|
|
|
|
|
const maxHp = parseInt(enemy.dataset.maxHp); |
|
|
const hpPercent = Math.max(0, (newHp / maxHp) * 100); |
|
|
enemy.querySelector('.hp-fill').style.width = hpPercent + '%'; |
|
|
|
|
|
|
|
|
enemy.style.animation = 'none'; |
|
|
enemy.offsetHeight; |
|
|
enemy.style.animation = 'enemyMove 3s ease-in-out infinite'; |
|
|
|
|
|
if (newHp <= 0) { |
|
|
defeatEnemy(enemy); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
gameState.clones.forEach(clone => { |
|
|
clone.style.transform = 'translateX(-50%) scale(1.2)'; |
|
|
setTimeout(() => { |
|
|
clone.style.transform = 'translateX(-50%) scale(1)'; |
|
|
}, 200); |
|
|
}); |
|
|
} |
|
|
|
|
|
function defeatEnemy(enemy) { |
|
|
const points = 50 + (gameState. |