User prompt
color gerekli degilse koddan sil
User prompt
Shape formu gerekli degilse koddan sil
User prompt
asset isimlerini dogrudan kodda kullan
User prompt
Shapetypes listesindeki isimleri asset isimleriyle aynı tap
User prompt
Cell ismini hucre yap
User prompt
Redcircle cilek yap
User prompt
Bluecircle ismini kiraz yap
User prompt
blueshape ismini ananas yap
User prompt
Yellow shape kaldir
User prompt
Orangecircle kaldir
User prompt
applecircle kaldır
User prompt
redshape kaldır
User prompt
leverHandlePassive kaldır
User prompt
Add the missing asset definitions to the initialization section, or 2. Remove references to the unused shape combinations
User prompt
goodsitemlerde bir açik mavi box kullanıyorsun onu assetlere ekle yada kaldir
User prompt
Açık mavi assetlerde olmayan bir box var. Buna asset ekle
User prompt
Hiç kullanılmayan assetleri kaldır.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var DropShape = Container.expand(function (shapeType, color, shapeForm) { var self = Container.call(this); self.shapeType = shapeType; self.color = color; self.shapeForm = shapeForm; self.speed = 0; self.targetY = 0; self.isMoving = false; self.lane = 0; self.row = -1; var assetId = color + shapeForm; // Replace redShape with karpuz if (assetId === 'redShape') { assetId = 'karpuz'; } // Replace yellowShape with muz if (assetId === 'yellowShape') { assetId = 'muz'; } // Handle orange and apple - use direct asset names and set proper shape form if (color === 'orange') { assetId = 'orange'; self.shapeForm = 'Shape'; // Ensure shapeForm is set for matching logic } if (color === 'apple') { assetId = 'apple'; self.shapeForm = 'Shape'; // Ensure shapeForm is set for matching logic } var shapeGraphics = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5, scaleX: 1.25, scaleY: 1.25 }); self.startDrop = function (lane, startY, endY, targetRow) { self.lane = lane; self.y = startY; self.targetY = endY; self.targetRow = targetRow; self.speed = 120; // Double the speed for much faster movement self.isMoving = true; self.rotationComplete = false; // Add slot machine spinning effect - faster rotation tween(self, { rotation: Math.PI * 4 }, { duration: 800, // Much faster rotation animation easing: tween.easeOut, onFinish: function onFinish() { self.rotationComplete = true; } }); }; self.update = function () { if (self.isMoving) { self.y += self.speed; // Much faster settling with aggressive deceleration var distanceToTarget = Math.abs(self.targetY - self.y); if (distanceToTarget < 150) { self.speed = Math.max(8, self.speed * 0.85); // Higher minimum speed and faster deceleration } // Stop at target with bounce effect if (self.y >= self.targetY) { self.y = self.targetY; self.isMoving = false; self.speed = 0; // No bounce animation to keep consistent size // Calculate which row this shape is in - use targetRow if available if (self.targetRow !== undefined) { self.row = self.targetRow; } else { self.row = Math.floor((self.y - gridStartY) / (cellSize + cellMargin)); } } } }; return self; }); var GoodsItem = Container.expand(function (goodsType) { var self = Container.call(this); self.goodsType = goodsType; self.isFromScore = false; // Code-based marker for score items var itemGraphics = self.attachAsset(goodsType, { anchorX: 0.5, anchorY: 0.5, scaleX: 1.25, scaleY: 1.25 }); self.down = function (x, y, obj) { // Prevent interaction while any sequence or animation is running if (isScoreRefunding || isSequenceRunning || isTweenAnimating) return; // Check if this item is from score and currently in inventory slot if (self.isFromScore && currentInventoryItem === self) { // Item is in inventory slot, destroy and refund to score // Set refund flag to prevent multiple clicks isScoreRefunding = true; // Store reference to item being refunded var itemToRefund = self; // Calculate score text position in game coordinates var targetX = 1024; // Center of screen horizontally var targetY = 150; // Below score text instead of at score text position // Animate item moving towards score display with shrinking effect tween(itemToRefund, { x: targetX, y: targetY, scaleX: 0.3, scaleY: 0.3, alpha: 0.7 }, { duration: 150, // Double speed (half duration) easing: tween.easeOut, onFinish: function onFinish() { // Add score and update display after animation LK.setScore(LK.getScore() + 1000); updateScore(); // Flash score text tween(scoreTxt, { scaleX: 1.3, scaleY: 1.3 }, { duration: 100, onFinish: function onFinish() { tween(scoreTxt, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100 }); } }); // Destroy item after score animation starts LK.setTimeout(function () { itemToRefund.destroy(); isScoreRefunding = false; }, 50); } }); // Clear from inventory currentInventoryItem = null; return; } // Check if this item is currently in goods grid (regardless of score status) var gridIndex = goodsGrid.indexOf(self); if (gridIndex !== -1) { // Item is in goods grid, move it to inventory slot moveToInventory(self); return; } // Move this item to inventory slot moveToInventory(self); }; return self; }); var Lever = Container.expand(function () { var self = Container.call(this); self.isPulled = false; self.canPull = true; var leverBase = self.attachAsset('lever', { anchorX: 0.5, anchorY: 1.0 }); self.leverHandle = self.attachAsset('leverHandle', { anchorX: 0.5, anchorY: 0.5 }); self.leverHandle.y = -700; self.pull = function () { if (!self.canPull || isShifting || isAnimating) return; // Check if player has enough money (10₺ required) if (money < 10) return; // Deduct 10₺ for using the slot machine money -= 10; updateMoney(); pullCount++; // Increment pull count self.canPull = false; self.isPulled = true; LK.getSound('leverPull').play(); // Animate lever handle moving down - much faster tween(self.leverHandle, { y: -100 }, { duration: 15, easing: tween.easeOut }); // Keep lever pulled state - will be reset on touch release // Allow immediate next pull self.canPull = true; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2a1810 }); /**** * Game Code ****/ var lanes = []; var dropItems = []; var cellSize = 300; // Square cell size var cellMargin = 15; // 15 pixel margin between cells var totalGridWidth = 4 * cellSize + 3 * cellMargin; // Total width of 4 columns with margins var totalGridHeight = 4 * cellSize + 3 * cellMargin; // Total height of 4 rows with margins var gridStartX = (2048 - totalGridWidth) / 2 - 200; // Shift the 4x5 grid to the left var gridStartY = 600 - (cellSize + cellMargin); // Shift grid up by one grid cell height var laneWidth = cellSize + cellMargin; // Width per column including margin var laneBackgroundWidth = cellSize; // Square cell background var cellHeight = cellSize + cellMargin; // Height per row including margin var shapeTypes = ['red', 'blue', 'green', 'yellow', 'orange', 'apple']; var shapeForms = ['Shape', 'Circle']; var lever; var scoreTxt; var money = 0; var moneyTxt; var goodsGrid = []; var inventorySlot = null; var currentInventoryItem = null; var sellButton = null; var buyButton = null; var goodsTypes = ['corn', 'grape', 'bread', 'cheese', 'meat', 'fish']; // Create background - render first to be behind all other elements var background = LK.getAsset('background', { anchorX: 0, anchorY: 0 }); background.x = 0; background.y = 0; game.addChild(background); // Create lane backgrounds for 4x4 grid - render first to be behind other elements for (var col = 0; col < 4; col++) { for (var row = 0; row < 4; row++) { var assetType = 'cell'; var cellBack = LK.getAsset(assetType, { width: cellSize, height: cellSize, anchorX: 0.5, anchorY: 0.5 }); cellBack.x = gridStartX + col * (cellSize + cellMargin) + cellSize / 2; cellBack.y = gridStartY + row * (cellSize + cellMargin) + cellSize / 2; game.addChild(cellBack); } } // Create goods grid backgrounds (4x3) - render first to be behind other elements var goodsGridStartX = gridStartX; var goodsGridStartY = gridStartY + totalGridHeight + 100; var goodsCellSize = cellSize; // Use same size as main grid cells (300px) var goodsMargin = cellMargin; // Use same margin as main grid (15px) for (var row = 0; row < 3; row++) { for (var col = 0; col < 4; col++) { // Create cell background var cellBack = LK.getAsset('goodsCell', { width: goodsCellSize, height: goodsCellSize, anchorX: 0.5, anchorY: 0.5 }); cellBack.x = goodsGridStartX + col * (goodsCellSize + goodsMargin) + goodsCellSize / 2; cellBack.y = goodsGridStartY + row * (goodsCellSize + goodsMargin) + goodsCellSize / 2; game.addChild(cellBack); } } // Create inventory slot background - render first to be behind other elements inventorySlot = LK.getAsset('inventorySlot', { width: goodsCellSize, height: goodsCellSize, anchorX: 0.5, anchorY: 0.5 }); inventorySlot.x = 1750; inventorySlot.y = goodsGridStartY + goodsCellSize / 2; inventorySlot.down = function (x, y, obj) { // Prevent interaction while any sequence or animation is running if (isScoreRefunding || isSequenceRunning || isTweenAnimating) return; // Prevent interaction when inventory slot is empty if (!currentInventoryItem) return; // If there's an item in inventory, handle refund if it's from score if (currentInventoryItem && currentInventoryItem.isFromScore) { // Set refund flag to prevent multiple clicks isScoreRefunding = true; // Store reference to item being refunded var itemToRefund = currentInventoryItem; // Calculate score text position in game coordinates var targetX = 1024; // Center of screen horizontally var targetY = 150; // Below score text instead of at score text position // Animate item moving towards score display with shrinking effect tween(itemToRefund, { x: targetX, y: targetY, scaleX: 0.3, scaleY: 0.3, alpha: 0.7 }, { duration: 150, // Double speed (half duration) easing: tween.easeOut, onFinish: function onFinish() { // Add score and update display after animation LK.setScore(LK.getScore() + 1000); updateScore(); // Flash score text tween(scoreTxt, { scaleX: 1.3, scaleY: 1.3 }, { duration: 100, onFinish: function onFinish() { tween(scoreTxt, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100 }); } }); // Destroy item after score animation starts LK.setTimeout(function () { itemToRefund.destroy(); isScoreRefunding = false; }, 50); } }); // Clear from goods grid if it was placed there var gridIndex = goodsGrid.indexOf(currentInventoryItem); if (gridIndex !== -1) { goodsGrid[gridIndex] = null; } currentInventoryItem = null; return; } else if (currentInventoryItem && !currentInventoryItem.isFromScore) { // Only allow non-score items to move to goods grid var gridIndex = goodsGrid.indexOf(currentInventoryItem); if (gridIndex !== -1) { var row = Math.floor(gridIndex / 4); var col = gridIndex % 4; var targetX = goodsGridStartX + col * (goodsCellSize + goodsMargin) + goodsCellSize / 2; var targetY = goodsGridStartY + row * (goodsCellSize + goodsMargin) + goodsCellSize / 2; tween(currentInventoryItem, { x: targetX, y: targetY }, { duration: 300, easing: tween.easeOut }); } currentInventoryItem = null; } else if (LK.getScore() >= 1000) { // Only generate item if inventory is empty and score >= 1000 var randomGoodsType = goodsTypes[Math.floor(Math.random() * goodsTypes.length)]; var goodsItem = new GoodsItem(randomGoodsType); goodsItem.x = inventorySlot.x; goodsItem.y = inventorySlot.y; // Mark as item generated from score goodsItem.isFromScore = true; game.addChild(goodsItem); currentInventoryItem = goodsItem; // Deduct 1000 from score LK.setScore(LK.getScore() - 1000); updateScore(); } }; game.addChild(inventorySlot); // Create buy button below inventory slot buyButton = LK.getAsset('buyButton', { width: goodsCellSize, height: goodsCellSize / 2, anchorX: 0.5, anchorY: 0.5 }); buyButton.x = inventorySlot.x; buyButton.y = inventorySlot.y + goodsCellSize / 2 + goodsMargin + goodsCellSize / 4; game.addChild(buyButton); // Create sell button below buy button sellButton = LK.getAsset('sellButton', { width: goodsCellSize, height: goodsCellSize / 2, anchorX: 0.5, anchorY: 0.5 }); sellButton.x = inventorySlot.x; sellButton.y = buyButton.y + goodsCellSize / 2 + goodsMargin; game.addChild(sellButton); // Result cell removed // Create lever lever = game.addChild(new Lever()); lever.x = 1700; // Move to the left lever.y = 1400 - (cellSize + cellMargin); // Move up by one cell height // Create score display scoreTxt = new Text2('Skor: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Create money display moneyTxt = new Text2('Para: 0₺', { size: 60, fill: 0x00ff00 }); moneyTxt.anchor.set(0.5, 0); moneyTxt.y = 100; LK.gui.top.addChild(moneyTxt); // Create goods items after backgrounds are rendered for (var row = 0; row < 3; row++) { for (var col = 0; col < 4; col++) { // Only create goods item for the first cell (start with 1 item) if (row === 0 && col === 0) { var randomGoodsType = goodsTypes[Math.floor(Math.random() * goodsTypes.length)]; var goodsItem = new GoodsItem(randomGoodsType); var cellX = goodsGridStartX + col * (goodsCellSize + goodsMargin) + goodsCellSize / 2; var cellY = goodsGridStartY + row * (goodsCellSize + goodsMargin) + goodsCellSize / 2; goodsItem.x = cellX; goodsItem.y = cellY; goodsItem.scaleX = 1.25; goodsItem.scaleY = 1.25; game.addChild(goodsItem); goodsGrid.push(goodsItem); } else { goodsGrid.push(null); } } } // Add buy button text var buyButtonText = new Text2('Al', { size: 80, fill: 0xffffff }); buyButtonText.anchor.set(0.5, 0.5); buyButtonText.x = buyButton.x; buyButtonText.y = buyButton.y; game.addChild(buyButtonText); // Add sell button text var sellButtonText = new Text2('Sat', { size: 80, fill: 0xffffff }); sellButtonText.anchor.set(0.5, 0.5); sellButtonText.x = sellButton.x; sellButtonText.y = sellButton.y; game.addChild(sellButtonText); function updateScore() { scoreTxt.setText('Skor: ' + LK.getScore()); } function updateMoney() { moneyTxt.setText('Para: ' + money + '₺'); } function moveToInventory(goodsItem) { // If clicking on the same item that's already in inventory, return it to grid if (currentInventoryItem === goodsItem) { var gridIndex = goodsGrid.indexOf(currentInventoryItem); if (gridIndex !== -1) { var row = Math.floor(gridIndex / 4); var col = gridIndex % 4; var targetX = goodsGridStartX + col * (goodsCellSize + goodsMargin) + goodsCellSize / 2; var targetY = goodsGridStartY + row * (goodsCellSize + goodsMargin) + goodsCellSize / 2; isTweenAnimating = true; tween(currentInventoryItem, { x: targetX, y: targetY }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { isTweenAnimating = false; } }); } currentInventoryItem = null; return; } if (currentInventoryItem) { // Return current item to its original position in grid var gridIndex = goodsGrid.indexOf(currentInventoryItem); if (gridIndex !== -1) { var row = Math.floor(gridIndex / 4); var col = gridIndex % 4; var targetX = goodsGridStartX + col * (goodsCellSize + goodsMargin) + goodsCellSize / 2; var targetY = goodsGridStartY + row * (goodsCellSize + goodsMargin) + goodsCellSize / 2; isTweenAnimating = true; tween(currentInventoryItem, { x: targetX, y: targetY }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { isTweenAnimating = false; } }); } } // Move new item to inventory - preserve score flag currentInventoryItem = goodsItem; // Keep the score flag so items can still be refunded if they were from score // currentInventoryItem.isFromScore remains unchanged isTweenAnimating = true; tween(goodsItem, { x: inventorySlot.x, y: inventorySlot.y }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { isTweenAnimating = false; } }); } function sellItem() { if (currentInventoryItem) { // Prevent interactions during sell animation isTweenAnimating = true; // Store reference to item being sold var itemToSell = currentInventoryItem; // Calculate money text position in game coordinates var moneyWorldPos = LK.gui.toLocal(moneyTxt.position); var targetX = 1024; // Center of screen horizontally var targetY = 250; // Below money text instead of at money text position // Animate item moving towards money display with shrinking effect tween(itemToSell, { x: targetX, y: targetY, scaleX: 0.3, scaleY: 0.3, alpha: 0.7 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Add money and update display after animation money += 100; updateMoney(); // Flash money text tween(moneyTxt, { scaleX: 1.3, scaleY: 1.3 }, { duration: 200, onFinish: function onFinish() { tween(moneyTxt, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200 }); } }); // Destroy item after money animation starts LK.setTimeout(function () { itemToSell.destroy(); isTweenAnimating = false; }, 100); } }); // Remove sold item from grid and inventory var gridIndex = goodsGrid.indexOf(currentInventoryItem); if (gridIndex !== -1) { goodsGrid[gridIndex] = null; } currentInventoryItem = null; } } function buyItemWithScore() { // Check if player has enough score (1000 required) if (LK.getScore() < 1000) return; // Check if inventory slot is empty if (currentInventoryItem !== null) return; // Prevent interactions during buy animation isTweenAnimating = true; // Deduct 1000 from score LK.setScore(LK.getScore() - 1000); updateScore(); // Flash score text tween(scoreTxt, { scaleX: 1.3, scaleY: 1.3 }, { duration: 200, onFinish: function onFinish() { tween(scoreTxt, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200 }); } }); // Create new random goods item starting from score position var randomGoodsType = goodsTypes[Math.floor(Math.random() * goodsTypes.length)]; var goodsItem = new GoodsItem(randomGoodsType); // Start item at score text position goodsItem.x = 1024; // Center of screen horizontally goodsItem.y = 150; // Below score text // Start small and transparent goodsItem.scaleX = 0.3; goodsItem.scaleY = 0.3; goodsItem.alpha = 0.7; // Mark as item generated from score goodsItem.isFromScore = true; game.addChild(goodsItem); // Animate item moving from score to inventory slot tween(goodsItem, { x: inventorySlot.x, y: inventorySlot.y, scaleX: 1.25, scaleY: 1.25, alpha: 1.0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { isTweenAnimating = false; } }); currentInventoryItem = goodsItem; } function buyItem() { // Original buy functionality (unchanged) // Check if player has enough money (50₺ required) if (money < 50) return; // Find first empty slot in goods grid var emptySlotIndex = -1; for (var i = 0; i < goodsGrid.length; i++) { if (goodsGrid[i] === null) { emptySlotIndex = i; break; } } // If no empty slot, don't buy if (emptySlotIndex === -1) return; // Deduct money for buying item money -= 50; updateMoney(); // Flash money text tween(moneyTxt, { scaleX: 1.3, scaleY: 1.3 }, { duration: 200, onFinish: function onFinish() { tween(moneyTxt, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200 }); } }); // Create new random goods item var randomGoodsType = goodsTypes[Math.floor(Math.random() * goodsTypes.length)]; var goodsItem = new GoodsItem(randomGoodsType); // Calculate position based on empty slot index var row = Math.floor(emptySlotIndex / 4); var col = emptySlotIndex % 4; var targetX = goodsGridStartX + col * (goodsCellSize + goodsMargin) + goodsCellSize / 2; var targetY = goodsGridStartY + row * (goodsCellSize + goodsMargin) + goodsCellSize / 2; goodsItem.x = targetX; goodsItem.y = targetY; goodsItem.scaleX = 1.25; goodsItem.scaleY = 1.25; game.addChild(goodsItem); goodsGrid[emptySlotIndex] = goodsItem; } function getRandomShape() { var color = shapeTypes[Math.floor(Math.random() * shapeTypes.length)]; var form; // Apple and orange always use 'Shape' form if (color === 'apple' || color === 'orange') { form = 'Shape'; } else { form = shapeForms[Math.floor(Math.random() * shapeForms.length)]; } return { color: color, form: form }; } function spawnShapes() { spawnNewShapes(); } function spawnNewShapes() { // Prevent spawning if already animating if (isAnimating || isSequenceRunning) return; // Set animation flags to prevent all interactions isAnimating = true; isSequenceRunning = true; // Fill all rows sequentially starting from row 3 (bottom) going up to row 0 (top) fillRowSequentially(3); } function fillRowSequentially(currentRow) { if (currentRow < 0) { // All 4 horizontal rows filled, now check vertical columns checkColumnsForMatches(function () { // All rows and columns checked, clear all animation flags isAnimating = false; isSequenceRunning = false; }); return; } // Fill current row with shapes var currentRowShapes = []; for (var i = 0; i < 4; i++) { (function (laneIndex) { LK.setTimeout(function () { var shapeData = getRandomShape(); var shape = new DropShape(shapeData.color + shapeData.form, shapeData.color, shapeData.form); shape.x = gridStartX + laneIndex * (cellSize + cellMargin) + cellSize / 2; var targetY = gridStartY + currentRow * (cellSize + cellMargin) + cellSize / 2; shape.startDrop(laneIndex, gridStartY - 100, targetY, currentRow); currentRowShapes.push(shape); game.addChild(shape); dropItems.push(shape); }, laneIndex * 50); // Stagger each lane by 50ms })(i); } // Wait for all rotation animations to complete before proceeding function waitForRotationComplete() { var allRotationComplete = true; for (var i = 0; i < currentRowShapes.length; i++) { if (!currentRowShapes[i].rotationComplete) { allRotationComplete = false; break; } } if (allRotationComplete) { // All rotations complete, now check matches and fill next row checkMatchesForRow(currentRow, function () { // After checking matches for current row, fill the next row up fillRowSequentially(currentRow - 1); }); } else { // Check again in 50ms LK.setTimeout(waitForRotationComplete, 50); } } // Start checking after shapes are spawned (account for stagger time) LK.setTimeout(waitForRotationComplete, 300); } function checkMatches() { // Check result row (row 3 - bottom row) for matches checkMatchesForRow(3); } function checkMatchesForRow(targetRow, callback) { // Check specific row for matches var rowShapes = []; for (var i = 0; i < dropItems.length; i++) { if (dropItems[i].row === targetRow) { rowShapes.push(dropItems[i]); } } if (rowShapes.length < 2) { // After row checking is complete, call final callback without column checking if (callback) callback(); return; } // Count identical shapes (same color + same form) var shapeColorCount = {}; for (var i = 0; i < rowShapes.length; i++) { var shape = rowShapes[i]; shapeColorCount[shape.color + shape.shapeForm] = (shapeColorCount[shape.color + shape.shapeForm] || 0) + 1; } // Find all matching groups var matchingGroups = []; for (var key in shapeColorCount) { if (shapeColorCount[key] === 4) { matchingGroups.push({ type: key, count: 4, points: 500 }); } else if (shapeColorCount[key] === 3) { matchingGroups.push({ type: key, count: 3, points: 250 }); } else if (shapeColorCount[key] === 2) { matchingGroups.push({ type: key, count: 2, points: 50 }); } } if (matchingGroups.length > 0) { // Process each matching group sequentially, then call final callback processMatchingGroups(matchingGroups, rowShapes, 0, callback); } else { // No horizontal match, call final callback if (callback) callback(); } } function processMatchingGroups(matchingGroups, rowShapes, groupIndex, callback) { if (groupIndex >= matchingGroups.length) { // All groups processed, call final callback if (callback) callback(); return; } var group = matchingGroups[groupIndex]; var points = group.points; // Add points for this group LK.setScore(LK.getScore() + points); updateScore(); updateMoney(); // Play sound based on match count if (points === 500 && group.count === 4) { LK.getSound('4xMatch').play(); } else if (points === 250) { LK.getSound('3xMatch').play(); } else if (points === 50 && group.count === 2) { LK.getSound('2xMatch').play(); } // Enhanced visual feedback for wins var flashColor = points >= 500 ? 0xffd700 : points >= 250 ? 0xff6600 : points >= 50 ? 0xffffff : 0xffffff; // Collect shapes for this specific group var scoringShapes = []; for (var i = 0; i < rowShapes.length; i++) { var shape = rowShapes[i]; if (shape.color + shape.shapeForm === group.type) { scoringShapes.push(shape); } } // Animate only the scoring shapes for this group var animationsCompleted = 0; var totalAnimations = scoringShapes.length; for (var i = 0; i < scoringShapes.length; i++) { var shape = scoringShapes[i]; LK.effects.flashObject(shape, flashColor, 1000); // Add temporary scaling and glow effect (function (currentShape) { tween(currentShape, { scaleX: 1.5, scaleY: 1.5, alpha: 1.5 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Return to original size and alpha tween(currentShape, { scaleX: 1.0, scaleY: 1.0, alpha: 1.0 }, { duration: 200, easing: tween.easeIn, onFinish: function onFinish() { animationsCompleted++; if (animationsCompleted >= totalAnimations) { // All animations for this group completed, process next group after delay LK.setTimeout(function () { processMatchingGroups(matchingGroups, rowShapes, groupIndex + 1, callback); }, 200); // Small delay between groups } } }); } }); })(shape); } // Animate score text on big wins if (points >= 250) { tween(scoreTxt, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, onFinish: function onFinish() { tween(scoreTxt, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200 }); } }); } } function isGridFull() { for (var laneIndex = 0; laneIndex < 4; laneIndex++) { var occupiedRows = 0; for (var j = 0; j < dropItems.length; j++) { if (dropItems[j].lane === laneIndex && !dropItems[j].isMoving) { occupiedRows++; } } if (occupiedRows >= 4) { return true; } } return false; } function shiftShapesDown() { isShifting = true; isAnimating = true; // Move all shapes down by one row var shapesToShift = 0; var shapesCompleted = 0; // Count shapes that need to be shifted for (var i = 0; i < dropItems.length; i++) { if (!dropItems[i].isMoving) { shapesToShift++; } } for (var i = 0; i < dropItems.length; i++) { var shape = dropItems[i]; if (!shape.isMoving) { shape.row += 1; var newTargetY = gridStartY + shape.row * (cellSize + cellMargin) + cellSize / 2; // Animate the shift down - much faster tween(shape, { y: newTargetY }, { duration: 120, // Much faster shift animation easing: tween.easeOut, onFinish: function onFinish() { shapesCompleted++; if (shapesCompleted >= shapesToShift) { isShifting = false; isAnimating = false; } } }); } } // Fallback to reset flag if no shapes to shift if (shapesToShift === 0) { isShifting = false; isAnimating = false; } } function cleanupOffscreenShapes() { // Check if any shape has reached row 4 (beyond the 4x4 grid) var shouldClearAll = false; for (var i = 0; i < dropItems.length; i++) { if (dropItems[i].row >= 4) { shouldClearAll = true; break; } } // If any shape reached row 4, clear all shapes from the grid if (shouldClearAll) { for (var i = dropItems.length - 1; i >= 0; i--) { var shape = dropItems[i]; shape.destroy(); dropItems.splice(i, 1); } } else { // Original cleanup logic for shapes that might be off-screen for (var i = dropItems.length - 1; i >= 0; i--) { var shape = dropItems[i]; // Clean up shapes that go beyond the bottom of the 4x4 grid (row 4 and beyond) if (shape.row >= 4) { // No scaling animation to keep consistent size shape.destroy(); dropItems.splice(i, 1); } } } } var lastLeverPulled = false; var isDragging = false; var dragStartY = 0; var dragThreshold = 200; // Minimum drag distance to trigger slot var isShifting = false; // Flag to prevent lever pulling during animations var isAnimating = false; // Flag to track if any animations are ongoing var pullCount = 0; // Track number of pulls var isScoreRefunding = false; // Flag to prevent clicks during score refund var isSequenceRunning = false; // Flag to prevent interactions during any sequence/animation var isTweenAnimating = false; // Flag to track tween animations // Add touch/drag functionality to game - only near lever handle game.down = function (x, y, obj) { // Prevent interaction while any sequence or animation is running if (isSequenceRunning || isTweenAnimating) return; // Check if sell button was clicked var sellButtonDistance = Math.sqrt(Math.pow(x - sellButton.x, 2) + Math.pow(y - sellButton.y, 2)); if (sellButtonDistance <= goodsCellSize / 2) { sellItem(); return; } // Check if buy button was clicked var buyButtonDistance = Math.sqrt(Math.pow(x - buyButton.x, 2) + Math.pow(y - buyButton.y, 2)); if (buyButtonDistance <= goodsCellSize / 2) { buyItemWithScore(); return; } // Check if clicked on goods grid cells when inventory has item if (currentInventoryItem) { for (var row = 0; row < 3; row++) { //{70} for (var col = 0; col < 4; col++) { var cellX = goodsGridStartX + col * (goodsCellSize + goodsMargin) + goodsCellSize / 2; var cellY = goodsGridStartY + row * (goodsCellSize + goodsMargin) + goodsCellSize / 2; var cellDistance = Math.sqrt(Math.pow(x - cellX, 2) + Math.pow(y - cellY, 2)); if (cellDistance <= goodsCellSize / 2) { var gridIndex = row * 4 + col; // Move inventory item to any clicked cell (empty or occupied) // Check if this item was already in the grid (existing item being moved) var wasAlreadyInGrid = goodsGrid.indexOf(currentInventoryItem) !== -1; var itemToMove = currentInventoryItem; // If target cell is occupied, swap items if (goodsGrid[gridIndex] !== null) { var targetItem = goodsGrid[gridIndex]; // Move target item to inventory isTweenAnimating = true; tween(targetItem, { x: inventorySlot.x, y: inventorySlot.y }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { isTweenAnimating = false; } }); // Keep target item's score flag so it can still be refunded if it was from score // targetItem.isFromScore remains unchanged currentInventoryItem = targetItem; } else { currentInventoryItem = null; } // Move the item to the clicked cell if (itemToMove) { isTweenAnimating = true; tween(itemToMove, { x: cellX, y: cellY }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { isTweenAnimating = false; } }); // Remove item from its old position if it was already in grid if (wasAlreadyInGrid) { var oldIndex = goodsGrid.indexOf(itemToMove); if (oldIndex !== -1) { goodsGrid[oldIndex] = null; } } // Place the item in the new grid position goodsGrid[gridIndex] = itemToMove; // Keep the score flag when placing in grid so it can still be refunded // itemToMove.isFromScore remains unchanged } return; } } } } if (!isShifting && !isAnimating) { // Calculate lever handle's world position var handleWorldX = lever.x; var handleWorldY = lever.y + lever.leverHandle.y; // Check if touch is near the lever handle (within 200 pixels) var distance = Math.sqrt(Math.pow(x - handleWorldX, 2) + Math.pow(y - handleWorldY, 2)); if (distance <= 200) { isDragging = true; dragStartY = y; } } }; game.move = function (x, y, obj) { if (isDragging && !isShifting && !isAnimating) { var dragDistance = y - dragStartY; // If dragged down enough, trigger lever pull if (dragDistance > dragThreshold) { lever.pull(); isDragging = false; // Prevent multiple triggers during same drag } } }; game.up = function (x, y, obj) { isDragging = false; // Only allow lever handle to return up when touch is released if (lever.isPulled) { // Animate lever handle back up when released - much faster tween(lever.leverHandle, { y: -700 }, { duration: 30, easing: tween.easeOut, onFinish: function onFinish() { // Play lever release sound when handle reaches top LK.getSound('leverRelease').play(); // Clear all cells first for (var i = dropItems.length - 1; i >= 0; i--) { var shape = dropItems[i]; shape.destroy(); dropItems.splice(i, 1); } // Reset isFromScore flag for all items when slot is pulled if (currentInventoryItem) { currentInventoryItem.isFromScore = false; } for (var i = 0; i < goodsGrid.length; i++) { if (goodsGrid[i] !== null) { goodsGrid[i].isFromScore = false; } } // Start spawning immediately after clearing spawnShapes(); } }); lever.isPulled = false; } }; game.update = function () { cleanupOffscreenShapes(); // Update lever appearance based on money availability if (money < 10) { // Show passive lever when not enough money if (lever.leverHandle.texture !== LK.getAsset('leverHandlePassive', {}).texture) { lever.removeChild(lever.leverHandle); lever.leverHandle = lever.attachAsset('leverHandlePassive', { anchorX: 0.5, anchorY: 0.5 }); lever.leverHandle.y = -700; } } else { // Show active lever when enough money if (lever.leverHandle.texture !== LK.getAsset('leverHandle', {}).texture) { lever.removeChild(lever.leverHandle); lever.leverHandle = lever.attachAsset('leverHandle', { anchorX: 0.5, anchorY: 0.5 }); lever.leverHandle.y = -700; } } }; updateScore(); function checkColumnsForMatches(callback) { // Check all columns from left to right (column 0 to 3) checkColumnMatches(0, callback); } function checkColumnMatches(targetColumn, callback) { if (targetColumn >= 4) { // All columns checked, call final callback if (callback) callback(); return; } // Get all shapes in the target column var columnShapes = []; for (var i = 0; i < dropItems.length; i++) { if (dropItems[i].lane === targetColumn) { columnShapes.push(dropItems[i]); } } if (columnShapes.length < 2) { // Move to next column checkColumnMatches(targetColumn + 1, callback); return; } // Count identical shapes (same color + same form) in this column var shapeColorCount = {}; for (var i = 0; i < columnShapes.length; i++) { var shape = columnShapes[i]; shapeColorCount[shape.color + shape.shapeForm] = (shapeColorCount[shape.color + shape.shapeForm] || 0) + 1; } // Find all matching groups in this column var matchingGroups = []; for (var key in shapeColorCount) { if (shapeColorCount[key] === 4) { matchingGroups.push({ type: key, count: 4, points: 500 }); } else if (shapeColorCount[key] === 3) { matchingGroups.push({ type: key, count: 3, points: 250 }); } else if (shapeColorCount[key] === 2) { matchingGroups.push({ type: key, count: 2, points: 50 }); } } if (matchingGroups.length > 0) { // Process each matching group sequentially for this column processMatchingGroups(matchingGroups, columnShapes, 0, function () { // After processing this column, move to next column checkColumnMatches(targetColumn + 1, callback); }); } else { // No match in this column, move to next column checkColumnMatches(targetColumn + 1, callback); } }
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var DropShape = Container.expand(function (shapeType, color, shapeForm) {
var self = Container.call(this);
self.shapeType = shapeType;
self.color = color;
self.shapeForm = shapeForm;
self.speed = 0;
self.targetY = 0;
self.isMoving = false;
self.lane = 0;
self.row = -1;
var assetId = color + shapeForm;
// Replace redShape with karpuz
if (assetId === 'redShape') {
assetId = 'karpuz';
}
// Replace yellowShape with muz
if (assetId === 'yellowShape') {
assetId = 'muz';
}
// Handle orange and apple - use direct asset names and set proper shape form
if (color === 'orange') {
assetId = 'orange';
self.shapeForm = 'Shape'; // Ensure shapeForm is set for matching logic
}
if (color === 'apple') {
assetId = 'apple';
self.shapeForm = 'Shape'; // Ensure shapeForm is set for matching logic
}
var shapeGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.25,
scaleY: 1.25
});
self.startDrop = function (lane, startY, endY, targetRow) {
self.lane = lane;
self.y = startY;
self.targetY = endY;
self.targetRow = targetRow;
self.speed = 120; // Double the speed for much faster movement
self.isMoving = true;
self.rotationComplete = false;
// Add slot machine spinning effect - faster rotation
tween(self, {
rotation: Math.PI * 4
}, {
duration: 800,
// Much faster rotation animation
easing: tween.easeOut,
onFinish: function onFinish() {
self.rotationComplete = true;
}
});
};
self.update = function () {
if (self.isMoving) {
self.y += self.speed;
// Much faster settling with aggressive deceleration
var distanceToTarget = Math.abs(self.targetY - self.y);
if (distanceToTarget < 150) {
self.speed = Math.max(8, self.speed * 0.85); // Higher minimum speed and faster deceleration
}
// Stop at target with bounce effect
if (self.y >= self.targetY) {
self.y = self.targetY;
self.isMoving = false;
self.speed = 0;
// No bounce animation to keep consistent size
// Calculate which row this shape is in - use targetRow if available
if (self.targetRow !== undefined) {
self.row = self.targetRow;
} else {
self.row = Math.floor((self.y - gridStartY) / (cellSize + cellMargin));
}
}
}
};
return self;
});
var GoodsItem = Container.expand(function (goodsType) {
var self = Container.call(this);
self.goodsType = goodsType;
self.isFromScore = false; // Code-based marker for score items
var itemGraphics = self.attachAsset(goodsType, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.25,
scaleY: 1.25
});
self.down = function (x, y, obj) {
// Prevent interaction while any sequence or animation is running
if (isScoreRefunding || isSequenceRunning || isTweenAnimating) return;
// Check if this item is from score and currently in inventory slot
if (self.isFromScore && currentInventoryItem === self) {
// Item is in inventory slot, destroy and refund to score
// Set refund flag to prevent multiple clicks
isScoreRefunding = true;
// Store reference to item being refunded
var itemToRefund = self;
// Calculate score text position in game coordinates
var targetX = 1024; // Center of screen horizontally
var targetY = 150; // Below score text instead of at score text position
// Animate item moving towards score display with shrinking effect
tween(itemToRefund, {
x: targetX,
y: targetY,
scaleX: 0.3,
scaleY: 0.3,
alpha: 0.7
}, {
duration: 150,
// Double speed (half duration)
easing: tween.easeOut,
onFinish: function onFinish() {
// Add score and update display after animation
LK.setScore(LK.getScore() + 1000);
updateScore();
// Flash score text
tween(scoreTxt, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 100,
onFinish: function onFinish() {
tween(scoreTxt, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
// Destroy item after score animation starts
LK.setTimeout(function () {
itemToRefund.destroy();
isScoreRefunding = false;
}, 50);
}
});
// Clear from inventory
currentInventoryItem = null;
return;
}
// Check if this item is currently in goods grid (regardless of score status)
var gridIndex = goodsGrid.indexOf(self);
if (gridIndex !== -1) {
// Item is in goods grid, move it to inventory slot
moveToInventory(self);
return;
}
// Move this item to inventory slot
moveToInventory(self);
};
return self;
});
var Lever = Container.expand(function () {
var self = Container.call(this);
self.isPulled = false;
self.canPull = true;
var leverBase = self.attachAsset('lever', {
anchorX: 0.5,
anchorY: 1.0
});
self.leverHandle = self.attachAsset('leverHandle', {
anchorX: 0.5,
anchorY: 0.5
});
self.leverHandle.y = -700;
self.pull = function () {
if (!self.canPull || isShifting || isAnimating) return;
// Check if player has enough money (10₺ required)
if (money < 10) return;
// Deduct 10₺ for using the slot machine
money -= 10;
updateMoney();
pullCount++; // Increment pull count
self.canPull = false;
self.isPulled = true;
LK.getSound('leverPull').play();
// Animate lever handle moving down - much faster
tween(self.leverHandle, {
y: -100
}, {
duration: 15,
easing: tween.easeOut
});
// Keep lever pulled state - will be reset on touch release
// Allow immediate next pull
self.canPull = true;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2a1810
});
/****
* Game Code
****/
var lanes = [];
var dropItems = [];
var cellSize = 300; // Square cell size
var cellMargin = 15; // 15 pixel margin between cells
var totalGridWidth = 4 * cellSize + 3 * cellMargin; // Total width of 4 columns with margins
var totalGridHeight = 4 * cellSize + 3 * cellMargin; // Total height of 4 rows with margins
var gridStartX = (2048 - totalGridWidth) / 2 - 200; // Shift the 4x5 grid to the left
var gridStartY = 600 - (cellSize + cellMargin); // Shift grid up by one grid cell height
var laneWidth = cellSize + cellMargin; // Width per column including margin
var laneBackgroundWidth = cellSize; // Square cell background
var cellHeight = cellSize + cellMargin; // Height per row including margin
var shapeTypes = ['red', 'blue', 'green', 'yellow', 'orange', 'apple'];
var shapeForms = ['Shape', 'Circle'];
var lever;
var scoreTxt;
var money = 0;
var moneyTxt;
var goodsGrid = [];
var inventorySlot = null;
var currentInventoryItem = null;
var sellButton = null;
var buyButton = null;
var goodsTypes = ['corn', 'grape', 'bread', 'cheese', 'meat', 'fish'];
// Create background - render first to be behind all other elements
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0
});
background.x = 0;
background.y = 0;
game.addChild(background);
// Create lane backgrounds for 4x4 grid - render first to be behind other elements
for (var col = 0; col < 4; col++) {
for (var row = 0; row < 4; row++) {
var assetType = 'cell';
var cellBack = LK.getAsset(assetType, {
width: cellSize,
height: cellSize,
anchorX: 0.5,
anchorY: 0.5
});
cellBack.x = gridStartX + col * (cellSize + cellMargin) + cellSize / 2;
cellBack.y = gridStartY + row * (cellSize + cellMargin) + cellSize / 2;
game.addChild(cellBack);
}
}
// Create goods grid backgrounds (4x3) - render first to be behind other elements
var goodsGridStartX = gridStartX;
var goodsGridStartY = gridStartY + totalGridHeight + 100;
var goodsCellSize = cellSize; // Use same size as main grid cells (300px)
var goodsMargin = cellMargin; // Use same margin as main grid (15px)
for (var row = 0; row < 3; row++) {
for (var col = 0; col < 4; col++) {
// Create cell background
var cellBack = LK.getAsset('goodsCell', {
width: goodsCellSize,
height: goodsCellSize,
anchorX: 0.5,
anchorY: 0.5
});
cellBack.x = goodsGridStartX + col * (goodsCellSize + goodsMargin) + goodsCellSize / 2;
cellBack.y = goodsGridStartY + row * (goodsCellSize + goodsMargin) + goodsCellSize / 2;
game.addChild(cellBack);
}
}
// Create inventory slot background - render first to be behind other elements
inventorySlot = LK.getAsset('inventorySlot', {
width: goodsCellSize,
height: goodsCellSize,
anchorX: 0.5,
anchorY: 0.5
});
inventorySlot.x = 1750;
inventorySlot.y = goodsGridStartY + goodsCellSize / 2;
inventorySlot.down = function (x, y, obj) {
// Prevent interaction while any sequence or animation is running
if (isScoreRefunding || isSequenceRunning || isTweenAnimating) return;
// Prevent interaction when inventory slot is empty
if (!currentInventoryItem) return;
// If there's an item in inventory, handle refund if it's from score
if (currentInventoryItem && currentInventoryItem.isFromScore) {
// Set refund flag to prevent multiple clicks
isScoreRefunding = true;
// Store reference to item being refunded
var itemToRefund = currentInventoryItem;
// Calculate score text position in game coordinates
var targetX = 1024; // Center of screen horizontally
var targetY = 150; // Below score text instead of at score text position
// Animate item moving towards score display with shrinking effect
tween(itemToRefund, {
x: targetX,
y: targetY,
scaleX: 0.3,
scaleY: 0.3,
alpha: 0.7
}, {
duration: 150,
// Double speed (half duration)
easing: tween.easeOut,
onFinish: function onFinish() {
// Add score and update display after animation
LK.setScore(LK.getScore() + 1000);
updateScore();
// Flash score text
tween(scoreTxt, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 100,
onFinish: function onFinish() {
tween(scoreTxt, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
// Destroy item after score animation starts
LK.setTimeout(function () {
itemToRefund.destroy();
isScoreRefunding = false;
}, 50);
}
});
// Clear from goods grid if it was placed there
var gridIndex = goodsGrid.indexOf(currentInventoryItem);
if (gridIndex !== -1) {
goodsGrid[gridIndex] = null;
}
currentInventoryItem = null;
return;
} else if (currentInventoryItem && !currentInventoryItem.isFromScore) {
// Only allow non-score items to move to goods grid
var gridIndex = goodsGrid.indexOf(currentInventoryItem);
if (gridIndex !== -1) {
var row = Math.floor(gridIndex / 4);
var col = gridIndex % 4;
var targetX = goodsGridStartX + col * (goodsCellSize + goodsMargin) + goodsCellSize / 2;
var targetY = goodsGridStartY + row * (goodsCellSize + goodsMargin) + goodsCellSize / 2;
tween(currentInventoryItem, {
x: targetX,
y: targetY
}, {
duration: 300,
easing: tween.easeOut
});
}
currentInventoryItem = null;
} else if (LK.getScore() >= 1000) {
// Only generate item if inventory is empty and score >= 1000
var randomGoodsType = goodsTypes[Math.floor(Math.random() * goodsTypes.length)];
var goodsItem = new GoodsItem(randomGoodsType);
goodsItem.x = inventorySlot.x;
goodsItem.y = inventorySlot.y;
// Mark as item generated from score
goodsItem.isFromScore = true;
game.addChild(goodsItem);
currentInventoryItem = goodsItem;
// Deduct 1000 from score
LK.setScore(LK.getScore() - 1000);
updateScore();
}
};
game.addChild(inventorySlot);
// Create buy button below inventory slot
buyButton = LK.getAsset('buyButton', {
width: goodsCellSize,
height: goodsCellSize / 2,
anchorX: 0.5,
anchorY: 0.5
});
buyButton.x = inventorySlot.x;
buyButton.y = inventorySlot.y + goodsCellSize / 2 + goodsMargin + goodsCellSize / 4;
game.addChild(buyButton);
// Create sell button below buy button
sellButton = LK.getAsset('sellButton', {
width: goodsCellSize,
height: goodsCellSize / 2,
anchorX: 0.5,
anchorY: 0.5
});
sellButton.x = inventorySlot.x;
sellButton.y = buyButton.y + goodsCellSize / 2 + goodsMargin;
game.addChild(sellButton);
// Result cell removed
// Create lever
lever = game.addChild(new Lever());
lever.x = 1700; // Move to the left
lever.y = 1400 - (cellSize + cellMargin); // Move up by one cell height
// Create score display
scoreTxt = new Text2('Skor: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create money display
moneyTxt = new Text2('Para: 0₺', {
size: 60,
fill: 0x00ff00
});
moneyTxt.anchor.set(0.5, 0);
moneyTxt.y = 100;
LK.gui.top.addChild(moneyTxt);
// Create goods items after backgrounds are rendered
for (var row = 0; row < 3; row++) {
for (var col = 0; col < 4; col++) {
// Only create goods item for the first cell (start with 1 item)
if (row === 0 && col === 0) {
var randomGoodsType = goodsTypes[Math.floor(Math.random() * goodsTypes.length)];
var goodsItem = new GoodsItem(randomGoodsType);
var cellX = goodsGridStartX + col * (goodsCellSize + goodsMargin) + goodsCellSize / 2;
var cellY = goodsGridStartY + row * (goodsCellSize + goodsMargin) + goodsCellSize / 2;
goodsItem.x = cellX;
goodsItem.y = cellY;
goodsItem.scaleX = 1.25;
goodsItem.scaleY = 1.25;
game.addChild(goodsItem);
goodsGrid.push(goodsItem);
} else {
goodsGrid.push(null);
}
}
}
// Add buy button text
var buyButtonText = new Text2('Al', {
size: 80,
fill: 0xffffff
});
buyButtonText.anchor.set(0.5, 0.5);
buyButtonText.x = buyButton.x;
buyButtonText.y = buyButton.y;
game.addChild(buyButtonText);
// Add sell button text
var sellButtonText = new Text2('Sat', {
size: 80,
fill: 0xffffff
});
sellButtonText.anchor.set(0.5, 0.5);
sellButtonText.x = sellButton.x;
sellButtonText.y = sellButton.y;
game.addChild(sellButtonText);
function updateScore() {
scoreTxt.setText('Skor: ' + LK.getScore());
}
function updateMoney() {
moneyTxt.setText('Para: ' + money + '₺');
}
function moveToInventory(goodsItem) {
// If clicking on the same item that's already in inventory, return it to grid
if (currentInventoryItem === goodsItem) {
var gridIndex = goodsGrid.indexOf(currentInventoryItem);
if (gridIndex !== -1) {
var row = Math.floor(gridIndex / 4);
var col = gridIndex % 4;
var targetX = goodsGridStartX + col * (goodsCellSize + goodsMargin) + goodsCellSize / 2;
var targetY = goodsGridStartY + row * (goodsCellSize + goodsMargin) + goodsCellSize / 2;
isTweenAnimating = true;
tween(currentInventoryItem, {
x: targetX,
y: targetY
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
isTweenAnimating = false;
}
});
}
currentInventoryItem = null;
return;
}
if (currentInventoryItem) {
// Return current item to its original position in grid
var gridIndex = goodsGrid.indexOf(currentInventoryItem);
if (gridIndex !== -1) {
var row = Math.floor(gridIndex / 4);
var col = gridIndex % 4;
var targetX = goodsGridStartX + col * (goodsCellSize + goodsMargin) + goodsCellSize / 2;
var targetY = goodsGridStartY + row * (goodsCellSize + goodsMargin) + goodsCellSize / 2;
isTweenAnimating = true;
tween(currentInventoryItem, {
x: targetX,
y: targetY
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
isTweenAnimating = false;
}
});
}
}
// Move new item to inventory - preserve score flag
currentInventoryItem = goodsItem;
// Keep the score flag so items can still be refunded if they were from score
// currentInventoryItem.isFromScore remains unchanged
isTweenAnimating = true;
tween(goodsItem, {
x: inventorySlot.x,
y: inventorySlot.y
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
isTweenAnimating = false;
}
});
}
function sellItem() {
if (currentInventoryItem) {
// Prevent interactions during sell animation
isTweenAnimating = true;
// Store reference to item being sold
var itemToSell = currentInventoryItem;
// Calculate money text position in game coordinates
var moneyWorldPos = LK.gui.toLocal(moneyTxt.position);
var targetX = 1024; // Center of screen horizontally
var targetY = 250; // Below money text instead of at money text position
// Animate item moving towards money display with shrinking effect
tween(itemToSell, {
x: targetX,
y: targetY,
scaleX: 0.3,
scaleY: 0.3,
alpha: 0.7
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Add money and update display after animation
money += 100;
updateMoney();
// Flash money text
tween(moneyTxt, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 200,
onFinish: function onFinish() {
tween(moneyTxt, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200
});
}
});
// Destroy item after money animation starts
LK.setTimeout(function () {
itemToSell.destroy();
isTweenAnimating = false;
}, 100);
}
});
// Remove sold item from grid and inventory
var gridIndex = goodsGrid.indexOf(currentInventoryItem);
if (gridIndex !== -1) {
goodsGrid[gridIndex] = null;
}
currentInventoryItem = null;
}
}
function buyItemWithScore() {
// Check if player has enough score (1000 required)
if (LK.getScore() < 1000) return;
// Check if inventory slot is empty
if (currentInventoryItem !== null) return;
// Prevent interactions during buy animation
isTweenAnimating = true;
// Deduct 1000 from score
LK.setScore(LK.getScore() - 1000);
updateScore();
// Flash score text
tween(scoreTxt, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 200,
onFinish: function onFinish() {
tween(scoreTxt, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200
});
}
});
// Create new random goods item starting from score position
var randomGoodsType = goodsTypes[Math.floor(Math.random() * goodsTypes.length)];
var goodsItem = new GoodsItem(randomGoodsType);
// Start item at score text position
goodsItem.x = 1024; // Center of screen horizontally
goodsItem.y = 150; // Below score text
// Start small and transparent
goodsItem.scaleX = 0.3;
goodsItem.scaleY = 0.3;
goodsItem.alpha = 0.7;
// Mark as item generated from score
goodsItem.isFromScore = true;
game.addChild(goodsItem);
// Animate item moving from score to inventory slot
tween(goodsItem, {
x: inventorySlot.x,
y: inventorySlot.y,
scaleX: 1.25,
scaleY: 1.25,
alpha: 1.0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
isTweenAnimating = false;
}
});
currentInventoryItem = goodsItem;
}
function buyItem() {
// Original buy functionality (unchanged)
// Check if player has enough money (50₺ required)
if (money < 50) return;
// Find first empty slot in goods grid
var emptySlotIndex = -1;
for (var i = 0; i < goodsGrid.length; i++) {
if (goodsGrid[i] === null) {
emptySlotIndex = i;
break;
}
}
// If no empty slot, don't buy
if (emptySlotIndex === -1) return;
// Deduct money for buying item
money -= 50;
updateMoney();
// Flash money text
tween(moneyTxt, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 200,
onFinish: function onFinish() {
tween(moneyTxt, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200
});
}
});
// Create new random goods item
var randomGoodsType = goodsTypes[Math.floor(Math.random() * goodsTypes.length)];
var goodsItem = new GoodsItem(randomGoodsType);
// Calculate position based on empty slot index
var row = Math.floor(emptySlotIndex / 4);
var col = emptySlotIndex % 4;
var targetX = goodsGridStartX + col * (goodsCellSize + goodsMargin) + goodsCellSize / 2;
var targetY = goodsGridStartY + row * (goodsCellSize + goodsMargin) + goodsCellSize / 2;
goodsItem.x = targetX;
goodsItem.y = targetY;
goodsItem.scaleX = 1.25;
goodsItem.scaleY = 1.25;
game.addChild(goodsItem);
goodsGrid[emptySlotIndex] = goodsItem;
}
function getRandomShape() {
var color = shapeTypes[Math.floor(Math.random() * shapeTypes.length)];
var form;
// Apple and orange always use 'Shape' form
if (color === 'apple' || color === 'orange') {
form = 'Shape';
} else {
form = shapeForms[Math.floor(Math.random() * shapeForms.length)];
}
return {
color: color,
form: form
};
}
function spawnShapes() {
spawnNewShapes();
}
function spawnNewShapes() {
// Prevent spawning if already animating
if (isAnimating || isSequenceRunning) return;
// Set animation flags to prevent all interactions
isAnimating = true;
isSequenceRunning = true;
// Fill all rows sequentially starting from row 3 (bottom) going up to row 0 (top)
fillRowSequentially(3);
}
function fillRowSequentially(currentRow) {
if (currentRow < 0) {
// All 4 horizontal rows filled, now check vertical columns
checkColumnsForMatches(function () {
// All rows and columns checked, clear all animation flags
isAnimating = false;
isSequenceRunning = false;
});
return;
}
// Fill current row with shapes
var currentRowShapes = [];
for (var i = 0; i < 4; i++) {
(function (laneIndex) {
LK.setTimeout(function () {
var shapeData = getRandomShape();
var shape = new DropShape(shapeData.color + shapeData.form, shapeData.color, shapeData.form);
shape.x = gridStartX + laneIndex * (cellSize + cellMargin) + cellSize / 2;
var targetY = gridStartY + currentRow * (cellSize + cellMargin) + cellSize / 2;
shape.startDrop(laneIndex, gridStartY - 100, targetY, currentRow);
currentRowShapes.push(shape);
game.addChild(shape);
dropItems.push(shape);
}, laneIndex * 50); // Stagger each lane by 50ms
})(i);
}
// Wait for all rotation animations to complete before proceeding
function waitForRotationComplete() {
var allRotationComplete = true;
for (var i = 0; i < currentRowShapes.length; i++) {
if (!currentRowShapes[i].rotationComplete) {
allRotationComplete = false;
break;
}
}
if (allRotationComplete) {
// All rotations complete, now check matches and fill next row
checkMatchesForRow(currentRow, function () {
// After checking matches for current row, fill the next row up
fillRowSequentially(currentRow - 1);
});
} else {
// Check again in 50ms
LK.setTimeout(waitForRotationComplete, 50);
}
}
// Start checking after shapes are spawned (account for stagger time)
LK.setTimeout(waitForRotationComplete, 300);
}
function checkMatches() {
// Check result row (row 3 - bottom row) for matches
checkMatchesForRow(3);
}
function checkMatchesForRow(targetRow, callback) {
// Check specific row for matches
var rowShapes = [];
for (var i = 0; i < dropItems.length; i++) {
if (dropItems[i].row === targetRow) {
rowShapes.push(dropItems[i]);
}
}
if (rowShapes.length < 2) {
// After row checking is complete, call final callback without column checking
if (callback) callback();
return;
}
// Count identical shapes (same color + same form)
var shapeColorCount = {};
for (var i = 0; i < rowShapes.length; i++) {
var shape = rowShapes[i];
shapeColorCount[shape.color + shape.shapeForm] = (shapeColorCount[shape.color + shape.shapeForm] || 0) + 1;
}
// Find all matching groups
var matchingGroups = [];
for (var key in shapeColorCount) {
if (shapeColorCount[key] === 4) {
matchingGroups.push({
type: key,
count: 4,
points: 500
});
} else if (shapeColorCount[key] === 3) {
matchingGroups.push({
type: key,
count: 3,
points: 250
});
} else if (shapeColorCount[key] === 2) {
matchingGroups.push({
type: key,
count: 2,
points: 50
});
}
}
if (matchingGroups.length > 0) {
// Process each matching group sequentially, then call final callback
processMatchingGroups(matchingGroups, rowShapes, 0, callback);
} else {
// No horizontal match, call final callback
if (callback) callback();
}
}
function processMatchingGroups(matchingGroups, rowShapes, groupIndex, callback) {
if (groupIndex >= matchingGroups.length) {
// All groups processed, call final callback
if (callback) callback();
return;
}
var group = matchingGroups[groupIndex];
var points = group.points;
// Add points for this group
LK.setScore(LK.getScore() + points);
updateScore();
updateMoney();
// Play sound based on match count
if (points === 500 && group.count === 4) {
LK.getSound('4xMatch').play();
} else if (points === 250) {
LK.getSound('3xMatch').play();
} else if (points === 50 && group.count === 2) {
LK.getSound('2xMatch').play();
}
// Enhanced visual feedback for wins
var flashColor = points >= 500 ? 0xffd700 : points >= 250 ? 0xff6600 : points >= 50 ? 0xffffff : 0xffffff;
// Collect shapes for this specific group
var scoringShapes = [];
for (var i = 0; i < rowShapes.length; i++) {
var shape = rowShapes[i];
if (shape.color + shape.shapeForm === group.type) {
scoringShapes.push(shape);
}
}
// Animate only the scoring shapes for this group
var animationsCompleted = 0;
var totalAnimations = scoringShapes.length;
for (var i = 0; i < scoringShapes.length; i++) {
var shape = scoringShapes[i];
LK.effects.flashObject(shape, flashColor, 1000);
// Add temporary scaling and glow effect
(function (currentShape) {
tween(currentShape, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 1.5
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Return to original size and alpha
tween(currentShape, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 1.0
}, {
duration: 200,
easing: tween.easeIn,
onFinish: function onFinish() {
animationsCompleted++;
if (animationsCompleted >= totalAnimations) {
// All animations for this group completed, process next group after delay
LK.setTimeout(function () {
processMatchingGroups(matchingGroups, rowShapes, groupIndex + 1, callback);
}, 200); // Small delay between groups
}
}
});
}
});
})(shape);
}
// Animate score text on big wins
if (points >= 250) {
tween(scoreTxt, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
onFinish: function onFinish() {
tween(scoreTxt, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200
});
}
});
}
}
function isGridFull() {
for (var laneIndex = 0; laneIndex < 4; laneIndex++) {
var occupiedRows = 0;
for (var j = 0; j < dropItems.length; j++) {
if (dropItems[j].lane === laneIndex && !dropItems[j].isMoving) {
occupiedRows++;
}
}
if (occupiedRows >= 4) {
return true;
}
}
return false;
}
function shiftShapesDown() {
isShifting = true;
isAnimating = true;
// Move all shapes down by one row
var shapesToShift = 0;
var shapesCompleted = 0;
// Count shapes that need to be shifted
for (var i = 0; i < dropItems.length; i++) {
if (!dropItems[i].isMoving) {
shapesToShift++;
}
}
for (var i = 0; i < dropItems.length; i++) {
var shape = dropItems[i];
if (!shape.isMoving) {
shape.row += 1;
var newTargetY = gridStartY + shape.row * (cellSize + cellMargin) + cellSize / 2;
// Animate the shift down - much faster
tween(shape, {
y: newTargetY
}, {
duration: 120,
// Much faster shift animation
easing: tween.easeOut,
onFinish: function onFinish() {
shapesCompleted++;
if (shapesCompleted >= shapesToShift) {
isShifting = false;
isAnimating = false;
}
}
});
}
}
// Fallback to reset flag if no shapes to shift
if (shapesToShift === 0) {
isShifting = false;
isAnimating = false;
}
}
function cleanupOffscreenShapes() {
// Check if any shape has reached row 4 (beyond the 4x4 grid)
var shouldClearAll = false;
for (var i = 0; i < dropItems.length; i++) {
if (dropItems[i].row >= 4) {
shouldClearAll = true;
break;
}
}
// If any shape reached row 4, clear all shapes from the grid
if (shouldClearAll) {
for (var i = dropItems.length - 1; i >= 0; i--) {
var shape = dropItems[i];
shape.destroy();
dropItems.splice(i, 1);
}
} else {
// Original cleanup logic for shapes that might be off-screen
for (var i = dropItems.length - 1; i >= 0; i--) {
var shape = dropItems[i];
// Clean up shapes that go beyond the bottom of the 4x4 grid (row 4 and beyond)
if (shape.row >= 4) {
// No scaling animation to keep consistent size
shape.destroy();
dropItems.splice(i, 1);
}
}
}
}
var lastLeverPulled = false;
var isDragging = false;
var dragStartY = 0;
var dragThreshold = 200; // Minimum drag distance to trigger slot
var isShifting = false; // Flag to prevent lever pulling during animations
var isAnimating = false; // Flag to track if any animations are ongoing
var pullCount = 0; // Track number of pulls
var isScoreRefunding = false; // Flag to prevent clicks during score refund
var isSequenceRunning = false; // Flag to prevent interactions during any sequence/animation
var isTweenAnimating = false; // Flag to track tween animations
// Add touch/drag functionality to game - only near lever handle
game.down = function (x, y, obj) {
// Prevent interaction while any sequence or animation is running
if (isSequenceRunning || isTweenAnimating) return;
// Check if sell button was clicked
var sellButtonDistance = Math.sqrt(Math.pow(x - sellButton.x, 2) + Math.pow(y - sellButton.y, 2));
if (sellButtonDistance <= goodsCellSize / 2) {
sellItem();
return;
}
// Check if buy button was clicked
var buyButtonDistance = Math.sqrt(Math.pow(x - buyButton.x, 2) + Math.pow(y - buyButton.y, 2));
if (buyButtonDistance <= goodsCellSize / 2) {
buyItemWithScore();
return;
}
// Check if clicked on goods grid cells when inventory has item
if (currentInventoryItem) {
for (var row = 0; row < 3; row++) {
//{70}
for (var col = 0; col < 4; col++) {
var cellX = goodsGridStartX + col * (goodsCellSize + goodsMargin) + goodsCellSize / 2;
var cellY = goodsGridStartY + row * (goodsCellSize + goodsMargin) + goodsCellSize / 2;
var cellDistance = Math.sqrt(Math.pow(x - cellX, 2) + Math.pow(y - cellY, 2));
if (cellDistance <= goodsCellSize / 2) {
var gridIndex = row * 4 + col;
// Move inventory item to any clicked cell (empty or occupied)
// Check if this item was already in the grid (existing item being moved)
var wasAlreadyInGrid = goodsGrid.indexOf(currentInventoryItem) !== -1;
var itemToMove = currentInventoryItem;
// If target cell is occupied, swap items
if (goodsGrid[gridIndex] !== null) {
var targetItem = goodsGrid[gridIndex];
// Move target item to inventory
isTweenAnimating = true;
tween(targetItem, {
x: inventorySlot.x,
y: inventorySlot.y
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
isTweenAnimating = false;
}
});
// Keep target item's score flag so it can still be refunded if it was from score
// targetItem.isFromScore remains unchanged
currentInventoryItem = targetItem;
} else {
currentInventoryItem = null;
}
// Move the item to the clicked cell
if (itemToMove) {
isTweenAnimating = true;
tween(itemToMove, {
x: cellX,
y: cellY
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
isTweenAnimating = false;
}
});
// Remove item from its old position if it was already in grid
if (wasAlreadyInGrid) {
var oldIndex = goodsGrid.indexOf(itemToMove);
if (oldIndex !== -1) {
goodsGrid[oldIndex] = null;
}
}
// Place the item in the new grid position
goodsGrid[gridIndex] = itemToMove;
// Keep the score flag when placing in grid so it can still be refunded
// itemToMove.isFromScore remains unchanged
}
return;
}
}
}
}
if (!isShifting && !isAnimating) {
// Calculate lever handle's world position
var handleWorldX = lever.x;
var handleWorldY = lever.y + lever.leverHandle.y;
// Check if touch is near the lever handle (within 200 pixels)
var distance = Math.sqrt(Math.pow(x - handleWorldX, 2) + Math.pow(y - handleWorldY, 2));
if (distance <= 200) {
isDragging = true;
dragStartY = y;
}
}
};
game.move = function (x, y, obj) {
if (isDragging && !isShifting && !isAnimating) {
var dragDistance = y - dragStartY;
// If dragged down enough, trigger lever pull
if (dragDistance > dragThreshold) {
lever.pull();
isDragging = false; // Prevent multiple triggers during same drag
}
}
};
game.up = function (x, y, obj) {
isDragging = false;
// Only allow lever handle to return up when touch is released
if (lever.isPulled) {
// Animate lever handle back up when released - much faster
tween(lever.leverHandle, {
y: -700
}, {
duration: 30,
easing: tween.easeOut,
onFinish: function onFinish() {
// Play lever release sound when handle reaches top
LK.getSound('leverRelease').play();
// Clear all cells first
for (var i = dropItems.length - 1; i >= 0; i--) {
var shape = dropItems[i];
shape.destroy();
dropItems.splice(i, 1);
}
// Reset isFromScore flag for all items when slot is pulled
if (currentInventoryItem) {
currentInventoryItem.isFromScore = false;
}
for (var i = 0; i < goodsGrid.length; i++) {
if (goodsGrid[i] !== null) {
goodsGrid[i].isFromScore = false;
}
}
// Start spawning immediately after clearing
spawnShapes();
}
});
lever.isPulled = false;
}
};
game.update = function () {
cleanupOffscreenShapes();
// Update lever appearance based on money availability
if (money < 10) {
// Show passive lever when not enough money
if (lever.leverHandle.texture !== LK.getAsset('leverHandlePassive', {}).texture) {
lever.removeChild(lever.leverHandle);
lever.leverHandle = lever.attachAsset('leverHandlePassive', {
anchorX: 0.5,
anchorY: 0.5
});
lever.leverHandle.y = -700;
}
} else {
// Show active lever when enough money
if (lever.leverHandle.texture !== LK.getAsset('leverHandle', {}).texture) {
lever.removeChild(lever.leverHandle);
lever.leverHandle = lever.attachAsset('leverHandle', {
anchorX: 0.5,
anchorY: 0.5
});
lever.leverHandle.y = -700;
}
}
};
updateScore();
function checkColumnsForMatches(callback) {
// Check all columns from left to right (column 0 to 3)
checkColumnMatches(0, callback);
}
function checkColumnMatches(targetColumn, callback) {
if (targetColumn >= 4) {
// All columns checked, call final callback
if (callback) callback();
return;
}
// Get all shapes in the target column
var columnShapes = [];
for (var i = 0; i < dropItems.length; i++) {
if (dropItems[i].lane === targetColumn) {
columnShapes.push(dropItems[i]);
}
}
if (columnShapes.length < 2) {
// Move to next column
checkColumnMatches(targetColumn + 1, callback);
return;
}
// Count identical shapes (same color + same form) in this column
var shapeColorCount = {};
for (var i = 0; i < columnShapes.length; i++) {
var shape = columnShapes[i];
shapeColorCount[shape.color + shape.shapeForm] = (shapeColorCount[shape.color + shape.shapeForm] || 0) + 1;
}
// Find all matching groups in this column
var matchingGroups = [];
for (var key in shapeColorCount) {
if (shapeColorCount[key] === 4) {
matchingGroups.push({
type: key,
count: 4,
points: 500
});
} else if (shapeColorCount[key] === 3) {
matchingGroups.push({
type: key,
count: 3,
points: 250
});
} else if (shapeColorCount[key] === 2) {
matchingGroups.push({
type: key,
count: 2,
points: 50
});
}
}
if (matchingGroups.length > 0) {
// Process each matching group sequentially for this column
processMatchingGroups(matchingGroups, columnShapes, 0, function () {
// After processing this column, move to next column
checkColumnMatches(targetColumn + 1, callback);
});
} else {
// No match in this column, move to next column
checkColumnMatches(targetColumn + 1, callback);
}
}
Corn. In-Game asset. 2d. High contrast. No shadows
Green apple. In-Game asset. 2d. High contrast. No shadows
Grape. In-Game asset. 2d. High contrast. No shadows
Green grape. In-Game asset. 2d. High contrast. No shadows
ekmek. In-Game asset. 2d. High contrast. No shadows
peynir. In-Game asset. 2d. High contrast. No shadows
meat. In-Game asset. 2d. High contrast. No shadows
fish. In-Game asset. 2d. High contrast. No shadows
red apple. In-Game asset. 2d. High contrast. No shadows
orange. In-Game asset. 2d. High contrast. No shadows
3d gray ball shiny. In-Game asset. 2d. High contrast. No shadows
200x800 inset corners box gray shiny. In-Game asset. 2d. High contrast. No shadows