User prompt
Oyundaki siyah arkaplan her gem yok olduğunda renk değiştirsin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Oyundan sariiii tuşunu kaldır
User prompt
Bo1 in işlevini sadece sarıgem yerine bütün gemler için yap ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Farklı bir dönüş animasyonu ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Timeout.tick error: self.startBo1Animation is not a function' in or related to this line: 'self.startBo1Animation();' Line Number: 77
User prompt
Bo1 farklı bir animasyonu olsun ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Bo1 patladığı Zaman oyun tahtası ve gemler biraz sağ sola titresin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Bo1 patladığı Zaman 5x6 bölümlük gem patlatsin
User prompt
Bo1 sadece bir kere haraket edebilsin ve sonrasinda oda patlasın
User prompt
Bo1 ekrana geldiğinde arkasında çıkan gem iconunu sil
User prompt
Bo1 sarı patladığı Zaman ekrana gelmiyor bunu cöž
User prompt
Bo1 yanlizca 1 adet çıksın ve 5 adet yanyana sarı gem patladığı Zaman patlayan sarı mücevher yerinde çıksın
User prompt
Bo1 lolo1 katmanına yerleştir
User prompt
5 adet yanyana sarıgem patladığı Zaman 3 kısımdaki sarıgem yerine bo1 gelsin ekrana
User prompt
Sariiii düğmesine basınca gelen 5x5 sadece yanyana 5 adet gelicek şekilde yap
User prompt
Sarı gem 5x5 olduğu zaman bo1 gelmesi yerine sadece 5 adet yanyana geldiği zaman orta kısımda gelsin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Oyun tahtasının hemen yan tarafına getir ve rengini siyah yap
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Gem = Container.expand(function (gemType, gridX, gridY) { var self = Container.call(this); self.gemType = gemType; self.gridX = gridX; self.gridY = gridY; self.isAnimating = false; var gemAssets = ['gemRed', 'gemBlue', 'gemGreen', 'gemYellow', 'gemPurple', 'gemOrange', 'bo1']; var gemGraphics = self.attachAsset(gemAssets[gemType], { anchorX: 0.5, anchorY: 0.5 }); self.setGridPosition = function (x, y) { self.gridX = x; self.gridY = y; }; self.animateToPosition = function (targetX, targetY, duration, onComplete) { if (!duration) duration = 200; self.isAnimating = true; tween(self, { x: targetX, y: targetY }, { duration: duration, easing: tween.easeOut, onFinish: function onFinish() { self.isAnimating = false; if (onComplete) onComplete(); } }); }; self.destroy = function () { // Play gem-specific destruction sound var gemSounds = ['gemRedDestroy', 'gemBlueDestroy', 'gemGreenDestroy', 'gemYellowDestroy', 'gemPurpleDestroy', 'gemOrangeDestroy', 'gemPinkDestroy']; if (self.gemType >= 0 && self.gemType < gemSounds.length) { try { LK.getSound(gemSounds[self.gemType]).play(); } catch (e) { console.log('Sound not found:', gemSounds[self.gemType]); } } // Special animation for red gems (gemType 0) if (self.gemType === 0) { self.createFlameExplosion(); } // Special animation for blue gems (gemType 1) if (self.gemType === 1) { self.createWaterExplosion(); } // Special animation for green gems (gemType 2) if (self.gemType === 2) { self.createLeafSpiral(); } // Special animation for yellow gems (gemType 3) if (self.gemType === 3) { self.createStarExplosion(); } // Special animation for purple gems (gemType 4) if (self.gemType === 4) { self.createPurpleImplosion(); } // Special animation for orange gems (gemType 5) if (self.gemType === 5) { self.createLavaMelting(); } // Special animation for pink gems (gemType 6) if (self.gemType === 6) { self.createHeartExplosion(); } // Create tween effect before actually destroying tween(self, { alpha: 0, scaleX: 0.2, scaleY: 0.2 }, { duration: 300, easing: tween.easeInOut, onFinish: function onFinish() { if (self.parent) { self.parent.removeChild(self); } } }); }; self.createFlameExplosion = function () { var flameCount = 6; // Reduced from 8 var radius = 100; for (var i = 0; i < flameCount; i++) { var angle = i / flameCount * Math.PI * 2; var flameParticle = LK.getAsset('flameParticle', { anchorX: 0.5, anchorY: 0.5 }); // Set initial position at gem center flameParticle.x = self.x; flameParticle.y = self.y; flameParticle.zIndex = 5; // Add to game if (self.parent) { self.parent.addChild(flameParticle); } // Calculate spiral target position var targetX = self.x + Math.cos(angle) * radius; var targetY = self.y + Math.sin(angle) * radius; // Create spiral rotation and movement animation tween(flameParticle, { x: targetX, y: targetY, rotation: Math.PI * 4, // 2 full rotations scaleX: 3.0, scaleY: 3.0 }, { duration: 400, easing: tween.easeOut }); // Fade out and disappear tween(flameParticle, { alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 600, easing: tween.easeInOut, onFinish: function onFinish() { if (flameParticle.parent) { flameParticle.parent.removeChild(flameParticle); } } }); // Add flame color transition from orange to red tween(flameParticle, { tint: 0xff0000 }, { duration: 300, easing: tween.easeInOut }); } }; self.createWaterExplosion = function () { var dropletCount = 8; // Reduced from 12 var maxRadius = 120; for (var i = 0; i < dropletCount; i++) { var angle = i / dropletCount * Math.PI * 2; var waterDroplet = LK.getAsset('waterDroplet', { anchorX: 0.5, anchorY: 0.5 }); // Set initial position at gem center waterDroplet.x = self.x; waterDroplet.y = self.y; waterDroplet.zIndex = 5; // Random radius for scattered effect var radius = 60 + Math.random() * 60; // Add to game if (self.parent) { self.parent.addChild(waterDroplet); } // Calculate target position for water droplet var targetX = self.x + Math.cos(angle) * radius; var targetY = self.y + Math.sin(angle) * radius; // Create bouncing water droplet movement tween(waterDroplet, { x: targetX, y: targetY, scaleX: 2.5, scaleY: 2.5 }, { duration: 350, easing: tween.bounceOut }); // Create ripple effect with scaling tween(waterDroplet, { scaleX: 0.8, scaleY: 1.2 }, { duration: 200, easing: tween.easeInOut }); // Fade out like evaporating water tween(waterDroplet, { alpha: 0, scaleY: 0.2 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { if (waterDroplet.parent) { waterDroplet.parent.removeChild(waterDroplet); } } }); // Add water color transition from light blue to transparent tween(waterDroplet, { tint: 0x00aaff }, { duration: 250, easing: tween.easeInOut }); } }; self.createPurpleImplosion = function () { var vortexCount = 10; // Reduced from 16 var initialRadius = 150; for (var i = 0; i < vortexCount; i++) { var angle = i / vortexCount * Math.PI * 2; var purpleVortex = LK.getAsset('purpleVortex', { anchorX: 0.5, anchorY: 0.5 }); // Set initial position in a circle around the gem var startX = self.x + Math.cos(angle) * initialRadius; var startY = self.y + Math.sin(angle) * initialRadius; purpleVortex.x = startX; purpleVortex.y = startY; purpleVortex.zIndex = 5; // Add purple tint and initial scale purpleVortex.tint = 0x8B00FF; purpleVortex.scaleX = 0.5; purpleVortex.scaleY = 0.5; // Add to game if (self.parent) { self.parent.addChild(purpleVortex); } // Create spiral inward movement animation tween(purpleVortex, { x: self.x, y: self.y, rotation: Math.PI * 6, // 3 full rotations inward scaleX: 3.5, scaleY: 3.5 }, { duration: 600, easing: tween.easeIn }); // Fade in then fade out with implosion effect tween(purpleVortex, { alpha: 1.0 }, { duration: 200, easing: tween.easeOut }); // Final implosion - scale down and disappear tween(purpleVortex, { alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 400, easing: tween.easeInOut, onFinish: function onFinish() { if (purpleVortex.parent) { purpleVortex.parent.removeChild(purpleVortex); } } }); // Color transition from purple to dark purple tween(purpleVortex, { tint: 0x4B0082 }, { duration: 300, easing: tween.easeInOut }); } }; self.createLeafSpiral = function () { var leafCount = 6; // Reduced from 10 var spiralRadius = 140; for (var i = 0; i < leafCount; i++) { var angle = i / leafCount * Math.PI * 2; var leafParticle = LK.getAsset('leafParticle', { anchorX: 0.5, anchorY: 0.5 }); // Set initial position at gem center leafParticle.x = self.x; leafParticle.y = self.y; leafParticle.zIndex = 5; // Add natural green tint and initial scale leafParticle.tint = 0x228B22; leafParticle.scaleX = 0.8; leafParticle.scaleY = 0.8; leafParticle.rotation = angle; // Initial rotation based on position // Add to game if (self.parent) { self.parent.addChild(leafParticle); } // Create spiral outward movement with natural floating motion var targetX = self.x + Math.cos(angle) * spiralRadius; var targetY = self.y + Math.sin(angle) * spiralRadius; // Add some randomness for natural leaf movement targetX += (Math.random() - 0.5) * 60; targetY += (Math.random() - 0.5) * 60; // Create floating leaf movement animation tween(leafParticle, { x: targetX, y: targetY, rotation: angle + Math.PI * 3, // 1.5 full rotations scaleX: 2.8, scaleY: 2.8 }, { duration: 500, easing: tween.easeOut }); // Add gentle swaying motion like leaves in wind tween(leafParticle, { x: targetX + Math.sin(angle * 2) * 30, y: targetY + Math.cos(angle * 2) * 20 }, { duration: 800, easing: tween.easeInOut }); // Fade out like autumn leaves tween(leafParticle, { alpha: 0, scaleX: 0.3, scaleY: 0.3, rotation: angle + Math.PI * 5 // Continue rotating as it fades }, { duration: 700, easing: tween.easeInOut, onFinish: function onFinish() { if (leafParticle.parent) { leafParticle.parent.removeChild(leafParticle); } } }); // Add leaf color transition from green to brown tween(leafParticle, { tint: 0x8B4513 // Brown color }, { duration: 400, easing: tween.easeInOut }); } }; self.createStarExplosion = function () { var starCount = 8; // Reduced from 14 var maxRadius = 160; for (var i = 0; i < starCount; i++) { var angle = i / starCount * Math.PI * 2; var starParticle = LK.getAsset('starParticle', { anchorX: 0.5, anchorY: 0.5 }); // Set initial position at gem center starParticle.x = self.x; starParticle.y = self.y; starParticle.zIndex = 5; // Add golden yellow tint and initial scale starParticle.tint = 0xFFD700; starParticle.scaleX = 0.3; starParticle.scaleY = 0.3; starParticle.rotation = angle; // Add to game if (self.parent) { self.parent.addChild(starParticle); } // Create spiral outward sun burst movement var radius = 80 + Math.random() * 80; var targetX = self.x + Math.cos(angle) * radius; var targetY = self.y + Math.sin(angle) * radius; // Add sparkle randomness for star effect targetX += (Math.random() - 0.5) * 40; targetY += (Math.random() - 0.5) * 40; // Create explosive star movement animation tween(starParticle, { x: targetX, y: targetY, rotation: angle + Math.PI * 4, // 2 full rotations scaleX: 5.0, scaleY: 5.0 }, { duration: 450, easing: tween.easeOut }); // Add pulsing sparkle effect tween(starParticle, { scaleX: 6.5, scaleY: 6.5 }, { duration: 150, easing: tween.easeInOut }); // Create secondary sparkle pulse tween(starParticle, { scaleX: 4.5, scaleY: 4.5, rotation: angle + Math.PI * 6 // Continue rotating }, { duration: 300, easing: tween.easeInOut }); // Fade out like fading starlight tween(starParticle, { alpha: 0, scaleX: 0.2, scaleY: 0.2, rotation: angle + Math.PI * 8 // Final rotation burst }, { duration: 600, easing: tween.easeInOut, onFinish: function onFinish() { if (starParticle.parent) { starParticle.parent.removeChild(starParticle); } } }); // Add star color transition from gold to bright white tween(starParticle, { tint: 0xFFFFFF // Bright white }, { duration: 350, easing: tween.easeInOut }); } }; self.createLavaMelting = function () { var lavaCount = 8; // Reduced from 12 var meltRadius = 130; for (var i = 0; i < lavaCount; i++) { var angle = i / lavaCount * Math.PI * 2; var lavaParticle = LK.getAsset('lavaParticle', { anchorX: 0.5, anchorY: 0.5 }); // Set initial position at gem center lavaParticle.x = self.x; lavaParticle.y = self.y; lavaParticle.zIndex = 5; // Add molten orange-red tint and initial scale lavaParticle.tint = 0xFF4500; lavaParticle.scaleX = 0.6; lavaParticle.scaleY = 0.6; lavaParticle.rotation = Math.random() * Math.PI * 2; // Add to game if (self.parent) { self.parent.addChild(lavaParticle); } // Create melting downward movement with spiral motion var radius = 70 + Math.random() * 60; var targetX = self.x + Math.cos(angle) * radius; var targetY = self.y + Math.sin(angle) * radius; // Add downward melting bias targetY += Math.random() * 80 + 40; // Add some randomness for natural lava flow targetX += (Math.random() - 0.5) * 50; // Create lava melting movement animation tween(lavaParticle, { x: targetX, y: targetY, rotation: angle + Math.PI * 3, // 1.5 full rotations scaleX: 3.2, scaleY: 3.2 }, { duration: 550, easing: tween.easeOut }); // Add viscous lava dripping effect tween(lavaParticle, { y: targetY + 60, scaleY: 4.0 // Stretch vertically like dripping lava }, { duration: 400, easing: tween.easeIn }); // Create molten glow pulsing effect tween(lavaParticle, { scaleX: 4.0, tint: 0xFF6600 // Brighter orange }, { duration: 300, easing: tween.easeInOut }); // Cool down and solidify effect tween(lavaParticle, { alpha: 0, scaleX: 0.4, scaleY: 0.2, tint: 0x8B0000, // Dark red when cooling rotation: angle + Math.PI * 5 // Continue rotating as it cools }, { duration: 650, easing: tween.easeInOut, onFinish: function onFinish() { if (lavaParticle.parent) { lavaParticle.parent.removeChild(lavaParticle); } } }); // Add secondary heat shimmer effect tween(lavaParticle, { scaleX: 2.8, scaleY: 3.5 }, { duration: 200, easing: tween.easeInOut }); } }; self.createHeartExplosion = function () { var heartCount = 8; // Heart-shaped particles var maxRadius = 140; for (var i = 0; i < heartCount; i++) { var angle = i / heartCount * Math.PI * 2; var heartParticle = LK.getAsset('starParticle', { anchorX: 0.5, anchorY: 0.5 }); // Set initial position at gem center heartParticle.x = self.x; heartParticle.y = self.y; heartParticle.zIndex = 5; // Add pink tint and initial scale heartParticle.tint = 0xFF69B4; // Hot pink color heartParticle.scaleX = 0.4; heartParticle.scaleY = 0.4; heartParticle.rotation = angle; // Add to game if (self.parent) { self.parent.addChild(heartParticle); } // Create heart-shaped movement pattern var radius = 80 + Math.random() * 60; var targetX = self.x + Math.cos(angle) * radius; var targetY = self.y + Math.sin(angle) * radius; // Add heart-like floating effect targetX += Math.sin(angle * 2) * 30; targetY += Math.cos(angle * 2) * 20; // Create romantic floating movement animation tween(heartParticle, { x: targetX, y: targetY, rotation: angle + Math.PI * 3, // 1.5 full rotations scaleX: 4.0, scaleY: 4.0 }, { duration: 500, easing: tween.easeOut }); // Add gentle floating motion like floating hearts tween(heartParticle, { y: targetY - 40, scaleX: 5.0, scaleY: 5.0 }, { duration: 400, easing: tween.easeInOut }); // Fade out like disappearing love tween(heartParticle, { alpha: 0, scaleX: 0.3, scaleY: 0.3, rotation: angle + Math.PI * 5 // Continue romantic spinning }, { duration: 700, easing: tween.easeInOut, onFinish: function onFinish() { if (heartParticle.parent) { heartParticle.parent.removeChild(heartParticle); } } }); // Add color transition from hot pink to light pink tween(heartParticle, { tint: 0xFFB6C1 // Light pink color }, { duration: 350, easing: tween.easeInOut }); } }; return self; }); var Particle = Container.expand(function (x, y, color) { var self = Container.call(this); var particleGraphics = self.attachAsset('particle', { anchorX: 0.5, anchorY: 0.5 }); self.reset = function (x, y, color) { // Set particle color particleGraphics.tint = color; // Set initial position self.x = x; self.y = y; // Random velocity - increased for more dramatic effect self.velocityX = (Math.random() - 0.5) * 300; self.velocityY = (Math.random() - 0.5) * 300; self.gravity = 600; self.life = 1.0; self.fadeSpeed = 1.0; self.scale = 1.0; self.scaleSpeed = 0.5; self.alpha = 1.0; self.scaleX = 1.0; self.scaleY = 1.0; }; // Initialize with provided values self.reset(x, y, color); self.update = function () { // Update position based on velocity self.x += self.velocityX * (1 / 60); self.y += self.velocityY * (1 / 60); // Apply gravity (positive for flipped board - particles fall down visually) self.velocityY += self.gravity * (1 / 60); // Fade out over time self.life -= self.fadeSpeed * (1 / 60); self.alpha = Math.max(0, self.life); // Scale down over time for dramatic effect self.scale -= self.scaleSpeed * (1 / 60); if (self.scale > 0) { self.scaleX = self.scale; self.scaleY = self.scale; } // Remove when fully faded if (self.life <= 0) { self.destroy(); } }; self.destroy = function () { if (self.parent) { self.parent.removeChild(self); // Remove from active particles array for (var i = 0; i < activeParticles.length; i++) { if (activeParticles[i] === self) { activeParticles.splice(i, 1); break; } } // Return to pool for reuse if (particlePool.length < 50) { particlePool.push(self); } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ var particlePool = []; var activeParticles = []; function createParticle(x, y, color) { var particle; if (particlePool.length > 0) { particle = particlePool.pop(); particle.reset(x, y, color); } else { particle = new Particle(x, y, color); } activeParticles.push(particle); return particle; } var GRID_SIZE_X = 6; var GRID_SIZE_Y = 9; var CELL_SIZE = 250; var BOARD_OFFSET_X = (2048 - GRID_SIZE_X * CELL_SIZE) / 2; var BOARD_OFFSET_Y = (2732 - GRID_SIZE_Y * CELL_SIZE) / 2; var gameBoard = []; var selectedGem = null; var draggedGem = null; var dragStartPos = null; var isDragging = false; var isSwapping = false; var score = 0; var comboMultiplier = 1; var consecutiveGemsDestroyed = 0; // Timer system - 7.5 minutes in seconds var gameTimeLimit = 7.5 * 60; // 7.5 minutes = 450 seconds var remainingTime = gameTimeLimit; var gameTimer = null; // Background removed - using plain black background // Update timer display function updateTimer() { var minutes = Math.floor(remainingTime / 60); var seconds = remainingTime % 60; var timeText = minutes + ':' + (seconds < 10 ? '0' : '') + seconds; timerTxt.setText(timeText); } // Update health bar display function updateHealthBar() { // Calculate how many segments should be visible (10 segments total) var visibleSegments = Math.ceil(playerHealth / 10); // Update health text healthTxt.setText('HEALTH: ' + playerHealth); // Remove segments that should no longer be visible for (var i = 0; i < healthSegments.length; i++) { var segment = healthSegments[i]; if (i >= visibleSegments && segment.parent) { // Animate segment removal with cutting effect tween(segment, { scaleX: 0, alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function (segmentToRemove) { return function () { if (segmentToRemove.parent) { segmentToRemove.parent.removeChild(segmentToRemove); } }; }(segment) }); } } // Add back segments that should be visible but are missing for (var i = 0; i < visibleSegments; i++) { var segment = healthSegments[i]; if (segment && !segment.parent) { // Re-add the segment to the GUI segment.scaleX = 1; segment.alpha = 1; segment.tint = 0x00ff00; lolo1.addChild(segment); // Animate segment restoration with growing effect tween(segment, { scaleX: 1, alpha: 1 }, { duration: 300, easing: tween.easeOut }); } } // Flash remaining segments red when taking damage if (playerHealth < maxHealth) { for (var j = 0; j < visibleSegments; j++) { if (healthSegments[j] && healthSegments[j].parent) { tween(healthSegments[j], { tint: 0xff6666 }, { duration: 200, easing: tween.easeInOut, onFinish: function (segmentToFlash) { return function () { tween(segmentToFlash, { tint: 0x00ff00 }, { duration: 200, easing: tween.easeInOut }); }; }(healthSegments[j]) }); } } } } // Reduce player health function reduceHealth(amount) { playerHealth = Math.max(0, playerHealth - amount); updateHealthBar(); // Flash screen red when taking damage LK.effects.flashScreen(0xff0000, 300); // Check for game over if (playerHealth <= 0) { LK.showGameOver(); } } // Create explosion effect at gem position function createExplosion(x, y, gemColor) { var particleCount = 8; // Reduced from 15 var gemColors = [0xff2222, 0x2222ff, 0x22ff22, 0xffff22, 0xff22ff, 0xff6622, 0xFF69B4]; var color = gemColors[gemColor] || 0xffffff; for (var i = 0; i < particleCount; i++) { var particle = createParticle(x, y, color); game.addChild(particle); } } // Board frame removed - using plain black background // Create background layer var lolo0 = new Container(); game.addChild(lolo0); lolo0.zIndex = 1; // Behind all other elements // Add black background to background layer var blackBg = lolo0.attachAsset('blackBackground', { anchorX: 0, anchorY: 0 }); blackBg.x = 0; blackBg.y = 0; // Create UI container for all game elements var lolo1 = new Container(); game.addChild(lolo1); lolo1.zIndex = 2; // In front of lolo0 layer // Create score display var scoreTxt = new Text2('SCORE: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); // Add purple shadow effect and purple border stroke if (scoreTxt.style) { scoreTxt.style.dropShadow = true; scoreTxt.style.dropShadowColor = "#8B00FF"; scoreTxt.style.dropShadowBlur = 3; scoreTxt.style.dropShadowDistance = 3; scoreTxt.style.stroke = "#8B00FF"; scoreTxt.style.strokeThickness = 4; } lolo1.addChild(scoreTxt); scoreTxt.x = BOARD_OFFSET_X + GRID_SIZE_X * CELL_SIZE / 2; scoreTxt.y = BOARD_OFFSET_Y + GRID_SIZE_Y * CELL_SIZE + 100; // Create health system var playerHealth = 100; var maxHealth = 100; // Create health bar background (red) var healthBarBg = LK.getAsset('healthBarBg', { anchorX: 0, anchorY: 0.5 }); healthBarBg.x = BOARD_OFFSET_X; healthBarBg.y = BOARD_OFFSET_Y - 150; lolo1.addChild(healthBarBg); // Create segmented health bar with 10 individual pieces var healthSegments = []; var segmentWidth = 40; // Each segment is 40px wide (400px total / 10 segments) for (var i = 0; i < 10; i++) { var healthSegment = LK.getAsset('healthBarFg', { anchorX: 0, anchorY: 0.5 }); healthSegment.width = segmentWidth; healthSegment.x = BOARD_OFFSET_X + i * segmentWidth; healthSegment.y = BOARD_OFFSET_Y - 150; healthSegment.segmentIndex = i; healthSegments.push(healthSegment); lolo1.addChild(healthSegment); } // Create health text var healthTxt = new Text2('HEALTH: 100', { size: 50, fill: 0x8B00FF }); // Make text bold and add styling for better visibility if (healthTxt.style) { healthTxt.style.fontWeight = "bold"; healthTxt.style.stroke = "#ffffff"; healthTxt.style.strokeThickness = 2; } healthTxt.anchor.set(0, 0.5); healthTxt.x = BOARD_OFFSET_X; healthTxt.y = BOARD_OFFSET_Y - 100; lolo1.addChild(healthTxt); // Create timer display var timerTxt = new Text2('7:30', { size: 60, fill: 0xFFFF00 }); // Make timer text bold and add styling for better visibility if (timerTxt.style) { timerTxt.style.fontWeight = "bold"; timerTxt.style.stroke = "#ffffff"; timerTxt.style.strokeThickness = 2; timerTxt.style.dropShadow = true; timerTxt.style.dropShadowColor = "#8B00FF"; timerTxt.style.dropShadowBlur = 3; timerTxt.style.dropShadowDistance = 3; } timerTxt.anchor.set(1, 0); // Anchor to top-right for positioning lolo1.addChild(timerTxt); timerTxt.x = BOARD_OFFSET_X + GRID_SIZE_X * CELL_SIZE; timerTxt.y = BOARD_OFFSET_Y - 250; // Initialize empty board function initializeBoard() { gameBoard = []; for (var x = 0; x < GRID_SIZE_X; x++) { gameBoard[x] = []; for (var y = 0; y < GRID_SIZE_Y; y++) { gameBoard[x][y] = null; } } } // Fill board with random gems function fillBoard() { for (var x = 0; x < GRID_SIZE_X; x++) { for (var y = 0; y < GRID_SIZE_Y; y++) { if (!gameBoard[x][y]) { var gemType = Math.floor(Math.random() * 6); // Only generate gems 0-5, excluding bo1 var gem = new Gem(gemType, x, y); var worldPos = gridToWorld(x, y); gem.x = worldPos.x; gem.y = worldPos.y; gem.zIndex = 4; gameBoard[x][y] = gem; lolo1.addChild(gem); } } } } // Convert grid coordinates to world coordinates function gridToWorld(gridX, gridY) { return { x: BOARD_OFFSET_X + gridX * CELL_SIZE + CELL_SIZE / 2, y: BOARD_OFFSET_Y + (GRID_SIZE_Y - 1 - gridY) * CELL_SIZE + CELL_SIZE / 2 }; } // Convert world coordinates to grid coordinates function worldToGrid(worldX, worldY) { var gridX = Math.floor((worldX - BOARD_OFFSET_X) / CELL_SIZE); var gridY = GRID_SIZE_Y - 1 - Math.floor((worldY - BOARD_OFFSET_Y) / CELL_SIZE); if (gridX < 0 || gridX >= GRID_SIZE_X || gridY < 0 || gridY >= GRID_SIZE_Y) { return null; } return { x: gridX, y: gridY }; } // Check if two grid positions are adjacent function areAdjacent(pos1, pos2) { var dx = Math.abs(pos1.x - pos2.x); var dy = Math.abs(pos1.y - pos2.y); return dx === 1 && dy === 0 || dx === 0 && dy === 1; } // Check for matches starting at position (2x2 squares and 3-in-a-row) function checkMatches(startX, startY) { var gem = gameBoard[startX][startY]; if (!gem) return []; var matches = []; var gemType = gem.gemType; // Check horizontal 3-in-a-row matches var horizontalCount = 1; var horizontalGems = [gem]; // Check right direction for (var x = startX + 1; x < GRID_SIZE_X; x++) { var rightGem = gameBoard[x][startY]; if (rightGem && rightGem.gemType === gemType) { horizontalCount++; horizontalGems.push(rightGem); } else { break; } } // Check left direction for (var x = startX - 1; x >= 0; x--) { var leftGem = gameBoard[x][startY]; if (leftGem && leftGem.gemType === gemType) { horizontalCount++; horizontalGems.unshift(leftGem); } else { break; } } // Add horizontal matches if 3 or more if (horizontalCount >= 3) { for (var h = 0; h < horizontalGems.length; h++) { matches.push(horizontalGems[h]); } } // Check vertical 3-in-a-row matches var verticalCount = 1; var verticalGems = [gem]; // Check up direction for (var y = startY + 1; y < GRID_SIZE_Y; y++) { var upGem = gameBoard[startX][y]; if (upGem && upGem.gemType === gemType) { verticalCount++; verticalGems.push(upGem); } else { break; } } // Check down direction for (var y = startY - 1; y >= 0; y--) { var downGem = gameBoard[startX][y]; if (downGem && downGem.gemType === gemType) { verticalCount++; verticalGems.unshift(downGem); } else { break; } } // Add vertical matches if 3 or more if (verticalCount >= 3) { for (var v = 0; v < verticalGems.length; v++) { var found = false; for (var m = 0; m < matches.length; m++) { if (matches[m] === verticalGems[v]) { found = true; break; } } if (!found) { matches.push(verticalGems[v]); } } } // Check if this gem is part of a 2x2 square // Check all possible 2x2 squares this gem could be part of var squarePositions = [ // Top-left corner [{ x: startX, y: startY }, { x: startX + 1, y: startY }, { x: startX, y: startY + 1 }, { x: startX + 1, y: startY + 1 }], // Top-right corner [{ x: startX - 1, y: startY }, { x: startX, y: startY }, { x: startX - 1, y: startY + 1 }, { x: startX, y: startY + 1 }], // Bottom-left corner [{ x: startX, y: startY - 1 }, { x: startX + 1, y: startY - 1 }, { x: startX, y: startY }, { x: startX + 1, y: startY }], // Bottom-right corner [{ x: startX - 1, y: startY - 1 }, { x: startX, y: startY - 1 }, { x: startX - 1, y: startY }, { x: startX, y: startY }]]; for (var s = 0; s < squarePositions.length; s++) { var square = squarePositions[s]; var validSquare = true; var squareGems = []; // Check if all positions in this square are valid and contain same gem type for (var p = 0; p < square.length; p++) { var pos = square[p]; if (pos.x < 0 || pos.x >= GRID_SIZE_X || pos.y < 0 || pos.y >= GRID_SIZE_Y) { validSquare = false; break; } var squareGem = gameBoard[pos.x][pos.y]; if (!squareGem || squareGem.gemType !== gemType) { validSquare = false; break; } squareGems.push(squareGem); } // If we found a valid 2x2 square, add all gems to matches if (validSquare) { for (var g = 0; g < squareGems.length; g++) { var found = false; for (var m = 0; m < matches.length; m++) { if (matches[m] === squareGems[g]) { found = true; break; } } if (!found) { matches.push(squareGems[g]); } } } } return matches; } // Check if any valid moves exist on the board function hasValidMoves() { for (var x = 0; x < GRID_SIZE_X; x++) { for (var y = 0; y < GRID_SIZE_Y; y++) { var currentGem = gameBoard[x][y]; if (!currentGem) continue; // Check all adjacent positions for potential swaps var adjacentPositions = [{ x: x + 1, y: y }, // Right { x: x - 1, y: y }, // Left { x: x, y: y + 1 }, // Up { x: x, y: y - 1 } // Down ]; for (var i = 0; i < adjacentPositions.length; i++) { var adjPos = adjacentPositions[i]; if (adjPos.x >= 0 && adjPos.x < GRID_SIZE_X && adjPos.y >= 0 && adjPos.y < GRID_SIZE_Y) { var adjacentGem = gameBoard[adjPos.x][adjPos.y]; if (adjacentGem) { // Temporarily swap gems to check if it creates matches var tempGem1Type = currentGem.gemType; var tempGem2Type = adjacentGem.gemType; currentGem.gemType = tempGem2Type; adjacentGem.gemType = tempGem1Type; // Check if this swap creates any matches var matches1 = checkMatches(x, y); var matches2 = checkMatches(adjPos.x, adjPos.y); // Restore original gem types currentGem.gemType = tempGem1Type; adjacentGem.gemType = tempGem2Type; // If either position has matches after swap, it's a valid move if (matches1.length > 0 || matches2.length > 0) { return true; } } } } } } return false; } // Shuffle gems on the board when no valid moves exist function shuffleBoard() { var gemTypes = []; // Collect all gem types currently on the board for (var x = 0; x < GRID_SIZE_X; x++) { for (var y = 0; y < GRID_SIZE_Y; y++) { if (gameBoard[x][y]) { gemTypes.push(gameBoard[x][y].gemType); } } } // Shuffle the gem types array for (var i = gemTypes.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = gemTypes[i]; gemTypes[i] = gemTypes[j]; gemTypes[j] = temp; } // Assign shuffled gem types back to the board var typeIndex = 0; for (var x = 0; x < GRID_SIZE_X; x++) { for (var y = 0; y < GRID_SIZE_Y; y++) { if (gameBoard[x][y]) { var gem = gameBoard[x][y]; var newGemType = gemTypes[typeIndex]; typeIndex++; // Create new gem with shuffled type var newGem = new Gem(newGemType, x, y); var worldPos = gridToWorld(x, y); newGem.x = worldPos.x; newGem.y = worldPos.y; newGem.zIndex = 4; // Remove old gem and add new one gem.destroy(); gameBoard[x][y] = newGem; lolo1.addChild(newGem); } } } } // Find all matches on the board function findAllMatches() { var allMatches = []; var processedGems = []; for (var x = 0; x < GRID_SIZE_X; x++) { for (var y = 0; y < GRID_SIZE_Y; y++) { if (gameBoard[x][y]) { var matches = checkMatches(x, y); for (var i = 0; i < matches.length; i++) { var gem = matches[i]; var found = false; for (var j = 0; j < processedGems.length; j++) { if (processedGems[j] === gem) { found = true; break; } } if (!found) { allMatches.push(gem); processedGems.push(gem); } } } } } return allMatches; } // Clear matched gems function clearMatches(matches) { if (matches.length === 0) return; LK.getSound('match').play(); var points = matches.length * 10 * comboMultiplier; var oldScore = score; score += points; scoreTxt.setText('SCORE: ' + score); // Health gain system - check if player should gain health every 1500 points var oldHealthGainLevel = Math.floor(oldScore / 1500); var newHealthGainLevel = Math.floor(score / 1500); if (newHealthGainLevel > oldHealthGainLevel && playerHealth < maxHealth) { // Player gains health, but don't exceed max health var healthToGain = Math.min(10, maxHealth - playerHealth); playerHealth += healthToGain; updateHealthBar(); // Flash screen green to show health gain LK.effects.flashScreen(0x00ff00, 500); } // Check for win condition - player reaches 10000 points if (score >= 10000) { LK.clearInterval(gameTimer); LK.showYouWin(); return; } // Store destroyed gems for bo1 placement detection var destroyedGems = []; for (var i = 0; i < matches.length; i++) { var gem = matches[i]; // Store gem info before destroying destroyedGems.push({ gridX: gem.gridX, gridY: gem.gridY, gemType: gem.gemType }); // Create explosion effect at gem position createExplosion(gem.x, gem.y, gem.gemType); gameBoard[gem.gridX][gem.gridY] = null; gem.destroy(); } // After clearing gems, apply gravity and fill empty spaces LK.setTimeout(function () { // Apply gravity repeatedly until no more gems fall function applyGravityRepeatedly() { var moved = applyGravity(); if (moved) { LK.setTimeout(applyGravityRepeatedly, 100); } else { fillEmptySpaces(destroyedGems); // Check for new matches after falling gems settle LK.setTimeout(function () { var newMatches = findAllMatches(); if (newMatches.length > 0) { comboMultiplier++; clearMatches(newMatches); } else { comboMultiplier = 1; consecutiveGemsDestroyed = 0; // Reset counter when no more matches isSwapping = false; // Check if any valid moves exist, if not shuffle the board if (!hasValidMoves()) { shuffleBoard(); } } }, 500); } } applyGravityRepeatedly(); }, 200); } // Apply gravity to make gems fall function applyGravity() { var moved = false; for (var x = 0; x < GRID_SIZE_X; x++) { // Collect all non-null gems in this column from bottom to top var gemsInColumn = []; for (var y = 0; y < GRID_SIZE_Y; y++) { if (gameBoard[x][y]) { gemsInColumn.push(gameBoard[x][y]); } gameBoard[x][y] = null; // Clear the position } // Place gems back from bottom (index 0) upward, filling gaps for (var i = 0; i < gemsInColumn.length; i++) { var gem = gemsInColumn[i]; var newY = i; // Place at bottom-most available position if (gem.gridY !== newY) { gem.setGridPosition(x, newY); var worldPos = gridToWorld(x, newY); gem.animateToPosition(worldPos.x, worldPos.y, 300); moved = true; } gameBoard[x][newY] = gem; } } return moved; } // Check if 5 consecutive yellow gems were just destroyed and return positions for 3 bo1 gems function hasYellow5x5Pattern(destroyedGems) { if (!destroyedGems || destroyedGems.length < 5) return null; // Check for horizontal 5-in-a-row yellow pattern in destroyed gems for (var y = 0; y < GRID_SIZE_Y; y++) { for (var startX = 0; startX <= GRID_SIZE_X - 5; startX++) { var yellowCount = 0; var consecutivePositions = []; // Check if 5 consecutive horizontal positions had yellow gems destroyed for (var x = startX; x < startX + 5; x++) { var wasYellowDestroyed = false; for (var i = 0; i < destroyedGems.length; i++) { var destroyedGem = destroyedGems[i]; if (destroyedGem.gridX === x && destroyedGem.gridY === y && destroyedGem.gemType === 3) { wasYellowDestroyed = true; break; } } if (wasYellowDestroyed) { yellowCount++; consecutivePositions.push({ x: x, y: y }); } else { break; // Not consecutive } } if (yellowCount === 5) { // Return 3 positions for bo1 gems (left, center, right of the 5-gem pattern) return [{ x: startX + 1, y: y }, { x: startX + 2, y: y }, { x: startX + 3, y: y }]; } } } // Check for vertical 5-in-a-row yellow pattern in destroyed gems for (var x = 0; x < GRID_SIZE_X; x++) { for (var startY = 0; startY <= GRID_SIZE_Y - 5; startY++) { var yellowCount = 0; var consecutivePositions = []; // Check if 5 consecutive vertical positions had yellow gems destroyed for (var y = startY; y < startY + 5; y++) { var wasYellowDestroyed = false; for (var i = 0; i < destroyedGems.length; i++) { var destroyedGem = destroyedGems[i]; if (destroyedGem.gridX === x && destroyedGem.gridY === y && destroyedGem.gemType === 3) { wasYellowDestroyed = true; break; } } if (wasYellowDestroyed) { yellowCount++; consecutivePositions.push({ x: x, y: y }); } else { break; // Not consecutive } } if (yellowCount === 5) { // Return 3 positions for bo1 gems (top, center, bottom of the 5-gem pattern) return [{ x: x, y: startY + 1 }, { x: x, y: startY + 2 }, { x: x, y: startY + 3 }]; } } } return null; } // Fill empty spaces with new gems function fillEmptySpaces(lastDestroyedGems) { var yellow5Positions = hasYellow5x5Pattern(lastDestroyedGems); for (var x = 0; x < GRID_SIZE_X; x++) { // Count how many empty spaces exist in this column var emptyCount = 0; for (var y = 0; y < GRID_SIZE_Y; y++) { if (!gameBoard[x][y]) { emptyCount++; } } // Fill empty spaces from top of column downward var fillIndex = 0; for (var y = 0; y < GRID_SIZE_Y; y++) { if (!gameBoard[x][y]) { var gemType; // Check if we should place bo1 gem at one of the 3 positions from yellow 5-pattern var shouldPlaceBo1 = false; if (yellow5Positions) { for (var i = 0; i < yellow5Positions.length; i++) { if (yellow5Positions[i].x === x && yellow5Positions[i].y === y) { shouldPlaceBo1 = true; break; } } } if (shouldPlaceBo1) { gemType = 6; // bo1 gem type } else { gemType = Math.floor(Math.random() * 6); // Only generate gems 0-5, excluding bo1 } var gem = new Gem(gemType, x, y); var worldPos = gridToWorld(x, y); gem.x = worldPos.x; // Start new gems from above the visible area gem.y = BOARD_OFFSET_Y - CELL_SIZE * (emptyCount - fillIndex + 1); gem.zIndex = 4; gameBoard[x][y] = gem; lolo1.addChild(gem); gem.animateToPosition(worldPos.x, worldPos.y, 200 + fillIndex * 50); // Staggered timing fillIndex++; } } } } // Swap two gems // Function to destroy gems in all directions from bo1 gem function destroyGemsInDirections(bo1X, bo1Y) { var gemsToDestroy = []; var directions = [{ dx: 0, dy: 1 }, // Up { dx: 0, dy: -1 }, // Down { dx: 1, dy: 0 }, // Right { dx: -1, dy: 0 } // Left ]; // For each direction, destroy all gems in that line for (var d = 0; d < directions.length; d++) { var dir = directions[d]; var currentX = bo1X + dir.dx; var currentY = bo1Y + dir.dy; // Continue in this direction until we hit the board edge while (currentX >= 0 && currentX < GRID_SIZE_X && currentY >= 0 && currentY < GRID_SIZE_Y) { var gem = gameBoard[currentX][currentY]; if (gem && gem.gemType !== 6) { // Don't destroy other bo1 gems gemsToDestroy.push(gem); } currentX += dir.dx; currentY += dir.dy; } } // Destroy all collected gems with animation for (var i = 0; i < gemsToDestroy.length; i++) { var gem = gemsToDestroy[i]; // Create explosion effect createExplosion(gem.x, gem.y, gem.gemType); // Clear from board gameBoard[gem.gridX][gem.gridY] = null; // Destroy gem with tween effect gem.destroy(); } // Add points for destroyed gems if (gemsToDestroy.length > 0) { var points = gemsToDestroy.length * 50; // Higher points for bo1 destruction score += points; scoreTxt.setText('SCORE: ' + score); } return gemsToDestroy.length; } function swapGems(gem1, gem2) { if (isSwapping) return; isSwapping = true; // Store original positions var originalGem1X = gem1.gridX; var originalGem1Y = gem1.gridY; var originalGem2X = gem2.gridX; var originalGem2Y = gem2.gridY; // Update grid positions gem1.setGridPosition(gem2.gridX, gem2.gridY); gem2.setGridPosition(originalGem1X, originalGem1Y); gameBoard[gem1.gridX][gem1.gridY] = gem1; gameBoard[gem2.gridX][gem2.gridY] = gem2; var pos1 = gridToWorld(gem1.gridX, gem1.gridY); var pos2 = gridToWorld(gem2.gridX, gem2.gridY); // Animate the swap gem1.animateToPosition(pos1.x, pos1.y, 200); gem2.animateToPosition(pos2.x, pos2.y, 200); LK.setTimeout(function () { // Check if either gem is bo1 and trigger directional destruction var bo1Activated = false; if (gem1.gemType === 6) { // bo1 gem type var destroyedCount = destroyGemsInDirections(gem1.gridX, gem1.gridY); if (destroyedCount > 0) bo1Activated = true; } if (gem2.gemType === 6) { // bo1 gem type var destroyedCount = destroyGemsInDirections(gem2.gridX, gem2.gridY); if (destroyedCount > 0) bo1Activated = true; } var matches = findAllMatches(); if (matches.length > 0 || bo1Activated) { // Valid swap - process matches if (matches.length > 0) { clearMatches(matches); } else if (bo1Activated) { // Only bo1 was activated, apply gravity and fill spaces LK.setTimeout(function () { function applyGravityRepeatedly() { var moved = applyGravity(); if (moved) { LK.setTimeout(applyGravityRepeatedly, 100); } else { fillEmptySpaces(); LK.setTimeout(function () { var newMatches = findAllMatches(); if (newMatches.length > 0) { comboMultiplier++; clearMatches(newMatches); } else { comboMultiplier = 1; isSwapping = false; if (!hasValidMoves()) { shuffleBoard(); } } }, 500); } } applyGravityRepeatedly(); }, 200); } } else { // Invalid move - reduce health by 10 and animate back to original positions reduceHealth(10); gem1.setGridPosition(originalGem1X, originalGem1Y); gem2.setGridPosition(originalGem2X, originalGem2Y); gameBoard[gem1.gridX][gem1.gridY] = gem1; gameBoard[gem2.gridX][gem2.gridY] = gem2; var pos1 = gridToWorld(gem1.gridX, gem1.gridY); var pos2 = gridToWorld(gem2.gridX, gem2.gridY); gem1.animateToPosition(pos1.x, pos1.y, 200); gem2.animateToPosition(pos2.x, pos2.y, 200); LK.setTimeout(function () { isSwapping = false; // Check if any valid moves exist after invalid swap if (!hasValidMoves()) { shuffleBoard(); } }, 200); } }, 200); } // Game input handling game.down = function (x, y, obj) { if (isSwapping) return; var gridPos = worldToGrid(x, y); if (!gridPos) return; var clickedGem = gameBoard[gridPos.x][gridPos.y]; if (!clickedGem) return; draggedGem = clickedGem; dragStartPos = { x: x, y: y }; isDragging = true; draggedGem.alpha = 0.7; }; game.move = function (x, y, obj) { if (!isDragging || !draggedGem || isSwapping) return; // Calculate drag distance var dragDeltaX = x - dragStartPos.x; var dragDeltaY = y - dragStartPos.y; var dragDistance = Math.sqrt(dragDeltaX * dragDeltaX + dragDeltaY * dragDeltaY); // Only process if drag distance is significant enough if (dragDistance > CELL_SIZE * 0.3) { // Determine drag direction var targetGridX = draggedGem.gridX; var targetGridY = draggedGem.gridY; if (Math.abs(dragDeltaX) > Math.abs(dragDeltaY)) { // Horizontal drag if (dragDeltaX > 0) { targetGridX = Math.min(GRID_SIZE_X - 1, draggedGem.gridX + 1); } else { targetGridX = Math.max(0, draggedGem.gridX - 1); } } else { // Vertical drag (flipped coordinate system) if (dragDeltaY > 0) { targetGridY = Math.max(0, draggedGem.gridY - 1); } else { targetGridY = Math.min(GRID_SIZE_Y - 1, draggedGem.gridY + 1); } } // Update visual position to show intended swap var targetWorldPos = gridToWorld(targetGridX, targetGridY); draggedGem.x = targetWorldPos.x; draggedGem.y = targetWorldPos.y; // Store target position for later use draggedGem.targetGridX = targetGridX; draggedGem.targetGridY = targetGridY; } }; game.up = function (x, y, obj) { if (!isDragging || !draggedGem || isSwapping) return; var startGridPos = { x: draggedGem.gridX, y: draggedGem.gridY }; // Check if we have a target position from dragging if (draggedGem.targetGridX !== undefined && draggedGem.targetGridY !== undefined) { var targetGridPos = { x: draggedGem.targetGridX, y: draggedGem.targetGridY }; // Check if target position is valid and adjacent if (areAdjacent(startGridPos, targetGridPos) && gameBoard[targetGridPos.x][targetGridPos.y]) { var targetGem = gameBoard[targetGridPos.x][targetGridPos.y]; // Attempt swap swapGems(draggedGem, targetGem); } else { // Invalid swap - animate back to original position var worldPos = gridToWorld(draggedGem.gridX, draggedGem.gridY); draggedGem.animateToPosition(worldPos.x, worldPos.y, 200); } // Clean up target position draggedGem.targetGridX = undefined; draggedGem.targetGridY = undefined; } else { // No significant drag - just return to original position var worldPos = gridToWorld(draggedGem.gridX, draggedGem.gridY); draggedGem.animateToPosition(worldPos.x, worldPos.y, 200); } draggedGem.alpha = 1.0; draggedGem = null; dragStartPos = null; isDragging = false; }; // Create grid lines around gems function createGridLines() { // Create vertical lines for (var x = 0; x <= GRID_SIZE_X; x++) { for (var lineY = 0; lineY < GRID_SIZE_Y * CELL_SIZE; lineY += 20) { var verticalLine = LK.getAsset('particle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.05, scaleY: 0.5 }); verticalLine.tint = 0x8B4513; verticalLine.x = BOARD_OFFSET_X + x * CELL_SIZE; verticalLine.y = BOARD_OFFSET_Y + lineY + 10; verticalLine.zIndex = 3; game.addChild(verticalLine); } } // Create horizontal lines for (var y = 0; y <= GRID_SIZE_Y; y++) { for (var lineX = 0; lineX < GRID_SIZE_X * CELL_SIZE; lineX += 20) { var horizontalLine = LK.getAsset('particle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.05 }); horizontalLine.tint = 0x8B4513; horizontalLine.x = BOARD_OFFSET_X + lineX + 10; horizontalLine.y = BOARD_OFFSET_Y + y * CELL_SIZE; horizontalLine.zIndex = 3; game.addChild(horizontalLine); } } } // Initialize the game initializeBoard(); fillBoard(); createGridLines(); // Add game update loop for continuous animations game.update = function () { // Clean up particles that are off-screen or dead for (var i = activeParticles.length - 1; i >= 0; i--) { var particle = activeParticles[i]; if (!particle.parent || particle.y > 3000 || particle.y < -500) { if (particle.parent) { particle.destroy(); } } } // Add gentle rotation animation to all gems for (var x = 0; x < GRID_SIZE_X; x++) { for (var y = 0; y < GRID_SIZE_Y; y++) { var gem = gameBoard[x][y]; if (gem && !gem.isAnimating && !gem.rotationStarted) { // Create gentle rotation effect gem.rotationStarted = true; var delay = (x + y) * 30; // Stagger the rotation animation LK.setTimeout(function (currentGem) { return function () { function createRotation() { if (currentGem.parent && !currentGem.isAnimating) { var currentRotation = currentGem.rotation || 0; tween(currentGem, { rotation: currentRotation + Math.PI * 2 }, { duration: 6000, easing: tween.linear, onFinish: function onFinish() { if (currentGem.parent && !currentGem.isAnimating) { createRotation(); // Continue rotating } } }); } } createRotation(); }; }(gem), delay); } } } }; // Start countdown timer gameTimer = LK.setInterval(function () { remainingTime--; updateTimer(); // Game over when time runs out if (remainingTime <= 0) { LK.clearInterval(gameTimer); LK.showGameOver(); } }, 1000); // Update every 1000ms (1 second) // Create sariiii button var sariiiButton = new Text2('sariiii', { size: 80, fill: 0x000000 }); sariiiButton.anchor.set(0.5, 0.5); // Add styling to make it look like a button if (sariiiButton.style) { sariiiButton.style.fontWeight = "bold"; sariiiButton.style.stroke = "#FFFFFF"; sariiiButton.style.strokeThickness = 4; } sariiiButton.x = BOARD_OFFSET_X + GRID_SIZE_X * CELL_SIZE + 150; sariiiButton.y = BOARD_OFFSET_Y + GRID_SIZE_Y * CELL_SIZE / 2; lolo1.addChild(sariiiButton); // Function to create 5 yellow gems in a row pattern function create5x5YellowPattern() { if (isSwapping) return; // Don't allow during other operations // Find best position for 5-in-a-row pattern (center of board if possible) var startX = Math.max(0, Math.min(GRID_SIZE_X - 5, Math.floor((GRID_SIZE_X - 5) / 2))); var startY = Math.floor(GRID_SIZE_Y / 2); // Center vertically // Create 5 yellow gems in a horizontal row for (var x = startX; x < startX + 5; x++) { // Remove existing gem if there is one if (gameBoard[x][startY]) { gameBoard[x][startY].destroy(); } // Create new yellow gem (gemType 3) var yellowGem = new Gem(3, x, startY); var worldPos = gridToWorld(x, startY); yellowGem.x = worldPos.x; yellowGem.y = worldPos.y; yellowGem.zIndex = 4; gameBoard[x][startY] = yellowGem; lolo1.addChild(yellowGem); // Add visual effect tween(yellowGem, { scaleX: 1.3, scaleY: 1.3 }, { duration: 200, easing: tween.easeOut, onFinish: function (gem) { return function () { tween(gem, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeOut }); }; }(yellowGem) }); } } // Add button press handler sariiiButton.down = function (x, y, obj) { create5x5YellowPattern(); // Visual feedback for button press tween(sariiiButton, { scaleX: 0.9, scaleY: 0.9, tint: 0xFFAA00 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(sariiiButton, { scaleX: 1.0, scaleY: 1.0, tint: 0xFFFFFF }, { duration: 100, easing: tween.easeOut }); } }); }; // Start background music LK.playMusic('background'); // Initialize timer display updateTimer(); // Initial match clearing LK.setTimeout(function () { var matches = findAllMatches(); if (matches.length > 0) { clearMatches(matches); } }, 100);
===================================================================
--- original.js
+++ change.js
@@ -1250,10 +1250,18 @@
LK.clearInterval(gameTimer);
LK.showYouWin();
return;
}
+ // Store destroyed gems for bo1 placement detection
+ var destroyedGems = [];
for (var i = 0; i < matches.length; i++) {
var gem = matches[i];
+ // Store gem info before destroying
+ destroyedGems.push({
+ gridX: gem.gridX,
+ gridY: gem.gridY,
+ gemType: gem.gemType
+ });
// Create explosion effect at gem position
createExplosion(gem.x, gem.y, gem.gemType);
gameBoard[gem.gridX][gem.gridY] = null;
gem.destroy();
@@ -1265,9 +1273,9 @@
var moved = applyGravity();
if (moved) {
LK.setTimeout(applyGravityRepeatedly, 100);
} else {
- fillEmptySpaces();
+ fillEmptySpaces(destroyedGems);
// Check for new matches after falling gems settle
LK.setTimeout(function () {
var newMatches = findAllMatches();
if (newMatches.length > 0) {
@@ -1314,57 +1322,96 @@
}
}
return moved;
}
-// Check if we have a 5-in-a-row yellow gem pattern on the board
-function hasYellow5x5Pattern() {
- // Check for horizontal 5-in-a-row yellow patterns
+// Check if 5 consecutive yellow gems were just destroyed and return positions for 3 bo1 gems
+function hasYellow5x5Pattern(destroyedGems) {
+ if (!destroyedGems || destroyedGems.length < 5) return null;
+ // Check for horizontal 5-in-a-row yellow pattern in destroyed gems
for (var y = 0; y < GRID_SIZE_Y; y++) {
for (var startX = 0; startX <= GRID_SIZE_X - 5; startX++) {
- var isHorizontal5 = true;
- // Check if 5 consecutive horizontal gems are yellow (gemType 3)
+ var yellowCount = 0;
+ var consecutivePositions = [];
+ // Check if 5 consecutive horizontal positions had yellow gems destroyed
for (var x = startX; x < startX + 5; x++) {
- var gem = gameBoard[x][y];
- if (!gem || gem.gemType !== 3) {
- isHorizontal5 = false;
- break;
+ var wasYellowDestroyed = false;
+ for (var i = 0; i < destroyedGems.length; i++) {
+ var destroyedGem = destroyedGems[i];
+ if (destroyedGem.gridX === x && destroyedGem.gridY === y && destroyedGem.gemType === 3) {
+ wasYellowDestroyed = true;
+ break;
+ }
}
+ if (wasYellowDestroyed) {
+ yellowCount++;
+ consecutivePositions.push({
+ x: x,
+ y: y
+ });
+ } else {
+ break; // Not consecutive
+ }
}
- if (isHorizontal5) {
- // Return center position for horizontal pattern
- return {
- startX: Math.max(0, startX + 1),
- startY: Math.max(0, y - 1)
- };
+ if (yellowCount === 5) {
+ // Return 3 positions for bo1 gems (left, center, right of the 5-gem pattern)
+ return [{
+ x: startX + 1,
+ y: y
+ }, {
+ x: startX + 2,
+ y: y
+ }, {
+ x: startX + 3,
+ y: y
+ }];
}
}
}
- // Check for vertical 5-in-a-row yellow patterns
+ // Check for vertical 5-in-a-row yellow pattern in destroyed gems
for (var x = 0; x < GRID_SIZE_X; x++) {
for (var startY = 0; startY <= GRID_SIZE_Y - 5; startY++) {
- var isVertical5 = true;
- // Check if 5 consecutive vertical gems are yellow (gemType 3)
+ var yellowCount = 0;
+ var consecutivePositions = [];
+ // Check if 5 consecutive vertical positions had yellow gems destroyed
for (var y = startY; y < startY + 5; y++) {
- var gem = gameBoard[x][y];
- if (!gem || gem.gemType !== 3) {
- isVertical5 = false;
- break;
+ var wasYellowDestroyed = false;
+ for (var i = 0; i < destroyedGems.length; i++) {
+ var destroyedGem = destroyedGems[i];
+ if (destroyedGem.gridX === x && destroyedGem.gridY === y && destroyedGem.gemType === 3) {
+ wasYellowDestroyed = true;
+ break;
+ }
}
+ if (wasYellowDestroyed) {
+ yellowCount++;
+ consecutivePositions.push({
+ x: x,
+ y: y
+ });
+ } else {
+ break; // Not consecutive
+ }
}
- if (isVertical5) {
- // Return center position for vertical pattern
- return {
- startX: Math.max(0, x - 1),
- startY: Math.max(0, startY + 1)
- };
+ if (yellowCount === 5) {
+ // Return 3 positions for bo1 gems (top, center, bottom of the 5-gem pattern)
+ return [{
+ x: x,
+ y: startY + 1
+ }, {
+ x: x,
+ y: startY + 2
+ }, {
+ x: x,
+ y: startY + 3
+ }];
}
}
}
return null;
}
// Fill empty spaces with new gems
-function fillEmptySpaces() {
- var yellow5x5 = hasYellow5x5Pattern();
+function fillEmptySpaces(lastDestroyedGems) {
+ var yellow5Positions = hasYellow5x5Pattern(lastDestroyedGems);
for (var x = 0; x < GRID_SIZE_X; x++) {
// Count how many empty spaces exist in this column
var emptyCount = 0;
for (var y = 0; y < GRID_SIZE_Y; y++) {
@@ -1376,10 +1423,19 @@
var fillIndex = 0;
for (var y = 0; y < GRID_SIZE_Y; y++) {
if (!gameBoard[x][y]) {
var gemType;
- // Check if we should place bo1 gem (only at center position of 5-in-a-row pattern)
- if (yellow5x5 && x === yellow5x5.startX + 2 && y === yellow5x5.startY + 2) {
+ // Check if we should place bo1 gem at one of the 3 positions from yellow 5-pattern
+ var shouldPlaceBo1 = false;
+ if (yellow5Positions) {
+ for (var i = 0; i < yellow5Positions.length; i++) {
+ if (yellow5Positions[i].x === x && yellow5Positions[i].y === y) {
+ shouldPlaceBo1 = true;
+ break;
+ }
+ }
+ }
+ if (shouldPlaceBo1) {
gemType = 6; // bo1 gem type
} else {
gemType = Math.floor(Math.random() * 6); // Only generate gems 0-5, excluding bo1
}
Alev spiral parçacık. In-Game asset. 2d. High contrast. No shadows
Su damlası patlama parçacık. In-Game asset. 2d. High contrast. No shadows
Karadelik vortex parçacık spiral. In-Game asset. 2d. High contrast. No shadows
Yeşil yaprak süzülen. In-Game asset. 2d. High contrast. No shadows
Yıldız patlama parlak. In-Game asset. 2d. High contrast. No shadows
Lav topu erimiş. In-Game asset. 2d. High contrast. No shadows
Health bar, grandyan, green,. In-Game asset. 2d. High contrast. No shadows
Hiç birşeye dokunma sadece yeşil olan kısımları kırmızı ile yer değiştir
Bomba şeklinide grandyan ama çizgili rengarenk olsun