File size: 10,102 Bytes
5920e02
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<html><head><base href="https://tamatris.com"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>TAMATRIS</title>
<style>@import url(https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&display=swap);body{font-family:'Space Mono',monospace;background:#1a1a1a;color:#fff;display:flex;justify-content:center;align-items:center;height:100vh;margin:0;overflow:hidden;user-select:none}.game-container{background:#2a2a2a;border-radius:15px;padding:15px;display:flex;flex-direction:column;align-items:center;box-shadow:0 0 40px rgba(255,255,255,.1)}.game-title{color:#ff6b6b;font-size:2.2em;margin:0 0 10px;letter-spacing:-2px;text-transform:uppercase}.game-content{display:flex;justify-content:center;align-items:flex-start}.tetris-grid{width:200px;height:400px;display:grid;grid-template-columns:repeat(10,1fr);gap:1px;background:#1a1a1a;border:2px solid #4a4a4a;border-radius:5px;position:relative;overflow:hidden}.tetris-cell{background:0 0;border-radius:2px;transition:background-color .2s ease}.controls{display:flex;justify-content:space-between;margin-top:20px;width:100%}.control-btn{background:#4a4a4a;color:#fff;border:none;padding:12px 0;border-radius:25px;cursor:pointer;font-family:'Space Mono',monospace;font-size:20px;transition:background .3s ease,transform .1s ease;width:22%;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;outline:0}.control-btn:hover{background:#ff6b6b;transform:translateY(-2px)}.control-btn:active{transform:translateY(1px);background:#ff6b6b}.stats{display:flex;flex-direction:column;margin-left:20px;width:90px;background:#3a3a3a;padding:10px;border-radius:10px;height:400px;box-sizing:border-box}.monkey-face{font-size:50px;text-align:center;margin-bottom:20px}.stat-icon{font-size:14px;margin-bottom:10px;display:flex;align-items:center;justify-content:space-between;padding:6px 10px;border-radius:20px;background:#4a4a4a;transition:background .3s ease}.stat-value{font-weight:700;transition:transform .2s ease}#hydration{color:#45aaf2}#nutrition{color:#4ecdc4}#mood{color:#feca57}.danger{background:#8c2a2a!important}.game-info{margin-top:auto}.info-box{background:#3a3a3a;border-radius:5px;padding:5px;width:100%;text-align:center;margin-bottom:5px}.info-label{font-size:.7em;text-transform:uppercase;color:#aaa;margin-bottom:2px}.info-value{font-size:1.2em;font-weight:700;transition:transform .2s ease}#score-value{color:#ff6b6b}#right-btn{margin-right:10%}.path-highlight{position:absolute;background:rgba(200,200,200,.1);pointer-events:none}.highlight-change{transform:scale(1.05)}</style>
</head>
<body>
<div class="game-container">
<h1 class="game-title">TAMATRIS</h1>
<div class="game-content">
<div class="tetris-grid"></div>
<div class="stats">
<div class="monkey-face" id="monkey-emoji">🐡</div>
<div class="stat-icon" id="hydration">πŸ’§ <span id="hydration-value" class="stat-value">0</span></div>
<div class="stat-icon" id="nutrition">🍏 <span id="nutrition-value" class="stat-value">0</span></div>
<div class="stat-icon" id="mood">😊 <span id="mood-value" class="stat-value">0</span></div>
<div class="game-info">
<div class="info-box">
<div class="info-label">LEVEL</div>
<div id="level-value" class="info-value">1</div>
</div>
<div class="info-box">
<div class="info-label">SCORE</div>
<div id="score-value" class="info-value">0</div>
</div>
</div>
</div>
</div>
<div class="controls">
<button class="control-btn" id="left-btn">←</button>
<button class="control-btn" id="rotate-btn">↻</button>
<button class="control-btn" id="right-btn">β†’</button>
<button class="control-btn" id="drop-btn">↓</button>
</div>
</div>
<script>const grid=document.querySelector(".tetris-grid"),hydrationEl=document.getElementById("hydration-value"),nutritionEl=document.getElementById("nutrition-value"),moodEl=document.getElementById("mood-value"),scoreEl=document.getElementById("score-value"),levelEl=document.getElementById("level-value"),monkeyEmoji=document.getElementById("monkey-emoji");let score=0,level=1,lines=0,hydration,nutrition,mood,currentShape,currentPos,currentColors,currentShapeIndex,gameSpeed=1e3,statDecayRate=1;const colors=["#ff6b6b","#4ecdc4","#feca57","#45aaf2"],shapes=[{shape:[[1,1,1,1]],width:4},{shape:[[1,1],[1,1]],width:2},{shape:[[1,1,1],[0,1,0]],width:3},{shape:[[1,1,1],[1,0,0]],width:3},{shape:[[1,1,1],[0,0,1]],width:3},{shape:[[1,1,0],[0,1,1]],width:3},{shape:[[0,1,1],[1,1,0]],width:3}];for(let e=0;e<200;e++){const t=document.createElement("div");t.classList.add("tetris-cell"),grid.appendChild(t)}function initializeStats(){const e=[20,30,40],t=e.sort(()=>Math.random()-.5);hydration=t[0],nutrition=t[1],mood=t[2],updateStats()}function newShape(){currentShapeIndex=Math.floor(Math.random()*shapes.length),currentShape=shapes[currentShapeIndex].shape,currentPos={x:Math.floor((10-shapes[currentShapeIndex].width)/2),y:0},currentColors=currentShape.map(e=>e.map(()=>colors[Math.floor(Math.random()*colors.length)])),collision()?gameOver():(draw(),updatePetStats(),updatePathHighlight())}function draw(){currentShape.forEach((e,t)=>{e.forEach((e,n)=>{if(e){const e=grid.children[10*(currentPos.y+t)+(currentPos.x+n)];e&&(e.style.backgroundColor=currentColors[t][n],e.style.boxShadow=`0 0 5px ${currentColors[t][n]}`)}})})}function erase(){currentShape.forEach((e,t)=>{e.forEach((e,n)=>{if(e){const e=grid.children[10*(currentPos.y+t)+(currentPos.x+n)];e&&(e.style.backgroundColor="",e.style.boxShadow="")}})})}function collision(){return currentShape.some((e,t)=>e.some((e,n)=>e&&(currentPos.y+t>=20||currentPos.x+n<0||currentPos.x+n>=10||grid.children[10*(currentPos.y+t)+(currentPos.x+n)].classList.contains("taken"))))}function solidify(){currentShape.forEach((e,t)=>{e.forEach((e,n)=>{e&&grid.children[10*(currentPos.y+t)+(currentPos.x+n)].classList.add("taken")})})}function clearRows(){let e=0,t=[0,0,0],n=0;for(let r=19;r>=0;r--){const o=Array.from(grid.children).slice(10*r,10*(r+1));o.every(e=>e.classList.contains("taken"))&&(o.forEach(e=>{const r=e.style.backgroundColor;"rgb(255, 107, 107)"===r?(t[0]++,n++):"rgb(78, 205, 196)"===r?t[1]++:"rgb(254, 202, 87)"===r&&t[2]++,e.style.backgroundColor="",e.style.boxShadow="",e.classList.remove("taken")}),grid.prepend(...Array.from(grid.children).splice(10*r,10)),e++,r++)}e&&(lines+=e,score+=100*n,updateLevel(),updatePetStatsOnClear(t),updateScoreAndLevel())}function updateLevel(){const e=Math.floor(score/1e3)+1;e>level&&(level=e,gameSpeed*=.9,statDecayRate*=1.1,updateGameSpeed(),highlightChange(levelEl))}function updatePetStats(){hydration=Math.max(0,hydration-.5*statDecayRate),nutrition=Math.max(0,nutrition-.5*statDecayRate),mood=Math.max(0,mood-.5*statDecayRate),updateStats(),hydration<=0||nutrition<=0||mood<=0?gameOver():void 0}function updatePetStatsOnClear(e){hydration=Math.min(100,hydration+e[0]),nutrition=Math.min(100,nutrition+e[1]),mood=Math.min(100,mood+e[2]),updateStats()}function updateStats(){updateStatWithHighlight(hydrationEl,Math.round(hydration)),updateStatWithHighlight(nutritionEl,Math.round(nutrition)),updateStatWithHighlight(moodEl,Math.round(mood));const e=hydration<10||nutrition<10||mood<10;document.getElementById("hydration").classList.toggle("danger",hydration<10),document.getElementById("nutrition").classList.toggle("danger",nutrition<10),document.getElementById("mood").classList.toggle("danger",mood<10),monkeyEmoji.textContent=e?"πŸ™Š":"🐡"}function updateScoreAndLevel(){updateStatWithHighlight(scoreEl,score),updateStatWithHighlight(levelEl,level)}function updateStatWithHighlight(e,t){const n=parseInt(e.textContent);n!==t&&(e.textContent=t,highlightChange(e))}function highlightChange(e){e.classList.add("highlight-change"),setTimeout(()=>{e.classList.remove("highlight-change")},200)}function gameOver(){alert(`Game Over! Your score: ${score}`),Array.from(grid.children).forEach(e=>{e.style.backgroundColor="",e.style.boxShadow="",e.classList.remove("taken")}),score=0,level=1,lines=0,gameSpeed=1e3,statDecayRate=1,initializeStats(),updateScoreAndLevel(),updateGameSpeed(),newShape()}["left-btn","right-btn","rotate-btn","drop-btn"].forEach(e=>{const t=document.getElementById(e);t.addEventListener("mousedown",n=>{"left-btn"===e?move(-1):"right-btn"===e?move(1):"rotate-btn"===e?rotate():"drop-btn"===e&&hardDrop(),n.preventDefault()}),t.addEventListener("touchstart",n=>{"left-btn"===e?move(-1):"right-btn"===e?move(1):"rotate-btn"===e?rotate():"drop-btn"===e&&hardDrop(),n.preventDefault()}),t.addEventListener("mouseup",()=>{t.blur()}),t.addEventListener("touchend",()=>{t.blur()})});function move(e){erase(),currentPos.x+=e,collision()?(currentPos.x-=e,draw()):(draw(),updatePathHighlight())}function rotate(){erase();const e=currentShape,t=currentColors;currentShape=currentShape[0].map((e,t)=>currentShape.map(e=>e[t]).reverse()),currentColors=currentColors[0].map((e,t)=>currentColors.map(e=>e[t]).reverse()),collision()?(currentShape=e,currentColors=t,draw()):(draw(),updatePathHighlight())}function hardDrop(){for(erase();!collision();)currentPos.y++;currentPos.y--,draw(),solidify(),clearRows(),newShape()}function moveDown(){erase(),currentPos.y++,collision()?(currentPos.y--,draw(),solidify(),clearRows(),newShape()):(draw(),updatePathHighlight())}function updateGameSpeed(){clearInterval(gameInterval),gameInterval=setInterval(moveDown,gameSpeed)}function updatePathHighlight(){const e=document.querySelectorAll(".path-highlight");e.forEach(e=>e.remove());const t=getShapeWidth(),n=document.createElement("div"),r=document.createElement("div");n.classList.add("path-highlight"),r.classList.add("path-highlight"),n.style.width="1px",r.style.width="1px",n.style.height="400px",r.style.height="400px",n.style.left=20*currentPos.x+"px",r.style.left=20*(currentPos.x+t)+"px",n.style.top="0px",r.style.top="0px",grid.appendChild(n),grid.appendChild(r)}function getShapeWidth(){let e=0;for(let t=0;t<currentShape[0].length;t++)currentShape.some(e=>e[t])&&e++;return e}initializeStats(),updateScoreAndLevel(),newShape();let gameInterval=setInterval(moveDown,gameSpeed);setInterval(updatePetStats,5e3);</script>
</body></html>