User prompt
Puanı ekranın altına al
User prompt
Level yazısının yanına alev koyabilir misin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Daha belirgin hale getir ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Ejdere animasyon ekle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Biraz daha soluklaştır
User prompt
Biraz daha soluklaştır
User prompt
Blokların düşeceği yeri önizle
User prompt
Ejderi 3 cm aşağı al
User prompt
Yukarıya ejderha koy ve blokları o atsın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
İçinde gösterilen bloğu oturt karenin içine
User prompt
Biraz daha büyüt
User prompt
Sağ taraftaki kareyi büyüt biraz
User prompt
Şimdi sonraki gelecek bloğu sağ tarafta göster
User prompt
Kenarları daralt
User prompt
Ekranı kapla
Code edit (1 edits merged)
Please save this source code
User prompt
Tetris Yap
Initial prompt
Tetris yap
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Dragon = Container.expand(function () {
var self = Container.call(this);
self.dragonGraphics = self.attachAsset('dragon', {
anchorX: 0.5,
anchorY: 0.5
});
// Start idle wing flapping animation
self.startIdleAnimation = function () {
// Wing flapping - more pronounced scale and rotation changes
tween(self.dragonGraphics, {
scaleX: 1.3,
scaleY: 0.8,
rotation: 0.15
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self.dragonGraphics, {
scaleX: 1.0,
scaleY: 1.0,
rotation: -0.15
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Continue the idle animation loop
self.startIdleAnimation();
}
});
}
});
};
// Start the idle animation immediately
self.startIdleAnimation();
self.throwPiece = function (piece) {
// Stop idle animation temporarily
tween.stop(self.dragonGraphics);
// Add throwing animation - more dramatic bounce effect
tween(self.dragonGraphics, {
scaleY: 0.5,
scaleX: 1.5,
rotation: 0.25
}, {
duration: 80,
easing: tween.easeOut
});
tween(self, {
scaleY: 0.6
}, {
duration: 120,
easing: tween.easeOut
});
tween(self, {
scaleY: 1.0
}, {
duration: 120,
easing: tween.easeOut,
onFinish: function onFinish() {
// Reset dragon graphics and restart idle animation
tween(self.dragonGraphics, {
scaleY: 1.0,
scaleX: 1.0,
rotation: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
self.startIdleAnimation();
}
});
// After throw animation, animate the piece falling
if (piece) {
var startY = piece.y;
piece.y = self.y + 50; // Start from dragon position
tween(piece, {
y: startY
}, {
duration: 800,
easing: tween.easeIn
});
}
}
});
};
return self;
});
var GhostBlock = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
self.blockGraphics = self.attachAsset('tetromino' + type, {
anchorX: 0,
anchorY: 0
});
// Make ghost block more transparent
self.blockGraphics.alpha = 0.08;
return self;
});
var Tetromino = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
self.blocks = [];
self.currentRotation = 0;
// Define tetromino shapes and rotations
self.shapes = {
'I': [[[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0]], [[0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0]], [[0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0]]],
'O': [[[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]]],
'T': [[[0, 1, 0], [1, 1, 1], [0, 0, 0]], [[0, 1, 0], [0, 1, 1], [0, 1, 0]], [[0, 0, 0], [1, 1, 1], [0, 1, 0]], [[0, 1, 0], [1, 1, 0], [0, 1, 0]]],
'S': [[[0, 1, 1], [1, 1, 0], [0, 0, 0]], [[0, 1, 0], [0, 1, 1], [0, 0, 1]], [[0, 0, 0], [0, 1, 1], [1, 1, 0]], [[1, 0, 0], [1, 1, 0], [0, 1, 0]]],
'Z': [[[1, 1, 0], [0, 1, 1], [0, 0, 0]], [[0, 0, 1], [0, 1, 1], [0, 1, 0]], [[0, 0, 0], [1, 1, 0], [0, 1, 1]], [[0, 1, 0], [1, 1, 0], [1, 0, 0]]],
'J': [[[1, 0, 0], [1, 1, 1], [0, 0, 0]], [[0, 1, 1], [0, 1, 0], [0, 1, 0]], [[0, 0, 0], [1, 1, 1], [0, 0, 1]], [[0, 1, 0], [0, 1, 0], [1, 1, 0]]],
'L': [[[0, 0, 1], [1, 1, 1], [0, 0, 0]], [[0, 1, 0], [0, 1, 0], [0, 1, 1]], [[0, 0, 0], [1, 1, 1], [1, 0, 0]], [[1, 1, 0], [0, 1, 0], [0, 1, 0]]]
};
self.createBlocks = function () {
// Clear existing blocks
for (var i = 0; i < self.blocks.length; i++) {
self.blocks[i].destroy();
}
self.blocks = [];
var shape = self.shapes[self.type][self.currentRotation];
for (var row = 0; row < shape.length; row++) {
for (var col = 0; col < shape[row].length; col++) {
if (shape[row][col] === 1) {
var block = new TetrominoBlock(self.type);
block.x = col * 100;
block.y = row * 100;
self.blocks.push(block);
self.addChild(block);
}
}
}
};
self.rotate = function () {
var newRotation = (self.currentRotation + 1) % 4;
var oldRotation = self.currentRotation;
self.currentRotation = newRotation;
self.createBlocks();
// Check if rotation is valid
if (!self.isValidPosition()) {
// Revert rotation if invalid
self.currentRotation = oldRotation;
self.createBlocks();
return false;
}
LK.getSound('rotate').play();
updateGhostPiece();
return true;
};
self.isValidPosition = function () {
var shape = self.shapes[self.type][self.currentRotation];
var boardX = Math.floor((self.x - boardOffsetX) / 100);
var boardY = Math.floor((self.y - boardOffsetY) / 100);
for (var row = 0; row < shape.length; row++) {
for (var col = 0; col < shape[row].length; col++) {
if (shape[row][col] === 1) {
var checkX = boardX + col;
var checkY = boardY + row;
// Check boundaries
if (checkX < 0 || checkX >= boardWidth || checkY >= boardHeight) {
return false;
}
// Check collision with placed blocks
if (checkY >= 0 && board[checkY] && board[checkY][checkX] !== null) {
return false;
}
}
}
}
return true;
};
// Initialize with blocks
self.createBlocks();
return self;
});
var TetrominoBlock = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
self.blockGraphics = self.attachAsset('tetromino' + type, {
anchorX: 0,
anchorY: 0
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x111111
});
/****
* Game Code
****/
// Game constants
// Tetromino blocks
// Board elements
// Sound effects
var boardWidth = 10;
var boardHeight = 20;
var blockSize = 100;
var boardOffsetX = 524;
var boardOffsetY = 200;
// Game state
var board = [];
var currentPiece = null;
var nextPiece = null;
var nextPieceType = null;
var nextPiecePreview = null;
var ghostPiece = null;
var nextPieces = ['I', 'O', 'T', 'S', 'Z', 'J', 'L'];
var fallTimer = 0;
var fallSpeed = 60; // frames per fall
var level = 1;
var linesCleared = 0;
var isGameOver = false;
var dragon = null;
// Initialize board
function initializeBoard() {
board = [];
for (var row = 0; row < boardHeight; row++) {
board[row] = [];
for (var col = 0; col < boardWidth; col++) {
board[row][col] = null;
}
}
}
// Create next piece preview area
function createNextPiecePreview() {
var previewX = boardOffsetX + boardWidth * blockSize + 50;
var previewY = boardOffsetY + 50;
var previewSize = 400;
// Preview border
var previewBorder = LK.getAsset('boardBorder', {
anchorX: 0,
anchorY: 0,
width: 4,
height: previewSize
});
previewBorder.x = previewX - 4;
previewBorder.y = previewY;
game.addChild(previewBorder);
var previewBorderRight = LK.getAsset('boardBorder', {
anchorX: 0,
anchorY: 0,
width: 4,
height: previewSize
});
previewBorderRight.x = previewX + previewSize;
previewBorderRight.y = previewY;
game.addChild(previewBorderRight);
var previewBorderTop = LK.getAsset('boardBorder', {
anchorX: 0,
anchorY: 0,
width: previewSize + 8,
height: 4
});
previewBorderTop.x = previewX - 4;
previewBorderTop.y = previewY - 4;
game.addChild(previewBorderTop);
var previewBorderBottom = LK.getAsset('boardBorder', {
anchorX: 0,
anchorY: 0,
width: previewSize + 8,
height: 4
});
previewBorderBottom.x = previewX - 4;
previewBorderBottom.y = previewY + previewSize;
game.addChild(previewBorderBottom);
// Next piece label
var nextLabel = new Text2('NEXT', {
size: 40,
fill: 0xFFFFFF
});
nextLabel.anchor.set(0.5, 1);
nextLabel.x = previewX + previewSize / 2;
nextLabel.y = previewY - 10;
game.addChild(nextLabel);
}
// Create board borders
function createBoardBorders() {
// Left border
var leftBorder = LK.getAsset('boardBorder', {
anchorX: 0,
anchorY: 0,
width: 4,
height: boardHeight * blockSize
});
leftBorder.x = boardOffsetX - 4;
leftBorder.y = boardOffsetY;
game.addChild(leftBorder);
// Right border
var rightBorder = LK.getAsset('boardBorder', {
anchorX: 0,
anchorY: 0,
width: 4,
height: boardHeight * blockSize
});
rightBorder.x = boardOffsetX + boardWidth * blockSize;
rightBorder.y = boardOffsetY;
game.addChild(rightBorder);
// Bottom border
var bottomBorder = LK.getAsset('boardBorder', {
anchorX: 0,
anchorY: 0,
width: boardWidth * blockSize + 8,
height: 4
});
bottomBorder.x = boardOffsetX - 4;
bottomBorder.y = boardOffsetY + boardHeight * blockSize;
game.addChild(bottomBorder);
}
// Generate random piece type
function getRandomPieceType() {
var types = ['I', 'O', 'T', 'S', 'Z', 'J', 'L'];
return types[Math.floor(Math.random() * types.length)];
}
// Update next piece preview
function updateNextPiecePreview() {
// Clear existing preview
if (nextPiecePreview) {
nextPiecePreview.destroy();
}
if (nextPieceType) {
var previewX = boardOffsetX + boardWidth * blockSize + 50;
var previewY = boardOffsetY + 50;
var previewSize = 400;
nextPiecePreview = new Tetromino(nextPieceType);
// Get piece dimensions to center it properly
var shape = nextPiecePreview.shapes[nextPieceType][0];
var pieceWidth = 0;
var pieceHeight = shape.length;
for (var row = 0; row < shape.length; row++) {
pieceWidth = Math.max(pieceWidth, shape[row].length);
}
// Calculate center position within preview area
var piecePixelWidth = pieceWidth * 100;
var piecePixelHeight = pieceHeight * 100;
var centerX = previewX + (previewSize - piecePixelWidth) / 2;
var centerY = previewY + (previewSize - piecePixelHeight) / 2;
nextPiecePreview.x = centerX;
nextPiecePreview.y = centerY;
// Scale down the preview piece
nextPiecePreview.scaleX = 1.0;
nextPiecePreview.scaleY = 1.0;
game.addChild(nextPiecePreview);
}
}
// Update ghost piece preview
function updateGhostPiece() {
// Clear existing ghost piece
if (ghostPiece) {
ghostPiece.destroy();
ghostPiece = null;
}
if (!currentPiece) return;
// Create ghost piece container
ghostPiece = new Container();
// Get current piece shape
var shape = currentPiece.shapes[currentPiece.type][currentPiece.currentRotation];
// Find the lowest valid position for the current piece
var testY = currentPiece.y;
var validY = currentPiece.y;
// Move test position down until it's no longer valid
while (true) {
testY += blockSize;
// Check if this position would be valid
var boardX = Math.floor((currentPiece.x - boardOffsetX) / blockSize);
var boardY = Math.floor((testY - boardOffsetY) / blockSize);
var isValid = true;
for (var row = 0; row < shape.length && isValid; row++) {
for (var col = 0; col < shape[row].length && isValid; col++) {
if (shape[row][col] === 1) {
var checkX = boardX + col;
var checkY = boardY + row;
// Check boundaries and collisions
if (checkX < 0 || checkX >= boardWidth || checkY >= boardHeight) {
isValid = false;
} else if (checkY >= 0 && board[checkY] && board[checkY][checkX] !== null) {
isValid = false;
}
}
}
}
if (!isValid) {
break;
}
validY = testY;
}
// Only show ghost piece if it's below the current piece
if (validY > currentPiece.y) {
// Create ghost blocks at the valid position
for (var row = 0; row < shape.length; row++) {
for (var col = 0; col < shape[row].length; col++) {
if (shape[row][col] === 1) {
var ghostBlock = new GhostBlock(currentPiece.type);
ghostBlock.x = currentPiece.x + col * 100;
ghostBlock.y = validY + row * 100;
ghostPiece.addChild(ghostBlock);
}
}
}
game.addChild(ghostPiece);
}
}
// Spawn new piece
function spawnNewPiece() {
if (currentPiece) {
currentPiece.destroy();
}
// Clear ghost piece when spawning new piece
if (ghostPiece) {
ghostPiece.destroy();
ghostPiece = null;
}
// Use next piece or generate first piece
var pieceType;
if (nextPieceType) {
pieceType = nextPieceType;
} else {
pieceType = getRandomPieceType();
}
// Generate new next piece
nextPieceType = getRandomPieceType();
updateNextPiecePreview();
currentPiece = new Tetromino(pieceType);
currentPiece.x = boardOffsetX + Math.floor(boardWidth / 2) * blockSize - blockSize;
currentPiece.y = boardOffsetY;
game.addChild(currentPiece);
// Dragon throws the piece
if (dragon) {
dragon.throwPiece(currentPiece);
}
// Update ghost piece for new piece
updateGhostPiece();
// Check if game over
if (!currentPiece.isValidPosition()) {
isGameOver = true;
LK.showGameOver();
}
}
// Move piece down
function movePieceDown() {
if (!currentPiece) return false;
currentPiece.y += blockSize;
if (!currentPiece.isValidPosition()) {
currentPiece.y -= blockSize;
placePiece();
return false;
}
updateGhostPiece();
return true;
}
// Move piece left
function movePieceLeft() {
if (!currentPiece) return;
currentPiece.x -= blockSize;
if (!currentPiece.isValidPosition()) {
currentPiece.x += blockSize;
} else {
updateGhostPiece();
}
}
// Move piece right
function movePieceRight() {
if (!currentPiece) return;
currentPiece.x += blockSize;
if (!currentPiece.isValidPosition()) {
currentPiece.x -= blockSize;
} else {
updateGhostPiece();
}
}
// Place piece on board
function placePiece() {
if (!currentPiece) return;
var shape = currentPiece.shapes[currentPiece.type][currentPiece.currentRotation];
var boardX = Math.floor((currentPiece.x - boardOffsetX) / blockSize);
var boardY = Math.floor((currentPiece.y - boardOffsetY) / blockSize);
// Place blocks on board
for (var row = 0; row < shape.length; row++) {
for (var col = 0; col < shape[row].length; col++) {
if (shape[row][col] === 1) {
var placeX = boardX + col;
var placeY = boardY + row;
if (placeY >= 0 && placeY < boardHeight && placeX >= 0 && placeX < boardWidth) {
// Create placed block
var placedBlock = new TetrominoBlock(currentPiece.type);
placedBlock.x = boardOffsetX + placeX * blockSize;
placedBlock.y = boardOffsetY + placeY * blockSize;
game.addChild(placedBlock);
board[placeY][placeX] = placedBlock;
}
}
}
}
LK.getSound('pieceLand').play();
// Check for completed lines
checkCompletedLines();
// Spawn new piece
spawnNewPiece();
}
// Check for completed lines
function checkCompletedLines() {
var completedLines = [];
// Find completed lines
for (var row = 0; row < boardHeight; row++) {
var isComplete = true;
for (var col = 0; col < boardWidth; col++) {
if (board[row][col] === null) {
isComplete = false;
break;
}
}
if (isComplete) {
completedLines.push(row);
}
}
// Clear completed lines
if (completedLines.length > 0) {
// Remove blocks from completed lines
for (var i = 0; i < completedLines.length; i++) {
var row = completedLines[i];
for (var col = 0; col < boardWidth; col++) {
if (board[row][col]) {
board[row][col].destroy();
board[row][col] = null;
}
}
}
// Drop lines above
for (var i = completedLines.length - 1; i >= 0; i--) {
var clearedRow = completedLines[i];
// Move all rows above down
for (var row = clearedRow; row > 0; row--) {
for (var col = 0; col < boardWidth; col++) {
board[row][col] = board[row - 1][col];
if (board[row][col]) {
board[row][col].y += blockSize;
}
}
}
// Clear top row
for (var col = 0; col < boardWidth; col++) {
board[0][col] = null;
}
// Adjust subsequent cleared rows
for (var j = i + 1; j < completedLines.length; j++) {
completedLines[j]++;
}
}
// Update score
var points = completedLines.length * 100 * level;
if (completedLines.length === 4) points *= 2; // Tetris bonus
LK.setScore(LK.getScore() + points);
scoreTxt.setText(LK.getScore());
linesCleared += completedLines.length;
level = Math.floor(linesCleared / 10) + 1;
fallSpeed = Math.max(10, 60 - (level - 1) * 5);
levelTxt.setText('Level: ' + level);
linesTxt.setText('Lines: ' + linesCleared);
LK.getSound('lineClear').play();
}
}
// Touch controls
var touchStartX = 0;
var touchStartY = 0;
var isTouching = false;
game.down = function (x, y, obj) {
touchStartX = x;
touchStartY = y;
isTouching = true;
};
game.up = function (x, y, obj) {
if (!isTouching) return;
isTouching = false;
var deltaX = x - touchStartX;
var deltaY = y - touchStartY;
// Swipe down for fast drop
if (deltaY > 50 && Math.abs(deltaX) < 30) {
while (movePieceDown()) {
// Keep dropping until piece lands
}
return;
}
// Tap piece to rotate
if (Math.abs(deltaX) < 30 && Math.abs(deltaY) < 30) {
if (currentPiece) {
currentPiece.rotate();
}
return;
}
// Swipe left/right to move
if (Math.abs(deltaX) > 30) {
if (deltaX > 0) {
movePieceRight();
} else {
movePieceLeft();
}
}
};
// Initialize UI
var scoreTxt = new Text2('0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.setText(LK.getScore());
LK.gui.top.addChild(scoreTxt);
var levelTxt = new Text2('Level: 1', {
size: 40,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0, 0);
levelTxt.x = 100;
levelTxt.y = 100;
LK.gui.topLeft.addChild(levelTxt);
// Add flame next to level text
var flameGraphics = LK.getAsset('flame', {
anchorX: 0.5,
anchorY: 0.5
});
flameGraphics.x = levelTxt.x + 200; // Position to the right of level text
flameGraphics.y = levelTxt.y + 20; // Center vertically with text
LK.gui.topLeft.addChild(flameGraphics);
// Add flickering animation to flame
function startFlameAnimation() {
tween(flameGraphics, {
scaleX: 1.2,
scaleY: 0.8,
alpha: 0.8
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(flameGraphics, {
scaleX: 0.9,
scaleY: 1.1,
alpha: 1.0
}, {
duration: 250,
easing: tween.easeInOut,
onFinish: function onFinish() {
startFlameAnimation();
}
});
}
});
}
startFlameAnimation();
var linesTxt = new Text2('Lines: 0', {
size: 40,
fill: 0xFFFFFF
});
linesTxt.anchor.set(0, 0);
linesTxt.x = 100;
linesTxt.y = 150;
LK.gui.topLeft.addChild(linesTxt);
// Initialize dragon
dragon = new Dragon();
dragon.x = boardOffsetX + boardWidth * blockSize / 2;
dragon.y = boardOffsetY - 80; // Position above the game area (moved 120px down from -200 to -80)
game.addChild(dragon);
// Initialize game
initializeBoard();
createBoardBorders();
createNextPiecePreview();
// Generate first next piece
nextPieceType = getRandomPieceType();
updateNextPiecePreview();
spawnNewPiece();
// Game update loop
game.update = function () {
if (isGameOver) return;
fallTimer++;
if (fallTimer >= fallSpeed) {
fallTimer = 0;
movePieceDown();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -198,12 +198,12 @@
/****
* Game Code
****/
-// Sound effects
-// Board elements
-// Tetromino blocks
// Game constants
+// Tetromino blocks
+// Board elements
+// Sound effects
var boardWidth = 10;
var boardHeight = 20;
var blockSize = 100;
var boardOffsetX = 524;
@@ -621,8 +621,41 @@
levelTxt.anchor.set(0, 0);
levelTxt.x = 100;
levelTxt.y = 100;
LK.gui.topLeft.addChild(levelTxt);
+// Add flame next to level text
+var flameGraphics = LK.getAsset('flame', {
+ anchorX: 0.5,
+ anchorY: 0.5
+});
+flameGraphics.x = levelTxt.x + 200; // Position to the right of level text
+flameGraphics.y = levelTxt.y + 20; // Center vertically with text
+LK.gui.topLeft.addChild(flameGraphics);
+// Add flickering animation to flame
+function startFlameAnimation() {
+ tween(flameGraphics, {
+ scaleX: 1.2,
+ scaleY: 0.8,
+ alpha: 0.8
+ }, {
+ duration: 300,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ tween(flameGraphics, {
+ scaleX: 0.9,
+ scaleY: 1.1,
+ alpha: 1.0
+ }, {
+ duration: 250,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ startFlameAnimation();
+ }
+ });
+ }
+ });
+}
+startFlameAnimation();
var linesTxt = new Text2('Lines: 0', {
size: 40,
fill: 0xFFFFFF
});