User prompt
add a little bit more rotation
User prompt
let the cannon be able to rotate slightly so it can shoot higher up and lower down ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
give the cannon a cool down of 15 seconds
User prompt
no animation just rotate it so that the long side is facing right.
User prompt
rotate cannon ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
let it only happen if the user clicks one of the cannons cannon balls.
User prompt
remove all three of those cannons. add 1 good looking cannon to the left side of the screen that shoot special effects that gives the user ability to slow down time it also gives a cool little lightning effect. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add cannons that shoot out special effects ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add a volume option whenever the game is paused ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
make sure the heart fully vanishes after selected ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
the heart still leaves a dot on the screen. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
the heart leaves a mark. make that not happen ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make the glow red not golden ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
when i select the heart dont let the screen turn red. add a special effect for the ehart ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
still not hearing anything
User prompt
okay make me hear it now
User prompt
add calm game music
User prompt
make the heart more heart shaped
User prompt
add a heart that floats about randomly but not too often that gives the user an extra life ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make the score look better ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add special effects when chosen the correct circle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
also let the balls despawn when its over 8
User prompt
okay dont add a timer for the game
User prompt
scrap that idea lets use something else
User prompt
fix the game
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
volume: 0.5
});
/****
* Classes
****/
var ColorCircle = Container.expand(function () {
var self = Container.call(this);
self.colorValue = 0xFFFFFF;
self.radius = 75;
self.speed = 2;
self.angle = Math.random() * Math.PI * 2;
self.lastWasIntersecting = false;
var circleGraphics = self.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1
});
self.setColor = function (color) {
self.colorValue = color;
circleGraphics.tint = color;
};
self.update = function () {
// Move in a circular pattern (affected by time slow)
var effectiveSpeed = timeSlowActive ? self.speed * 0.3 : self.speed;
self.x += Math.cos(self.angle) * effectiveSpeed;
self.y += Math.sin(self.angle) * effectiveSpeed;
// Bounce off walls
if (self.x < self.radius || self.x > 2048 - self.radius) {
self.angle = Math.PI - self.angle;
self.x = Math.max(self.radius, Math.min(2048 - self.radius, self.x));
}
if (self.y < self.radius || self.y > 2732 - self.radius) {
self.angle = -self.angle;
self.y = Math.max(self.radius, Math.min(2732 - self.radius, self.y));
}
};
self.down = function (x, y, obj) {
// Circle was tapped
self.wasTapped = true;
};
return self;
});
var Heart = Container.expand(function () {
var self = Container.call(this);
self.collected = false;
self.floatSpeed = 2;
self.floatAngle = Math.random() * Math.PI * 2;
self.floatRadius = 100;
self.centerX = 0;
self.centerY = 0;
self.floatTime = 0;
// Create heart shape using two circles for the top lobes and a triangle-like bottom
var topLeft = self.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.4,
scaleY: 0.4,
tint: 0xFF1744
});
topLeft.x = -12;
topLeft.y = -8;
var topRight = self.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.4,
scaleY: 0.4,
tint: 0xFF1744
});
topRight.x = 12;
topRight.y = -8;
// Create bottom part using multiple small circles to form a point
var bottom1 = self.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.35,
scaleY: 0.35,
tint: 0xFF1744
});
bottom1.x = 0;
bottom1.y = 5;
var bottom2 = self.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.25,
scaleY: 0.25,
tint: 0xFF1744
});
bottom2.x = 0;
bottom2.y = 15;
var bottom3 = self.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.15,
scaleY: 0.15,
tint: 0xFF1744
});
bottom3.x = 0;
bottom3.y = 22;
// Add middle fill circles for better shape
var middle1 = self.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3,
tint: 0xFF1744
});
middle1.x = -6;
middle1.y = 0;
var middle2 = self.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3,
tint: 0xFF1744
});
middle2.x = 6;
middle2.y = 0;
// Pulsing effect
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Repeat pulsing
if (!self.collected && self.parent) {
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: arguments.callee
});
}
}
});
}
});
self.update = function () {
if (self.collected) return;
// Float in a smooth pattern
self.floatTime += 0.02;
var offsetX = Math.sin(self.floatTime) * self.floatRadius;
var offsetY = Math.cos(self.floatTime * 0.7) * self.floatRadius * 0.5;
self.x = self.centerX + offsetX;
self.y = self.centerY + offsetY;
// Slight rotation for visual interest
self.rotation = Math.sin(self.floatTime * 0.5) * 0.1;
};
self.down = function (x, y, obj) {
if (!self.collected) {
self.collected = true;
}
};
return self;
});
var TargetIndicator = Container.expand(function () {
var self = Container.call(this);
self.targetColor = 0xFFFFFF;
var ringGraphics = self.attachAsset('targetRing', {
anchorX: 0.5,
anchorY: 0.5
});
var innerCircle = self.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
self.setTargetColor = function (color) {
self.targetColor = color;
innerCircle.tint = color;
ringGraphics.tint = color;
};
return self;
});
var TimeSlowCannon = Container.expand(function () {
var self = Container.call(this);
self.shootTimer = 0;
self.shootInterval = 180; // 3 seconds at 60fps
self.cannonColor = 0x4A90E2;
// Cannon base - sleek blue design
var cannonBase = self.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5,
tint: 0x2E5A8A
});
// Cannon barrel - elongated and futuristic
var cannonBarrel = self.attachAsset('targetRing', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 2.0
});
cannonBarrel.tint = self.cannonColor;
// Energy core in center
var energyCore = self.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6,
tint: 0x00FFFF
});
// Pulsing energy core animation
tween(energyCore, {
scaleX: 0.8,
scaleY: 0.8,
alpha: 0.7
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(energyCore, {
scaleX: 0.6,
scaleY: 0.6,
alpha: 1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: arguments.callee
});
}
});
// Continuous rotation animation for the cannon
tween(self, {
rotation: Math.PI * 2
}, {
duration: 8000,
easing: tween.linear,
onFinish: function onFinish() {
self.rotation = 0; // Reset rotation to prevent accumulation
// Restart the rotation animation
tween(self, {
rotation: Math.PI * 2
}, {
duration: 8000,
easing: tween.linear,
onFinish: arguments.callee
});
}
});
self.update = function () {
self.shootTimer++;
if (self.shootTimer >= self.shootInterval) {
self.shoot();
self.shootTimer = 0;
}
};
self.shoot = function () {
// Create electric charge buildup
var chargeEffect = game.addChild(new Container());
var charge = chargeEffect.attachAsset('targetRing', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0,
tint: 0x00FFFF,
alpha: 0.0
});
chargeEffect.x = self.x;
chargeEffect.y = self.y;
// Charge buildup animation
tween(chargeEffect, {
scaleX: 0.5,
scaleY: 0.5,
alpha: 1.0
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
// Create projectile instead of instant effect
var projectile = game.addChild(new TimeSlowProjectile());
projectile.x = self.x;
projectile.y = self.y;
// Aim projectile towards center of screen
var targetX = 1024;
var targetY = 1366;
projectile.angle = Math.atan2(targetY - projectile.y, targetX - projectile.x);
// Add projectile to tracking array
timeSlowProjectiles.push(projectile);
chargeEffect.destroy();
}
});
// Cannon recoil with electric sparks
var recoilSparks = game.addChild(new Container());
for (var s = 0; s < 8; s++) {
var spark = recoilSparks.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.2,
scaleY: 0.2,
tint: 0x00FFFF
});
spark.x = self.x + (Math.random() - 0.5) * 100;
spark.y = self.y + (Math.random() - 0.5) * 100;
tween(spark, {
alpha: 0,
scaleX: 0.4,
scaleY: 0.4
}, {
duration: 500,
easing: tween.easeOut
});
}
// Animate recoil sparks container
tween(recoilSparks, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
recoilSparks.destroy();
}
});
// Cannon recoil effect
tween(self, {
y: self.y + 30
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
y: self.y - 30
}, {
duration: 300,
easing: tween.bounceOut
});
}
});
};
return self;
});
var TimeSlowProjectile = Container.expand(function () {
var self = Container.call(this);
self.speed = 5;
self.angle = 0;
self.used = false;
// Create glowing projectile
var projectileCore = self.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
tint: 0x00FFFF
});
// Add outer glow ring
var glowRing = self.attachAsset('targetRing', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2,
tint: 0x00FFFF,
alpha: 0.5
});
// Pulsing glow animation
tween(glowRing, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0.3
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(glowRing, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 0.5
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: arguments.callee
});
}
});
self.update = function () {
if (self.used) return;
// Move projectile
self.x += Math.cos(self.angle) * self.speed;
self.y += Math.sin(self.angle) * self.speed;
};
self.down = function (x, y, obj) {
if (self.used) return;
self.used = true;
// Lightning bolt effect - create zigzag pattern
for (var l = 0; l < 5; l++) {
var lightning = game.addChild(new Container());
var bolt = lightning.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 3.0,
tint: 0xFFFFFF
});
lightning.x = self.x + (Math.random() - 0.5) * 200;
lightning.y = self.y - l * 100;
lightning.rotation = (Math.random() - 0.5) * 0.5;
lightning.alpha = 0.8;
// Lightning flash effect
tween(lightning, {
alpha: 0,
scaleY: 4.0
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
lightning.destroy();
}
});
}
// Screen flash for dramatic effect
LK.effects.flashScreen(0x00FFFF, 400);
// Time slow effect implementation
timeSlowActive = true;
timeSlowDuration = 300; // 5 seconds at 60fps
// Visual feedback for time slow
var timeIndicator = game.addChild(new Container());
var indicator = timeIndicator.attachAsset('targetRing', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 8.0,
scaleY: 8.0,
tint: 0x00FFFF,
alpha: 0.2
});
timeIndicator.x = 1024;
timeIndicator.y = 1366;
tween(timeIndicator, {
scaleX: 12.0,
scaleY: 12.0,
alpha: 0
}, {
duration: 5000,
easing: tween.easeOut,
onFinish: function onFinish() {
timeIndicator.destroy();
}
});
// Destroy projectile with explosion effect
tween(self, {
scaleX: 3,
scaleY: 3,
alpha: 0
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
/****
* Initialize Game
****/
// Game variables
var game = new LK.Game({
backgroundColor: 0x0a0a0a
});
/****
* Game Code
****/
// Game variables
var circles = [];
var targetColor = 0xFFFFFF;
var gameRunning = true;
var combo = 0;
var level = 1;
var circleSpeed = 2;
var spawnTimer = 0;
var spawnInterval = 90; // 1.5 seconds at 60fps
var lives = 3;
var hearts = [];
var heartSpawnTimer = 0;
var heartSpawnInterval = 600; // 10 seconds at 60fps
var cannons = [];
var timeSlowProjectiles = [];
var timeSlowActive = false;
var timeSlowDuration = 0;
// Color palette
var colors = [0xFF6B6B,
// Red
0x4ECDC4,
// Cyan
0x45B7D1,
// Blue
0xF7DC6F,
// Yellow
0x58D68D,
// Green
0xBB8FCE,
// Purple
0xF8B500,
// Orange
0xE91E63 // Pink
];
// UI Elements
var scoreContainer = new Container();
LK.gui.top.addChild(scoreContainer);
scoreContainer.y = 50;
// Score background
var scoreBg = scoreContainer.attachAsset('targetRing', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.8,
tint: 0x222222,
alpha: 0.8
});
// Score text with gradient-like effect
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFD700
});
scoreTxt.anchor.set(0.5, 0.5);
scoreContainer.addChild(scoreTxt);
// Score label
var scoreLabel = new Text2('SCORE', {
size: 30,
fill: 0xFFFFFF
});
scoreLabel.anchor.set(0.5, 0.5);
scoreLabel.y = -40;
scoreContainer.addChild(scoreLabel);
// Animated score value for smooth transitions
var displayedScore = 0;
var targetScore = 0;
var comboTxt = new Text2('', {
size: 50,
fill: 0xFFD700
});
comboTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(comboTxt);
comboTxt.y = 130;
var levelTxt = new Text2('Level 1', {
size: 40,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(levelTxt);
levelTxt.x = -200;
levelTxt.y = 50;
var livesTxt = new Text2('Lives: 3', {
size: 40,
fill: 0xFF6B6B
});
livesTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(livesTxt);
livesTxt.x = -200;
livesTxt.y = 100;
// Create target indicator
var targetIndicator = game.addChild(new TargetIndicator());
targetIndicator.x = 1024;
targetIndicator.y = 2600;
// Set initial target color
function setNewTargetColor() {
targetColor = colors[Math.floor(Math.random() * colors.length)];
targetIndicator.setTargetColor(targetColor);
// Pulse animation for new target
tween(targetIndicator, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
onFinish: function onFinish() {
tween(targetIndicator, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
}
function spawnHeart() {
if (!gameRunning || hearts.length > 0) return; // Only one heart at a time
var heart = game.addChild(new Heart());
// Random position within play area
heart.centerX = 200 + Math.random() * 1648;
heart.centerY = 400 + Math.random() * 1932;
heart.x = heart.centerX;
heart.y = heart.centerY;
hearts.push(heart);
// Auto-remove after 5 seconds if not collected
LK.setTimeout(function () {
if (!heart.collected && heart.parent) {
tween(heart, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 500,
onFinish: function onFinish() {
heart.destroy();
var index = hearts.indexOf(heart);
if (index > -1) {
hearts.splice(index, 1);
}
}
});
}
}, 5000);
}
function spawnCircle() {
if (!gameRunning) return;
var circle = game.addChild(new ColorCircle());
// Random position on edges
var edge = Math.floor(Math.random() * 4);
if (edge === 0) {
// Top
circle.x = Math.random() * 2048;
circle.y = -50;
} else if (edge === 1) {
// Right
circle.x = 2098;
circle.y = Math.random() * 2732;
} else if (edge === 2) {
// Bottom
circle.x = Math.random() * 2048;
circle.y = 2782;
} else {
// Left
circle.x = -50;
circle.y = Math.random() * 2732;
}
// Set random color
var color = colors[Math.floor(Math.random() * colors.length)];
circle.setColor(color);
// Set speed based on level
circle.speed = circleSpeed + (level - 1) * 0.5;
// Aim towards center area with some randomness
var targetX = 1024 + (Math.random() - 0.5) * 800;
var targetY = 1366 + (Math.random() - 0.5) * 800;
circle.angle = Math.atan2(targetY - circle.y, targetX - circle.x);
circles.push(circle);
}
function checkCircleTap(circle) {
if (circle.colorValue === targetColor) {
// Correct tap
combo++;
var points = 10 * combo;
LK.setScore(LK.getScore() + points);
// Create floating score popup
var scorePopup = game.addChild(new Container());
var popupBg = scorePopup.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.8,
tint: 0x000000,
alpha: 0.6
});
var popupText = new Text2('+' + points, {
size: 60,
fill: 0xFFD700
});
popupText.anchor.set(0.5, 0.5);
scorePopup.addChild(popupText);
scorePopup.x = circle.x;
scorePopup.y = circle.y;
scorePopup.alpha = 0;
// Animate floating score
tween(scorePopup, {
y: circle.y - 150,
alpha: 1
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(scorePopup, {
y: circle.y - 200,
alpha: 0
}, {
duration: 500,
easing: tween.easeIn,
onFinish: function onFinish() {
scorePopup.destroy();
}
});
}
});
if (combo % 5 === 0) {
LK.getSound('combo').play();
// Bonus flash
LK.effects.flashScreen(0xFFD700, 300);
} else {
LK.getSound('correct').play();
}
// Create particle burst effect
for (var p = 0; p < 8; p++) {
var particle = game.addChild(new Container());
var particleGraphics = particle.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3
});
particleGraphics.tint = circle.colorValue;
particle.x = circle.x;
particle.y = circle.y;
var angle = Math.PI * 2 / 8 * p;
var distance = 150;
tween(particle, {
x: circle.x + Math.cos(angle) * distance,
y: circle.y + Math.sin(angle) * distance,
alpha: 0
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
particle.destroy();
}
});
}
// Success animation with enhanced effects
tween(circle, {
scaleX: 2,
scaleY: 2,
alpha: 0,
rotation: Math.PI * 2
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
circle.destroy();
}
});
// Add ring pulse effect
var ringEffect = game.addChild(new Container());
var ring = ringEffect.attachAsset('targetRing', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
ring.tint = circle.colorValue;
ringEffect.x = circle.x;
ringEffect.y = circle.y;
ringEffect.alpha = 0.8;
tween(ringEffect, {
scaleX: 3,
scaleY: 3,
alpha: 0
}, {
duration: 600,
easing: tween.easeOut,
onFinish: function onFinish() {
ringEffect.destroy();
}
});
// Update UI
targetScore = LK.getScore();
// Pulse effect on score change
tween(scoreContainer, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(scoreContainer, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeIn
});
}
});
// Flash score color
tween(scoreTxt, {
tint: 0xFFFFFF
}, {
duration: 100,
onFinish: function onFinish() {
tween(scoreTxt, {
tint: 0xFFD700
}, {
duration: 300
});
}
});
if (combo > 1) {
comboTxt.setText('Combo x' + combo);
// Combo text pulse effect
tween(comboTxt, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 200,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(comboTxt, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
}
// Target indicator celebration effect
tween(targetIndicator, {
rotation: Math.PI * 0.1
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(targetIndicator, {
rotation: -Math.PI * 0.1
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(targetIndicator, {
rotation: 0
}, {
duration: 100
});
}
});
}
});
// Set new target color
setNewTargetColor();
} else {
// Wrong tap
combo = 0;
lives--;
LK.getSound('wrong').play();
// Error animation
tween(circle, {
tint: 0x333333,
scaleX: 0.5,
scaleY: 0.5,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
circle.destroy();
}
});
// Flash screen red
LK.effects.flashScreen(0xFF0000, 500);
// Update UI
comboTxt.setText('');
livesTxt.setText('Lives: ' + lives);
if (lives <= 0) {
gameOver();
}
}
// Remove from array
var index = circles.indexOf(circle);
if (index > -1) {
circles.splice(index, 1);
}
}
function nextLevel() {
level++;
circleSpeed += 0.5;
spawnInterval = Math.max(30, spawnInterval - 10); // Spawn faster
// Clear all circles
for (var i = circles.length - 1; i >= 0; i--) {
circles[i].destroy();
}
circles = [];
// Level up effects
LK.getSound('levelup').play();
LK.effects.flashScreen(0x4ECDC4, 1000);
// Update UI
levelTxt.setText('Level ' + level);
// Show level notification
var levelNotification = new Text2('Level ' + level + '!', {
size: 100,
fill: 0x4ECDC4
});
levelNotification.anchor.set(0.5, 0.5);
levelNotification.x = 1024;
levelNotification.y = 1366;
game.addChild(levelNotification);
tween(levelNotification, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
levelNotification.destroy();
}
});
}
function gameOver() {
gameRunning = false;
// Clear all circles
for (var i = circles.length - 1; i >= 0; i--) {
circles[i].destroy();
}
// Check for win condition (reached level 10)
if (level >= 10) {
LK.showYouWin();
} else {
LK.showGameOver();
}
}
// Game update loop
game.update = function () {
if (!gameRunning) return;
// Handle time slow effect
if (timeSlowActive) {
timeSlowDuration--;
if (timeSlowDuration <= 0) {
timeSlowActive = false;
}
}
// Spawn circles (affected by time slow)
spawnTimer++;
var effectiveSpawnInterval = timeSlowActive ? spawnInterval * 2 : spawnInterval;
if (spawnTimer >= effectiveSpawnInterval) {
spawnCircle();
spawnTimer = 0;
}
// Spawn hearts
heartSpawnTimer++;
if (heartSpawnTimer >= heartSpawnInterval) {
spawnHeart();
heartSpawnTimer = 0;
// Randomize next spawn interval (10-20 seconds)
heartSpawnInterval = 600 + Math.floor(Math.random() * 600);
}
// Check for collected hearts
for (var h = hearts.length - 1; h >= 0; h--) {
var heart = hearts[h];
if (heart.collected) {
// Add life
lives = Math.min(lives + 1, 5); // Cap at 5 lives
livesTxt.setText('Lives: ' + lives);
// Collection effect - golden flash instead of red
LK.effects.flashScreen(0xFFD700, 300);
LK.getSound('levelup').play();
// Create enhanced sparkle effect with red particles
for (var s = 0; s < 16; s++) {
var sparkle = game.addChild(new Container());
var sparkleGraphics = sparkle.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3,
tint: 0xFF0000
});
sparkle.x = heartX;
sparkle.y = heartY;
var angle = Math.PI * 2 / 16 * s;
var distance = 150 + Math.random() * 100;
// Add initial scale pulse
tween(sparkle, {
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(sparkle, {
x: heartX + Math.cos(angle) * distance,
y: heartY + Math.sin(angle) * distance,
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 700,
easing: tween.easeOut,
onFinish: function onFinish() {
sparkle.destroy();
}
});
}
});
}
// Store heart position for effects before removing it
var heartX = heart.x;
var heartY = heart.y;
// Remove heart from game immediately and destroy it
heart.destroy();
hearts.splice(h, 1);
// Special heart collection effect with red glow
// First create a red glow effect
var heartGlow = game.addChild(new Container());
var glowRing = heartGlow.attachAsset('targetRing', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
tint: 0xFF0000,
alpha: 0.8
});
heartGlow.x = heartX;
heartGlow.y = heartY;
// Animate glow ring expanding
tween(heartGlow, {
scaleX: 4,
scaleY: 4,
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
heartGlow.destroy();
}
});
}
}
// Despawn oldest circles if there are more than 8
while (circles.length > 8) {
var oldestCircle = circles.shift(); // Remove first (oldest) circle
oldestCircle.destroy();
}
// Check for tapped circles
for (var i = circles.length - 1; i >= 0; i--) {
var circle = circles[i];
if (circle.wasTapped) {
circle.wasTapped = false;
checkCircleTap(circle);
break; // Only process one tap per frame
}
// Remove circles that went off screen
if (circle.x < -100 || circle.x > 2148 || circle.y < -100 || circle.y > 2832) {
circles.splice(i, 1);
circle.destroy();
}
}
// Manage time slow projectiles
for (var p = timeSlowProjectiles.length - 1; p >= 0; p--) {
var projectile = timeSlowProjectiles[p];
// Remove projectiles that went off screen or were used
if (projectile.used || projectile.x < -100 || projectile.x > 2148 || projectile.y < -100 || projectile.y > 2832) {
timeSlowProjectiles.splice(p, 1);
if (!projectile.used) {
projectile.destroy();
}
}
}
// Smooth score counter animation
if (displayedScore < targetScore) {
var diff = targetScore - displayedScore;
var increment = Math.max(1, Math.floor(diff / 10));
displayedScore = Math.min(displayedScore + increment, targetScore);
scoreTxt.setText(displayedScore.toString());
// Add subtle scale effect while counting
var scaleFactor = 1 + diff / 1000 * 0.1;
scoreTxt.scale.set(Math.min(1.2, scaleFactor));
} else if (displayedScore > targetScore) {
displayedScore = targetScore;
scoreTxt.setText(displayedScore.toString());
scoreTxt.scale.set(1);
}
};
// Volume control variables
var currentVolume = storage.volume || 0.5;
var volumeSlider = null;
var volumeContainer = null;
var isPaused = false;
// Pause handler to show volume controls
LK.on('pause', function () {
isPaused = true;
// Create volume control container
volumeContainer = new Container();
LK.gui.center.addChild(volumeContainer);
// Background for volume controls
var volumeBg = volumeContainer.attachAsset('targetRing', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 2,
tint: 0x222222,
alpha: 0.9
});
// Volume label
var volumeLabel = new Text2('VOLUME', {
size: 50,
fill: 0xFFFFFF
});
volumeLabel.anchor.set(0.5, 0.5);
volumeLabel.y = -50;
volumeContainer.addChild(volumeLabel);
// Volume slider background
var sliderBg = volumeContainer.attachAsset('targetRing', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 0.3,
tint: 0x444444
});
sliderBg.y = 20;
// Volume slider handle
volumeSlider = volumeContainer.attachAsset('circle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
tint: 0xFFD700
});
volumeSlider.y = 20;
volumeSlider.x = (currentVolume - 0.5) * 300; // Position based on volume (0-1 maps to -150 to +150)
// Volume percentage display
var volumePercent = new Text2(Math.round(currentVolume * 100) + '%', {
size: 40,
fill: 0xFFD700
});
volumePercent.anchor.set(0.5, 0.5);
volumePercent.y = 80;
volumeContainer.addChild(volumePercent);
// Handle volume slider interaction
volumeSlider.down = function (x, y, obj) {
volumeSlider.isDragging = true;
};
volumeContainer.move = function (x, y, obj) {
if (volumeSlider && volumeSlider.isDragging) {
// Convert global position to local slider position
var localX = Math.max(-150, Math.min(150, x - volumeContainer.x));
volumeSlider.x = localX;
// Update volume (slider range -150 to +150 maps to volume 0 to 1)
currentVolume = Math.max(0, Math.min(1, (localX + 150) / 300));
// Update display
volumePercent.setText(Math.round(currentVolume * 100) + '%');
// Save to storage
storage.volume = currentVolume;
// Update music volume immediately
LK.stopMusic();
LK.playMusic('calmMusic', {
volume: currentVolume
});
}
};
volumeContainer.up = function (x, y, obj) {
if (volumeSlider) {
volumeSlider.isDragging = false;
}
};
});
// Resume handler to clean up volume controls
LK.on('resume', function () {
isPaused = false;
if (volumeContainer) {
volumeContainer.destroy();
volumeContainer = null;
volumeSlider = null;
}
});
// Create single time slow cannon on left side
var timeSlowCannon = game.addChild(new TimeSlowCannon());
timeSlowCannon.x = 200;
timeSlowCannon.y = 1366; // Center vertically
cannons.push(timeSlowCannon);
// Initialize game
setNewTargetColor();
// Play calm background music
LK.playMusic('calmMusic', {
volume: currentVolume
}); ===================================================================
--- original.js
+++ change.js
@@ -238,8 +238,26 @@
onFinish: arguments.callee
});
}
});
+ // Continuous rotation animation for the cannon
+ tween(self, {
+ rotation: Math.PI * 2
+ }, {
+ duration: 8000,
+ easing: tween.linear,
+ onFinish: function onFinish() {
+ self.rotation = 0; // Reset rotation to prevent accumulation
+ // Restart the rotation animation
+ tween(self, {
+ rotation: Math.PI * 2
+ }, {
+ duration: 8000,
+ easing: tween.linear,
+ onFinish: arguments.callee
+ });
+ }
+ });
self.update = function () {
self.shootTimer++;
if (self.shootTimer >= self.shootInterval) {
self.shoot();