User prompt
el efecto ratatorio nunca termina. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Cuando este en el menu se mueve el efecto en partida no.
User prompt
Cuando este en el menu se mueve el efecto en partida no.
User prompt
Quita los efectos del infinito ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Quita los wfwcros del infinito ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Has otro efecto que no me gusta ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Has otro efecto no me gusta ya no hagas combinaciones algo que involucre el simbolo del infinito. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Has otro no me gustó. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Ponle mejores efectos al infinito has como una combinacion de todo. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
El efecto es por siempre que pare .
User prompt
Has que el efecto sea por siempre has que pases a otro rango
User prompt
Quita el multiplicador.
User prompt
Los efectos deben de estar en el escudo del rango.
User prompt
Pon los efectos como estaban antas con la gui
User prompt
Quita el contenedor
User prompt
Has que en partida siguan los efectos
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
masterVolume: 0.7,
musicVolume: 0.8,
sfxVolume: 0.8,
graphicsQuality: "high",
playerName: "Player",
currentRank: "noob I",
lifetimeScore: 0,
lastSessionScore: 0
});
/****
* Classes
****/
var Arrow = Container.expand(function (direction, column) {
var self = Container.call(this);
var arrowGraphic = self.attachAsset('arrow_' + direction, {
anchorX: 0.5,
anchorY: 0.5
});
self.direction = direction;
self.column = column;
// Calculate dynamic speed based on current level and speed multiplier
var currentSpeed = baseSpeed * speedMultiplier;
self.speed = Math.min(currentSpeed, baseSpeed * maxSpeedMultiplier); // Apply speed cap
self.hitTested = false;
self.animationPhase = Math.random() * Math.PI * 2; // Random phase for animations
self.pulseSpeed = 0.8 + Math.random() * 0.4; // Random pulse speed
self.glowIntensity = 0.3 + Math.random() * 0.7; // Random glow intensity
self.sparkleTimer = Math.random() * 60; // Random sparkle timing
// Add initial entrance animation
arrowGraphic.scaleX = 0.1;
arrowGraphic.scaleY = 0.1;
arrowGraphic.alpha = 0.5;
tween(arrowGraphic, {
scaleX: 1,
scaleY: 1,
alpha: 1
}, {
duration: 300,
easing: tween.bounceOut
});
self.update = function () {
self.y += self.speed;
// Add dynamic pulsing animation
self.animationPhase += self.pulseSpeed * 0.1;
arrowGraphic.scaleX = 1 + 0.1 * Math.sin(self.animationPhase);
arrowGraphic.scaleY = 1 + 0.1 * Math.sin(self.animationPhase + 1);
// Add rotation wobble
arrowGraphic.rotation = 0.1 * Math.sin(self.animationPhase * 0.7);
// Add glow effect
arrowGraphic.alpha = 0.8 + 0.2 * Math.sin(self.animationPhase * 1.5);
// Add sparkle effect periodically
self.sparkleTimer++;
if (self.sparkleTimer >= 30) {
self.sparkleTimer = 0;
var sparkle = LK.getAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1,
alpha: 0.8
});
sparkle.x = self.x + (Math.random() - 0.5) * 60;
sparkle.y = self.y + (Math.random() - 0.5) * 60;
sparkle.tint = self.direction === 'left' ? 0xff4757 : self.direction === 'down' ? 0x5352ed : self.direction === 'up' ? 0x2ed573 : 0xffa502;
game.addChild(sparkle);
tween(sparkle, {
scaleX: 0.3,
scaleY: 0.3,
alpha: 0,
y: sparkle.y - 50
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
sparkle.destroy();
}
});
}
};
return self;
});
var ComboEffect = Container.expand(function (x, y, comboValue) {
var self = Container.call(this);
// Create combo burst effect
var comboText = new Text2(comboValue + 'x COMBO!', {
size: 80,
fill: 0xFFD700
});
comboText.anchor.set(0.5, 0.5);
comboText.x = 0;
comboText.y = 0;
comboText.scaleX = 0.1;
comboText.scaleY = 0.1;
comboText.alpha = 1;
self.addChild(comboText);
// Create sparkle effects around combo text
for (var i = 0; i < 8; i++) {
var sparkle = self.addChild(LK.getAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1,
alpha: 0.8
}));
var angle = i / 8 * Math.PI * 2;
var radius = 80;
sparkle.x = Math.cos(angle) * radius;
sparkle.y = Math.sin(angle) * radius;
sparkle.tint = 0xFFD700;
// Animate sparkles
tween(sparkle, {
scaleX: 0.3,
scaleY: 0.3,
alpha: 0,
x: Math.cos(angle) * (radius + 100),
y: Math.sin(angle) * (radius + 100)
}, {
duration: 1000,
easing: tween.easeOut
});
}
self.x = x;
self.y = y;
// Animate combo text
tween(comboText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(comboText, {
scaleX: 0.8,
scaleY: 0.8,
alpha: 0,
y: -50
}, {
duration: 700,
easing: tween.easeOut
});
}
});
// Destroy after animation
LK.setTimeout(function () {
self.destroy();
}, 1200);
return self;
});
var HitEffect = Container.expand(function (x, y) {
var self = Container.call(this);
var effectGraphic = self.attachAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3,
alpha: 0.8
});
self.x = x;
self.y = y;
// Animate the effect
tween(effectGraphic, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
return self;
});
var MissEffect = Container.expand(function (x, y) {
var self = Container.call(this);
// Create multiple miss text elements that animate outward
var missTexts = [];
var directions = [{
x: -1,
y: -1
}, {
x: 1,
y: -1
}, {
x: -1,
y: 1
}, {
x: 1,
y: 1
}, {
x: 0,
y: -1
}, {
x: 0,
y: 1
}, {
x: -1,
y: 0
}, {
x: 1,
y: 0
}];
for (var i = 0; i < 4; i++) {
var missText = new Text2('MISS', {
size: 60 + Math.random() * 40,
fill: 0xFF3333
});
missText.anchor.set(0.5, 0.5);
missText.x = 0;
missText.y = 0;
missText.alpha = 0.9;
self.addChild(missText);
missTexts.push(missText);
}
self.x = x;
self.y = y;
// Animate miss texts flying outward
for (var i = 0; i < missTexts.length; i++) {
var text = missTexts[i];
var dir = directions[i % directions.length];
var distance = 150 + Math.random() * 100;
tween(text, {
x: dir.x * distance,
y: dir.y * distance,
alpha: 0,
rotation: (Math.random() - 0.5) * Math.PI,
scaleX: 0.3,
scaleY: 0.3
}, {
duration: 800,
easing: tween.easeOut
});
}
// Destroy after animation
LK.setTimeout(function () {
self.destroy();
}, 900);
return self;
});
var RankEffect = Container.expand(function (rankData, x, y) {
var self = Container.call(this);
self.x = x;
self.y = y;
self.rankData = rankData;
self.effectTimer = 0;
self.particles = [];
// Create effects based on rank tier
self.createEffects = function () {
var rankName = rankData.name.toLowerCase();
if (rankName.includes('noob')) {
// Noob: Simple subtle glow
self.createBasicGlow();
} else if (rankName.includes('pro')) {
// Pro: Green energy particles
self.createEnergyParticles(0x00ff00, 3);
} else if (rankName.includes('dios')) {
// Dios: Golden aura with sparkles
self.createAura(0xffd700);
self.createSparkles(0xffd700, 5);
} else if (rankName.includes('hacker')) {
// Hacker: Digital glitch effects
self.createGlitchEffect(0xff00ff);
self.createDataStreams(0xff00ff);
} else if (rankName.includes('imparable')) {
// Imparable: Cyan lightning bolts
self.createLightning(0x00ffff);
self.createEnergyField(0x00ffff);
} else if (rankName.includes('leyenda')) {
// Leyenda: Star constellation effect
self.createStarConstellation(0xff8800);
self.createCosmicDust(0xff8800);
} else if (rankName.includes('supremo')) {
// Supremo: Enhanced rainbow prismatic effect with multiple layers
self.createPrismaticEffect();
self.createEnergyWaves(0xff0088);
self.createSupremoAura();
self.createRainbowBurst();
self.createPowerRings();
} else if (rankName.includes('infinito')) {
// Infinito: Ultimate transcendent effects combining all elements
self.createInfinityEffect();
self.createDimensionalRift();
self.createInfinityAura();
self.createInfinityBurst();
self.createCosmicStorm();
self.createEternityField();
}
};
self.createBasicGlow = function () {
var glow = self.attachAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
alpha: 0.2
});
glow.tint = rankData.color;
tween(glow, {
scaleX: 0.7,
scaleY: 0.7,
alpha: 0.1
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(glow, {
scaleX: 0.5,
scaleY: 0.5,
alpha: 0.2
}, {
duration: 2000,
easing: tween.easeInOut
});
}
});
};
self.createEnergyParticles = function (color, count) {
for (var i = 0; i < count; i++) {
LK.setTimeout(function () {
var particle = self.attachAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1,
alpha: 0.8
});
particle.tint = color;
var angle = Math.random() * Math.PI * 2;
var distance = 30 + Math.random() * 50;
particle.x = Math.cos(angle) * 20;
particle.y = Math.sin(angle) * 20;
tween(particle, {
x: Math.cos(angle) * distance,
y: Math.sin(angle) * distance,
scaleX: 0.05,
scaleY: 0.05,
alpha: 0
}, {
duration: 1500,
easing: tween.easeOut,
onFinish: function onFinish() {
particle.destroy();
}
});
}, i * 200);
}
};
self.createAura = function (color) {
var aura = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5,
alpha: 0.1
});
aura.tint = color;
tween(aura, {
scaleX: 2,
scaleY: 2,
alpha: 0.3,
rotation: Math.PI
}, {
duration: 3000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(aura, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0.1,
rotation: Math.PI * 2
}, {
duration: 3000,
easing: tween.easeInOut
});
}
});
};
self.createSparkles = function (color, count) {
for (var i = 0; i < count; i++) {
var sparkle = self.attachAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.05,
scaleY: 0.05,
alpha: 0
});
sparkle.tint = color;
var radius = 60;
var angle = i / count * Math.PI * 2;
sparkle.x = Math.cos(angle) * radius;
sparkle.y = Math.sin(angle) * radius;
self.particles.push({
obj: sparkle,
angle: angle,
radius: radius,
speed: 0.02 + Math.random() * 0.02
});
}
};
self.createStarConstellation = function (color) {
// Create multiple stars in a constellation pattern
var starPositions = [{
x: 0,
y: -40
}, {
x: 30,
y: -20
}, {
x: 40,
y: 10
}, {
x: 20,
y: 30
}, {
x: -20,
y: 30
}, {
x: -40,
y: 10
}, {
x: -30,
y: -20
}];
for (var i = 0; i < starPositions.length; i++) {
var star = self.attachAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1,
alpha: 0.6
});
star.x = starPositions[i].x;
star.y = starPositions[i].y;
star.tint = color;
// Make stars twinkle
(function (starObj) {
tween(starObj, {
scaleX: 0.15,
scaleY: 0.15,
alpha: 1
}, {
duration: 500 + Math.random() * 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(starObj, {
scaleX: 0.1,
scaleY: 0.1,
alpha: 0.6
}, {
duration: 500 + Math.random() * 1000,
easing: tween.easeInOut
});
}
});
})(star);
}
};
self.createGlitchEffect = function (color) {
var glitchLayers = [];
for (var i = 0; i < 3; i++) {
var glitch = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1,
alpha: 0.2
});
glitch.tint = color;
glitchLayers.push(glitch);
}
// Animate glitch layers
glitchLayers.forEach(function (layer, index) {
tween(layer, {
x: (Math.random() - 0.5) * 10,
y: (Math.random() - 0.5) * 10,
alpha: Math.random() * 0.3
}, {
duration: 100 + Math.random() * 200,
easing: tween.linear,
onFinish: function onFinish() {
tween(layer, {
x: 0,
y: 0,
alpha: 0.2
}, {
duration: 100 + Math.random() * 200,
easing: tween.linear
});
}
});
});
};
self.createDataStreams = function (color) {
// Create vertical data stream effect
for (var i = 0; i < 5; i++) {
LK.setTimeout(function () {
var stream = self.attachAsset('arrow_down', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.3,
alpha: 0.6
});
stream.tint = color;
stream.x = (Math.random() - 0.5) * 80;
stream.y = -40;
tween(stream, {
y: 40,
alpha: 0,
scaleY: 0.5
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
stream.destroy();
}
});
}, i * 200);
}
};
self.createLightning = function (color) {
var lightning = self.attachAsset('arrow_down', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 2,
alpha: 0
});
lightning.tint = color;
lightning.rotation = Math.random() * Math.PI * 2;
tween(lightning, {
alpha: 0.8,
scaleX: 0.5,
scaleY: 3
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(lightning, {
alpha: 0,
scaleX: 0.1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
lightning.destroy();
}
});
}
});
};
self.createEnergyField = function (color) {
// Create an energy field effect
var field = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
alpha: 0.2
});
field.tint = color;
// Animate energy field pulsing
tween(field, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0.4,
rotation: Math.PI
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(field, {
scaleX: 0.8,
scaleY: 0.8,
alpha: 0.2,
rotation: Math.PI * 2
}, {
duration: 1500,
easing: tween.easeInOut
});
}
});
};
self.createCosmicDust = function (color) {
// Create floating cosmic dust particles
for (var i = 0; i < 8; i++) {
var dust = self.attachAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.03 + Math.random() * 0.05,
scaleY: 0.03 + Math.random() * 0.05,
alpha: 0.4 + Math.random() * 0.4
});
dust.tint = color;
var radius = 40 + Math.random() * 60;
var angle = Math.random() * Math.PI * 2;
dust.x = Math.cos(angle) * radius;
dust.y = Math.sin(angle) * radius;
// Animate dust floating
tween(dust, {
x: dust.x + (Math.random() - 0.5) * 40,
y: dust.y + (Math.random() - 0.5) * 40,
alpha: 0,
scaleX: 0.01,
scaleY: 0.01
}, {
duration: 2000 + Math.random() * 2000,
easing: tween.easeOut,
onFinish: function onFinish() {
dust.destroy();
}
});
}
};
self.createPrismaticEffect = function () {
// Create enhanced rainbow prismatic effect with multiple layers
var colors = [0xFF0000, 0xFF7F00, 0xFFFF00, 0x00FF00, 0x0000FF, 0x4B0082, 0x9400D3];
// Create three layers of prisms for depth
for (var layer = 0; layer < 3; layer++) {
for (var i = 0; i < colors.length; i++) {
var prism = self.attachAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3 + layer * 0.15,
scaleY: 0.3 + layer * 0.15,
alpha: 0.5 - layer * 0.15
});
prism.tint = colors[i];
var angle = i / colors.length * Math.PI * 2 + layer * 0.2;
var radius = 50 + layer * 20;
prism.x = Math.cos(angle) * radius;
prism.y = Math.sin(angle) * radius;
self.particles.push({
obj: prism,
angle: angle,
radius: radius,
speed: 0.03 + layer * 0.01,
layer: layer
});
}
}
// Add central crown effect
var crown = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
alpha: 0.4
});
crown.tint = 0xFFD700;
crown.rotation = 0;
self.crownEffect = crown;
};
self.createEnergyWaves = function (color) {
// Create multiple types of expanding energy waves
for (var i = 0; i < 5; i++) {
LK.setTimeout(function () {
var wave = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3,
alpha: 0.7
});
wave.tint = color;
// Alternate between circular and diamond shapes
if (i % 2 === 0) {
wave.rotation = Math.PI / 4;
}
tween(wave, {
scaleX: 3,
scaleY: 3,
alpha: 0,
rotation: wave.rotation + Math.PI * 2
}, {
duration: 2000,
easing: tween.easeOut,
onFinish: function onFinish() {
wave.destroy();
}
});
}, i * 300);
}
// Add pulsing core energy
var core = self.attachAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
alpha: 0.8
});
core.tint = 0xFFFFFF;
self.energyCore = core;
};
self.createInfinityEffect = function () {
// Create multiple infinity symbols with enhanced particle effects
for (var layer = 0; layer < 3; layer++) {
var infinityPath = [];
for (var t = 0; t < Math.PI * 2; t += 0.2) {
var scale = 50 + layer * 20;
var x = scale * Math.cos(t) / (1 + Math.sin(t) * Math.sin(t));
var y = scale * Math.sin(t) * Math.cos(t) / (1 + Math.sin(t) * Math.sin(t));
infinityPath.push({
x: x,
y: y
});
}
infinityPath.forEach(function (pos, index) {
LK.setTimeout(function () {
var particle = self.attachAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.15 - layer * 0.03,
scaleY: 0.15 - layer * 0.03,
alpha: 0.9 - layer * 0.2
});
particle.x = pos.x;
particle.y = pos.y;
// Rainbow color cycling for infinity particles
var hue = (index * 20 + layer * 120) % 360;
particle.tint = self.hslToRgb(hue / 360, 1, 0.7);
self.particles.push({
obj: particle,
originalX: pos.x,
originalY: pos.y,
phase: index * 0.2,
layer: layer,
type: 'infinityParticle'
});
}, index * 30 + layer * 200);
});
}
// Add central cosmic core
var cosmicCore = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
alpha: 0.8
});
cosmicCore.tint = 0xFFFFFF;
self.cosmicCore = cosmicCore;
// Add rotating galaxy rings
for (var r = 0; r < 4; r++) {
var galaxyRing = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5 + r * 0.3,
scaleY: 0.1,
alpha: 0.4 - r * 0.08
});
galaxyRing.tint = 0xFFFFFF;
galaxyRing.rotation = r * Math.PI / 4;
self.particles.push({
obj: galaxyRing,
radius: 60 + r * 20,
angle: r * Math.PI / 4,
speed: 0.02 + r * 0.01,
type: 'galaxyRing'
});
}
};
self.createDimensionalRift = function () {
// Create multiple swirling dimensional rifts
for (var i = 0; i < 5; i++) {
var rift = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0 - i * 0.2,
scaleY: 0.05 + i * 0.02,
alpha: 0.6 - i * 0.1
});
var colors = [0x9400D3, 0xFF00FF, 0x00FFFF, 0xFFFFFF, 0xFF00FF];
rift.tint = colors[i];
rift.rotation = i * Math.PI / 5;
// Animate each rift with different timing
(function (riftObj, index) {
tween(riftObj, {
rotation: riftObj.rotation + Math.PI * 6,
scaleX: 0.05,
scaleY: 2.5 - index * 0.3,
alpha: 0
}, {
duration: 4000 + index * 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
riftObj.destroy();
}
});
})(rift, i);
}
// Add space-time distortion waves
self.createSpaceTimeWaves();
// Add quantum particles
self.createQuantumParticles();
};
self.createSupremoAura = function () {
// Create multi-layered aura effect
for (var i = 0; i < 4; i++) {
var aura = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2 + i * 0.3,
scaleY: 1.2 + i * 0.3,
alpha: 0.3 - i * 0.05
});
var colors = [0xFF0088, 0xFF00FF, 0x00FFFF, 0xFFFF00];
aura.tint = colors[i % colors.length];
// Animate each aura layer differently
(function (auraObj, index) {
tween(auraObj, {
rotation: Math.PI * 2,
scaleX: auraObj.scaleX + 0.2,
scaleY: auraObj.scaleY + 0.2,
alpha: 0.1
}, {
duration: 3000 + index * 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(auraObj, {
rotation: 0,
scaleX: 1.2 + index * 0.3,
scaleY: 1.2 + index * 0.3,
alpha: 0.3 - index * 0.05
}, {
duration: 3000 + index * 500,
easing: tween.easeInOut
});
}
});
})(aura, i);
}
};
self.createRainbowBurst = function () {
// Create periodic rainbow burst effect
self.rainbowBurstTimer = 0;
};
self.createPowerRings = function () {
// Create rotating power rings around the character
var ringColors = [0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF];
for (var i = 0; i < 6; i++) {
var ring = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 2,
alpha: 0.6
});
ring.tint = ringColors[i];
ring.rotation = i * Math.PI / 3;
self.particles.push({
obj: ring,
angle: i * Math.PI / 3,
radius: 0,
speed: 0.05,
type: 'powerRing'
});
}
};
self.createSpaceTimeWaves = function () {
// Create expanding space-time distortion waves
for (var i = 0; i < 8; i++) {
LK.setTimeout(function () {
var wave = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1,
alpha: 0.9
});
wave.tint = 0xFFFFFF;
tween(wave, {
scaleX: 4,
scaleY: 4,
alpha: 0,
rotation: Math.PI * 4
}, {
duration: 3000,
easing: tween.easeOut,
onFinish: function onFinish() {
wave.destroy();
}
});
}, i * 400);
}
};
self.createQuantumParticles = function () {
// Create quantum particle field effect
for (var i = 0; i < 20; i++) {
var quantum = self.attachAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.05,
scaleY: 0.05,
alpha: 0.8
});
var angle = Math.random() * Math.PI * 2;
var radius = 30 + Math.random() * 70;
quantum.x = Math.cos(angle) * radius;
quantum.y = Math.sin(angle) * radius;
quantum.tint = 0xFFFFFF;
self.particles.push({
obj: quantum,
angle: angle,
radius: radius,
speed: 0.1 + Math.random() * 0.05,
phase: Math.random() * Math.PI * 2,
type: 'quantum'
});
}
};
self.createInfinityAura = function () {
// Create ultimate infinity aura with multiple layers
for (var i = 0; i < 6; i++) {
var aura = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0 + i * 0.4,
scaleY: 1.0 + i * 0.4,
alpha: 0.4 - i * 0.06
});
// Shifting colors for each layer
var colors = [0xFFFFFF, 0xFF00FF, 0x00FFFF, 0xFFFF00, 0xFF0088, 0x00FF00];
aura.tint = colors[i];
(function (auraObj, index) {
tween(auraObj, {
rotation: Math.PI * 4,
scaleX: auraObj.scaleX + 0.3,
scaleY: auraObj.scaleY + 0.3,
alpha: 0.05
}, {
duration: 4000 + index * 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(auraObj, {
rotation: 0,
scaleX: 1.0 + index * 0.4,
scaleY: 1.0 + index * 0.4,
alpha: 0.4 - index * 0.06
}, {
duration: 4000 + index * 600,
easing: tween.easeInOut
});
}
});
})(aura, i);
}
};
self.createInfinityBurst = function () {
// Create periodic infinity burst effect
self.infinityBurstTimer = 0;
};
self.createCosmicStorm = function () {
// Create swirling cosmic storm effect
for (var i = 0; i < 15; i++) {
var storm = self.attachAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1 + Math.random() * 0.1,
scaleY: 0.1 + Math.random() * 0.1,
alpha: 0.6 + Math.random() * 0.3
});
var angle = Math.random() * Math.PI * 2;
var radius = 40 + Math.random() * 80;
storm.x = Math.cos(angle) * radius;
storm.y = Math.sin(angle) * radius;
// Rainbow colors for cosmic storm
var hue = Math.random() * 360;
storm.tint = self.hslToRgb(hue / 360, 1, 0.7);
self.particles.push({
obj: storm,
angle: angle,
radius: radius,
speed: 0.08 + Math.random() * 0.04,
orbitRadius: 20 + Math.random() * 40,
type: 'cosmicStorm'
});
}
};
self.createEternityField = function () {
// Create eternal energy field with complex patterns
var eternityCore = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
alpha: 0.2
});
eternityCore.tint = 0xFFFFFF;
self.eternityCore = eternityCore;
// Create orbital elements
for (var i = 0; i < 8; i++) {
var orbital = self.attachAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3,
alpha: 0.8
});
orbital.tint = 0xFFFFFF;
self.particles.push({
obj: orbital,
angle: i * Math.PI / 4,
radius: 80,
speed: 0.05,
type: 'eternal',
pulsePhase: i * Math.PI / 4
});
}
};
self.createInfinityLightning = function () {
// Create spectacular infinity lightning effect
var lightningCount = 8;
for (var i = 0; i < lightningCount; i++) {
var lightning = self.attachAsset('arrow_down', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 3,
alpha: 0
});
lightning.tint = 0xFFFFFF;
lightning.rotation = i * Math.PI / 4;
tween(lightning, {
alpha: 1,
scaleX: 0.8,
scaleY: 4
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(lightning, {
alpha: 0,
scaleX: 0.1,
scaleY: 2
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
lightning.destroy();
}
});
}
});
}
};
self.update = function () {
self.effectTimer++;
// Update rotating particles with enhanced animations for supremo
for (var i = 0; i < self.particles.length; i++) {
var p = self.particles[i];
p.angle += p.speed;
// Special animations for supremo particles
if (self.rankData.name.toLowerCase().includes('supremo')) {
if (p.layer !== undefined) {
// Multi-layer prismatic effect
var radiusOscillation = Math.sin(self.effectTimer * 0.02 + p.layer) * 10;
p.obj.x = Math.cos(p.angle) * (p.radius + radiusOscillation);
p.obj.y = Math.sin(p.angle) * (p.radius + radiusOscillation);
p.obj.alpha = 0.5 + 0.3 * Math.sin(self.effectTimer * 0.05 + i);
// Color shifting for rainbow effect
var hue = (self.effectTimer * 2 + i * 30) % 360;
var rgb = self.hslToRgb(hue / 360, 1, 0.5);
p.obj.tint = rgb;
} else if (p.type === 'powerRing') {
// Animate power rings
p.obj.rotation += 0.03;
p.radius = 40 + 30 * Math.sin(self.effectTimer * 0.03 + i);
p.obj.x = Math.cos(p.angle) * p.radius;
p.obj.y = Math.sin(p.angle) * p.radius;
p.obj.scaleX = 0.1 + 0.05 * Math.sin(self.effectTimer * 0.04 + i);
p.obj.alpha = 0.4 + 0.4 * Math.sin(self.effectTimer * 0.06 + i);
} else if (p.type === 'infinityParticle') {
// Animate infinity particles with flowing motion
var flow = Math.sin(self.effectTimer * 0.04 + p.phase);
p.obj.x = p.originalX + flow * 10;
p.obj.y = p.originalY + Math.cos(self.effectTimer * 0.04 + p.phase) * 10;
p.obj.alpha = 0.5 + 0.5 * Math.sin(self.effectTimer * 0.08 + p.phase);
// Color shift through rainbow
var particleHue = (self.effectTimer * 3 + p.phase * 60) % 360;
p.obj.tint = self.hslToRgb(particleHue / 360, 1, 0.8);
} else if (p.type === 'galaxyRing') {
// Animate galaxy rings with rotation
p.angle += p.speed;
p.obj.rotation = p.angle;
p.obj.alpha = 0.4 + 0.2 * Math.sin(self.effectTimer * 0.05 + i);
p.obj.scaleY = 0.1 + 0.05 * Math.sin(self.effectTimer * 0.06 + i);
} else if (p.type === 'quantum') {
// Animate quantum particles with erratic motion
p.angle += p.speed;
var quantumRadius = p.radius + 20 * Math.sin(self.effectTimer * 0.1 + p.phase);
p.obj.x = Math.cos(p.angle) * quantumRadius + Math.sin(self.effectTimer * 0.15 + p.phase) * 10;
p.obj.y = Math.sin(p.angle) * quantumRadius + Math.cos(self.effectTimer * 0.15 + p.phase) * 10;
p.obj.alpha = 0.3 + 0.7 * Math.abs(Math.sin(self.effectTimer * 0.2 + p.phase));
// Quantum color flickering
if (Math.random() < 0.1) {
var quantumColors = [0xFFFFFF, 0xFF00FF, 0x00FFFF, 0xFFFF00];
p.obj.tint = quantumColors[Math.floor(Math.random() * quantumColors.length)];
}
} else if (p.type === 'cosmicStorm') {
// Animate cosmic storm particles with spiral motion
p.angle += p.speed;
var spiralRadius = p.radius + p.orbitRadius * Math.sin(self.effectTimer * 0.04 + i);
p.obj.x = Math.cos(p.angle) * spiralRadius;
p.obj.y = Math.sin(p.angle) * spiralRadius;
p.obj.scaleX = p.obj.scaleY = 0.1 + 0.1 * Math.sin(self.effectTimer * 0.08 + i);
p.obj.alpha = 0.3 + 0.5 * Math.sin(self.effectTimer * 0.06 + i);
} else if (p.type === 'eternal') {
// Animate eternal orbital elements
p.angle += p.speed;
p.obj.x = Math.cos(p.angle) * p.radius;
p.obj.y = Math.sin(p.angle) * p.radius;
var pulse = Math.sin(self.effectTimer * 0.1 + p.pulsePhase);
p.obj.scaleX = p.obj.scaleY = 0.3 + 0.2 * pulse;
p.obj.alpha = 0.5 + 0.3 * pulse;
// Eternal color shifting
var eternalHue = (self.effectTimer * 4 + p.pulsePhase * 45) % 360;
p.obj.tint = self.hslToRgb(eternalHue / 360, 1, 0.9);
}
} else {
// Normal particle animation
p.obj.x = Math.cos(p.angle) * p.radius;
p.obj.y = Math.sin(p.angle) * p.radius;
p.obj.alpha = 0.3 + 0.7 * Math.sin(self.effectTimer * 0.05 + i);
}
}
// Special supremo animations
if (self.rankData.name.toLowerCase().includes('supremo')) {
// Animate crown effect
if (self.crownEffect) {
self.crownEffect.rotation += 0.02;
self.crownEffect.scaleX = 0.8 + 0.1 * Math.sin(self.effectTimer * 0.04);
self.crownEffect.scaleY = 0.8 + 0.1 * Math.sin(self.effectTimer * 0.04);
self.crownEffect.alpha = 0.4 + 0.2 * Math.sin(self.effectTimer * 0.06);
}
// Animate energy core
if (self.energyCore) {
self.energyCore.scaleX = 0.5 + 0.2 * Math.sin(self.effectTimer * 0.08);
self.energyCore.scaleY = 0.5 + 0.2 * Math.sin(self.effectTimer * 0.08);
self.energyCore.alpha = 0.8 + 0.2 * Math.sin(self.effectTimer * 0.1);
var coreHue = self.effectTimer * 3 % 360;
var coreRgb = self.hslToRgb(coreHue / 360, 1, 0.7);
self.energyCore.tint = coreRgb;
}
// Create rainbow burst periodically
if (self.rainbowBurstTimer !== undefined) {
self.rainbowBurstTimer++;
if (self.rainbowBurstTimer >= 120) {
self.createRainbowBurstEffect();
self.rainbowBurstTimer = 0;
}
}
}
// Special infinito animations - the ultimate effects
if (self.rankData.name.toLowerCase().includes('infinito')) {
// Animate cosmic core with complex pulsing
if (self.cosmicCore) {
self.cosmicCore.rotation += 0.03;
var coreScale = 0.5 + 0.3 * Math.sin(self.effectTimer * 0.05) + 0.2 * Math.sin(self.effectTimer * 0.13);
self.cosmicCore.scaleX = coreScale;
self.cosmicCore.scaleY = coreScale;
self.cosmicCore.alpha = 0.6 + 0.4 * Math.sin(self.effectTimer * 0.07);
// Ultra rainbow effect
var cosmicHue = self.effectTimer * 5 % 360;
self.cosmicCore.tint = self.hslToRgb(cosmicHue / 360, 1, 0.8);
}
// Animate eternity core
if (self.eternityCore) {
self.eternityCore.rotation -= 0.01;
self.eternityCore.scaleX = 2 + 0.5 * Math.sin(self.effectTimer * 0.03);
self.eternityCore.scaleY = 2 + 0.5 * Math.sin(self.effectTimer * 0.03);
self.eternityCore.alpha = 0.2 + 0.1 * Math.sin(self.effectTimer * 0.09);
}
// Create infinity burst periodically
if (self.infinityBurstTimer !== undefined) {
self.infinityBurstTimer++;
if (self.infinityBurstTimer >= 90) {
self.createInfinityBurstEffect();
self.createInfinityLightning();
self.infinityBurstTimer = 0;
}
}
}
// Don't recreate effects periodically - they persist until rank changes
};
// Helper function to convert HSL to RGB
self.hslToRgb = function (h, s, l) {
var r, g, b;
if (s === 0) {
r = g = b = l;
} else {
var hue2rgb = function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
};
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return Math.floor(r * 255) << 16 | Math.floor(g * 255) << 8 | Math.floor(b * 255);
};
self.createRainbowBurstEffect = function () {
// Create spectacular rainbow burst
var burstCount = 12;
for (var i = 0; i < burstCount; i++) {
var burst = self.attachAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1,
alpha: 1
});
var angle = i / burstCount * Math.PI * 2;
var hue = i / burstCount * 360;
burst.tint = self.hslToRgb(hue / 360, 1, 0.5);
burst.x = 0;
burst.y = 0;
tween(burst, {
x: Math.cos(angle) * 100,
y: Math.sin(angle) * 100,
scaleX: 0.5,
scaleY: 0.5,
alpha: 0,
rotation: Math.PI * 2
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
burst.destroy();
}
});
}
};
self.createInfinityBurstEffect = function () {
// Create ultimate infinity burst with multiple layers
var layers = 3;
var particlesPerLayer = 20;
for (var l = 0; l < layers; l++) {
for (var i = 0; i < particlesPerLayer; i++) {
var burst = self.attachAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.05 + l * 0.05,
scaleY: 0.05 + l * 0.05,
alpha: 1 - l * 0.2
});
var angle = i / particlesPerLayer * Math.PI * 2 + l * Math.PI / 6;
var baseRadius = 50 + l * 30;
burst.x = Math.cos(angle) * baseRadius * 0.1;
burst.y = Math.sin(angle) * baseRadius * 0.1;
// Ultra rainbow effect
var hue = (i / particlesPerLayer * 360 + l * 120) % 360;
burst.tint = self.hslToRgb(hue / 360, 1, 0.8);
tween(burst, {
x: Math.cos(angle) * baseRadius * 2,
y: Math.sin(angle) * baseRadius * 2,
scaleX: 0.8 - l * 0.1,
scaleY: 0.8 - l * 0.1,
alpha: 0,
rotation: Math.PI * 4
}, {
duration: 1500 + l * 300,
easing: tween.easeOut,
onFinish: function onFinish() {
burst.destroy();
}
});
}
}
// Create central nova explosion
var nova = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1,
alpha: 1
});
nova.tint = 0xFFFFFF;
tween(nova, {
scaleX: 5,
scaleY: 5,
alpha: 0,
rotation: Math.PI * 8
}, {
duration: 2000,
easing: tween.easeOut,
onFinish: function onFinish() {
nova.destroy();
}
});
};
// Initialize effects
self.createEffects();
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c2c54
});
/****
* Game Code
****/
// Game constants
var COLUMN_COUNT = 4;
var currentRankEffect = null;
var COLUMN_WIDTH = 2048 / COLUMN_COUNT;
var TARGET_Y = 2400;
var SPAWN_Y = -100;
var HIT_ZONE_HEIGHT = 80;
// Game state
var arrows = [];
var score = 0;
var combo = 0;
var missCount = 0;
var maxMisses = 10;
var gameStarted = false;
var gameState = 'start'; // 'start', 'countdown', 'playing', 'gameover'
var countdownValue = 3;
var countdownTimer = 0;
var arrowSpawnTimer = 0;
var spawnInterval = 45; // frames between arrow spawns
// Health bar system
var healthBar = 50; // Current health (0-100)
var maxHealth = 100;
var healthPerHit = 15; // Health gained per successful hit (increased)
var healthPerMiss = 8; // Health lost per miss (reduced for fairness)
var currentLevelHits = 0; // Current hits in this level (tracking for statistics)
// Level system with progressive speed increases
var level = 1;
var baseSpeed = 8;
var baseSpawnInterval = 45;
var speedMultiplier = 1.0; // Speed multiplier that increases with level
var maxSpeedMultiplier = 3.0; // Maximum speed cap for balance
var scoresPerLevel = [0, 1000, 2500, 5000, 8000, 12000, 17000, 23000, 30000, 40000];
// Direction mapping
var directions = ['left', 'down', 'up', 'right'];
var columnPositions = [];
// Expanded rank system with sub-levels and reduced score requirements
var ranks = [{
name: "noob I",
minScore: 0,
color: 0x666666
}, {
name: "noob II",
minScore: 500,
color: 0x777777
}, {
name: "noob III",
minScore: 1200,
color: 0x888888
}, {
name: "pro I",
minScore: 2000,
color: 0x00aa00
}, {
name: "pro II",
minScore: 3500,
color: 0x00cc00
}, {
name: "pro III",
minScore: 5500,
color: 0x00ff00
}, {
name: "dios I",
minScore: 8000,
color: 0xccaa00
}, {
name: "dios II",
minScore: 12000,
color: 0xddbb00
}, {
name: "dios III",
minScore: 18000,
color: 0xffd700
}, {
name: "hacker I",
minScore: 25000,
color: 0xcc00cc
}, {
name: "hacker II",
minScore: 35000,
color: 0xdd00dd
}, {
name: "hacker III",
minScore: 50000,
color: 0xff00ff
}, {
name: "imparable I",
minScore: 70000,
color: 0x00cccc
}, {
name: "imparable II",
minScore: 95000,
color: 0x00dddd
}, {
name: "imparable III",
minScore: 125000,
color: 0x00ffff
}, {
name: "leyenda I",
minScore: 160000,
color: 0xff6600
}, {
name: "leyenda II",
minScore: 200000,
color: 0xff7700
}, {
name: "leyenda III",
minScore: 250000,
color: 0xff8800
}, {
name: "supremo I",
minScore: 310000,
color: 0xff0066
}, {
name: "supremo II",
minScore: 380000,
color: 0xff0077
}, {
name: "supremo III",
minScore: 460000,
color: 0xff0088
}, {
name: "infinito",
minScore: 550000,
color: 0xffffff
}];
function getRankFromScore(score) {
var currentRank = ranks[0];
for (var i = 0; i < ranks.length; i++) {
if (score >= ranks[i].minScore) {
currentRank = ranks[i];
}
}
return currentRank;
}
function updatePlayerRank(score) {
// Initialize lifetime score if it doesn't exist
if (!storage.lifetimeScore) {
storage.lifetimeScore = 0;
}
// Add current game points to lifetime total
var pointsToAdd = score - (storage.lastSessionScore || 0);
if (pointsToAdd > 0) {
storage.lifetimeScore += pointsToAdd;
storage.lastSessionScore = score;
}
var newRank = getRankFromScore(storage.lifetimeScore);
var oldRankName = storage.currentRank;
if (newRank.name !== oldRankName) {
storage.currentRank = newRank.name;
showRankUpEffect(newRank);
return true;
}
return false;
}
function showRankUpEffect(rank) {
// Create rank up text
var rankUpTxt = new Text2('RANK UP!', {
size: 100,
fill: rank.color
});
rankUpTxt.anchor.set(0.5, 0.5);
rankUpTxt.x = 0;
rankUpTxt.y = -50;
rankUpTxt.alpha = 0;
rankUpTxt.scaleX = 0.1;
rankUpTxt.scaleY = 0.1;
LK.gui.center.addChild(rankUpTxt);
// Create new rank text
var newRankTxt = new Text2(rank.name.toUpperCase(), {
size: 80,
fill: rank.color
});
newRankTxt.anchor.set(0.5, 0.5);
newRankTxt.x = 0;
newRankTxt.y = 50;
newRankTxt.alpha = 0;
newRankTxt.scaleX = 0.1;
newRankTxt.scaleY = 0.1;
LK.gui.center.addChild(newRankTxt);
// Animate rank up effect
tween(rankUpTxt, {
alpha: 1,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 800,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(rankUpTxt, {
alpha: 0,
y: -150
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
rankUpTxt.destroy();
}
});
}
});
// Animate new rank text
LK.setTimeout(function () {
tween(newRankTxt, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 600,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(newRankTxt, {
alpha: 0,
y: 150
}, {
duration: 1200,
easing: tween.easeOut,
onFinish: function onFinish() {
newRankTxt.destroy();
}
});
}
});
}, 400);
// Flash screen with rank color
LK.effects.flashScreen(rank.color, 1000);
// Create large animated shield for rank up effect
var rankUpShield = LK.getAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1,
alpha: 0
});
rankUpShield.x = 0;
rankUpShield.y = 0;
rankUpShield.tint = rank.color;
LK.gui.center.addChild(rankUpShield);
// Create multiple shield layers for enhanced effect
var shieldLayers = [];
for (var sl = 0; sl < 3; sl++) {
var shieldLayer = LK.getAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1,
alpha: 0
});
shieldLayer.x = 0;
shieldLayer.y = 0;
shieldLayer.tint = rank.color;
LK.gui.center.addChild(shieldLayer);
shieldLayers.push(shieldLayer);
}
// Animate the main rank up shield
tween(rankUpShield, {
scaleX: 4,
scaleY: 4,
alpha: 1,
rotation: Math.PI * 3
}, {
duration: 1500,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(rankUpShield, {
scaleX: 0.1,
scaleY: 0.1,
alpha: 0,
rotation: Math.PI * 6
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
rankUpShield.destroy();
}
});
}
});
// Animate shield layers with staggered timing
for (var sl = 0; sl < shieldLayers.length; sl++) {
(function (layer, index) {
LK.setTimeout(function () {
tween(layer, {
scaleX: 2 + index * 0.5,
scaleY: 2 + index * 0.5,
alpha: 0.7 - index * 0.2,
rotation: Math.PI * (2 + index)
}, {
duration: 1200 + index * 200,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(layer, {
scaleX: 0.1,
scaleY: 0.1,
alpha: 0,
rotation: Math.PI * (4 + index * 2)
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
layer.destroy();
}
});
}
});
}, index * 300);
})(shieldLayers[sl], sl);
}
// Create celebration particles
for (var i = 0; i < 20; i++) {
LK.setTimeout(function () {
var particle = game.addChild(LK.getAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.2,
scaleY: 0.2,
alpha: 0.8
}));
particle.x = 1024 + (Math.random() - 0.5) * 600;
particle.y = 1366 + (Math.random() - 0.5) * 400;
particle.tint = rank.color;
var angle = Math.random() * Math.PI * 2;
var distance = 200 + Math.random() * 300;
tween(particle, {
x: particle.x + Math.cos(angle) * distance,
y: particle.y + Math.sin(angle) * distance,
scaleX: 0.05,
scaleY: 0.05,
alpha: 0,
rotation: Math.PI * 4
}, {
duration: 2000,
easing: tween.easeOut,
onFinish: function onFinish() {
particle.destroy();
}
});
}, i * 50);
}
// Update rank effect to match new rank at shield position
if (currentRankEffect) {
currentRankEffect.destroy();
}
currentRankEffect = new RankEffect(rank, -280, 135);
LK.gui.topRight.addChild(currentRankEffect);
}
// Calculate column positions
for (var i = 0; i < COLUMN_COUNT; i++) {
columnPositions.push(COLUMN_WIDTH * i + COLUMN_WIDTH / 2);
}
// Create target zones
var targetZones = [];
for (var i = 0; i < COLUMN_COUNT; i++) {
var targetZone = game.addChild(LK.getAsset('target_zone', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
}));
targetZone.x = columnPositions[i];
targetZone.y = TARGET_Y;
targetZones.push(targetZone);
// Add enhanced pulsing animation to target zones with particle effects
tween(targetZone, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 0.6
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(targetZone, {
scaleX: 0.9,
scaleY: 0.9,
alpha: 0.2
}, {
duration: 800,
easing: tween.easeInOut
});
}
});
// Add floating particles around target zone
LK.setTimeout(function () {
for (var p = 0; p < 4; p++) {
var particle = game.addChild(LK.getAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.05,
scaleY: 0.05,
alpha: 0.8
}));
var angle = p / 4 * Math.PI * 2;
var radius = 80;
particle.x = targetZone.x + Math.cos(angle) * radius;
particle.y = targetZone.y + Math.sin(angle) * radius;
particle.tint = i === 0 ? 0xff4757 : i === 1 ? 0x5352ed : i === 2 ? 0x2ed573 : 0xffa502;
tween(particle, {
scaleX: 0.15,
scaleY: 0.15,
alpha: 0,
x: targetZone.x + Math.cos(angle) * (radius + 60),
y: targetZone.y + Math.sin(angle) * (radius + 60)
}, {
duration: 2000,
easing: tween.easeOut,
onFinish: function onFinish() {
particle.destroy();
}
});
}
}, Math.random() * 1000);
}
// Create control zones at bottom of screen
var controlZones = [];
// Position control zones at the very bottom for better mobile reach
var controlZoneY = TARGET_Y + 200; // Moved even further down
// Make the control zones smaller to prevent overlapping but still comfortable for mobile
var controlZoneWidth = COLUMN_WIDTH * 0.9;
var controlZoneHeight = 350; // Reduced height to prevent button overlap
for (var i = 0; i < COLUMN_COUNT; i++) {
var controlZone = game.addChild(LK.getAsset('target_zone', {
anchorX: 0.5,
anchorY: 0.5,
// Slightly visible for better feedback
alpha: 0.15,
width: controlZoneWidth,
height: controlZoneHeight
}));
controlZone.x = columnPositions[i];
controlZone.y = controlZoneY;
controlZone.columnIndex = i;
// Color coding for visual feedback
controlZone.tint = i === 0 ? 0xff4757 : i === 1 ? 0x5352ed : i === 2 ? 0x2ed573 : 0xffa502;
controlZones.push(controlZone);
}
// Add decorative background elements
var rockets = [];
var confetti = [];
var comets = [];
// Create rocket decorations
for (var i = 0; i < 8; i++) {
var rocket = game.addChild(LK.getAsset('arrow_up', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.8,
alpha: 0.15
}));
rocket.x = Math.random() * 2048;
rocket.y = Math.random() * 2732;
rocket.speed = 1 + Math.random() * 2;
rocket.tint = Math.random() > 0.5 ? 0xFF6B6B : 0x4ECDC4;
rockets.push(rocket);
}
// Create confetti pieces with enhanced colors
for (var i = 0; i < 25; i++) {
var confettiPiece = game.addChild(LK.getAsset('target_zone', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1,
alpha: 0.2
}));
confettiPiece.x = Math.random() * 2048;
confettiPiece.y = Math.random() * 2732;
confettiPiece.speed = 0.3 + Math.random() * 1;
confettiPiece.rotationSpeed = (Math.random() - 0.5) * 0.1;
var colors = [0xFF6B6B, 0xF9CA24, 0xF0932B, 0xEB4D4B, 0x6C5CE7, 0xFF00FF, 0x00FF00];
confettiPiece.tint = colors[Math.floor(Math.random() * colors.length)];
confetti.push(confettiPiece);
}
// Create comet decorations
for (var i = 0; i < 6; i++) {
var comet = game.addChild(LK.getAsset('arrow_right', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.2,
alpha: 0.25
}));
comet.x = Math.random() * 2048;
comet.y = Math.random() * 2732;
comet.speed = 2 + Math.random() * 3;
comet.rotation = Math.random() * Math.PI * 2;
comet.tint = Math.random() > 0.5 ? 0x00FFFF : 0xFFFFFF;
comets.push(comet);
}
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
scoreTxt.x = 50;
scoreTxt.y = 50;
LK.gui.topLeft.addChild(scoreTxt);
var comboTxt = new Text2('Combo: 0', {
size: 50,
fill: 0xFFD700
});
comboTxt.anchor.set(0.5, 0);
comboTxt.x = 0;
comboTxt.y = 120;
LK.gui.top.addChild(comboTxt);
var levelTxt = new Text2('Level: 1', {
size: 50,
fill: 0xFF6B6B
});
levelTxt.anchor.set(1, 0);
levelTxt.x = -50;
levelTxt.y = 50;
LK.gui.topRight.addChild(levelTxt);
// Initialize rank text with stored rank
var storedRank = storage.currentRank || "noob I";
var initialRankData = null;
for (var r = 0; r < ranks.length; r++) {
if (ranks[r].name === storedRank) {
initialRankData = ranks[r];
break;
}
}
if (!initialRankData) {
initialRankData = ranks[0]; // fallback to noob
}
var rankTxt = new Text2('RANK: ' + initialRankData.name.toUpperCase(), {
size: 45,
fill: initialRankData.color
});
rankTxt.anchor.set(1, 0);
rankTxt.x = -50;
rankTxt.y = 110;
LK.gui.topRight.addChild(rankTxt);
// Add shield icon next to rank text with enhanced properties
var rankShield = LK.getAsset('shield', {
anchorX: 1,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 1.0
});
rankShield.x = -280;
rankShield.y = 135;
rankShield.tint = initialRankData.color;
rankShield.rotation = 0;
LK.gui.topRight.addChild(rankShield);
// Add shield glow effect
var shieldGlow = LK.getAsset('shield', {
anchorX: 1,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2,
alpha: 0.3
});
shieldGlow.x = -280;
shieldGlow.y = 135;
shieldGlow.tint = initialRankData.color;
LK.gui.topRight.addChild(shieldGlow);
// Create initial rank effect on GUI at shield position
currentRankEffect = new RankEffect(initialRankData, -280, 135);
LK.gui.topRight.addChild(currentRankEffect);
// Start shield glow animation
tween(shieldGlow, {
scaleX: 1.4,
scaleY: 1.4,
alpha: 0.1
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(shieldGlow, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 0.3
}, {
duration: 1500,
easing: tween.easeInOut
});
}
});
// Health bar UI with improved visuals
var healthBarBg = LK.getAsset('target_zone', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 0.8,
alpha: 0.6
});
healthBarBg.tint = 0x333333;
healthBarBg.x = 0;
healthBarBg.y = 150;
LK.gui.top.addChild(healthBarBg);
var healthBarBorder = LK.getAsset('target_zone', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4.2,
scaleY: 1,
alpha: 0.8
});
healthBarBorder.tint = 0xFFFFFF;
healthBarBorder.x = 0;
healthBarBorder.y = 150;
LK.gui.top.addChild(healthBarBorder);
var healthBarFill = LK.getAsset('target_zone', {
anchorX: 0,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.6
});
healthBarFill.tint = 0x00FF88;
healthBarFill.x = -280;
healthBarFill.y = 150;
LK.gui.top.addChild(healthBarFill);
var healthTxt = new Text2('FILL TO LEVEL UP', {
size: 45,
fill: 0xFFFFFF
});
healthTxt.anchor.set(0.5, 0.5);
healthTxt.x = 0;
healthTxt.y = 200;
LK.gui.top.addChild(healthTxt);
var accuracyTxt = new Text2('', {
size: 80,
fill: 0xFFFFFF
});
accuracyTxt.anchor.set(0.5, 0.5);
accuracyTxt.x = 0;
accuracyTxt.y = -200;
accuracyTxt.alpha = 0;
LK.gui.center.addChild(accuracyTxt);
// Start screen elements
var startTxt = new Text2('TAP TO START', {
size: 100,
fill: 0xFFFFFF
});
startTxt.anchor.set(0.5, 0.5);
startTxt.x = 0;
startTxt.y = 0;
LK.gui.center.addChild(startTxt);
var titleTxt = new Text2('RHYTHM ARROWS', {
size: 120,
fill: 0x00FFFF
});
titleTxt.anchor.set(0.5, 0.5);
titleTxt.x = 0;
titleTxt.y = -300;
LK.gui.center.addChild(titleTxt);
var subtitleTxt = new Text2('Hit the arrows in rhythm!', {
size: 50,
fill: 0xFFD700
});
subtitleTxt.anchor.set(0.5, 0.5);
subtitleTxt.x = 0;
subtitleTxt.y = 100;
LK.gui.center.addChild(subtitleTxt);
var countdownTxt = new Text2('3', {
size: 200,
fill: 0xFFD700
});
countdownTxt.anchor.set(0.5, 0.5);
countdownTxt.x = 0;
countdownTxt.y = 0;
countdownTxt.alpha = 0;
LK.gui.center.addChild(countdownTxt);
// Game over screen elements
var gameOverTxt = new Text2('GAME OVER', {
size: 100,
fill: 0xFF0000
});
gameOverTxt.anchor.set(0.5, 0.5);
gameOverTxt.x = 0;
gameOverTxt.y = -200;
gameOverTxt.alpha = 0;
LK.gui.center.addChild(gameOverTxt);
var finalComboTxt = new Text2('', {
size: 60,
fill: 0xFFD700
});
finalComboTxt.anchor.set(0.5, 0.5);
finalComboTxt.x = 0;
finalComboTxt.y = -100;
finalComboTxt.alpha = 0;
LK.gui.center.addChild(finalComboTxt);
var finalMissTxt = new Text2('', {
size: 60,
fill: 0xFF6B6B
});
finalMissTxt.anchor.set(0.5, 0.5);
finalMissTxt.x = 0;
finalMissTxt.y = -40;
finalMissTxt.alpha = 0;
LK.gui.center.addChild(finalMissTxt);
var restartTxt = new Text2('TAP TO PLAY AGAIN', {
size: 80,
fill: 0x00FFFF
});
restartTxt.anchor.set(0.5, 0.5);
restartTxt.x = 0;
restartTxt.y = 100;
restartTxt.alpha = 0;
LK.gui.center.addChild(restartTxt);
// Loading screen elements
var loadingTxt = new Text2('LOADING...', {
size: 80,
fill: 0x00FFFF
});
loadingTxt.anchor.set(0.5, 0.5);
loadingTxt.x = 0;
loadingTxt.y = 0;
loadingTxt.alpha = 0;
LK.gui.center.addChild(loadingTxt);
var loadingBar = LK.getAsset('target_zone', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0,
scaleY: 0.5,
alpha: 0
});
loadingBar.tint = 0x00FFFF;
loadingBar.x = 0;
loadingBar.y = 100;
LK.gui.center.addChild(loadingBar);
// Reset Points Function
function resetPlayerPoints() {
// Reset lifetime score to zero
storage.lifetimeScore = 0;
// Reset session score
storage.lastSessionScore = 0;
// Reset current rank to noob I (not hacker)
storage.currentRank = "noob I";
// Also reset the current game score to 0
score = 0;
// Update UI to reflect changes
updateUI();
// Show confirmation message
showAccuracyText('SCORE & RANK RESET!', 0xff0000);
LK.effects.flashScreen(0xff0000, 500);
}
// Reset Rank Function
function resetPlayerRank() {
// Reset current rank to noob I
storage.currentRank = "noob I";
// Update UI to reflect rank change
updateUI();
// Show confirmation message
showAccuracyText('RANK RESET TO NOOB I!', 0xff0000);
LK.effects.flashScreen(0xff0000, 500);
}
// Functions
function spawnArrow() {
var column = Math.floor(Math.random() * COLUMN_COUNT);
var direction = directions[column];
var arrow = new Arrow(direction, column);
arrow.x = columnPositions[column];
arrow.y = SPAWN_Y;
arrows.push(arrow);
game.addChild(arrow);
// Add enhanced entrance trail effect based on speed level
var trailCount = Math.min(5, 3 + Math.floor(speedMultiplier));
for (var t = 0; t < trailCount; t++) {
var trail = game.addChild(LK.getAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.2 + speedMultiplier * 0.1,
scaleY: 0.2 + speedMultiplier * 0.1,
alpha: 0.6 + speedMultiplier * 0.2
}));
trail.x = arrow.x + (Math.random() - 0.5) * (40 + speedMultiplier * 10);
trail.y = arrow.y - t * (30 + speedMultiplier * 5);
trail.tint = direction === 'left' ? 0xff4757 : direction === 'down' ? 0x5352ed : direction === 'up' ? 0x2ed573 : 0xffa502;
// Add intensity glow for higher speeds
if (speedMultiplier > 1.5) {
trail.tint = 0xFFFFFF; // White hot trail for high speeds
}
var trailDuration = Math.max(400, 600 - speedMultiplier * 50);
tween(trail, {
scaleX: 0.05,
scaleY: 0.05,
alpha: 0,
y: trail.y + (100 + speedMultiplier * 20)
}, {
duration: trailDuration,
easing: tween.easeOut,
onFinish: function onFinish() {
trail.destroy();
}
});
}
// Add entrance burst effect
var burst = game.addChild(LK.getAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1,
alpha: 1
}));
burst.x = arrow.x;
burst.y = arrow.y;
burst.tint = 0xFFFFFF;
tween(burst, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
burst.destroy();
}
});
}
function checkHit(arrow) {
var distance = Math.abs(arrow.y - TARGET_Y);
if (distance <= HIT_ZONE_HEIGHT * 0.8) {
// Perfect hit - more generous perfect zone
return 'perfect';
} else if (distance <= HIT_ZONE_HEIGHT * 3) {
// Good hit - much more generous good zone
return 'good';
}
return null;
}
function processHit(arrow, accuracy) {
var points = 0;
var comboMultiplier = Math.floor(combo / 10) + 1;
if (accuracy === 'perfect') {
points = 100 * comboMultiplier;
var perfectSound = LK.getSound('hit_perfect');
perfectSound.volume = storage.masterVolume * storage.sfxVolume;
perfectSound.play();
showAccuracyText('PERFECT!', 0x00ff00);
// Extra effect for perfect hits
LK.effects.flashScreen(0x00ff00, 100);
} else if (accuracy === 'good') {
points = 50 * comboMultiplier;
var goodSound = LK.getSound('hit_good');
goodSound.volume = storage.masterVolume * storage.sfxVolume;
goodSound.play();
showAccuracyText('GOOD', 0xffff00);
}
score += points;
combo++;
// Check for rank up
updatePlayerRank(score);
// Increase health bar
healthBar = Math.min(maxHealth, healthBar + healthPerHit);
currentLevelHits++;
// Check if health bar is full to advance to next level
if (healthBar >= maxHealth) {
level++;
currentLevelHits = 0;
// Reset health bar to starting level for next challenge
healthBar = 50;
// Increase speed multiplier progressively with each level
speedMultiplier = Math.min(1.0 + (level - 1) * 0.15, maxSpeedMultiplier);
// Slightly reduce spawn interval for more challenge but keep it balanced
spawnInterval = Math.max(25, baseSpawnInterval - Math.floor((level - 1) * 1.2));
// Show enhanced level up effect with speed notification
showAccuracyText('LEVEL ' + level + '! HEALTH FULL!', 0x00ffff);
LK.effects.flashScreen(0x00ffff, 700);
// Add speed burst visual effect
tween(game, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 200,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(game, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 300,
easing: tween.easeOut
});
}
});
}
// Create multiple hit effects for high combos
var effectCount = Math.min(3, Math.floor(combo / 25) + 1);
for (var i = 0; i < effectCount; i++) {
LK.setTimeout(function () {
var effect = new HitEffect(arrow.x + (Math.random() - 0.5) * 50, arrow.y + (Math.random() - 0.5) * 50);
game.addChild(effect);
}, i * 50);
}
// Enhanced combo system with multiple milestone effects
if (combo % 5 === 0 && combo > 0) {
// Create spectacular combo effect
var comboEffect = new ComboEffect(arrow.x, arrow.y - 100, combo);
game.addChild(comboEffect);
// Different effects based on combo milestones
if (combo >= 100) {
// LEGENDARY combo (100+)
LK.effects.flashScreen(0xFFD700, 800);
tween(comboTxt, {
scaleX: 3,
scaleY: 3,
tint: 0xFFD700,
rotation: 0.5
}, {
duration: 500,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(comboTxt, {
scaleX: 1.5,
scaleY: 1.5,
tint: 0xFFD700,
rotation: 0
}, {
duration: 600,
easing: tween.easeOut
});
}
});
} else if (combo >= 50) {
// EPIC combo (50+)
LK.effects.flashScreen(0xFF6B6B, 500);
tween(comboTxt, {
scaleX: 2.5,
scaleY: 2.5,
tint: 0xFF6B6B,
rotation: 0.3
}, {
duration: 400,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(comboTxt, {
scaleX: 1.3,
scaleY: 1.3,
tint: 0xFFD700,
rotation: 0
}, {
duration: 500,
easing: tween.easeOut
});
}
});
} else if (combo >= 25) {
// SUPER combo (25+)
LK.effects.flashScreen(0x4ECDC4, 300);
tween(comboTxt, {
scaleX: 2.2,
scaleY: 2.2,
tint: 0x4ECDC4
}, {
duration: 350,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(comboTxt, {
scaleX: 1.2,
scaleY: 1.2,
tint: 0xFFD700
}, {
duration: 450,
easing: tween.easeOut
});
}
});
} else {
// Regular combo milestone (5, 10, 15, 20)
tween(comboTxt, {
scaleX: 2,
scaleY: 2,
tint: 0x00FFFF
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(comboTxt, {
scaleX: 1,
scaleY: 1,
tint: 0xFFD700
}, {
duration: 400,
easing: tween.easeOut
});
}
});
}
// Create confetti burst for high combos
if (combo >= 25) {
var confettiCount = Math.min(30, combo / 2);
for (var c = 0; c < confettiCount; c++) {
LK.setTimeout(function () {
var burstConfetti = game.addChild(LK.getAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.15,
scaleY: 0.15,
alpha: 0.9
}));
burstConfetti.x = arrow.x + (Math.random() - 0.5) * 300;
burstConfetti.y = arrow.y + (Math.random() - 0.5) * 300;
var colors = [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0xF9CA24, 0xF0932B, 0xFFD700, 0x00FFFF];
burstConfetti.tint = colors[Math.floor(Math.random() * colors.length)];
tween(burstConfetti, {
y: burstConfetti.y - 400,
x: burstConfetti.x + (Math.random() - 0.5) * 200,
alpha: 0,
rotation: Math.random() * Math.PI * 4,
scaleX: 0.02,
scaleY: 0.02
}, {
duration: 2000,
easing: tween.easeOut,
onFinish: function onFinish() {
burstConfetti.destroy();
}
});
}, c * 20);
}
}
// Create firework effect for mega combos
if (combo >= 75) {
for (var f = 0; f < 5; f++) {
var firework = game.addChild(LK.getAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1,
alpha: 1
}));
firework.x = arrow.x + (Math.random() - 0.5) * 400;
firework.y = arrow.y + (Math.random() - 0.5) * 200;
firework.tint = 0xFFFFFF;
tween(firework, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
firework.destroy();
}
});
}
}
}
// Remove arrow
arrow.destroy();
var arrowIndex = arrows.indexOf(arrow);
if (arrowIndex > -1) {
arrows.splice(arrowIndex, 1);
}
updateUI();
}
function processMiss() {
combo = 0;
missCount++;
var missSound = LK.getSound('miss');
missSound.volume = storage.masterVolume * storage.sfxVolume;
missSound.play();
showAccuracyText('MISS', 0xff0000);
// Create miss effect animation instead of screen flash
var missEffect = new MissEffect(1024, 1366);
game.addChild(missEffect);
// Shake the screen slightly for miss feedback
tween(game, {
x: 10
}, {
duration: 50,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(game, {
x: -10
}, {
duration: 50,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(game, {
x: 0
}, {
duration: 100,
easing: tween.easeOut
});
}
});
}
});
// Decrease health bar
healthBar = Math.max(0, healthBar - healthPerMiss);
// Check if health bar reached 0
if (healthBar <= 0) {
showGameOverScreen();
}
updateUI();
}
function showAccuracyText(text, color) {
accuracyTxt.setText(text);
accuracyTxt.fill = color;
accuracyTxt.alpha = 1;
accuracyTxt.scaleX = 0.2;
accuracyTxt.scaleY = 0.2;
accuracyTxt.rotation = 0;
// Create spectacular effects based on accuracy type
if (text === 'PERFECT!') {
// Create burst of sparkles for perfect hits
for (var s = 0; s < 12; s++) {
var sparkle = game.addChild(LK.getAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1,
alpha: 1
}));
sparkle.x = 1024;
sparkle.y = 1366;
sparkle.tint = s % 2 === 0 ? 0x00FFFF : 0xFFD700;
var angle = s / 12 * Math.PI * 2;
var distance = 200 + Math.random() * 100;
tween(sparkle, {
x: 1024 + Math.cos(angle) * distance,
y: 1366 + Math.sin(angle) * distance,
scaleX: 0.5,
scaleY: 0.5,
alpha: 0,
rotation: Math.PI * 2
}, {
duration: 1200,
easing: tween.easeOut,
onFinish: function onFinish() {
sparkle.destroy();
}
});
}
// Enhanced perfect text animation
tween(accuracyTxt, {
scaleX: 2.5,
scaleY: 2.5,
rotation: 0.5
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(accuracyTxt, {
scaleX: 1.8,
scaleY: 1.8,
rotation: 0,
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut
});
}
});
} else if (text === 'GOOD') {
// Create ring effect for good hits
for (var r = 0; r < 8; r++) {
var ring = game.addChild(LK.getAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.2,
scaleY: 0.2,
alpha: 0.8
}));
ring.x = 1024;
ring.y = 1366;
ring.tint = 0xFFFF00;
var ringAngle = r / 8 * Math.PI * 2;
var ringDistance = 120;
tween(ring, {
x: 1024 + Math.cos(ringAngle) * ringDistance,
y: 1366 + Math.sin(ringAngle) * ringDistance,
scaleX: 0.4,
scaleY: 0.4,
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
ring.destroy();
}
});
}
// Enhanced good text animation
tween(accuracyTxt, {
scaleX: 2.0,
scaleY: 2.0,
rotation: 0.2
}, {
duration: 250,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(accuracyTxt, {
scaleX: 1.2,
scaleY: 1.2,
rotation: 0,
alpha: 0
}, {
duration: 700,
easing: tween.easeOut
});
}
});
} else {
// Default animation for MISS
tween(accuracyTxt, {
scaleX: 1.5,
scaleY: 1.5,
rotation: text === 'PERFECT!' ? 0.3 : 0.1
}, {
duration: 200,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(accuracyTxt, {
scaleX: 1,
scaleY: 1,
rotation: 0,
alpha: 0
}, {
duration: 800,
easing: tween.easeOut
});
}
});
}
}
function updateUI() {
scoreTxt.setText('Score: ' + score);
comboTxt.setText('Combo: ' + combo);
levelTxt.setText('Level: ' + level);
// Update rank display using stored rank
var storedRank = storage.currentRank || "noob I";
var currentRankData = null;
for (var r = 0; r < ranks.length; r++) {
if (ranks[r].name === storedRank) {
currentRankData = ranks[r];
break;
}
}
if (!currentRankData) {
currentRankData = ranks[0]; // fallback to noob
}
// Find next rank for progress display
var nextRank = null;
for (var nr = 0; nr < ranks.length; nr++) {
if (ranks[nr].minScore > (storage.lifetimeScore || 0)) {
nextRank = ranks[nr];
break;
}
}
var rankDisplayText = 'RANK: ' + currentRankData.name.toUpperCase();
if (nextRank) {
var progress = storage.lifetimeScore || 0;
var needed = nextRank.minScore - progress;
rankDisplayText += ' (' + needed + ' TO ' + nextRank.name.toUpperCase() + ')';
}
rankTxt.setText(rankDisplayText);
rankTxt.fill = currentRankData.color;
// Update shield color to match current rank
rankShield.tint = currentRankData.color;
shieldGlow.tint = currentRankData.color;
// Add enhanced pulsing animation to shield for visual appeal
tween(rankShield, {
scaleX: 1.1,
scaleY: 1.1,
alpha: 1,
rotation: 0.1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(rankShield, {
scaleX: 0.9,
scaleY: 0.9,
alpha: 0.95,
rotation: -0.1
}, {
duration: 1000,
easing: tween.easeInOut
});
}
});
// Add rotation effect for higher ranks
if (currentRankData.name.includes('dios') || currentRankData.name.includes('hacker') || currentRankData.name.includes('imparable') || currentRankData.name.includes('leyenda') || currentRankData.name.includes('supremo') || currentRankData.name.includes('infinito')) {
tween(rankShield, {
rotation: rankShield.rotation + Math.PI * 2
}, {
duration: 3000,
easing: tween.easeInOut
});
}
// Update health bar with smooth animation
var healthPercent = healthBar / maxHealth;
var targetScaleX = 2 * healthPercent;
// Animate health bar changes smoothly
tween(healthBarFill, {
scaleX: targetScaleX
}, {
duration: 300,
easing: tween.easeOut
});
// Change color based on health level with smooth transitions
var targetColor;
if (healthPercent > 0.7) {
targetColor = 0x00FF88; // Bright green
} else if (healthPercent > 0.5) {
targetColor = 0x88FF00; // Yellow-green
} else if (healthPercent > 0.3) {
targetColor = 0xFFAA00; // Orange
} else {
targetColor = 0xFF3333; // Bright red
}
// Animate color change
tween(healthBarFill, {
tint: targetColor
}, {
duration: 200,
easing: tween.easeOut
});
// Pulse effect when health is critical
if (healthPercent <= 0.2) {
tween(healthBarFill, {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(healthBarFill, {
alpha: 1
}, {
duration: 300,
easing: tween.easeInOut
});
}
});
}
}
function startCountdown() {
gameState = 'countdown';
startTxt.alpha = 0;
// Fade out title elements
tween(titleTxt, {
alpha: 0,
y: -400
}, {
duration: 800,
easing: tween.easeOut
});
tween(subtitleTxt, {
alpha: 0,
y: 200
}, {
duration: 800,
easing: tween.easeOut
});
countdownTxt.alpha = 1;
countdownValue = 3;
countdownTimer = 0;
}
function showCountdownNumber() {
if (countdownValue > 0) {
countdownTxt.setText(countdownValue.toString());
countdownTxt.fill = countdownValue === 3 ? 0xFF0000 : countdownValue === 2 ? 0xFFA500 : 0x00FF00;
} else {
countdownTxt.setText('GO!');
countdownTxt.fill = 0x00FFFF;
}
countdownTxt.scaleX = 3;
countdownTxt.scaleY = 3;
countdownTxt.rotation = 0.5;
countdownTxt.alpha = 1;
// Animate scale down with bounce effect
tween(countdownTxt, {
scaleX: 1,
scaleY: 1,
rotation: 0
}, {
duration: 800,
easing: tween.bounceOut
});
// Animate alpha fade out after scale animation
LK.setTimeout(function () {
tween(countdownTxt, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut
});
}, 600);
}
function restartGame() {
// Show loading screen first
gameState = 'loading';
loadingTxt.alpha = 1;
loadingBar.alpha = 1;
loadingBar.scaleX = 0;
// Animate loading bar
tween(loadingBar, {
scaleX: 3
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
// After loading, reset game
// Reset all game variables
score = 0;
combo = 0;
missCount = 0;
level = 1;
healthBar = 50;
currentLevelHits = 0;
arrowSpawnTimer = 0;
spawnInterval = 45;
speedMultiplier = 1.0; // Reset speed multiplier to base level
gameState = 'start';
gameStarted = false;
// Reset session score tracking but keep lifetime score and current rank
storage.lastSessionScore = 0;
// Clear all arrows
for (var i = arrows.length - 1; i >= 0; i--) {
arrows[i].destroy();
}
arrows = [];
// Stop music
LK.stopMusic();
// Reset UI visibility - show title again
startTxt.alpha = 1;
titleTxt.alpha = 1; // Show title again
titleTxt.y = -300;
titleTxt.rotation = 0;
subtitleTxt.alpha = 1;
subtitleTxt.y = 100;
countdownTxt.alpha = 0;
// Properly hide all game over elements
gameOverTxt.alpha = 0;
gameOverTxt.scaleX = 1;
gameOverTxt.scaleY = 1;
finalComboTxt.alpha = 0;
finalComboTxt.y = -100;
finalMissTxt.alpha = 0;
finalMissTxt.y = -40;
restartTxt.alpha = 0;
accuracyTxt.alpha = 0;
// Stop any active tweens on game over elements
tween.stop(gameOverTxt);
tween.stop(finalComboTxt);
tween.stop(finalMissTxt);
tween.stop(restartTxt);
// Hide loading screen
loadingTxt.alpha = 0;
loadingBar.alpha = 0;
// Reset shield to stored rank state
var currentStoredRank = storage.currentRank || "noob";
var currentStoredRankData = null;
for (var sr = 0; sr < ranks.length; sr++) {
if (ranks[sr].name === currentStoredRank) {
currentStoredRankData = ranks[sr];
break;
}
}
if (!currentStoredRankData) {
currentStoredRankData = ranks[0]; // fallback to noob
}
rankShield.tint = currentStoredRankData.color;
rankShield.scaleX = 1.0;
rankShield.scaleY = 1.0;
rankShield.alpha = 1.0;
rankShield.rotation = 0;
// Reset shield glow
shieldGlow.tint = currentStoredRankData.color;
shieldGlow.scaleX = 1.2;
shieldGlow.scaleY = 1.2;
shieldGlow.alpha = 0.3;
// Update UI
updateUI();
// Keep existing rank effect if it matches current rank
if (currentRankEffect && currentRankEffect.rankData.name !== currentStoredRankData.name) {
currentRankEffect.destroy();
currentRankEffect = null;
}
// Only create new rank effect if it doesn't exist
if (!currentRankEffect) {
currentRankEffect = new RankEffect(currentStoredRankData, -280, 135);
LK.gui.topRight.addChild(currentRankEffect);
}
}
});
}
function showGameOverScreen() {
gameState = 'gameover';
// Flash screen with dramatic effect
LK.effects.flashScreen(0x8B0000, 1000);
// Show game over elements with staggered animations
gameOverTxt.alpha = 0;
gameOverTxt.scaleX = 0.1;
gameOverTxt.scaleY = 0.1;
tween(gameOverTxt, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 800,
easing: tween.bounceOut
});
// Animate final stats with delay
LK.setTimeout(function () {
finalComboTxt.setText('Level Reached: ' + level);
finalComboTxt.alpha = 0;
finalComboTxt.y = -50;
tween(finalComboTxt, {
alpha: 1,
y: -100
}, {
duration: 600,
easing: tween.easeOut
});
}, 400);
LK.setTimeout(function () {
finalMissTxt.setText('Misses: ' + missCount);
finalMissTxt.alpha = 0;
finalMissTxt.y = 10;
tween(finalMissTxt, {
alpha: 1,
y: -40
}, {
duration: 600,
easing: tween.easeOut
});
}, 800);
// Remove restart text animation - keep it hidden
restartTxt.alpha = 0;
}
function handleColumnTap(columnIndex) {
// Find the closest arrow in the specified column
var closestArrow = null;
var closestDistance = Infinity;
var closestArrowIndex = -1;
for (var i = 0; i < arrows.length; i++) {
var arrow = arrows[i];
if (!arrow.hitTested && arrow.column === columnIndex) {
var distance = Math.abs(arrow.y - TARGET_Y);
if (distance < closestDistance) {
closestDistance = distance;
closestArrow = arrow;
closestArrowIndex = i;
}
}
}
if (closestArrow) {
// Check if arrow is close enough to the target zone to register a hit
// Use a larger detection range (150 pixels) to detect arrows approaching the target
if (closestDistance <= 150) {
var accuracy = checkHit(closestArrow);
if (accuracy) {
// Remove arrow from array and destroy it
closestArrow.destroy();
arrows.splice(closestArrowIndex, 1);
// Process the hit without calling processHit (which also destroys the arrow)
var points = 0;
var comboMultiplier = Math.floor(combo / 10) + 1;
if (accuracy === 'perfect') {
points = 100 * comboMultiplier;
var perfectSound = LK.getSound('hit_perfect');
perfectSound.volume = storage.masterVolume * storage.sfxVolume;
perfectSound.play();
showAccuracyText('PERFECT!', 0x00ff00);
// Extra effect for perfect hits
LK.effects.flashScreen(0x00ff00, 100);
} else if (accuracy === 'good') {
points = 50 * comboMultiplier;
var goodSound = LK.getSound('hit_good');
goodSound.volume = storage.masterVolume * storage.sfxVolume;
goodSound.play();
showAccuracyText('GOOD', 0xffff00);
}
score += points;
combo++;
// Check for rank up
updatePlayerRank(score);
// Increase health bar
healthBar = Math.min(maxHealth, healthBar + healthPerHit);
currentLevelHits++;
// Check if health bar is full to advance to next level
if (healthBar >= maxHealth) {
level++;
currentLevelHits = 0;
// Reset health bar to starting level for next challenge
healthBar = 50;
// Increase speed multiplier progressively with each level
speedMultiplier = Math.min(1.0 + (level - 1) * 0.15, maxSpeedMultiplier);
// Slightly reduce spawn interval for more challenge but keep it balanced
spawnInterval = Math.max(25, baseSpawnInterval - Math.floor((level - 1) * 1.2));
// Show enhanced level up effect with speed notification
showAccuracyText('LEVEL ' + level + '! HEALTH FULL!', 0x00ffff);
LK.effects.flashScreen(0x00ffff, 700);
// Add speed burst visual effect
tween(game, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 200,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(game, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 300,
easing: tween.easeOut
});
}
});
}
// Create multiple hit effects for high combos
var effectCount = Math.min(3, Math.floor(combo / 25) + 1);
for (var i = 0; i < effectCount; i++) {
LK.setTimeout(function () {
var effect = new HitEffect(closestArrow.x + (Math.random() - 0.5) * 50, closestArrow.y + (Math.random() - 0.5) * 50);
game.addChild(effect);
}, i * 50);
}
// Enhanced combo animations with milestone effects
if (combo % 5 === 0 && combo > 0) {
// Create combo effect at hit location
var comboEffect = new ComboEffect(closestArrow.x, closestArrow.y - 100, combo);
game.addChild(comboEffect);
// Scale combo text animation based on milestone
var targetScale = combo >= 50 ? 2.5 : combo >= 25 ? 2.0 : 1.8;
var targetColor = combo >= 100 ? 0xFFD700 : combo >= 50 ? 0xFF6B6B : combo >= 25 ? 0x4ECDC4 : 0x00FFFF;
tween(comboTxt, {
scaleX: targetScale,
scaleY: targetScale,
tint: targetColor
}, {
duration: 400,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(comboTxt, {
scaleX: combo >= 25 ? 1.2 : 1,
scaleY: combo >= 25 ? 1.2 : 1,
tint: 0xFFD700
}, {
duration: 500,
easing: tween.easeOut
});
}
});
}
updateUI();
} else {
processMiss();
}
} else {
// Arrow exists but is too far from target zone - count as miss
processMiss();
}
} else {
// Tapped when no arrow was in range for this column
processMiss();
}
}
// Input handling
var titleTapCount = 0;
var titleTapTimer = 0;
var rankResetTapCount = 0;
var rankResetTapTimer = 0;
game.down = function (x, y, obj) {
// Start countdown when screen is tapped
if (gameState === 'start') {
// Check for multiple taps on title to reset points
titleTapCount++;
titleTapTimer = 0;
// If tapped 5 times quickly, reset points
if (titleTapCount >= 5) {
resetPlayerPoints();
titleTapCount = 0;
return;
}
// Check for taps on rank shield area to reset rank
if (x >= 1700 && x <= 2048 && y >= 90 && y <= 160) {
rankResetTapCount++;
rankResetTapTimer = 0;
// If tapped rank shield 3 times quickly, reset rank
if (rankResetTapCount >= 3) {
resetPlayerRank();
rankResetTapCount = 0;
return;
}
return; // Prevent starting countdown when tapping rank area
}
startCountdown();
return; // Prevent other actions when start countdown begins
}
if (gameState === 'gameover') {
restartGame();
} else if (gameState === 'playing') {
// x10 is always active, no need to check for button tap
// Determine which column was tapped based on x position
var tappedColumn = -1;
for (var i = 0; i < COLUMN_COUNT; i++) {
var columnLeft = columnPositions[i] - COLUMN_WIDTH / 2;
var columnRight = columnPositions[i] + COLUMN_WIDTH / 2;
if (x >= columnLeft && x <= columnRight) {
tappedColumn = i;
break;
}
}
if (tappedColumn >= 0) {
// Enhanced visual feedback for control zone tap
var controlZone = controlZones[tappedColumn];
var originalAlpha = controlZone.alpha;
var originalScale = controlZone.scaleX;
// Flash and scale effect
controlZone.alpha = 0.8;
controlZone.scaleX = originalScale * 1.1;
controlZone.scaleY = controlZone.scaleY * 1.1;
tween(controlZone, {
alpha: originalAlpha,
scaleX: originalScale,
scaleY: originalScale
}, {
duration: 150,
easing: tween.easeOut
});
// Add ripple effect
var effect = new HitEffect(controlZone.x, controlZone.y - 50);
game.addChild(effect);
handleColumnTap(tappedColumn);
} else {
processMiss();
}
}
};
// Main game loop
game.update = function () {
// Enhanced rocket animations with trails and speed variation
for (var i = 0; i < rockets.length; i++) {
var rocket = rockets[i];
rocket.y -= rocket.speed + Math.sin(LK.ticks * 0.05 + i) * 0.5;
rocket.rotation += 0.02 + Math.sin(LK.ticks * 0.03 + i) * 0.01;
// Enhanced wobble with varying amplitude
rocket.x += Math.sin(LK.ticks * 0.02 + i) * (1 + Math.cos(LK.ticks * 0.01 + i));
// Scale pulsing effect
rocket.scaleX = 0.3 + 0.05 * Math.sin(LK.ticks * 0.08 + i);
rocket.scaleY = 0.8 + 0.1 * Math.sin(LK.ticks * 0.06 + i);
// Color shifting
var colorPhase = LK.ticks * 0.03 + i;
if (i % 2 === 0) {
rocket.alpha = 0.15 + 0.1 * Math.sin(colorPhase);
}
if (rocket.y < -100) {
rocket.y = 2732 + 100;
rocket.x = Math.random() * 2048;
rocket.speed = 1 + Math.random() * 3; // Randomize speed on reset
}
}
// Enhanced confetti with spiral motion and color cycling
for (var i = 0; i < confetti.length; i++) {
var piece = confetti[i];
piece.y -= piece.speed;
piece.rotation += piece.rotationSpeed + Math.sin(LK.ticks * 0.02 + i) * 0.02;
// Enhanced spiral motion
var spiralRadius = 20 + 10 * Math.sin(LK.ticks * 0.015 + i);
piece.x += Math.sin(LK.ticks * 0.01 + i) * 0.5 + Math.cos(LK.ticks * 0.02 + i) * spiralRadius * 0.02;
// Scale animation
piece.scaleX = 0.1 + 0.05 * Math.sin(LK.ticks * 0.05 + i);
piece.scaleY = 0.1 + 0.05 * Math.cos(LK.ticks * 0.04 + i);
// Alpha pulsing
piece.alpha = 0.2 + 0.15 * Math.sin(LK.ticks * 0.06 + i);
if (piece.y < -50) {
piece.y = 2732 + 50;
piece.x = Math.random() * 2048;
}
}
// Enhanced comets with dynamic trails and speed bursts
for (var i = 0; i < comets.length; i++) {
var comet = comets[i];
// Enhanced movement with speed bursts
var speedMultiplier = 1 + 0.5 * Math.sin(LK.ticks * 0.02 + i);
comet.x += Math.cos(comet.rotation) * comet.speed * speedMultiplier;
comet.y += Math.sin(comet.rotation) * comet.speed * speedMultiplier;
// Enhanced trail effect with varying opacity and scale
comet.alpha = 0.15 + 0.15 * Math.sin(LK.ticks * 0.1 + i);
comet.scaleX = 0.6 + 0.2 * Math.sin(LK.ticks * 0.08 + i);
comet.scaleY = 0.2 + 0.1 * Math.cos(LK.ticks * 0.06 + i);
// Slight rotation wobble
comet.rotation += Math.sin(LK.ticks * 0.03 + i) * 0.01;
// Reset position when off screen
if (comet.x < -100 || comet.x > 2148 || comet.y < -100 || comet.y > 2832) {
comet.x = Math.random() * 2048;
comet.y = Math.random() * 2732;
comet.rotation = Math.random() * Math.PI * 2;
comet.speed = 2 + Math.random() * 4; // Randomize speed on reset
}
}
if (gameState === 'loading') {
// Animate loading text
loadingTxt.alpha = 0.7 + 0.3 * Math.sin(LK.ticks * 0.15);
return;
}
if (gameState === 'start') {
// Reset title tap count after timeout
titleTapTimer++;
if (titleTapTimer > 180) {
// 3 seconds at 60fps
titleTapCount = 0;
titleTapTimer = 0;
}
// Reset rank reset tap count after timeout
rankResetTapTimer++;
if (rankResetTapTimer > 180) {
// 3 seconds at 60fps
rankResetTapCount = 0;
rankResetTapTimer = 0;
}
// Update rank display on start screen
updateUI();
// Animate start text with rainbow effect and enhanced pulsing
startTxt.alpha = 0.7 + 0.3 * Math.sin(LK.ticks * 0.15);
startTxt.scaleX = 1 + 0.1 * Math.sin(LK.ticks * 0.12);
startTxt.scaleY = 1 + 0.1 * Math.sin(LK.ticks * 0.12);
var colorPhase = LK.ticks * 0.08;
var r = Math.sin(colorPhase) * 127 + 128;
var g = Math.sin(colorPhase + 2) * 127 + 128;
var b = Math.sin(colorPhase + 4) * 127 + 128;
startTxt.fill = Math.floor(r) << 16 | Math.floor(g) << 8 | Math.floor(b);
// Enhanced title animation with floating and rotation
titleTxt.y = -300 + 15 * Math.sin(LK.ticks * 0.08);
titleTxt.rotation = 0.15 * Math.sin(LK.ticks * 0.06);
titleTxt.scaleX = 1 + 0.05 * Math.sin(LK.ticks * 0.1);
titleTxt.scaleY = 1 + 0.05 * Math.sin(LK.ticks * 0.1);
// Enhanced subtitle animation with color shifting
subtitleTxt.alpha = 0.6 + 0.4 * Math.sin(LK.ticks * 0.12);
subtitleTxt.y = 100 + 5 * Math.sin(LK.ticks * 0.1);
var subColorPhase = LK.ticks * 0.06;
var subR = Math.sin(subColorPhase + 1) * 127 + 128;
var subG = Math.sin(subColorPhase + 3) * 127 + 128;
var subB = Math.sin(subColorPhase + 5) * 127 + 128;
subtitleTxt.fill = Math.floor(subR) << 16 | Math.floor(subG) << 8 | Math.floor(subB);
return;
}
if (gameState === 'countdown') {
countdownTimer++;
if (countdownTimer === 1) {
showCountdownNumber();
} else if (countdownTimer >= 60) {
countdownValue--;
if (countdownValue > 0) {
countdownTimer = 0;
showCountdownNumber();
} else {
// Start the game
gameState = 'playing';
gameStarted = true;
countdownTxt.alpha = 0;
LK.playMusic('background_music');
}
}
return;
}
if (gameState === 'gameover') {
// Keep restart text hidden and add animated background effects
restartTxt.alpha = 0;
// Add swirling particles effect during game over
for (var p = 0; p < 3; p++) {
if (Math.random() < 0.1) {
var particle = game.addChild(LK.getAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1,
alpha: 0.3
}));
particle.x = Math.random() * 2048;
particle.y = 2732 + 50;
particle.tint = Math.random() > 0.5 ? 0xFF6B6B : 0x4ECDC4;
tween(particle, {
y: -50,
rotation: Math.PI * 4,
alpha: 0,
scaleX: 0.3,
scaleY: 0.3
}, {
duration: 3000,
easing: tween.easeOut,
onFinish: function onFinish() {
particle.destroy();
}
});
}
}
return;
}
// Game playing state
// Spawn arrows
arrowSpawnTimer++;
if (arrowSpawnTimer >= spawnInterval) {
spawnArrow();
arrowSpawnTimer = 0;
}
// Update arrows and check for misses
for (var i = arrows.length - 1; i >= 0; i--) {
var arrow = arrows[i];
// Check if arrow passed the target zone without being hit
if (!arrow.hitTested && arrow.y > TARGET_Y + HIT_ZONE_HEIGHT) {
arrow.hitTested = true;
processMiss();
}
// Remove arrows that are off screen
if (arrow.y > 2732 + 100) {
arrow.destroy();
arrows.splice(i, 1);
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -1187,12 +1187,9 @@
self.infinityBurstTimer = 0;
}
}
}
- // Recreate effects periodically
- if (self.effectTimer % 180 === 0) {
- self.createEffects();
- }
+ // Don't recreate effects periodically - they persist until rank changes
};
// Helper function to convert HSL to RGB
self.hslToRgb = function (h, s, l) {
var r, g, b;
@@ -2783,16 +2780,18 @@
shieldGlow.scaleY = 1.2;
shieldGlow.alpha = 0.3;
// Update UI
updateUI();
- // Destroy any existing rank effect
- if (currentRankEffect) {
+ // Keep existing rank effect if it matches current rank
+ if (currentRankEffect && currentRankEffect.rankData.name !== currentStoredRankData.name) {
currentRankEffect.destroy();
currentRankEffect = null;
}
- // Create new rank effect on GUI at shield position
- currentRankEffect = new RankEffect(currentStoredRankData, -280, 135);
- LK.gui.topRight.addChild(currentRankEffect);
+ // Only create new rank effect if it doesn't exist
+ if (!currentRankEffect) {
+ currentRankEffect = new RankEffect(currentStoredRankData, -280, 135);
+ LK.gui.topRight.addChild(currentRankEffect);
+ }
}
});
}
function showGameOverScreen() {