test / index.html
Darrellthedesigner's picture
Add 2 files
05afcbe verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tons of Gold: Stacking Bricks</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700&family=Poppins:wght@400;600&family=Roboto+Condensed:wght@700&display=swap');
body {
font-family: 'Poppins', sans-serif;
background: linear-gradient(135deg, #f5d742 0%, #d4af37 50%, #996515 100%);
min-height: 100vh;
overflow: hidden;
}
.title {
font-family: 'Roboto Condensed', sans-serif;
text-transform: uppercase;
letter-spacing: 2px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.game-container {
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
border: 4px solid #d4af37;
background-color: rgba(0, 0, 0, 0.7);
}
.grid {
display: grid;
grid-template-rows: repeat(20, 1fr);
grid-template-columns: repeat(10, 1fr);
gap: 1px;
border: 2px solid #d4af37;
}
.cell {
aspect-ratio: 1;
background-color: rgba(0, 0, 0, 0.1);
position: relative;
overflow: hidden;
}
.gold {
background: linear-gradient(135deg, #ffd700 0%, #daa520 50%, #b8860b 100%);
border: 1px solid #fff;
box-shadow:
inset 0 0 10px rgba(255, 215, 0, 0.5),
0 0 5px rgba(255, 215, 0, 0.8);
position: relative;
clip-path: polygon(0% 20%, 20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%);
}
.gold::after {
content: '$';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 1.2em;
font-weight: bold;
color: #6a4a0a;
opacity: 0.7;
text-shadow: 1px 1px 1px rgba(0,0,0,0.3);
}
.gold::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 30%;
background: linear-gradient(to bottom, rgba(255,255,255,0.4), rgba(255,255,255,0.1));
transform: rotate(-45deg) translate(-25%, -50%);
}
.gold-light {
background: linear-gradient(135deg, #fff8c6 0%, #ffd700 50%, #daa520 100%);
border: 1px solid #fff;
box-shadow:
inset 0 0 10px rgba(255, 215, 0, 0.8),
0 0 8px rgba(255, 215, 0, 0.9);
position: relative;
clip-path: polygon(0% 20%, 20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%);
}
.gold-light::after {
content: '$';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 1.2em;
font-weight: bold;
color: #6a4a0a;
opacity: 0.7;
text-shadow: 1px 1px 1px rgba(0,0,0,0.3);
}
.gold-light::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 30%;
background: linear-gradient(to bottom, rgba(255,255,255,0.6), rgba(255,255,255,0.2));
transform: rotate(-45deg) translate(-25%, -50%);
}
.next-piece-container {
border: 2px solid #d4af37;
background-color: rgba(0, 0, 0, 0.3);
}
.controls-btn {
background: linear-gradient(135deg, #d4af37 0%, #b8860b 100%);
border: none;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.2s;
}
.controls-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.2);
}
.controls-btn:active {
transform: translateY(0);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.game-over {
background-color: rgba(0, 0, 0, 0.8);
backdrop-filter: blur(5px);
}
.score-display {
background: linear-gradient(135deg, rgba(212, 175, 55, 0.2) 0%, rgba(184, 134, 11, 0.3) 100%);
border: 2px solid #d4af37;
}
.text-gold-dark {
color: #6a4a0a;
}
.start-screen {
background-color: rgba(0, 0, 0, 0.8);
backdrop-filter: blur(5px);
}
@media (max-width: 768px) {
.game-grid-container {
flex-direction: column;
}
.game-container {
margin-bottom: 1rem;
}
.controls-container {
width: 100%;
}
}
.control-panel {
max-height: calc(100vh - 60px);
padding-bottom: 60px;
overflow: hidden;
}
.game-area {
max-height: 100vh;
padding-top: 20px;
}
</style>
</head>
<body class="flex flex-col items-center justify-start py-2 px-2 overflow-hidden">
<div class="flex flex-col items-center mb-1 sm:mb-2">
<h1 class="title text-3xl sm:text-4xl md:text-5xl font-bold text-gold-dark">TONS OF GOLD</h1>
<h2 class="text-lg sm:text-xl font-semibold text-gold-dark">Stacking Bricks</h2>
</div>
<div class="flex flex-col lg:flex-row items-center justify-center gap-2 sm:gap-4 md:gap-6 w-full max-w-5xl px-2 game-area">
<div class="game-container relative" style="width: 70vmin; height: 140vmin; max-width: 300px; max-height: 600px;">
<div id="grid" class="grid w-full h-full"></div>
<div id="game-over" class="game-over absolute inset-0 hidden flex-col items-center justify-center text-gold-dark">
<h3 class="text-2xl sm:text-3xl font-bold mb-4">Game Over!</h3>
<p class="text-lg sm:text-xl mb-6">Your score: <span id="final-score" class="font-bold">0</span></p>
<button id="restart-btn" class="controls-btn px-6 py-2 rounded-full text-white font-bold">
Play Again
</button>
</div>
<div id="start-screen" class="start-screen absolute inset-0 flex flex-col items-center justify-center text-gold-dark">
<h3 class="text-2xl sm:text-3xl font-bold mb-6">TONS OF GOLD</h3>
<button id="start-btn" class="controls-btn px-8 py-3 rounded-full text-white font-bold text-lg">
START GAME
</button>
</div>
</div>
<div class="flex flex-col gap-2 sm:gap-4 w-full control-panel" style="max-width: 200px;">
<div class="score-display p-3 rounded-lg">
<div class="flex justify-between mb-2">
<span class="text-gold-dark font-semibold">Score:</span>
<span id="score" class="text-gold-dark font-bold">0</span>
</div>
<div class="flex justify-between mb-2">
<span class="text-gold-dark font-semibold">Level:</span>
<span id="level" class="text-gold-dark font-bold">1</span>
</div>
<div class="flex justify-between">
<span class="text-gold-dark font-semibold">Lines:</span>
<span id="lines" class="text-gold-dark font-bold">0</span>
</div>
</div>
<div class="next-piece-container p-3 rounded-lg">
<h3 class="text-gold-dark font-semibold mb-2 text-center">Next Piece</h3>
<div id="next-piece" class="grid grid-cols-4 grid-rows-4 w-20 h-20 gap-1 mx-auto"></div>
</div>
<div class="bg-black bg-opacity-30 p-3 rounded-lg">
<h3 class="text-gold-dark font-semibold mb-2 text-center">Controls</h3>
<div class="grid grid-cols-3 gap-2 text-gold-dark text-xs sm:text-sm">
<div class="text-center">
<div class="controls-btn w-8 h-8 mx-auto mb-1 flex items-center justify-center"></div>
<span>Rotate</span>
</div>
<div class="text-center">
<div class="controls-btn w-8 h-8 mx-auto mb-1 flex items-center justify-center"></div>
<span>Left</span>
</div>
<div class="text-center">
<div class="controls-btn w-8 h-8 mx-auto mb-1 flex items-center justify-center"></div>
<span>Right</span>
</div>
<div class="text-center col-span-3">
<div class="controls-btn w-full h-8 mx-auto mb-1 flex items-center justify-center text-xs">↓ Drop Faster</div>
</div>
<div class="text-center col-span-3">
<div class="controls-btn w-full h-8 mx-auto mb-1 flex items-center justify-center text-xs">Space Instant Drop</div>
</div>
<div class="text-center col-span-3">
<div class="controls-btn w-full h-8 mx-auto mb-1 flex items-center justify-center text-xs">P Pause</div>
</div>
</div>
</div>
</div>
</div>
<div class="mt-2 sm:mt-3 text-center px-2">
<p class="text-xs sm:text-sm text-gold-dark">Stack the gold bars to complete lines and earn points!</p>
<p class="text-xs mt-1 text-gold-dark">Each line cleared increases your score and level.</p>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
// Game constants
const COLS = 10;
const ROWS = 20;
const NEXT_PIECE_SIZE = 4;
// Game variables
let grid = Array(ROWS).fill().map(() => Array(COLS).fill(0));
let currentPiece = null;
let nextPiece = null;
let score = 0;
let level = 1;
let lines = 0;
let gameOver = false;
let isPaused = false;
let dropInterval;
let dropSpeed = 1000; // Initial speed in ms
let gameStarted = false;
// DOM elements
const gridElement = document.getElementById('grid');
const nextPieceElement = document.getElementById('next-piece');
const scoreElement = document.getElementById('score');
const levelElement = document.getElementById('level');
const linesElement = document.getElementById('lines');
const gameOverElement = document.getElementById('game-over');
const finalScoreElement = document.getElementById('final-score');
const restartBtn = document.getElementById('restart-btn');
const startBtn = document.getElementById('start-btn');
const startScreen = document.getElementById('start-screen');
// Piece shapes (gold bars)
const SHAPES = [
// I shape (long gold bar)
[
[0, 0, 0, 0],
[1, 1, 1, 1],
[0, 0, 0, 0],
[0, 0, 0, 0]
],
// J shape
[
[1, 0, 0],
[1, 1, 1],
[0, 0, 0]
],
// L shape
[
[0, 0, 1],
[1, 1, 1],
[0, 0, 0]
],
// O shape (gold cube)
[
[1, 1],
[1, 1]
],
// S shape
[
[0, 1, 1],
[1, 1, 0],
[0, 0, 0]
],
// T shape
[
[0, 1, 0],
[1, 1, 1],
[0, 0, 0]
],
// Z shape
[
[1, 1, 0],
[0, 1, 1],
[0, 0, 0]
]
];
// Colors for pieces (different shades of gold)
const COLORS = [
'#FFD700', // Gold
'#DAA520', // Goldenrod
'#F0E68C', // Khaki
'#EEE8AA', // Pale Goldenrod
'#B8860B', // Dark Goldenrod
'#FFDF00', // Golden Yellow
'#E6BE8A' // Gold (metallic)
];
// Initialize the game
function init() {
createGrid();
renderGrid();
updateScore();
addEventListeners();
}
// Start the game
function startGame() {
gameStarted = true;
gameOver = false;
score = 0;
level = 1;
lines = 0;
grid = Array(ROWS).fill().map(() => Array(COLS).fill(0));
updateScore();
renderGrid();
generateNewPiece();
generateNextPiece();
resetDropInterval();
startScreen.classList.add('hidden');
gameOverElement.classList.add('hidden');
}
// Create the game grid
function createGrid() {
gridElement.innerHTML = '';
for (let row = 0; row < ROWS; row++) {
for (let col = 0; col < COLS; col++) {
const cell = document.createElement('div');
cell.className = 'cell';
cell.id = `cell-${row}-${col}`;
gridElement.appendChild(cell);
}
}
}
// Generate a new random piece
function generateNewPiece() {
if (nextPiece) {
currentPiece = nextPiece;
} else {
const randomShapeIndex = Math.floor(Math.random() * SHAPES.length);
const randomColorIndex = Math.floor(Math.random() * COLORS.length);
currentPiece = {
shape: SHAPES[randomShapeIndex],
color: COLORS[randomColorIndex],
x: Math.floor(COLS / 2) - Math.floor(SHAPES[randomShapeIndex][0].length / 2),
y: 0
};
}
// Check if game over
if (collision()) {
endGame();
}
generateNextPiece();
}
// Generate the next piece to show in the preview
function generateNextPiece() {
const randomShapeIndex = Math.floor(Math.random() * SHAPES.length);
const randomColorIndex = Math.floor(Math.random() * COLORS.length);
nextPiece = {
shape: SHAPES[randomShapeIndex],
color: COLORS[randomColorIndex],
x: 0,
y: 0
};
renderNextPiece();
}
// Render the next piece preview
function renderNextPiece() {
nextPieceElement.innerHTML = '';
for (let row = 0; row < NEXT_PIECE_SIZE; row++) {
for (let col = 0; col < NEXT_PIECE_SIZE; col++) {
const cell = document.createElement('div');
cell.className = 'cell';
if (nextPiece.shape[row] && nextPiece.shape[row][col]) {
cell.style.backgroundColor = nextPiece.color;
cell.style.border = '1px solid #fff';
cell.style.boxShadow = 'inset 0 0 5px rgba(255, 255, 255, 0.5)';
cell.style.clipPath = 'polygon(0% 20%, 20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%)';
// Add dollar sign to preview pieces
const dollarSign = document.createElement('div');
dollarSign.textContent = '$';
dollarSign.style.position = 'absolute';
dollarSign.style.top = '50%';
dollarSign.style.left = '50%';
dollarSign.style.transform = 'translate(-50%, -50%)';
dollarSign.style.color = '#6a4a0a';
dollarSign.style.opacity = '0.7';
dollarSign.style.fontWeight = 'bold';
dollarSign.style.textShadow = '1px 1px 1px rgba(0,0,0,0.3)';
cell.appendChild(dollarSign);
} else {
cell.style.backgroundColor = 'transparent';
}
nextPieceElement.appendChild(cell);
}
}
}
// Draw the current piece on the grid
function drawPiece() {
clearPiece();
for (let row = 0; row < currentPiece.shape.length; row++) {
for (let col = 0; col < currentPiece.shape[row].length; col++) {
if (currentPiece.shape[row][col]) {
const gridRow = currentPiece.y + row;
const gridCol = currentPiece.x + col;
if (gridRow >= 0 && gridRow < ROWS && gridCol >= 0 && gridCol < COLS) {
const cell = document.getElementById(`cell-${gridRow}-${gridCol}`);
cell.classList.add('gold');
cell.style.backgroundColor = currentPiece.color;
}
}
}
}
}
// Clear the current piece from the grid
function clearPiece() {
for (let row = 0; row < ROWS; row++) {
for (let col = 0; col < COLS; col++) {
const cell = document.getElementById(`cell-${row}-${col}`);
if (cell.classList.contains('gold')) {
cell.classList.remove('gold');
cell.style.backgroundColor = '';
}
}
}
}
// Check for collisions
function collision() {
for (let row = 0; row < currentPiece.shape.length; row++) {
for (let col = 0; col < currentPiece.shape[row].length; col++) {
if (currentPiece.shape[row][col]) {
const gridRow = currentPiece.y + row;
const gridCol = currentPiece.x + col;
// Check boundaries and other pieces
if (
gridRow >= ROWS ||
gridCol < 0 ||
gridCol >= COLS ||
(gridRow >= 0 && grid[gridRow][gridCol])
) {
return true;
}
}
}
}
return false;
}
// Rotate the current piece
function rotate() {
if (isPaused || gameOver || !gameStarted) return;
const originalShape = currentPiece.shape;
const originalX = currentPiece.x;
const originalY = currentPiece.y;
// Transpose and reverse rows to rotate
const rotated = currentPiece.shape[0].map((_, i) =>
currentPiece.shape.map(row => row[i]).reverse()
);
currentPiece.shape = rotated;
// If rotation causes collision, try wall kicks
if (collision()) {
// Try moving left
currentPiece.x -= 1;
if (collision()) {
// Try moving right
currentPiece.x += 2;
if (collision()) {
// Revert to original position if all kicks fail
currentPiece.x = originalX;
currentPiece.shape = originalShape;
return;
}
}
}
drawPiece();
}
// Move the piece left
function moveLeft() {
if (isPaused || gameOver || !gameStarted) return;
currentPiece.x -= 1;
if (collision()) {
currentPiece.x += 1;
}
drawPiece();
}
// Move the piece right
function moveRight() {
if (isPaused || gameOver || !gameStarted) return;
currentPiece.x += 1;
if (collision()) {
currentPiece.x -= 1;
}
drawPiece();
}
// Move the piece down
function moveDown() {
if (isPaused || gameOver || !gameStarted) return;
currentPiece.y += 1;
if (collision()) {
currentPiece.y -= 1;
lockPiece();
}
drawPiece();
}
// Hard drop - instantly drop the piece
function hardDrop() {
if (isPaused || gameOver || !gameStarted) return;
while (!collision()) {
currentPiece.y += 1;
}
currentPiece.y -= 1;
lockPiece();
drawPiece();
}
// Lock the piece in place and check for completed lines
function lockPiece() {
// Add piece to the grid
for (let row = 0; row < currentPiece.shape.length; row++) {
for (let col = 0; col < currentPiece.shape[row].length; col++) {
if (currentPiece.shape[row][col]) {
const gridRow = currentPiece.y + row;
const gridCol = currentPiece.x + col;
if (gridRow >= 0) {
grid[gridRow][gridCol] = 1;
const cell = document.getElementById(`cell-${gridRow}-${gridCol}`);
cell.classList.remove('gold');
cell.classList.add('gold-light');
cell.style.backgroundColor = currentPiece.color;
}
}
}
}
// Check for completed lines
checkLines();
// Generate new piece
generateNewPiece();
}
// Check for completed lines and clear them
function checkLines() {
let linesCleared = 0;
for (let row = ROWS - 1; row >= 0; row--) {
if (grid[row].every(cell => cell === 1)) {
// Remove the line
grid.splice(row, 1);
// Add new empty line at the top
grid.unshift(Array(COLS).fill(0));
linesCleared++;
row++; // Check the same row again after shifting
}
}
if (linesCleared > 0) {
// Update score based on lines cleared
const points = [0, 40, 100, 300, 1200][linesCleared] * level;
score += points;
lines += linesCleared;
// Level up every 10 lines
level = Math.floor(lines / 10) + 1;
// Increase speed
dropSpeed = Math.max(100, 1000 - (level - 1) * 100);
resetDropInterval();
updateScore();
renderGrid();
}
}
// Render the entire grid
function renderGrid() {
for (let row = 0; row < ROWS; row++) {
for (let col = 0; col < COLS; col++) {
const cell = document.getElementById(`cell-${row}-${col}`);
if (grid[row][col]) {
cell.classList.add('gold-light');
cell.style.backgroundColor = '';
} else {
cell.classList.remove('gold-light');
cell.style.backgroundColor = '';
}
}
}
}
// Update the score display
function updateScore() {
scoreElement.textContent = score;
levelElement.textContent = level;
linesElement.textContent = lines;
}
// End the game
function endGame() {
gameOver = true;
gameStarted = false;
clearInterval(dropInterval);
finalScoreElement.textContent = score;
gameOverElement.classList.remove('hidden');
}
// Reset the drop interval with current speed
function resetDropInterval() {
if (dropInterval) {
clearInterval(dropInterval);
}
dropInterval = setInterval(moveDown, dropSpeed);
}
// Toggle pause
function togglePause() {
if (gameOver || !gameStarted) return;
isPaused = !isPaused;
if (isPaused) {
clearInterval(dropInterval);
} else {
resetDropInterval();
}
}
// Add event listeners
function addEventListeners() {
document.addEventListener('keydown', (e) => {
if (!gameStarted && e.key === 'Enter') {
startGame();
return;
}
if (gameOver && e.key === 'Enter') {
startGame();
return;
}
switch (e.key) {
case 'ArrowLeft':
moveLeft();
break;
case 'ArrowRight':
moveRight();
break;
case 'ArrowDown':
moveDown();
break;
case 'ArrowUp':
rotate();
break;
case ' ':
hardDrop();
break;
case 'p':
case 'P':
togglePause();
break;
}
});
restartBtn.addEventListener('click', startGame);
startBtn.addEventListener('click', startGame);
}
// Initialize 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=Darrellthedesigner/test" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>