make the blockes move able from a place to another by drag and drop
Browse files
game.html
CHANGED
|
@@ -220,103 +220,149 @@ const languageBtn = document.getElementById('language-btn');
|
|
| 220 |
}
|
| 221 |
});
|
| 222 |
}
|
| 223 |
-
|
| 224 |
// Create initial blocks
|
| 225 |
function generateBlocks() {
|
| 226 |
const blocksArea = document.getElementById('blocks-area');
|
| 227 |
blocksArea.innerHTML = '';
|
| 228 |
|
| 229 |
-
for (let i = 0; i <
|
| 230 |
const block = document.createElement('div');
|
| 231 |
-
block.className = 'block w-
|
| 232 |
block.style.position = 'relative';
|
| 233 |
block.style.transform = `rotate(${Math.random() * 10 - 5}deg)`;
|
|
|
|
| 234 |
|
| 235 |
-
block.addEventListener('mousedown',
|
| 236 |
-
if (gameState.isPaused) return;
|
| 237 |
-
|
| 238 |
-
// Create a clone to drag
|
| 239 |
-
const heldBlock = block.cloneNode(true);
|
| 240 |
-
heldBlock.classList.add('block-held');
|
| 241 |
-
heldBlock.style.position = 'fixed';
|
| 242 |
-
heldBlock.style.left = `${e.clientX - 30}px`;
|
| 243 |
-
heldBlock.style.top = `${e.clientY - 30}px`;
|
| 244 |
-
heldBlock.style.zIndex = '100';
|
| 245 |
-
heldBlock.style.transform = 'rotate(5deg)';
|
| 246 |
-
heldBlock.style.filter = 'drop-shadow(0 0 5px rgba(0,0,0,0.5))';
|
| 247 |
-
document.body.appendChild(heldBlock);
|
| 248 |
-
|
| 249 |
-
gameState.heldBlock = heldBlock;
|
| 250 |
-
block.style.opacity = '0.5';
|
| 251 |
-
|
| 252 |
-
e.preventDefault(); // Prevent text selection
|
| 253 |
-
});
|
| 254 |
-
|
| 255 |
blocksArea.appendChild(block);
|
| 256 |
}
|
| 257 |
}
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 261 |
|
|
|
|
| 262 |
const constructionArea = document.getElementById('construction-area');
|
| 263 |
const areaRect = constructionArea.getBoundingClientRect();
|
| 264 |
|
|
|
|
| 265 |
if (e.clientX >= areaRect.left && e.clientX <= areaRect.right &&
|
| 266 |
e.clientY >= areaRect.top && e.clientY <= areaRect.bottom) {
|
| 267 |
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
// Calculate position in row
|
| 279 |
-
const rowY = 8 + (row * 8); // Each row is 8px higher
|
| 280 |
-
const spacing = (320 - (blocksInRow * 64)) / (blocksInRow + 1);
|
| 281 |
-
const blockX = spacing + ((gameState.blocksInRow[row] || 0) * (64 + spacing));
|
| 282 |
-
|
| 283 |
-
block.style.bottom = `${rowY}px`;
|
| 284 |
-
block.style.left = `${blockX}px`;
|
| 285 |
-
|
| 286 |
-
constructionArea.appendChild(block);
|
| 287 |
-
|
| 288 |
-
// Update counts
|
| 289 |
-
gameState.blocksStacked++;
|
| 290 |
-
gameState.blocksInRow[row] = (gameState.blocksInRow[row] || 0) + 1;
|
| 291 |
-
|
| 292 |
-
// Check if row is complete
|
| 293 |
-
if (gameState.blocksInRow[row] >= blocksInRow) {
|
| 294 |
-
gameState.blocksInRow[row + 1] = 0;
|
| 295 |
-
}
|
| 296 |
-
|
| 297 |
-
updateUI();
|
| 298 |
-
|
| 299 |
-
// Check for win condition
|
| 300 |
-
if (gameState.blocksStacked >= 15) {
|
| 301 |
-
pauseGame();
|
| 302 |
-
pauseTitle.textContent = translations[gameState.language].gameComplete;
|
| 303 |
-
}
|
| 304 |
-
|
| 305 |
-
// Create particles
|
| 306 |
-
createParticles(block);
|
| 307 |
-
}
|
| 308 |
|
| 309 |
-
//
|
| 310 |
-
|
| 311 |
-
blocks.forEach(b => b.style.opacity = '1');
|
| 312 |
}
|
| 313 |
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
gameState.heldBlock = null;
|
| 318 |
-
}
|
| 319 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 320 |
// Create particle effects
|
| 321 |
function createParticles(element) {
|
| 322 |
const rect = element.getBoundingClientRect();
|
|
@@ -401,7 +447,6 @@ const languageBtn = document.getElementById('language-btn');
|
|
| 401 |
}
|
| 402 |
// Setup event listeners
|
| 403 |
function setupEventListeners() {
|
| 404 |
-
document.addEventListener('mouseup', dropBlock);
|
| 405 |
pauseBtn.addEventListener('click', () => {
|
| 406 |
if (gameState.isPaused) {
|
| 407 |
resumeGame();
|
|
@@ -454,26 +499,7 @@ pauseBtn.addEventListener('click', () => {
|
|
| 454 |
});
|
| 455 |
|
| 456 |
// Keyboard controls
|
| 457 |
-
|
| 458 |
-
if (gameState.isPaused) return;
|
| 459 |
-
|
| 460 |
-
if (e.key === 'ArrowLeft') {
|
| 461 |
-
gameState.playerPosition = Math.max(0, gameState.playerPosition - 0.05);
|
| 462 |
-
player.style.left = `${gameState.playerPosition * 80 + 10}%`;
|
| 463 |
-
player.classList.add('player-walk');
|
| 464 |
-
} else if (e.key === 'ArrowRight') {
|
| 465 |
-
gameState.playerPosition = Math.min(1, gameState.playerPosition + 0.05);
|
| 466 |
-
player.style.left = `${gameState.playerPosition * 80 + 10}%`;
|
| 467 |
-
player.classList.add('player-walk');
|
| 468 |
-
}
|
| 469 |
-
});
|
| 470 |
-
|
| 471 |
-
document.addEventListener('keyup', (e) => {
|
| 472 |
-
if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
|
| 473 |
-
player.classList.remove('player-walk');
|
| 474 |
-
}
|
| 475 |
-
});
|
| 476 |
-
}
|
| 477 |
|
| 478 |
// Initialize the game
|
| 479 |
initGame();
|
|
|
|
| 220 |
}
|
| 221 |
});
|
| 222 |
}
|
|
|
|
| 223 |
// Create initial blocks
|
| 224 |
function generateBlocks() {
|
| 225 |
const blocksArea = document.getElementById('blocks-area');
|
| 226 |
blocksArea.innerHTML = '';
|
| 227 |
|
| 228 |
+
for (let i = 0; i < 10; i++) {
|
| 229 |
const block = document.createElement('div');
|
| 230 |
+
block.className = 'block w-12 h-12 bg-amber-600 rounded-sm shadow-md cursor-grab';
|
| 231 |
block.style.position = 'relative';
|
| 232 |
block.style.transform = `rotate(${Math.random() * 10 - 5}deg)`;
|
| 233 |
+
block.dataset.id = `block-${i}`;
|
| 234 |
|
| 235 |
+
block.addEventListener('mousedown', startDrag);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 236 |
blocksArea.appendChild(block);
|
| 237 |
}
|
| 238 |
}
|
| 239 |
+
|
| 240 |
+
// Start dragging a block
|
| 241 |
+
function startDrag(e) {
|
| 242 |
+
if (gameState.isPaused) return;
|
| 243 |
+
|
| 244 |
+
const block = e.target;
|
| 245 |
+
gameState.draggedBlock = block;
|
| 246 |
+
|
| 247 |
+
// Calculate initial positions
|
| 248 |
+
gameState.dragStartX = e.clientX;
|
| 249 |
+
gameState.dragStartY = e.clientY;
|
| 250 |
+
gameState.blockStartX = block.getBoundingClientRect().left;
|
| 251 |
+
gameState.blockStartY = block.getBoundingClientRect().top;
|
| 252 |
+
|
| 253 |
+
// Style the dragged block
|
| 254 |
+
block.style.position = 'fixed';
|
| 255 |
+
block.style.zIndex = '100';
|
| 256 |
+
block.style.transform = 'rotate(5deg)';
|
| 257 |
+
block.style.filter = 'drop-shadow(0 0 5px rgba(0,0,0,0.5))';
|
| 258 |
+
block.style.left = `${gameState.blockStartX}px`;
|
| 259 |
+
block.style.top = `${gameState.blockStartY}px`;
|
| 260 |
+
|
| 261 |
+
document.addEventListener('mousemove', dragBlock);
|
| 262 |
+
document.addEventListener('mouseup', stopDrag);
|
| 263 |
+
|
| 264 |
+
e.preventDefault();
|
| 265 |
+
}
|
| 266 |
+
|
| 267 |
+
// Drag block movement
|
| 268 |
+
function dragBlock(e) {
|
| 269 |
+
if (!gameState.draggedBlock) return;
|
| 270 |
+
|
| 271 |
+
const block = gameState.draggedBlock;
|
| 272 |
+
const dx = e.clientX - gameState.dragStartX;
|
| 273 |
+
const dy = e.clientY - gameState.dragStartY;
|
| 274 |
+
|
| 275 |
+
block.style.left = `${gameState.blockStartX + dx}px`;
|
| 276 |
+
block.style.top = `${gameState.blockStartY + dy}px`;
|
| 277 |
+
}
|
| 278 |
+
|
| 279 |
+
// Stop dragging and drop block
|
| 280 |
+
function stopDrag(e) {
|
| 281 |
+
if (!gameState.draggedBlock) return;
|
| 282 |
|
| 283 |
+
const block = gameState.draggedBlock;
|
| 284 |
const constructionArea = document.getElementById('construction-area');
|
| 285 |
const areaRect = constructionArea.getBoundingClientRect();
|
| 286 |
|
| 287 |
+
// Check if dropped in construction area
|
| 288 |
if (e.clientX >= areaRect.left && e.clientX <= areaRect.right &&
|
| 289 |
e.clientY >= areaRect.top && e.clientY <= areaRect.bottom) {
|
| 290 |
|
| 291 |
+
placeInPyramid(block);
|
| 292 |
+
} else {
|
| 293 |
+
// Return to original position
|
| 294 |
+
block.style.position = 'relative';
|
| 295 |
+
block.style.left = 'auto';
|
| 296 |
+
block.style.top = 'auto';
|
| 297 |
+
block.style.zIndex = 'auto';
|
| 298 |
+
block.style.transform = '';
|
| 299 |
+
block.style.filter = '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 300 |
|
| 301 |
+
// Move back to blocks area
|
| 302 |
+
document.getElementById('blocks-area').appendChild(block);
|
|
|
|
| 303 |
}
|
| 304 |
|
| 305 |
+
document.removeEventListener('mousemove', dragBlock);
|
| 306 |
+
document.removeEventListener('mouseup', stopDrag);
|
| 307 |
+
gameState.draggedBlock = null;
|
|
|
|
|
|
|
| 308 |
}
|
| 309 |
+
}
|
| 310 |
+
// Place block in pyramid
|
| 311 |
+
function placeInPyramid(block) {
|
| 312 |
+
if (gameState.isPaused) return;
|
| 313 |
+
|
| 314 |
+
// Calculate pyramid row
|
| 315 |
+
const baseWidth = 5; // Base has 5 blocks
|
| 316 |
+
const row = Math.floor(Math.sqrt(gameState.blocksStacked * 2));
|
| 317 |
+
const blocksInRow = baseWidth - row;
|
| 318 |
+
|
| 319 |
+
// Only place block if there's space in the row
|
| 320 |
+
if (blocksInRow > 0) {
|
| 321 |
+
block.className = 'pyramid-block w-12 h-12 bg-amber-700 rounded-sm shadow-md absolute';
|
| 322 |
+
block.style.position = 'absolute';
|
| 323 |
+
block.style.cursor = 'default';
|
| 324 |
+
|
| 325 |
+
// Calculate position in row
|
| 326 |
+
const rowY = 12 + (row * 12); // Each row is 12px higher
|
| 327 |
+
const spacing = (320 - (blocksInRow * 48)) / (blocksInRow + 1);
|
| 328 |
+
const blockX = spacing + ((gameState.blocksInRow[row] || 0) * (48 + spacing));
|
| 329 |
+
|
| 330 |
+
block.style.bottom = `${rowY}px`;
|
| 331 |
+
block.style.left = `${blockX}px`;
|
| 332 |
+
|
| 333 |
+
document.getElementById('construction-area').appendChild(block);
|
| 334 |
+
|
| 335 |
+
// Update counts
|
| 336 |
+
gameState.blocksStacked++;
|
| 337 |
+
gameState.blocksInRow[row] = (gameState.blocksInRow[row] || 0) + 1;
|
| 338 |
+
|
| 339 |
+
// Check if row is complete
|
| 340 |
+
if (gameState.blocksInRow[row] >= blocksInRow) {
|
| 341 |
+
gameState.blocksInRow[row + 1] = 0;
|
| 342 |
+
}
|
| 343 |
+
|
| 344 |
+
updateUI();
|
| 345 |
+
|
| 346 |
+
// Check for win condition
|
| 347 |
+
if (gameState.blocksStacked >= 10) {
|
| 348 |
+
pauseGame();
|
| 349 |
+
pauseTitle.textContent = translations[gameState.language].gameComplete;
|
| 350 |
+
}
|
| 351 |
+
|
| 352 |
+
// Create particles
|
| 353 |
+
createParticles(block);
|
| 354 |
+
} else {
|
| 355 |
+
// Return to blocks area if no space
|
| 356 |
+
block.style.position = 'relative';
|
| 357 |
+
block.style.left = 'auto';
|
| 358 |
+
block.style.top = 'auto';
|
| 359 |
+
block.style.zIndex = 'auto';
|
| 360 |
+
block.style.transform = '';
|
| 361 |
+
block.style.filter = '';
|
| 362 |
+
|
| 363 |
+
document.getElementById('blocks-area').appendChild(block);
|
| 364 |
+
}
|
| 365 |
+
}
|
| 366 |
// Create particle effects
|
| 367 |
function createParticles(element) {
|
| 368 |
const rect = element.getBoundingClientRect();
|
|
|
|
| 447 |
}
|
| 448 |
// Setup event listeners
|
| 449 |
function setupEventListeners() {
|
|
|
|
| 450 |
pauseBtn.addEventListener('click', () => {
|
| 451 |
if (gameState.isPaused) {
|
| 452 |
resumeGame();
|
|
|
|
| 499 |
});
|
| 500 |
|
| 501 |
// Keyboard controls
|
| 502 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 503 |
|
| 504 |
// Initialize the game
|
| 505 |
initGame();
|