User prompt
oyunda bazen siyah top çıkıyor. bunu istemiyorum. ancak oyuna bir kaç özel top ekleyelim. bunlardan birincisi beyaz top olsun. atıldığında tüm zinciri 2 saniye boyunca durdursun. ve sayım ekranda çıksın. siyah top ekleyelim. bu da atıldığında zincire değerse, yanındaki 5 topu yok etsin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
toplar, rotanın sonuna doğru birbirine giriyor. bunu istemiyorum
User prompt
zincirin hızı oyun boyunca sadece normal,hızlı ve en hızlı tuşuna basınca değişsin.
User prompt
oyunun normal hızını biraz daha yavaş yapalım. hızlı olan kısmını da yavaşlatalım. en hızlı modu da yavaşlatalım
User prompt
arka plan dinamik uzay görüntüsü olsun. arka plandaki renkli kareleri istemiyorum. 10 saniyede bir arka planda yıldız kaysın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
daha gerçekçi uzay olsun.
User prompt
oyunun arka planı uzay olsun.
User prompt
normal speed can be decrease
User prompt
The score system should be 1x for normal, 1.5x for fast and 2x for very fast. The points received will flash on the screen during the reading period. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
the normal game speed can be faster
User prompt
normal, fast and very fast speed increase
User prompt
The acceleration button works, but let's modify it. There are 3 levels of speed in the game: normal, fast and very fast. And let these work on a single button. If I press it once, it's fast. If I press it again, it's very fast. If I press it again, it goes back to normal.
User prompt
First, if I put 3 balls of the same color together, they should disappear. Then, when the gap between them is closed, the balls of the same color should touch each other and then disappear. Yes, these things happened, but what I wanted was the disappearance animation in order. First, when the balls of the same color come together, there will be an explosion effect, then when the gap closes, the balls of the same color that come together will disappear. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
First, if I put 3 balls of the same color together, they should disappear. Then, when the gap between them is closed, the balls of the same color should touch each other and then disappear.
User prompt
Yes, it disappears when you hit balls of the same color. However, when the gap in the chain is closed and the same colors appear side by side in front and behind, the balls should disappear. this happened. However, the balls should disappear when they touch each other.
User prompt
Yes, it disappears when you hit balls of the same color. However, when the gap in the chain is closed and the same colors appear side by side in front and behind, the balls should disappear.
User prompt
when i press the accelerate nothing happen. chain will not faster
User prompt
Add a clickable button to the game. When you press this button, the chain accelerates. Press again and it will return to its previous speed.
User prompt
the balls overlapping when comes near tyhe hole
User prompt
The balls are still overlapping each other as they move towards the hole.
User prompt
the hole position shoulde be near the shooter
User prompt
The route should not contact the shooter
User prompt
The route does not currently go to the hole. let's fix this. The end of the route must end at the hole. but there should be a longer route
User prompt
The route may be slightly longer. but the balls are still intertwined. In this case, there should be equal space between them and the balls should touch each other but not be intertwined.
User prompt
the route follows a single path towards the hole in a swirling pattern
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Ball = Container.expand(function (color) {
var self = Container.call(this);
self.color = color;
self.ballColors = ['red', 'blue', 'green', 'yellow', 'purple', 'orange'];
self.isSpecial = false;
self.specialType = null; // 'explosive', 'freeze', 'rapid'
var ballGraphics = self.attachAsset('ball_' + color, {
anchorX: 0.5,
anchorY: 0.5
});
// 5% chance for special balls
if (Math.random() < 0.05) {
// Start pulsing animation
var _pulseEffect = function pulseEffect() {
tween(ballGraphics, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(ballGraphics, {
scaleX: 1.15,
scaleY: 1.15
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: _pulseEffect
});
}
});
};
self.isSpecial = true;
var specials = ['explosive', 'freeze', 'rapid'];
self.specialType = specials[Math.floor(Math.random() * specials.length)];
ballGraphics.alpha = 0.9;
// Add glow effect for special balls
ballGraphics.scaleX = 1.15;
ballGraphics.scaleY = 1.15;
// Add pulsing effect
if (self.specialType === 'explosive') {
ballGraphics.tint = 0xFF4500;
} else if (self.specialType === 'freeze') {
ballGraphics.tint = 0x00FFFF;
} else if (self.specialType === 'rapid') {
ballGraphics.tint = 0xFFFF00;
}
_pulseEffect();
}
self.trackPosition = 0;
self.trackX = 0;
self.trackY = 0;
self.isMoving = false;
return self;
});
var ChainBall = Ball.expand(function (color) {
var self = Ball.call(this, color);
self.chainIndex = 0;
self.targetX = 0;
self.targetY = 0;
self.update = function () {
if (self.isMoving) {
// Smooth movement towards target position
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
self.x += dx * 0.3;
self.y += dy * 0.3;
if (Math.abs(dx) < 1 && Math.abs(dy) < 1) {
self.isMoving = false;
self.x = self.targetX;
self.y = self.targetY;
}
}
};
return self;
});
var Shooter = Container.expand(function () {
var self = Container.call(this);
var shooterGraphics = self.attachAsset('shooter', {
anchorX: 0.5,
anchorY: 0.5
});
// Add cannon barrel
var barrel = self.attachAsset('track', {
anchorX: 0,
anchorY: 0.5,
scaleX: 4,
scaleY: 1.5,
x: 0,
y: 0
});
barrel.tint = 0x333333;
self.angle = 0;
self.currentBall = null;
self.nextBall = null;
self.rapidFire = false;
self.rapidFireTimer = 0;
self.shootCooldown = 0;
self.loadBall = function () {
if (self.currentBall) {
self.currentBall.destroy();
}
self.currentBall = self.nextBall;
if (self.currentBall) {
self.currentBall.x = 0;
self.currentBall.y = -40;
self.addChild(self.currentBall);
// Add glowing effect to current ball
tween(self.currentBall, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 500,
easing: tween.easeInOut
});
// Start pulsing and shining animation
animateShooterBall();
}
// Generate next ball
var colors = ['red', 'blue', 'green', 'yellow', 'purple'];
var randomColor = colors[Math.floor(Math.random() * colors.length)];
self.nextBall = new Ball(randomColor);
};
self.aimAt = function (x, y) {
var dx = x - self.x;
var dy = y - self.y;
self.angle = Math.atan2(dy, dx);
self.rotation = self.angle;
};
self.shoot = function () {
if (self.shootCooldown > 0 || !self.currentBall) return null;
var ball = self.currentBall;
self.removeChild(ball);
// Set ball velocity
var speed = 8;
ball.vx = Math.cos(self.angle) * speed;
ball.vy = Math.sin(self.angle) * speed;
ball.x = self.x;
ball.y = self.y;
self.loadBall();
// Set cooldown
self.shootCooldown = self.rapidFire ? 10 : 20;
LK.getSound('shoot').play();
return ball;
};
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
if (self.rapidFire) {
self.rapidFireTimer--;
if (self.rapidFireTimer <= 0) {
self.rapidFire = false;
// Remove glow effect
tween.stop(self, {
tint: true
});
self.tint = 0xFFFFFF;
} else {
// Maintain glow effect
if (self.tint === 0xFFFFFF) {
tween(self, {
tint: 0xFFFF88
}, {
duration: 200,
easing: tween.easeInOut
});
}
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0a0a1a
});
/****
* Game Code
****/
// Create realistic space background with multiple cosmic elements
function createSpaceBackground() {
// Create distant galaxies as background elements
for (var i = 0; i < 4; i++) {
var galaxy = game.addChild(LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 8 + Math.random() * 6,
scaleY: 6 + Math.random() * 4
}));
galaxy.x = Math.random() * 2048;
galaxy.y = Math.random() * 2732;
galaxy.alpha = 0.02 + Math.random() * 0.03;
galaxy.tint = 0x9370DB;
galaxy.rotation = Math.random() * Math.PI * 2;
}
// Create complex starfield with realistic star colors and sizes
var starColors = [0xFFFFFF, 0xFFE4B5, 0xFFB347, 0x87CEEB, 0xF0F8FF, 0xFFF8DC];
var starSizes = [0.5, 0.8, 1.2, 1.8, 2.5, 3.2];
for (var layer = 0; layer < 5; layer++) {
var numStars = layer === 0 ? 200 : layer === 1 ? 150 : layer === 2 ? 100 : layer === 3 ? 60 : 30;
var baseAlpha = layer === 0 ? 0.2 : layer === 1 ? 0.4 : layer === 2 ? 0.6 : layer === 3 ? 0.8 : 1.0;
for (var i = 0; i < numStars; i++) {
var starSize = starSizes[Math.floor(Math.random() * starSizes.length)];
var star = game.addChild(LK.getAsset('track', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: starSize * 0.1,
scaleY: starSize * 0.1
}));
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
star.alpha = baseAlpha + Math.random() * 0.3;
star.tint = starColors[Math.floor(Math.random() * starColors.length)];
// Add realistic twinkling based on star size and distance
if (layer >= 2 && Math.random() < 0.4) {
var twinkleDelay = Math.random() * 3000;
LK.setTimeout(function () {
var _twinkleEffect = function twinkleEffect() {
if (star && star.parent) {
tween(star, {
alpha: star.alpha * 0.2
}, {
duration: 1000 + Math.random() * 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (star && star.parent) {
tween(star, {
alpha: baseAlpha + Math.random() * 0.3
}, {
duration: 1000 + Math.random() * 800,
easing: tween.easeInOut,
onFinish: _twinkleEffect
});
}
}
});
}
};
_twinkleEffect();
}, twinkleDelay);
}
}
}
// Add realistic planets at different distances
var planetColors = [0xFF6B47, 0x4682B4, 0xDEB887, 0x9370DB, 0xF4A460, 0x708090];
for (var i = 0; i < 3; i++) {
var planet = game.addChild(LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5 + Math.random() * 2.5,
scaleY: 1.5 + Math.random() * 2.5
}));
planet.x = Math.random() * 2048;
planet.y = Math.random() * 2732;
planet.alpha = 0.3 + Math.random() * 0.4;
planet.tint = planetColors[Math.floor(Math.random() * planetColors.length)];
}
// Create animated cosmic dust clouds
for (var i = 0; i < 12; i++) {
var dust = game.addChild(LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2 + Math.random() * 3,
scaleY: 1 + Math.random() * 2
}));
dust.x = Math.random() * 2048;
dust.y = Math.random() * 2732;
dust.alpha = 0.03 + Math.random() * 0.05;
dust.rotation = Math.random() * Math.PI * 2;
// Realistic dust cloud colors
var dustColors = [0x4B0082, 0x800080, 0x8B008B, 0x9400D3, 0x1E90FF, 0x00CED1, 0x483D8B];
dust.tint = dustColors[Math.floor(Math.random() * dustColors.length)];
// Add slow rotation animation
var rotationSpeed = (Math.random() - 0.5) * 0.001;
var dustRotation = dust.rotation;
var _dustRotate = function dustRotate() {
if (dust && dust.parent) {
dustRotation += rotationSpeed;
dust.rotation = dustRotation;
LK.setTimeout(_dustRotate, 50);
}
};
_dustRotate();
}
// Add some brighter nebula formations
for (var i = 0; i < 6; i++) {
var nebula = game.addChild(LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4 + Math.random() * 5,
scaleY: 3 + Math.random() * 4
}));
nebula.x = Math.random() * 2048;
nebula.y = Math.random() * 2732;
nebula.alpha = 0.08 + Math.random() * 0.12;
nebula.rotation = Math.random() * Math.PI * 2;
// More vibrant nebula colors
var nebulaColors = [0xFF1493, 0x00FA9A, 0xFF4500, 0x9370DB, 0x00CED1, 0xFF69B4];
nebula.tint = nebulaColors[Math.floor(Math.random() * nebulaColors.length)];
// Add gentle pulsing effect
var pulseDelay = Math.random() * 4000;
LK.setTimeout(function () {
var _nebulaEffect = function nebulaEffect() {
if (nebula && nebula.parent) {
tween(nebula, {
alpha: nebula.alpha * 0.5,
scaleX: nebula.scaleX * 1.1,
scaleY: nebula.scaleY * 1.1
}, {
duration: 2000 + Math.random() * 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (nebula && nebula.parent) {
tween(nebula, {
alpha: 0.08 + Math.random() * 0.12,
scaleX: 4 + Math.random() * 5,
scaleY: 3 + Math.random() * 4
}, {
duration: 2000 + Math.random() * 1000,
easing: tween.easeInOut,
onFinish: _nebulaEffect
});
}
}
});
}
};
_nebulaEffect();
}, pulseDelay);
}
}
// Initialize space background
createSpaceBackground();
// Game variables
var chain = [];
var flyingBalls = [];
var shooter;
var trackPoints = [];
var chainSpeed = 0.0005; // Decreased normal chain speed
var normalChainSpeed = 0.0005; // Store normal speed
var fastChainSpeed = 0.004; // Fast chain speed - 4x faster
var veryFastChainSpeed = 0.01; // Very fast chain speed - 10x faster
var speedLevel = 0; // 0 = normal, 1 = fast, 2 = very fast
var chainFrozen = false;
var freezeTimer = 0;
var level = 1;
var gameWon = false;
var gameLost = false;
// Score multiplier system
var scoreMultipliers = [1.0, 1.5, 2.0]; // normal, fast, very fast
var pointsDisplays = []; // Array to track active point displays
// Create vortex track path
function createTrackPath() {
trackPoints = [];
var centerX = 1024;
var centerY = 1366;
var holeX = 1024;
var holeY = 1200; // Hole position - closer to shooter
var segments = 1500; // Longer track for better gameplay
// Create single swirling path towards the hole - starts from outside and spirals inward in one continuous motion
for (var i = 0; i < segments; i++) {
var progress = i / segments;
// Single spiral angle - creates one continuous swirl towards center
var spiralAngle = progress * Math.PI * 6; // 3 full rotations for longer swirling path
// Radius decreases linearly for smooth inward movement
var baseRadius = 1000 * (1 - progress); // Linear decrease for steady approach to center
// Add gentle wave motion for swirling effect
var waveMotion = Math.sin(progress * Math.PI * 12) * (60 * (1 - progress)); // Gentle swirling motion
var currentRadius = baseRadius + waveMotion;
// Ensure minimum radius for playability at center
currentRadius = Math.max(currentRadius, 40);
// Calculate position on spiral path - interpolate towards hole position
var spiralX = centerX + Math.cos(spiralAngle) * currentRadius;
var spiralY = centerY + Math.sin(spiralAngle) * currentRadius;
// Gradually move towards hole position in final segment
var holeProgress = Math.max(0, (progress - 0.9) / 0.1); // Last 10% of track moves to hole
var x = spiralX + (holeX - spiralX) * holeProgress;
var y = spiralY + (holeY - spiralY) * holeProgress;
// Ensure the path stays within screen bounds with padding
x = Math.max(150, Math.min(1898, x));
y = Math.max(300, Math.min(2600, y));
trackPoints.push({
x: x,
y: y
});
}
// Create visual track markers with vortex effect
for (var i = 0; i < trackPoints.length; i += 6) {
var trackMarker = game.addChild(LK.getAsset('track', {
anchorX: 0.5,
anchorY: 0.5
}));
trackMarker.x = trackPoints[i].x;
trackMarker.y = trackPoints[i].y;
trackMarker.alpha = 0.3 + i / trackPoints.length * 0.3; // Fade in towards center
// Scale markers smaller as they approach center for vortex effect
var scaleProgress = i / trackPoints.length;
trackMarker.scaleX = 0.5 + (1 - scaleProgress) * 0.5;
trackMarker.scaleY = 0.5 + (1 - scaleProgress) * 0.5;
}
}
// Create hole at end of track
var hole = game.addChild(LK.getAsset('hole', {
anchorX: 0.5,
anchorY: 0.5
}));
// Create shooter
shooter = game.addChild(new Shooter());
shooter.x = 1024; // Center of screen horizontally (2048/2 = 1024)
shooter.y = 1366; // Position near the center hole
// Initialize first balls
shooter.loadBall();
shooter.loadBall();
// Create initial chain
function createChain() {
chain = [];
var chainLength = 15 + level * 5;
var colors = ['red', 'blue', 'green', 'yellow', 'purple'];
var ballSpacing = 50; // Space between balls - balls touch each other
var trackSpacing = 5.0; // Increased track position spacing to prevent overlap
// Ensure better color distribution by cycling through colors
for (var i = 0; i < chainLength; i++) {
// Use a mix of sequential and random distribution
var colorIndex;
if (i % 8 < 5) {
// First 5 of every 8 balls use sequential colors
colorIndex = i % colors.length;
} else {
// Last 3 of every 8 balls use random colors
colorIndex = Math.floor(Math.random() * colors.length);
}
var color = colors[colorIndex];
var ball = game.addChild(new ChainBall(color));
ball.chainIndex = i;
// Initialize track position with consistent spacing for vortex
ball.trackPosition = i * 7.0; // Use consistent spacing to prevent overlap
// Position ball immediately on track
positionBallOnTrack(ball, ball.trackPosition);
chain.push(ball);
}
}
// Position ball on track
function positionBallOnTrack(ball, trackPosition) {
if (trackPosition >= trackPoints.length || trackPoints.length === 0) {
if (trackPoints.length > 0) {
ball.x = trackPoints[trackPoints.length - 1].x;
ball.y = trackPoints[trackPoints.length - 1].y;
} else {
ball.x = 1024;
ball.y = 1366;
}
return;
}
var pointIndex = Math.floor(Math.max(0, trackPosition));
var nextIndex = Math.min(pointIndex + 1, trackPoints.length - 1);
var t = trackPosition - pointIndex;
var point1 = trackPoints[pointIndex];
var point2 = trackPoints[nextIndex];
// Add safety check for undefined points
if (!point1 || !point2) {
ball.x = 1024;
ball.y = 1366;
ball.isMoving = false;
return;
}
// Calculate position with anti-overlap adjustment near the hole
var baseX = point1.x + (point2.x - point1.x) * t;
var baseY = point1.y + (point2.y - point1.y) * t;
// Apply spacing adjustment to prevent overlap near hole
var progressToHole = trackPosition / trackPoints.length;
if (progressToHole > 0.8) {
// Near the hole (last 20% of track)
// Add slight offset based on ball's chain position to prevent stacking
var offsetAngle = ball.chainIndex * 0.3; // Small angular offset per ball
var offsetRadius = 15 * (progressToHole - 0.8) * 5; // Increase offset near hole
baseX += Math.cos(offsetAngle) * offsetRadius;
baseY += Math.sin(offsetAngle) * offsetRadius;
}
ball.targetX = baseX;
ball.targetY = baseY;
ball.isMoving = true;
}
// Update chain positions
function updateChain() {
if (chainFrozen) {
freezeTimer--;
if (freezeTimer <= 0) {
chainFrozen = false;
// Remove ice tint from all chain balls
for (var i = 0; i < chain.length; i++) {
var chainBall = chain[i];
tween(chainBall, {
tint: 0xFFFFFF
}, {
duration: 300
});
}
}
return;
}
// Move all balls forward and maintain equal spacing for vortex
var trackSpacing = 7.0; // Increased spacing to prevent overlap, especially near hole
for (var i = 0; i < chain.length; i++) {
var ball = chain[i];
// Move chain forward in vortex pattern
ball.trackPosition += chainSpeed;
// Check if reached hole (vortex center)
if (ball.trackPosition >= trackPoints.length - 1) {
gameLost = true;
LK.showGameOver();
return;
}
}
// Maintain equal spacing between balls for vortex movement
for (var i = 0; i < chain.length; i++) {
var ball = chain[i];
// Ensure proper spacing from previous ball
if (i > 0) {
var previousBall = chain[i - 1];
var expectedPosition = previousBall.trackPosition + trackSpacing;
// Enforce minimum spacing to prevent overlap
ball.trackPosition = Math.max(ball.trackPosition, expectedPosition);
}
positionBallOnTrack(ball, ball.trackPosition);
}
}
// Check for matches
function checkMatches() {
var matches = [];
var currentColor = null;
var currentMatch = [];
// First, ensure all balls are positioned correctly on the track
for (var i = 0; i < chain.length; i++) {
var ball = chain[i];
positionBallOnTrack(ball, ball.trackPosition);
}
// Check for consecutive balls of the same color
for (var i = 0; i < chain.length; i++) {
var ball = chain[i];
if (ball.color === currentColor) {
currentMatch.push(ball);
} else {
if (currentMatch.length >= 3) {
matches.push(currentMatch.slice());
}
currentColor = ball.color;
currentMatch = [ball];
}
}
// Check last group
if (currentMatch.length >= 3) {
matches.push(currentMatch.slice());
}
// Remove matches
for (var m = 0; m < matches.length; m++) {
var match = matches[m];
var baseScore = match.length * 10;
var multiplier = scoreMultipliers[speedLevel];
var score = Math.floor(baseScore * multiplier);
// Calculate display position (center of the match)
var displayX = 0;
var displayY = 0;
for (var b = 0; b < match.length; b++) {
displayX += match[b].x;
displayY += match[b].y;
}
displayX /= match.length;
displayY /= match.length;
// Display flashing points
displayPoints(score, displayX, displayY);
// Check for special balls
for (var b = 0; b < match.length; b++) {
var ball = match[b];
if (ball.isSpecial) {
handleSpecialBall(ball);
}
}
// Store the first index of the match to know where the gap starts
var firstMatchIndex = chain.indexOf(match[0]);
var trackSpacing = 7.0; // Increased spacing to prevent overlap
var gapSize = match.length * trackSpacing; // Calculate gap size based on track spacing
// Remove matched balls
for (var b = 0; b < match.length; b++) {
var ball = match[b];
var index = chain.indexOf(ball);
if (index > -1) {
chain.splice(index, 1);
ball.destroy();
}
}
// Close the gap by moving all balls after the removed section forward
for (var i = firstMatchIndex; i < chain.length; i++) {
var ball = chain[i];
// Move the ball's track position forward to close the gap
ball.trackPosition -= gapSize;
}
// Re-space all balls to maintain equal intervals after gap closing
for (var i = 1; i < chain.length; i++) {
var previousBall = chain[i - 1];
var currentBall = chain[i];
var expectedPosition = previousBall.trackPosition + trackSpacing;
// Enforce minimum spacing to prevent overlap
currentBall.trackPosition = Math.max(currentBall.trackPosition, expectedPosition);
// Position the ball immediately to detect matches faster
positionBallOnTrack(currentBall, currentBall.trackPosition);
// Animate the ball to its new position smoothly
tween(currentBall, {
x: currentBall.targetX,
y: currentBall.targetY
}, {
duration: 200,
// Faster animation for quicker match detection
easing: tween.easeOut
});
}
LK.setScore(LK.getScore() + score);
LK.getSound('match').play();
// Pull chain back slightly when balls are removed
chainSpeed = Math.max(0.5, chainSpeed - 0.1);
}
// Always check for new matches after gap closure, regardless of previous matches
// This ensures balls disappear when they touch each other after gap closure
if (matches.length > 0) {
// After removing matches and closing gaps, check for new matches that may have formed
// Use a timeout to allow animations to settle before checking
LK.setTimeout(function () {
checkMatches();
}, 50); // Reduced timeout for faster response
} else {
// Even if no matches were found initially, check again after any repositioning
// This handles cases where balls of the same color touch after repositioning
var hasRepositioned = false;
for (var i = 1; i < chain.length; i++) {
var prevBall = chain[i - 1];
var currBall = chain[i];
if (prevBall.color === currBall.color) {
// Check if these balls are close enough to be considered touching
var distance = Math.sqrt(Math.pow(currBall.x - prevBall.x, 2) + Math.pow(currBall.y - prevBall.y, 2));
if (distance < 60) {
// Balls are touching
hasRepositioned = true;
break;
}
}
}
if (hasRepositioned) {
LK.setTimeout(function () {
checkMatches();
}, 50);
}
}
// Check win condition
if (chain.length === 0) {
gameWon = true;
level++;
LK.showYouWin();
}
}
// Display flashing points
function displayPoints(points, x, y) {
var pointsText = new Text2('+' + points, {
size: 80,
fill: 0xFFFF00
});
pointsText.anchor.set(0.5, 0.5);
pointsText.x = x;
pointsText.y = y;
pointsText.alpha = 1.0;
pointsText.scaleX = 0.5;
pointsText.scaleY = 0.5;
game.addChild(pointsText);
pointsDisplays.push(pointsText);
// Animate the points display
tween(pointsText, {
scaleX: 1.2,
scaleY: 1.2,
y: y - 100
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(pointsText, {
alpha: 0,
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
pointsText.destroy();
var index = pointsDisplays.indexOf(pointsText);
if (index > -1) {
pointsDisplays.splice(index, 1);
}
}
});
}
});
}
// Handle special ball effects
function handleSpecialBall(ball) {
if (ball.specialType === 'explosive') {
var _shakeEffect = function shakeEffect() {
if (shakeTimer < shakeDuration) {
game.x = originalX + (Math.random() - 0.5) * shakeIntensity;
game.y = originalY + (Math.random() - 0.5) * shakeIntensity;
shakeTimer += 16;
LK.setTimeout(_shakeEffect, 16);
} else {
game.x = originalX;
game.y = originalY;
}
};
// Remove nearby balls
var explosionRadius = 3;
var ballIndex = chain.indexOf(ball);
var toRemove = [];
for (var i = Math.max(0, ballIndex - explosionRadius); i < Math.min(chain.length, ballIndex + explosionRadius + 1); i++) {
if (chain[i] !== ball) {
toRemove.push(chain[i]);
}
}
for (var i = 0; i < toRemove.length; i++) {
var index = chain.indexOf(toRemove[i]);
if (index > -1) {
chain.splice(index, 1);
toRemove[i].destroy();
}
}
LK.effects.flashScreen(0xff8000, 300);
// Add screen shake effect
var originalX = game.x;
var originalY = game.y;
var shakeIntensity = 10;
var shakeDuration = 300;
var shakeTimer = 0;
_shakeEffect();
} else if (ball.specialType === 'freeze') {
chainFrozen = true;
freezeTimer = 180; // 3 seconds at 60fps
LK.effects.flashScreen(0x00ffff, 500);
// Add ice tint to all chain balls
for (var i = 0; i < chain.length; i++) {
var chainBall = chain[i];
tween(chainBall, {
tint: 0x88DDFF
}, {
duration: 300
});
}
} else if (ball.specialType === 'rapid') {
shooter.rapidFire = true;
shooter.rapidFireTimer = 300; // 5 seconds at 60fps
LK.effects.flashScreen(0xffff00, 200);
}
LK.getSound('powerup').play();
}
// Insert ball into chain
function insertBallIntoChain(ball, insertIndex) {
var chainBall = new ChainBall(ball.color);
chainBall.isSpecial = ball.isSpecial;
chainBall.specialType = ball.specialType;
chainBall.x = ball.x;
chainBall.y = ball.y;
chainBall.scaleX = 0.1;
chainBall.scaleY = 0.1;
game.addChild(chainBall);
// Animate ball insertion
tween(chainBall, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
chain.splice(insertIndex, 0, chainBall);
// Update chain indices
for (var i = 0; i < chain.length; i++) {
chain[i].chainIndex = i;
}
checkMatches();
}
// Initialize game
createTrackPath();
createChain();
// Position hole at the end of the track - near the shooter
hole.x = 1024;
hole.y = 1200; // Position hole closer to shooter
// Add pulsing and shining animation to shooter ball
function animateShooterBall() {
if (shooter.currentBall) {
// Pulsing effect
tween(shooter.currentBall, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(shooter.currentBall, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: animateShooterBall
});
}
});
// Shining effect with alpha animation
tween(shooter.currentBall, {
alpha: 0.7
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(shooter.currentBall, {
alpha: 1.0
}, {
duration: 600,
easing: tween.easeInOut
});
}
});
}
}
// Score display
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Level display
var levelTxt = new Text2('Level: 1', {
size: 50,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0, 0);
levelTxt.x = 120;
levelTxt.y = 20;
LK.gui.top.addChild(levelTxt);
// Next ball preview
var nextBallTxt = new Text2('Next:', {
size: 40,
fill: 0xFFFFFF
});
nextBallTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(nextBallTxt);
// Create accelerate button
var accelerateBtn = new Text2('NORMAL', {
size: 50,
fill: 0xFFFFFF
});
accelerateBtn.anchor.set(1, 1);
accelerateBtn.x = -20;
accelerateBtn.y = -20;
LK.gui.bottomRight.addChild(accelerateBtn);
// Button press handler
accelerateBtn.down = function (x, y, obj) {
speedLevel = (speedLevel + 1) % 3; // Cycle through 0, 1, 2
if (speedLevel === 0) {
accelerateBtn.setText('NORMAL');
accelerateBtn.fill = 0xFFFFFF;
} else if (speedLevel === 1) {
accelerateBtn.setText('FAST');
accelerateBtn.fill = 0xFFFF00;
} else {
accelerateBtn.setText('VERY FAST');
accelerateBtn.fill = 0xFF4444;
}
};
// Game input
game.down = function (x, y, obj) {
shooter.aimAt(x, y);
var ball = shooter.shoot();
if (ball) {
flyingBalls.push(ball);
game.addChild(ball);
}
};
// Main game loop
game.update = function () {
if (gameWon || gameLost) return;
// Update chain
updateChain();
// Update flying balls
for (var i = flyingBalls.length - 1; i >= 0; i--) {
var ball = flyingBalls[i];
ball.x += ball.vx;
ball.y += ball.vy;
// Check collision with chain
var inserted = false;
var collisionIndex = -1;
for (var j = 0; j < chain.length; j++) {
var chainBall = chain[j];
if (ball.intersects(chainBall)) {
collisionIndex = j;
break;
}
}
// If collision detected, insert at collision position
if (collisionIndex !== -1) {
// Insert after the collided ball
var insertIndex = collisionIndex + 1;
var trackSpacing = 7.0; // Increased spacing to prevent overlap
// Adjust track positions for all balls after insertion point
for (var k = insertIndex; k < chain.length; k++) {
chain[k].trackPosition += trackSpacing; // Move balls back to make space
}
insertBallIntoChain(ball, insertIndex);
// Set the inserted ball's track position with proper spacing
if (insertIndex < chain.length) {
chain[insertIndex].trackPosition = chain[collisionIndex].trackPosition + trackSpacing;
positionBallOnTrack(chain[insertIndex], chain[insertIndex].trackPosition);
}
// Re-space all balls after insertion to maintain equal intervals
for (var k = insertIndex + 1; k < chain.length; k++) {
var expectedPosition = chain[k - 1].trackPosition + trackSpacing;
// Enforce minimum spacing to prevent overlap
chain[k].trackPosition = Math.max(chain[k].trackPosition, expectedPosition);
}
ball.destroy();
flyingBalls.splice(i, 1);
inserted = true;
}
// Remove if off screen
if (!inserted && (ball.x < -100 || ball.x > 2148 || ball.y < -100 || ball.y > 2832)) {
ball.destroy();
flyingBalls.splice(i, 1);
}
}
// Update shooter
shooter.update();
// Update UI
scoreTxt.setText('Score: ' + LK.getScore());
levelTxt.setText('Level: ' + level);
// Show next ball preview
if (shooter.nextBall) {
if (shooter.nextBall.parent) {
shooter.nextBall.parent.removeChild(shooter.nextBall);
}
shooter.nextBall.x = -50;
shooter.nextBall.y = 60;
shooter.nextBall.scaleX = 0.8;
shooter.nextBall.scaleY = 0.8;
LK.gui.topRight.addChild(shooter.nextBall);
}
// Increase chain speed over time (faster increase)
normalChainSpeed += 0.00005;
// Update other speeds to maintain ratios
fastChainSpeed = normalChainSpeed * 4; // 4x faster when fast
veryFastChainSpeed = normalChainSpeed * 10; // 10x faster when very fast
if (speedLevel === 0) {
chainSpeed = normalChainSpeed;
} else if (speedLevel === 1) {
chainSpeed = fastChainSpeed;
} else {
chainSpeed = veryFastChainSpeed;
}
}; ===================================================================
--- original.js
+++ change.js
@@ -189,43 +189,59 @@
/****
* Game Code
****/
-// Create space background with stars
+// Create realistic space background with multiple cosmic elements
function createSpaceBackground() {
- // Create multiple layers of stars for depth
- for (var layer = 0; layer < 3; layer++) {
- var numStars = layer === 0 ? 150 : layer === 1 ? 100 : 50;
- var starSize = layer === 0 ? 2 : layer === 1 ? 4 : 6;
- var starAlpha = layer === 0 ? 0.3 : layer === 1 ? 0.6 : 0.9;
+ // Create distant galaxies as background elements
+ for (var i = 0; i < 4; i++) {
+ var galaxy = game.addChild(LK.getAsset('centerCircle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 8 + Math.random() * 6,
+ scaleY: 6 + Math.random() * 4
+ }));
+ galaxy.x = Math.random() * 2048;
+ galaxy.y = Math.random() * 2732;
+ galaxy.alpha = 0.02 + Math.random() * 0.03;
+ galaxy.tint = 0x9370DB;
+ galaxy.rotation = Math.random() * Math.PI * 2;
+ }
+ // Create complex starfield with realistic star colors and sizes
+ var starColors = [0xFFFFFF, 0xFFE4B5, 0xFFB347, 0x87CEEB, 0xF0F8FF, 0xFFF8DC];
+ var starSizes = [0.5, 0.8, 1.2, 1.8, 2.5, 3.2];
+ for (var layer = 0; layer < 5; layer++) {
+ var numStars = layer === 0 ? 200 : layer === 1 ? 150 : layer === 2 ? 100 : layer === 3 ? 60 : 30;
+ var baseAlpha = layer === 0 ? 0.2 : layer === 1 ? 0.4 : layer === 2 ? 0.6 : layer === 3 ? 0.8 : 1.0;
for (var i = 0; i < numStars; i++) {
+ var starSize = starSizes[Math.floor(Math.random() * starSizes.length)];
var star = game.addChild(LK.getAsset('track', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: starSize * 0.1,
scaleY: starSize * 0.1
}));
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
- star.alpha = starAlpha;
- star.tint = 0xFFFFFF;
- // Add twinkling effect to larger stars
- if (layer === 2) {
- var twinkleDelay = Math.random() * 2000;
+ star.alpha = baseAlpha + Math.random() * 0.3;
+ star.tint = starColors[Math.floor(Math.random() * starColors.length)];
+ // Add realistic twinkling based on star size and distance
+ if (layer >= 2 && Math.random() < 0.4) {
+ var twinkleDelay = Math.random() * 3000;
LK.setTimeout(function () {
var _twinkleEffect = function twinkleEffect() {
if (star && star.parent) {
tween(star, {
- alpha: starAlpha * 0.3
+ alpha: star.alpha * 0.2
}, {
- duration: 800 + Math.random() * 400,
+ duration: 1000 + Math.random() * 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (star && star.parent) {
tween(star, {
- alpha: starAlpha
+ alpha: baseAlpha + Math.random() * 0.3
}, {
- duration: 800 + Math.random() * 400,
+ duration: 1000 + Math.random() * 800,
easing: tween.easeInOut,
onFinish: _twinkleEffect
});
}
@@ -237,22 +253,94 @@
}, twinkleDelay);
}
}
}
- // Add some nebula-like effects using colored circles
- for (var i = 0; i < 8; i++) {
+ // Add realistic planets at different distances
+ var planetColors = [0xFF6B47, 0x4682B4, 0xDEB887, 0x9370DB, 0xF4A460, 0x708090];
+ for (var i = 0; i < 3; i++) {
+ var planet = game.addChild(LK.getAsset('centerCircle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 1.5 + Math.random() * 2.5,
+ scaleY: 1.5 + Math.random() * 2.5
+ }));
+ planet.x = Math.random() * 2048;
+ planet.y = Math.random() * 2732;
+ planet.alpha = 0.3 + Math.random() * 0.4;
+ planet.tint = planetColors[Math.floor(Math.random() * planetColors.length)];
+ }
+ // Create animated cosmic dust clouds
+ for (var i = 0; i < 12; i++) {
+ var dust = game.addChild(LK.getAsset('centerCircle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 2 + Math.random() * 3,
+ scaleY: 1 + Math.random() * 2
+ }));
+ dust.x = Math.random() * 2048;
+ dust.y = Math.random() * 2732;
+ dust.alpha = 0.03 + Math.random() * 0.05;
+ dust.rotation = Math.random() * Math.PI * 2;
+ // Realistic dust cloud colors
+ var dustColors = [0x4B0082, 0x800080, 0x8B008B, 0x9400D3, 0x1E90FF, 0x00CED1, 0x483D8B];
+ dust.tint = dustColors[Math.floor(Math.random() * dustColors.length)];
+ // Add slow rotation animation
+ var rotationSpeed = (Math.random() - 0.5) * 0.001;
+ var dustRotation = dust.rotation;
+ var _dustRotate = function dustRotate() {
+ if (dust && dust.parent) {
+ dustRotation += rotationSpeed;
+ dust.rotation = dustRotation;
+ LK.setTimeout(_dustRotate, 50);
+ }
+ };
+ _dustRotate();
+ }
+ // Add some brighter nebula formations
+ for (var i = 0; i < 6; i++) {
var nebula = game.addChild(LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
- scaleX: 3 + Math.random() * 4,
+ scaleX: 4 + Math.random() * 5,
scaleY: 3 + Math.random() * 4
}));
nebula.x = Math.random() * 2048;
nebula.y = Math.random() * 2732;
- nebula.alpha = 0.05 + Math.random() * 0.1;
- // Random nebula colors
- var nebulaColors = [0x4B0082, 0x800080, 0x8B008B, 0x9400D3, 0x1E90FF, 0x00CED1];
+ nebula.alpha = 0.08 + Math.random() * 0.12;
+ nebula.rotation = Math.random() * Math.PI * 2;
+ // More vibrant nebula colors
+ var nebulaColors = [0xFF1493, 0x00FA9A, 0xFF4500, 0x9370DB, 0x00CED1, 0xFF69B4];
nebula.tint = nebulaColors[Math.floor(Math.random() * nebulaColors.length)];
+ // Add gentle pulsing effect
+ var pulseDelay = Math.random() * 4000;
+ LK.setTimeout(function () {
+ var _nebulaEffect = function nebulaEffect() {
+ if (nebula && nebula.parent) {
+ tween(nebula, {
+ alpha: nebula.alpha * 0.5,
+ scaleX: nebula.scaleX * 1.1,
+ scaleY: nebula.scaleY * 1.1
+ }, {
+ duration: 2000 + Math.random() * 1000,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ if (nebula && nebula.parent) {
+ tween(nebula, {
+ alpha: 0.08 + Math.random() * 0.12,
+ scaleX: 4 + Math.random() * 5,
+ scaleY: 3 + Math.random() * 4
+ }, {
+ duration: 2000 + Math.random() * 1000,
+ easing: tween.easeInOut,
+ onFinish: _nebulaEffect
+ });
+ }
+ }
+ });
+ }
+ };
+ _nebulaEffect();
+ }, pulseDelay);
}
}
// Initialize space background
createSpaceBackground();
8 ball billard with fire. In-Game asset. 2d. High contrast. No shadows
green neon ball. In-Game asset. 2d. High contrast. No shadows
blach hole gif. In-Game asset. 2d. High contrast. No shadows
space shooter cannon. In-Game asset. 2d. High contrast. No shadows
fire effect. In-Game asset. 2d. High contrast. No shadows
space track point. In-Game asset. 2d. High contrast. No shadows
aim . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
ice. In-Game asset. 2d. High contrast. No shadows
flying superman
laser beam. In-Game asset. 2d. High contrast. No shadows
green goblin. In-Game asset. 2d. High contrast. No shadows
rocket. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
shoot
Sound effect
match
Sound effect
powerup
Sound effect
Gameplay
Music
gameover
Sound effect
frozen
Sound effect
celebration
Sound effect
white_shoot
Sound effect
fire_flying
Sound effect
superman_flying
Sound effect
superman_laser
Sound effect
villain_flying
Sound effect
villain_laser
Sound effect