User prompt
Its broken
User prompt
Design a Tetris-style block stacking game with a vibrant neon aesthetic. Use a dark black background to make the glowing neon blocks stand out — use colors like cyan, magenta, electric blue, and neon green. As each block moves, add a subtle neon trail effect. Include a synthwave-style background soundtrack with a futuristic vibe. Blocks should have unique animations when they land or when a line is cleared — like a quick pulse or shimmer effect. Occasionally spawn special power-up blocks: A 'Time Freeze' block that pauses the falling for 3 seconds A 'Line Blaster' that clears 2 lines at once A 'Slow Motion' block that slows game speed temporarily The game should speed up gradually over time. Display the score and level in the top corners using glowing neon fonts. The UI should be sleek and minimal, with futuristic UI buttons that pulse when touched. Make the game compatible with both desktop and mobile devices, and add satisfying sound effects when lines are cleared. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
ben ı bloğu için assest ekledim ama kendi tekrar ediyor bir bütün olmalı
User prompt
cyberpunk teması olsun
User prompt
eline sağlık tam istediğim gibi olmuş ama biraz efekt ekleyelim
User prompt
bak şimdi hani blok düşüyor ya işte yana ekle görünsün bir sonraki gelicek blok
User prompt
yanda bir sonraki düşecek bloğu göster ve oyun ekranını biraz genişlet
User prompt
hayır geri getir nerde o
User prompt
şimdi hiç görünmüyor
User prompt
güzel şuanda ama yanda bir sonraki bloğu gösteriyor ya o biraz dışarıda kalmış
User prompt
müzik ekle
User prompt
bloklar indiğinde yok oluyor düzelt bu sorunu
User prompt
bozuk bu
Code edit (1 edits merged)
Please save this source code
User prompt
Tetris Evolution
Initial prompt
tetris yap ama gelişmiş
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Tetromino class var Tetromino = Container.expand(function () { var self = Container.call(this); // Properties self.type = null; self.shape = null; // array of [x,y] self.rotation = 0; self.blocks = []; self.x = 0; // board col self.y = 0; // board row self.isPowerup = false; self.powerupType = null; // Initialize tetromino self.init = function (type, isPowerup) { self.type = type; self.isPowerup = !!isPowerup; self.rotation = 0; self.shape = []; // Copy shape var base = TETROMINO_SHAPES[type][0]; for (var i = 0; i < base.length; i++) { self.shape.push([base[i][0], base[i][1]]); } self.blocks = []; self.removeChildren(); for (var i = 0; i < self.shape.length; i++) { var block; if (self.isPowerup && i === 0) { block = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, width: CELL_SIZE, height: CELL_SIZE }); self.powerupType = 'clearLine'; // Only one powerup for MVP } else { block = self.attachAsset(self.type, { anchorX: 0.5, anchorY: 0.5, width: CELL_SIZE, height: CELL_SIZE }); } self.blocks.push(block); } self.x = Math.floor(BOARD_COLS / 2) - 2; self.y = 0; self.updateBlockPositions(); }; // Update block positions self.updateBlockPositions = function () { for (var i = 0; i < self.shape.length; i++) { var pos = self.shape[i]; self.blocks[i].x = (self.x + pos[0]) * CELL_SIZE + CELL_SIZE / 2; self.blocks[i].y = (self.y + pos[1]) * CELL_SIZE + CELL_SIZE / 2; } }; // Try move self.tryMove = function (dx, dy, board) { if (self.canMove(dx, dy, self.shape, board)) { self.x += dx; self.y += dy; self.updateBlockPositions(); return true; } return false; }; // Try rotate self.tryRotate = function (board) { var rotated = rotateShape(self.shape); if (self.canMove(0, 0, rotated, board)) { self.shape = rotated; self.updateBlockPositions(); return true; } return false; }; // Can move/rotate self.canMove = function (dx, dy, shape, board) { for (var i = 0; i < shape.length; i++) { var nx = self.x + shape[i][0] + dx; var ny = self.y + shape[i][1] + dy; if (nx < 0 || nx >= BOARD_COLS || ny < 0 || ny >= BOARD_ROWS) return false; if (board[ny][nx]) return false; } return true; }; // Lock tetromino into board self.lockToBoard = function (board, blockRefs) { for (var i = 0; i < self.shape.length; i++) { var nx = self.x + self.shape[i][0]; var ny = self.y + self.shape[i][1]; board[ny][nx] = self.isPowerup && i === 0 ? 'powerup' : self.type; blockRefs[ny][nx] = self.blocks[i]; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ // No title, no description // Always backgroundColor is black backgroundColor: 0x000000 }); /**** * Game Code ****/ // Tetromino definitions (relative coordinates for each block in the tetromino) // Power-up effect // Power-up block // New shapes // Colors for each tetromino type // Tetromino shapes (classic + new) // Board state: 2D array [row][col], 0 = empty, else type string var TETROMINO_SHAPES = { I: [[[0, 1], [1, 1], [2, 1], [3, 1]]], O: [[[1, 0], [2, 0], [1, 1], [2, 1]]], T: [[[1, 0], [0, 1], [1, 1], [2, 1]]], S: [[[1, 0], [2, 0], [0, 1], [1, 1]]], Z: [[[0, 0], [1, 0], [1, 1], [2, 1]]], J: [[[0, 0], [0, 1], [1, 1], [2, 1]]], L: [[[2, 0], [0, 1], [1, 1], [2, 1]]], U: [[[0, 0], [2, 0], [0, 1], [1, 1], [2, 1]]], P: [[[0, 0], [1, 0], [0, 1], [1, 1], [0, 2]]], Dot: [[[1, 1]]] }; var TETROMINO_TYPES = ['I', 'O', 'T', 'S', 'Z', 'J', 'L', 'U', 'P']; var POWERUP_CHANCE = 0.08; // 8% chance for a powerup block // Board settings var BOARD_COLS = 10; var BOARD_ROWS = 20; var CELL_SIZE = 90; // px, fits well on 2048x2732 var BOARD_OFFSET_X = Math.floor((2048 - BOARD_COLS * CELL_SIZE) / 2); var BOARD_OFFSET_Y = 300; // Helper: rotate a shape (array of [x,y]) 90deg clockwise function rotateShape(shape) { var maxX = 0, maxY = 0; for (var i = 0; i < shape.length; i++) { if (shape[i][0] > maxX) maxX = shape[i][0]; if (shape[i][1] > maxY) maxY = shape[i][1]; } var rotated = []; for (var i = 0; i < shape.length; i++) { var x = shape[i][0], y = shape[i][1]; rotated.push([maxY - y, x]); } return rotated; } var board = []; var blockRefs = []; // 2D array of block display objects for (var r = 0; r < BOARD_ROWS; r++) { board[r] = []; blockRefs[r] = []; for (var c = 0; c < BOARD_COLS; c++) { board[r][c] = 0; blockRefs[r][c] = null; } } // Score and level var score = 0; var level = 1; var linesCleared = 0; var fallInterval = 1000; // ms, decreases with level // GUI var scoreTxt = new Text2('0', { size: 100, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var levelTxt = new Text2('Lv.1', { size: 60, fill: "#fff" }); levelTxt.anchor.set(0.5, 0); LK.gui.top.addChild(levelTxt); levelTxt.y = 110; // Next tetromino preview var nextTetrominoType = null; var nextTetrominoPreview = new Container(); LK.gui.right.addChild(nextTetrominoPreview); nextTetrominoPreview.y = 200; // Current falling tetromino var currentTetromino = null; // Game state var isGameOver = false; var isDropping = false; var dropTimer = null; var moveTimer = null; var moveDir = 0; // -1 left, 1 right, 0 none // Helper: spawn new tetromino function spawnTetromino() { var type = nextTetrominoType; if (!type) { type = TETROMINO_TYPES[Math.floor(Math.random() * TETROMINO_TYPES.length)]; } var isPowerup = Math.random() < POWERUP_CHANCE; var tetro = new Tetromino(); tetro.init(type, isPowerup); game.addChild(tetro); currentTetromino = tetro; // Next nextTetrominoType = TETROMINO_TYPES[Math.floor(Math.random() * TETROMINO_TYPES.length)]; updateNextPreview(); // If cannot place, game over if (!tetro.canMove(0, 0, tetro.shape, board)) { isGameOver = true; LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } } // Helper: update next preview function updateNextPreview() { nextTetrominoPreview.removeChildren(); var type = nextTetrominoType; if (!type) return; var shape = TETROMINO_SHAPES[type][0]; for (var i = 0; i < shape.length; i++) { var block = LK.getAsset(type, { anchorX: 0.5, anchorY: 0.5, width: CELL_SIZE, height: CELL_SIZE }); block.x = shape[i][0] * CELL_SIZE + CELL_SIZE / 2; block.y = shape[i][1] * CELL_SIZE + CELL_SIZE / 2; nextTetrominoPreview.addChild(block); } // Center preview // Place preview with a margin so it's fully visible and not outside the screen // Place it at a visible position near the right edge, but inside the screen nextTetrominoPreview.x = 2048 - CELL_SIZE * 4 - 100; } // Helper: clear full lines function clearLines() { var lines = []; for (var r = 0; r < BOARD_ROWS; r++) { var full = true; for (var c = 0; c < BOARD_COLS; c++) { if (!board[r][c]) { full = false; break; } } if (full) lines.push(r); } if (lines.length === 0) return 0; // Animate and remove lines for (var i = 0; i < lines.length; i++) { var row = lines[i]; for (var c = 0; c < BOARD_COLS; c++) { if (blockRefs[row][c]) { tween(blockRefs[row][c], { alpha: 0 }, { duration: 200, onFinish: function (obj) { if (obj.parent) obj.parent.removeChild(obj); }.bind(null, blockRefs[row][c]) }); } } } // Remove from board for (var i = 0; i < lines.length; i++) { var row = lines[i]; for (var c = 0; c < BOARD_COLS; c++) { board[row][c] = 0; blockRefs[row][c] = null; } } // Drop above lines for (var i = lines.length - 1; i >= 0; i--) { var row = lines[i]; for (var r = row - 1; r >= 0; r--) { for (var c = 0; c < BOARD_COLS; c++) { board[r + 1][c] = board[r][c]; blockRefs[r + 1][c] = blockRefs[r][c]; if (blockRefs[r + 1][c]) { tween(blockRefs[r + 1][c], { y: blockRefs[r + 1][c].y + CELL_SIZE }, { duration: 100 }); } } } // Clear top row for (var c = 0; c < BOARD_COLS; c++) { board[0][c] = 0; blockRefs[0][c] = null; } } return lines.length; } // Helper: activate powerup function activatePowerup(row) { // For MVP: clear the row where powerup landed for (var c = 0; c < BOARD_COLS; c++) { if (blockRefs[row][c]) { tween(blockRefs[row][c], { alpha: 0 }, { duration: 200, onFinish: function (obj) { if (obj.parent) obj.parent.removeChild(obj); }.bind(null, blockRefs[row][c]) }); board[row][c] = 0; blockRefs[row][c] = null; } } // Drop above lines for (var r = row - 1; r >= 0; r--) { for (var c = 0; c < BOARD_COLS; c++) { board[r + 1][c] = board[r][c]; blockRefs[r + 1][c] = blockRefs[r][c]; if (blockRefs[r + 1][c]) { tween(blockRefs[r + 1][c], { y: blockRefs[r + 1][c].y + CELL_SIZE }, { duration: 100 }); } } } // Clear top row for (var c = 0; c < BOARD_COLS; c++) { board[0][c] = 0; blockRefs[0][c] = null; } } // Helper: update score/level function updateScore(lines) { var points = [0, 100, 300, 500, 800]; score += points[lines] || 0; linesCleared += lines; scoreTxt.setText(score); var newLevel = 1 + Math.floor(linesCleared / 10); if (newLevel !== level) { level = newLevel; levelTxt.setText('Lv.' + level); fallInterval = Math.max(150, 1000 - (level - 1) * 100); } } // Helper: draw board grid (for visual reference) var gridLines = new Container(); game.addChild(gridLines); for (var r = 0; r <= BOARD_ROWS; r++) { for (var c = 0; c <= BOARD_COLS; c++) { if (r < BOARD_ROWS && c < BOARD_COLS) { var cell = LK.getAsset('O', { anchorX: 0.5, anchorY: 0.5, width: CELL_SIZE - 4, height: CELL_SIZE - 4, color: 0x222222 }); cell.x = c * CELL_SIZE + CELL_SIZE / 2; cell.y = r * CELL_SIZE + CELL_SIZE / 2; cell.alpha = 0.15; gridLines.addChild(cell); } } } gridLines.x = BOARD_OFFSET_X; gridLines.y = BOARD_OFFSET_Y; // Move all blocks/containers to board offset function updateBoardDisplayOffsets() { gridLines.x = BOARD_OFFSET_X; gridLines.y = BOARD_OFFSET_Y; for (var r = 0; r < BOARD_ROWS; r++) { for (var c = 0; c < BOARD_COLS; c++) { if (blockRefs[r][c]) { blockRefs[r][c].x = c * CELL_SIZE + CELL_SIZE / 2 + BOARD_OFFSET_X; blockRefs[r][c].y = r * CELL_SIZE + CELL_SIZE / 2 + BOARD_OFFSET_Y; } } } if (currentTetromino) { for (var i = 0; i < currentTetromino.blocks.length; i++) { currentTetromino.blocks[i].x += BOARD_OFFSET_X; currentTetromino.blocks[i].y += BOARD_OFFSET_Y; } } } // Remove board offset from tetromino before logic function removeTetrominoOffset() { if (currentTetromino) { for (var i = 0; i < currentTetromino.blocks.length; i++) { currentTetromino.blocks[i].x -= BOARD_OFFSET_X; currentTetromino.blocks[i].y -= BOARD_OFFSET_Y; } } } // Touch controls var dragStartX = null; var dragStartY = null; var dragTetrominoX = null; var dragTetrominoY = null; var lastTouchMove = 0; var touchDown = false; var hardDrop = false; // Convert screen x,y to board col,row function screenToBoard(x, y) { var bx = Math.floor((x - BOARD_OFFSET_X) / CELL_SIZE); var by = Math.floor((y - BOARD_OFFSET_Y) / CELL_SIZE); return { col: bx, row: by }; } // Touch/mouse events game.down = function (x, y, obj) { if (isGameOver || !currentTetromino) return; dragStartX = x; dragStartY = y; dragTetrominoX = currentTetromino.x; dragTetrominoY = currentTetromino.y; touchDown = true; hardDrop = false; lastTouchMove = Date.now(); }; game.move = function (x, y, obj) { if (isGameOver || !currentTetromino || !touchDown) return; var dx = x - dragStartX; var dy = y - dragStartY; var moved = false; // Horizontal drag: move left/right if (Math.abs(dx) > CELL_SIZE / 2) { var dir = dx > 0 ? 1 : -1; if (currentTetromino.tryMove(dir, 0, board)) { dragStartX = x; dragTetrominoX = currentTetromino.x; moved = true; } } // Vertical drag: hard drop if (dy > CELL_SIZE * 2 && !hardDrop) { // Hard drop while (currentTetromino.tryMove(0, 1, board)) {} hardDrop = true; moved = true; } // Tap: rotate (handled in up) if (moved) { currentTetromino.updateBlockPositions(); updateBoardDisplayOffsets(); } }; game.up = function (x, y, obj) { if (isGameOver || !currentTetromino) return; touchDown = false; var dt = Date.now() - lastTouchMove; var dx = x - dragStartX; var dy = y - dragStartY; // Tap: rotate if (Math.abs(dx) < 30 && Math.abs(dy) < 30 && dt < 400) { removeTetrominoOffset(); currentTetromino.tryRotate(board); currentTetromino.updateBlockPositions(); updateBoardDisplayOffsets(); } }; // Auto fall function scheduleDrop() { if (dropTimer) LK.clearTimeout(dropTimer); if (isGameOver) return; dropTimer = LK.setTimeout(function () { if (isGameOver) return; removeTetrominoOffset(); var moved = currentTetromino.tryMove(0, 1, board); currentTetromino.updateBlockPositions(); updateBoardDisplayOffsets(); if (!moved) { // Lock to board currentTetromino.lockToBoard(board, blockRefs); // Powerup check var landedPowerup = false; for (var i = 0; i < currentTetromino.shape.length; i++) { var nx = currentTetromino.x + currentTetromino.shape[i][0]; var ny = currentTetromino.y + currentTetromino.shape[i][1]; if (board[ny][nx] === 'powerup') { activatePowerup(ny); landedPowerup = true; } } // Clear lines var lines = clearLines(); updateScore(lines); // Do not remove tetromino blocks here; they are now part of the board and will be removed when lines are cleared currentTetromino = null; // Spawn next spawnTetromino(); updateBoardDisplayOffsets(); } scheduleDrop(); }, fallInterval); } // Game update game.update = function () { // No per-frame logic needed for MVP }; // Start game function startGame() { // Reset board for (var r = 0; r < BOARD_ROWS; r++) { for (var c = 0; c < BOARD_COLS; c++) { board[r][c] = 0; if (blockRefs[r][c]) { if (blockRefs[r][c].parent) blockRefs[r][c].parent.removeChild(blockRefs[r][c]); blockRefs[r][c] = null; } } } score = 0; level = 1; linesCleared = 0; fallInterval = 1000; scoreTxt.setText(score); levelTxt.setText('Lv.1'); isGameOver = false; nextTetrominoType = TETROMINO_TYPES[Math.floor(Math.random() * TETROMINO_TYPES.length)]; updateNextPreview(); if (currentTetromino) { for (var i = 0; i < currentTetromino.blocks.length; i++) { if (currentTetromino.blocks[i].parent) currentTetromino.blocks[i].parent.removeChild(currentTetromino.blocks[i]); } currentTetromino = null; } spawnTetromino(); updateBoardDisplayOffsets(); scheduleDrop(); } // On game over, restart on new game LK.on('gameStart', function () { startGame(); }); // Initial start LK.playMusic('tetris_bgm'); startGame();
===================================================================
--- original.js
+++ change.js
@@ -241,9 +241,10 @@
nextTetrominoPreview.addChild(block);
}
// Center preview
// Place preview with a margin so it's fully visible and not outside the screen
- nextTetrominoPreview.x = Math.max(0, 2048 - CELL_SIZE * 4 - 60);
+ // Place it at a visible position near the right edge, but inside the screen
+ nextTetrominoPreview.x = 2048 - CELL_SIZE * 4 - 100;
}
// Helper: clear full lines
function clearLines() {
var lines = [];