User prompt
Yatay ve dikey 1 piksel yap
User prompt
Toplar birbirine daha yakın olsun
User prompt
Yukardan düşün top statik topa carptıgında statik toplar saga sola kaysın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Fırlayan top oyun alanından cıkmasın
User prompt
Yukarıdan düşen top oyun alanındaki topa çarptıgın alan etkisi yaratsın çerptıgı toplar saga sola fırlasın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Yukarıdan gelen topa agırlık fizigi ekle çarpıştıgında bölgedeki toplar hareket etsin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Yukardan düşen top oyın alanındaki toplarla çarpiştiginda alttaki toplar hareket etsin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Yukardan düşen top düştügü alandaki topları hareket ettirsin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Farklı top boyutlarını hesaba katan daha gelişmiş paketleme kullan
User prompt
Aralıklar hala çok fazla
User prompt
Yan ve üstten toplar birbirine temas etsin
User prompt
Hala temas yok
User prompt
Oyun alanındaki Toplar birbirine sıfıra sıfır temas etsin
User prompt
Topların birbirine tam temasını sagla
User prompt
Hala fazla
User prompt
Top aralıkları hala cok fazla
User prompt
Topların büyüklügüme göre top aralıklarını ayarla olabildigince temas
User prompt
Birlelme sesi arttır
User prompt
Topları biraz daha büyğlt
User prompt
Toplar sürekli zıplıyor düzelt
User prompt
Please fix the bug: 'TypeError: tween.stopAll is not a function' in or related to this line: 'tween.stopAll(balls[i]);' Line Number: 669 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
1. 2. 4. 5. 6. Gerçekleştir
User prompt
Birleşme efecti ekle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
30 yap
User prompt
Daha sıkı top yerleşimi için toplar arası yatay dikey çapraz aralıgı 40 piksel
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Ball = Container.expand(function (value) { var self = Container.call(this); self.value = value || 2; self.velocityX = 0; self.velocityY = 0; self.gravity = 0.8; self.bounce = 0.4; self.friction = 0.98; // Set radius based on ball value for proper physics var radiusMap = { 2: 140, 4: 145, 8: 155, 16: 165, 32: 175, 64: 185, 128: 195, 256: 205, 512: 215, 1024: 220, 2048: 230 }; self.radius = radiusMap[self.value] || 60; self.isStatic = false; self.mergeTimer = 0; self.hasBeenMerged = false; var ballAsset; try { ballAsset = self.attachAsset('ball' + self.value, { anchorX: 0.5, anchorY: 0.5 }); } catch (e) { // Fallback for 2048 ball if image asset fails if (self.value === 2048) { ballAsset = self.attachAsset('ball2048top', { anchorX: 0.5, anchorY: 0.5 }); } else { throw e; } } var valueText = new Text2(self.value.toString(), { size: 56, fill: 0xFFFFFF }); valueText.anchor.set(0.5, 0.5); self.addChild(valueText); self.update = function () { if (self.hasBeenMerged) return; if (self.mergeTimer > 0) { self.mergeTimer--; return; } // Apply physics only if not static if (!self.isStatic) { // Store previous position for continuous collision detection var prevX = self.x; var prevY = self.y; // Apply gravity self.velocityY += self.gravity; // Calculate intended new position var newX = self.x + self.velocityX; var newY = self.y + self.velocityY; // Continuous collision detection - check path from current to intended position var stepCount = Math.max(1, Math.ceil(Math.abs(self.velocityX) + Math.abs(self.velocityY)) / (self.radius * 0.5)); var stepX = (newX - self.x) / stepCount; var stepY = (newY - self.y) / stepCount; var collisionOccurred = false; // Check each step along the movement path for (var step = 1; step <= stepCount && !collisionOccurred; step++) { var testX = self.x + stepX * step; var testY = self.y + stepY * step; // Test collision with other balls for (var i = 0; i < balls.length; i++) { var otherBall = balls[i]; if (otherBall === self || otherBall.hasBeenMerged || otherBall.mergeTimer > 0) continue; var dx = otherBall.x - testX; var dy = otherBall.y - testY; var distance = Math.sqrt(dx * dx + dy * dy); var minDistance = self.radius + otherBall.radius; if (distance < minDistance) { // Collision detected - stop at safe position var safeDistance = minDistance + 2; // Add small buffer if (distance > 0) { var normalX = dx / distance; var normalY = dy / distance; self.x = otherBall.x - normalX * safeDistance; self.y = otherBall.y - normalY * safeDistance; // Check for merge first - increased sensitivity for same-numbered balls var mergeDistance = self.value === otherBall.value ? minDistance * 1.4 : minDistance; if (self.value === otherBall.value && self.mergeTimer === 0 && otherBall.mergeTimer === 0 && distance < mergeDistance) { // Special case: when two 2048 balls merge, they explode and disappear if (self.value === 2048) { // Create explosion effect for both 2048 balls tween(self, { scaleX: 3.0, scaleY: 3.0, alpha: 0 }, { duration: 600, easing: tween.easeOut }); tween(otherBall, { scaleX: 3.0, scaleY: 3.0, alpha: 0 }, { duration: 600, easing: tween.easeOut }); // Mark both balls for removal self.hasBeenMerged = true; otherBall.hasBeenMerged = true; LK.getSound('merge').play(); if (scoringActive) { LK.setScore(LK.getScore() + 1); scoreText.setText(LK.getScore()); } return; } var newValue = self.value * 2; if (newValue <= 2048) { var newBall = new Ball(newValue); newBall.x = (self.x + otherBall.x) / 2; newBall.y = (self.y + otherBall.y) / 2; newBall.velocityX = (self.velocityX + otherBall.velocityX) / 2; newBall.velocityY = (self.velocityY + otherBall.velocityY) / 2; newBall.mergeTimer = 10; // Add merge animation - scale and pulse effect newBall.scaleX = 0.2; // Start very small newBall.scaleY = 0.2; // Start very small newBall.alpha = 0.7; // Start semi-transparent tween(newBall, { scaleX: 1.3, scaleY: 1.3, alpha: 1 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { // Pulse back to normal size tween(newBall, { scaleX: 1, scaleY: 1 }, { duration: 150, easing: tween.easeInOut }); } }); // Animate merging balls with shrink and fade tween(self, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 250, easing: tween.easeIn }); tween(otherBall, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 250, easing: tween.easeIn }); balls.push(newBall); gameArea.addChild(newBall); // Mark for removal self.hasBeenMerged = true; otherBall.hasBeenMerged = true; LK.getSound('merge').play(); if (scoringActive) { LK.setScore(LK.getScore() + 1); scoreText.setText(LK.getScore()); } // No win condition - game continues even after reaching 2048 return; } } // Enhanced collision response for better stacking var relativeVelX = self.velocityX - otherBall.velocityX; var relativeVelY = self.velocityY - otherBall.velocityY; var relativeSpeed = relativeVelX * normalX + relativeVelY * normalY; if (relativeSpeed > 0) { // Calculate mass-based collision response (assume equal mass) var restitution = 0.3; // Lower restitution for more stable stacking var impulse = (1 + restitution) * relativeSpeed * 0.5; self.velocityX -= impulse * normalX; self.velocityY -= impulse * normalY; otherBall.velocityX += impulse * normalX; otherBall.velocityY += impulse * normalY; // Apply different friction based on collision angle var collisionAngle = Math.atan2(normalY, normalX); var frictionFactor = Math.abs(Math.sin(collisionAngle)) * 0.8 + 0.2; self.velocityX *= self.friction * frictionFactor; self.velocityY *= self.friction * frictionFactor; otherBall.velocityX *= otherBall.friction * frictionFactor; otherBall.velocityY *= otherBall.friction * frictionFactor; // Enhanced static detection for stacking if (Math.abs(self.velocityY) < 0.5 && Math.abs(self.velocityX) < 0.5) { // Check if ball is supported (has another ball below it or touching ground) var supportFound = false; var localBottom = gameAreaHeight - 20; // Check ground support if (self.y + self.radius >= localBottom - 5) { supportFound = true; } else { // Check support from other balls for (var j = 0; j < balls.length; j++) { var supportBall = balls[j]; if (supportBall === self || supportBall.hasBeenMerged) continue; var supportDx = supportBall.x - self.x; var supportDy = supportBall.y - self.y; var supportDistance = Math.sqrt(supportDx * supportDx + supportDy * supportDy); // Check if this ball is resting on another ball (other ball is below) if (supportDistance < (self.radius + supportBall.radius) * 1.1 && supportDy > 0) { supportFound = true; break; } } } if (supportFound) { self.isStatic = true; self.velocityX = 0; self.velocityY = 0; } } } } collisionOccurred = true; break; } } } // If no collision occurred, move to intended position if (!collisionOccurred) { self.x = newX; self.y = newY; } // Boundary collisions after position update var localWidth = gameAreaRight - gameAreaLeft; var localBottom = gameAreaHeight - 20; // gameAreaHeight minus bottom wall height // Ground collision if (self.y + self.radius > localBottom) { self.y = localBottom - self.radius; self.velocityY *= -self.bounce; self.velocityX *= self.friction; if (Math.abs(self.velocityY) < 1) { self.velocityY = 0; self.isStatic = true; } } // Side walls collision if (self.x - self.radius < 0) { self.x = self.radius; self.velocityX *= -self.bounce; } if (self.x + self.radius > localWidth) { self.x = localWidth - self.radius; self.velocityX *= -self.bounce; } } // Enhanced merge detection pass - check for nearby same-numbered balls for (var i = 0; i < balls.length; i++) { var otherBall = balls[i]; if (otherBall === self || otherBall.hasBeenMerged || otherBall.mergeTimer > 0 || self.mergeTimer > 0) continue; var dx = otherBall.x - self.x; var dy = otherBall.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); var minDistance = self.radius + otherBall.radius; // Enhanced merge sensitivity for same-numbered balls if (self.value === otherBall.value) { var mergeTriggerDistance = minDistance * 1.3; // 30% more sensitive if (distance < mergeTriggerDistance) { // Special case: when two 2048 balls merge, they explode and disappear if (self.value === 2048) { // Create explosion effect for both 2048 balls tween(self, { scaleX: 3.0, scaleY: 3.0, alpha: 0 }, { duration: 600, easing: tween.easeOut }); tween(otherBall, { scaleX: 3.0, scaleY: 3.0, alpha: 0 }, { duration: 600, easing: tween.easeOut }); // Mark both balls for removal self.hasBeenMerged = true; otherBall.hasBeenMerged = true; LK.getSound('merge').play(); if (scoringActive) { LK.setScore(LK.getScore() + 1); scoreText.setText(LK.getScore()); } return; } var newValue = self.value * 2; if (newValue <= 2048) { var newBall = new Ball(newValue); newBall.x = (self.x + otherBall.x) / 2; newBall.y = (self.y + otherBall.y) / 2; newBall.velocityX = (self.velocityX + otherBall.velocityX) / 2; newBall.velocityY = (self.velocityY + otherBall.velocityY) / 2; newBall.mergeTimer = 10; // Add merge animation - scale and pulse effect newBall.scaleX = 0.2; // Start very small newBall.scaleY = 0.2; // Start very small newBall.alpha = 0.7; // Start semi-transparent tween(newBall, { scaleX: 1.3, scaleY: 1.3, alpha: 1 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { // Pulse back to normal size tween(newBall, { scaleX: 1, scaleY: 1 }, { duration: 150, easing: tween.easeInOut }); } }); // Animate merging balls with shrink and fade tween(self, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 250, easing: tween.easeIn }); tween(otherBall, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 250, easing: tween.easeIn }); balls.push(newBall); gameArea.addChild(newBall); // Mark for removal self.hasBeenMerged = true; otherBall.hasBeenMerged = true; LK.getSound('merge').play(); if (scoringActive) { LK.setScore(LK.getScore() + 1); scoreText.setText(LK.getScore()); } // No win condition - game continues even after reaching 2048 return; } } } // Enhanced separation for stable stacking if (distance < minDistance && distance > 0) { var overlap = minDistance - distance; var normalX = dx / distance; var normalY = dy / distance; // Different separation strategies based on ball positions var separationForce = overlap * 0.5; // If one ball is static and the other is moving, adjust separation if (self.isStatic && !otherBall.isStatic) { // Static ball moves less self.x -= normalX * separationForce * 0.2; self.y -= normalY * separationForce * 0.2; otherBall.x += normalX * separationForce * 0.8; otherBall.y += normalY * separationForce * 0.8; } else if (!self.isStatic && otherBall.isStatic) { // Other ball is static self.x -= normalX * separationForce * 0.8; self.y -= normalY * separationForce * 0.8; otherBall.x += normalX * separationForce * 0.2; otherBall.y += normalY * separationForce * 0.2; } else { // Both moving or both static - equal separation self.x -= normalX * separationForce; self.y -= normalY * separationForce; otherBall.x += normalX * separationForce; otherBall.y += normalY * separationForce; } // Ensure balls stay within bounds after separation var localWidth = gameAreaRight - gameAreaLeft; var localBottom = gameAreaHeight - 20; // gameAreaHeight minus bottom wall height self.x = Math.max(self.radius, Math.min(localWidth - self.radius, self.x)); self.y = Math.max(self.radius, Math.min(localBottom - self.radius, self.y)); // Re-check static state after separation if (self.isStatic && (Math.abs(self.x - (self.x - normalX * separationForce)) > 1 || Math.abs(self.y - (self.y - normalY * separationForce)) > 1)) { self.isStatic = false; // Ball was moved significantly, make it dynamic again } } } // Periodic re-evaluation of static state for better stacking if (LK.ticks % 10 === 0 && !self.hasBeenMerged) { // Check every 10 frames if (!self.isStatic && Math.abs(self.velocityX) < 0.3 && Math.abs(self.velocityY) < 0.3) { // Check if ball should become static var supportFound = false; var localBottom = gameAreaHeight - 20; // Check ground support if (self.y + self.radius >= localBottom - 2) { supportFound = true; } else { // Check support from other static balls for (var k = 0; k < balls.length; k++) { var checkBall = balls[k]; if (checkBall === self || checkBall.hasBeenMerged || !checkBall.isStatic) continue; var checkDx = checkBall.x - self.x; var checkDy = checkBall.y - self.y; var checkDistance = Math.sqrt(checkDx * checkDx + checkDy * checkDy); // Ball is resting on another static ball if (checkDistance < (self.radius + checkBall.radius) * 1.05 && checkDy > 0) { supportFound = true; break; } } } if (supportFound) { self.isStatic = true; self.velocityX = 0; self.velocityY = 0; } } else if (self.isStatic) { // Check if static ball should become dynamic (lost support) var stillSupported = false; var localBottom = gameAreaHeight - 20; // Check ground support if (self.y + self.radius >= localBottom - 2) { stillSupported = true; } else { // Check support from other balls for (var k = 0; k < balls.length; k++) { var supportBall = balls[k]; if (supportBall === self || supportBall.hasBeenMerged) continue; var supportDx = supportBall.x - self.x; var supportDy = supportBall.y - self.y; var supportDistance = Math.sqrt(supportDx * supportDx + supportDy * supportDy); if (supportDistance < (self.radius + supportBall.radius) * 1.05 && supportDy > 0) { stillSupported = true; break; } } } if (!stillSupported) { self.isStatic = false; // Ball lost support, make it fall } } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xf5f5dc }); /**** * Game Code ****/ var balls = []; var nextBallValue = 2; var gameAreaLeft = 0; var gameAreaRight = 2048; var gameAreaTop = 0; var gameAreaBottom = 2732; var dropCooldown = 0; var gameAreaHeight = gameAreaBottom - gameAreaTop; var dangerZoneImmunity = 300; // 5 seconds at 60fps var scoringActive = false; // Flag to track when scoring should be active // Create game area background var gameAreaBg = game.addChild(LK.getAsset('gameArea', { anchorX: 0.5, anchorY: 0, x: 1024, y: gameAreaTop })); // Create game area container for balls var gameArea = new Container(); gameArea.x = gameAreaLeft; gameArea.y = gameAreaTop; game.addChild(gameArea); // Create visible walls var leftWall = game.addChild(LK.getAsset('leftWall', { anchorX: 1, anchorY: 0, x: gameAreaLeft, y: gameAreaTop })); var rightWall = game.addChild(LK.getAsset('rightWall', { anchorX: 0, anchorY: 0, x: gameAreaRight, y: gameAreaTop })); var bottomWall = game.addChild(LK.getAsset('bottomWall', { anchorX: 0.5, anchorY: 0, x: 1024, y: gameAreaBottom })); // Create danger zone line (visible red line showing danger threshold) var dangerZoneLine = game.addChild(LK.getAsset('gameOverLine', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: gameAreaTop + 350, alpha: 0.8, visible: true })); // Create score display var scoreText = new Text2('0', { size: 100, fill: 0xFFFFFF }); scoreText.anchor.set(1, 0); LK.gui.topRight.addChild(scoreText); scoreText.x = -50; // Small offset from right edge scoreText.y = 100; // Create next ball preview var nextBallPreview = LK.getAsset('ball' + nextBallValue, { anchorX: 0.5, anchorY: 1.0, x: 1024, y: gameAreaTop + 350, scaleX: 1.4, scaleY: 1.4 }); game.addChild(nextBallPreview); // Create next ball value text var nextBallText = new Text2(nextBallValue.toString(), { size: 48, fill: 0xFFFFFF }); nextBallText.anchor.set(0.5, 0.5); nextBallText.x = 1024; nextBallText.y = gameAreaTop + 200; game.addChild(nextBallText); function getRandomNextBallValue() { var values = [2, 4, 8]; return values[Math.floor(Math.random() * values.length)]; } function updateNextBallPreview() { game.removeChild(nextBallPreview); game.removeChild(nextBallText); nextBallPreview = LK.getAsset('ball' + nextBallValue, { anchorX: 0.5, anchorY: 1.0, x: 1024, y: gameAreaTop + 350, scaleX: 1.4, scaleY: 1.4 }); game.addChild(nextBallPreview); nextBallText = new Text2(nextBallValue.toString(), { size: 48, fill: 0xFFFFFF }); nextBallText.anchor.set(0.5, 0.5); nextBallText.x = 1024; nextBallText.y = gameAreaTop + 200; game.addChild(nextBallText); } function checkGameOver() { // Skip game over check during immunity period if (dangerZoneImmunity > 0) return; for (var i = 0; i < balls.length; i++) { // Check if ball touches the danger zone (first 350 pixels of game area) // Since balls are in gameArea container, we use local coordinates // Only trigger game over if ball is static (not actively falling) and in danger zone if (balls[i].y - balls[i].radius <= 350 && balls[i].isStatic) { LK.showGameOver(); return; } } } function cleanupMergedBalls() { for (var i = balls.length - 1; i >= 0; i--) { if (balls[i].hasBeenMerged) { gameArea.removeChild(balls[i]); balls[i].destroy(); balls.splice(i, 1); } } } // Create initial balls to fill container to the top function createInitialBalls() { var localWidth = gameAreaRight - gameAreaLeft; var ballsPerRow = Math.floor(localWidth / 40); // Space balls 40px apart for tighter spacing var startX = (localWidth - (ballsPerRow - 1) * 40) / 2; // Center the row for (var row = 0; row < 18; row++) { for (var col = 0; col < ballsPerRow; col++) { var initialBall = new Ball(getRandomNextBallValue()); initialBall.x = startX + col * 40; initialBall.y = gameAreaHeight - 100 - row * 40; // Start from bottom, 40px spacing initialBall.velocityX = 0; initialBall.velocityY = 0; initialBall.isStatic = true; // Start as static for stable stacking balls.push(initialBall); gameArea.addChild(initialBall); } } } // Initialize the starting balls createInitialBalls(); game.down = function (x, y, obj) { if (dropCooldown > 0) return; // Activate scoring system when first ball is dropped if (!scoringActive) { scoringActive = true; } // Constrain drop position to game area (convert to local coordinates) var localWidth = gameAreaRight - gameAreaLeft; var localX = x - gameAreaLeft; var dropX = Math.max(80, Math.min(localWidth - 80, localX)); var newBall = new Ball(nextBallValue); newBall.x = dropX; newBall.y = 420; // Start below the danger zone (350px) plus ball radius (60px) plus buffer newBall.velocityX = 0; newBall.velocityY = 0; balls.push(newBall); gameArea.addChild(newBall); LK.getSound('drop').play(); // Update next ball nextBallValue = getRandomNextBallValue(); updateNextBallPreview(); dropCooldown = 30; // 0.5 seconds at 60fps }; game.update = function () { if (dropCooldown > 0) { dropCooldown--; } // Handle danger zone immunity countdown if (dangerZoneImmunity > 0) { dangerZoneImmunity--; } cleanupMergedBalls(); checkGameOver(); // Update score display scoreText.setText(LK.getScore()); };
===================================================================
--- original.js
+++ change.js
@@ -10,24 +10,24 @@
var self = Container.call(this);
self.value = value || 2;
self.velocityX = 0;
self.velocityY = 0;
- self.gravity = 0.3;
- self.bounce = 0.2;
- self.friction = 0.95;
+ self.gravity = 0.8;
+ self.bounce = 0.4;
+ self.friction = 0.98;
// Set radius based on ball value for proper physics
var radiusMap = {
- 2: 120,
- 4: 125,
- 8: 135,
- 16: 145,
- 32: 155,
- 64: 165,
- 128: 175,
- 256: 185,
- 512: 195,
- 1024: 200,
- 2048: 210
+ 2: 140,
+ 4: 145,
+ 8: 155,
+ 16: 165,
+ 32: 175,
+ 64: 185,
+ 128: 195,
+ 256: 205,
+ 512: 215,
+ 1024: 220,
+ 2048: 230
};
self.radius = radiusMap[self.value] || 60;
self.isStatic = false;
self.mergeTimer = 0;
@@ -79,17 +79,12 @@
// Check each step along the movement path
for (var step = 1; step <= stepCount && !collisionOccurred; step++) {
var testX = self.x + stepX * step;
var testY = self.y + stepY * step;
- // Optimize collision detection - skip distant balls
+ // Test collision with other balls
for (var i = 0; i < balls.length; i++) {
var otherBall = balls[i];
if (otherBall === self || otherBall.hasBeenMerged || otherBall.mergeTimer > 0) continue;
- // Skip collision check if balls are too far apart (optimization)
- var quickDx = Math.abs(otherBall.x - testX);
- var quickDy = Math.abs(otherBall.y - testY);
- var maxRadius = Math.max(self.radius, otherBall.radius);
- if (quickDx > maxRadius * 3 || quickDy > maxRadius * 3) continue;
var dx = otherBall.x - testX;
var dy = otherBall.y - testY;
var distance = Math.sqrt(dx * dx + dy * dy);
var minDistance = self.radius + otherBall.radius;
@@ -213,9 +208,9 @@
self.velocityY *= self.friction * frictionFactor;
otherBall.velocityX *= otherBall.friction * frictionFactor;
otherBall.velocityY *= otherBall.friction * frictionFactor;
// Enhanced static detection for stacking
- if (Math.abs(self.velocityY) < 1.5 && Math.abs(self.velocityX) < 1.5) {
+ if (Math.abs(self.velocityY) < 0.5 && Math.abs(self.velocityX) < 0.5) {
// Check if ball is supported (has another ball below it or touching ground)
var supportFound = false;
var localBottom = gameAreaHeight - 20;
// Check ground support
@@ -261,9 +256,9 @@
if (self.y + self.radius > localBottom) {
self.y = localBottom - self.radius;
self.velocityY *= -self.bounce;
self.velocityX *= self.friction;
- if (Math.abs(self.velocityY) < 2) {
+ if (Math.abs(self.velocityY) < 1) {
self.velocityY = 0;
self.isStatic = true;
}
}
@@ -276,16 +271,12 @@
self.x = localWidth - self.radius;
self.velocityX *= -self.bounce;
}
}
- // Enhanced merge detection pass - check for nearby same-numbered balls with optimization
+ // Enhanced merge detection pass - check for nearby same-numbered balls
for (var i = 0; i < balls.length; i++) {
var otherBall = balls[i];
if (otherBall === self || otherBall.hasBeenMerged || otherBall.mergeTimer > 0 || self.mergeTimer > 0) continue;
- // Pre-screen with quick distance check
- var quickDx = Math.abs(otherBall.x - self.x);
- var quickDy = Math.abs(otherBall.y - self.y);
- if (quickDx > 200 || quickDy > 200) continue; // Skip if clearly too far
var dx = otherBall.x - self.x;
var dy = otherBall.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var minDistance = self.radius + otherBall.radius;
@@ -424,9 +415,9 @@
}
// Periodic re-evaluation of static state for better stacking
if (LK.ticks % 10 === 0 && !self.hasBeenMerged) {
// Check every 10 frames
- if (!self.isStatic && Math.abs(self.velocityX) < 1.0 && Math.abs(self.velocityY) < 1.0) {
+ if (!self.isStatic && Math.abs(self.velocityX) < 0.3 && Math.abs(self.velocityY) < 0.3) {
// Check if ball should become static
var supportFound = false;
var localBottom = gameAreaHeight - 20;
// Check ground support
@@ -573,38 +564,28 @@
function getRandomNextBallValue() {
var values = [2, 4, 8];
return values[Math.floor(Math.random() * values.length)];
}
-// Asset pool for next ball previews to reduce memory allocation
-var previewAssetPool = {};
-function initializePreviewAssets() {
- var values = [2, 4, 8];
- for (var i = 0; i < values.length; i++) {
- var value = values[i];
- previewAssetPool[value] = LK.getAsset('ball' + value, {
- anchorX: 0.5,
- anchorY: 1.0,
- scaleX: 1.4,
- scaleY: 1.4,
- visible: false
- });
- game.addChild(previewAssetPool[value]);
- }
-}
function updateNextBallPreview() {
- // Hide current preview
- if (nextBallPreview) {
- nextBallPreview.visible = false;
- }
- // Show new preview from pool
- nextBallPreview = previewAssetPool[nextBallValue];
- if (nextBallPreview) {
- nextBallPreview.x = 1024;
- nextBallPreview.y = gameAreaTop + 350;
- nextBallPreview.visible = true;
- }
- // Update text
- nextBallText.setText(nextBallValue.toString());
+ game.removeChild(nextBallPreview);
+ game.removeChild(nextBallText);
+ nextBallPreview = LK.getAsset('ball' + nextBallValue, {
+ anchorX: 0.5,
+ anchorY: 1.0,
+ x: 1024,
+ y: gameAreaTop + 350,
+ scaleX: 1.4,
+ scaleY: 1.4
+ });
+ game.addChild(nextBallPreview);
+ nextBallText = new Text2(nextBallValue.toString(), {
+ size: 48,
+ fill: 0xFFFFFF
+ });
+ nextBallText.anchor.set(0.5, 0.5);
+ nextBallText.x = 1024;
+ nextBallText.y = gameAreaTop + 200;
+ game.addChild(nextBallText);
}
function checkGameOver() {
// Skip game over check during immunity period
if (dangerZoneImmunity > 0) return;
@@ -620,36 +601,14 @@
}
function cleanupMergedBalls() {
for (var i = balls.length - 1; i >= 0; i--) {
if (balls[i].hasBeenMerged) {
- // Force stop any active tweens before cleanup
- tween.stop(balls[i]);
gameArea.removeChild(balls[i]);
balls[i].destroy();
balls.splice(i, 1);
}
}
}
-// Add memory monitoring variables
-var ballCountCheck = 0;
-var maxBallsAllowed = 100;
-function performMemoryCheck() {
- ballCountCheck++;
- if (ballCountCheck % 300 === 0) {
- // Check every 5 seconds
- if (balls.length > maxBallsAllowed) {
- // Emergency cleanup of oldest static balls
- var staticBalls = balls.filter(function (ball) {
- return ball.isStatic && !ball.hasBeenMerged;
- });
- if (staticBalls.length > 50) {
- for (var i = 0; i < 10 && i < staticBalls.length; i++) {
- staticBalls[i].hasBeenMerged = true;
- }
- }
- }
- }
-}
// Create initial balls to fill container to the top
function createInitialBalls() {
var localWidth = gameAreaRight - gameAreaLeft;
var ballsPerRow = Math.floor(localWidth / 40); // Space balls 40px apart for tighter spacing
@@ -668,10 +627,8 @@
}
}
// Initialize the starting balls
createInitialBalls();
-// Initialize preview asset pool for memory optimization
-initializePreviewAssets();
game.down = function (x, y, obj) {
if (dropCooldown > 0) return;
// Activate scoring system when first ball is dropped
if (!scoringActive) {
@@ -702,12 +659,8 @@
if (dangerZoneImmunity > 0) {
dangerZoneImmunity--;
}
cleanupMergedBalls();
- performMemoryCheck();
checkGameOver();
- // Update score display only when changed (optimization)
- var currentScore = LK.getScore();
- if (scoreText.text !== currentScore.toString()) {
- scoreText.setText(currentScore);
- }
+ // Update score display
+ scoreText.setText(LK.getScore());
};
\ No newline at end of file
Koyu yeşil bilye. In-Game asset. 2d. High contrast. No shadows
Kahverengi bilye. In-Game asset. 2d. High contrast. No shadows
Bprdo renk bilye. In-Game asset. 2d. High contrast. No shadows
Açık kahve bilye. In-Game asset. 2d. High contrast. No shadows
Gri bilye. In-Game asset. 2d. High contrast. No shadows