User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'currentLeaderboard[currentLeaderboard.length] = {' Line Number: 659 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'currentLeaderboard[currentLeaderboard.length] = {' Line Number: 654 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'currentLeaderboard.push({' Line Number: 652 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'storage.leaderboard.push(newEntry);' Line Number: 657 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'storage.leaderboard.push(newEntry);' Line Number: 656. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Has una tabla de clasificación de todas las personas que juegene el juego. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Has que cuando la barra este llena pase de nivel cada vez mas dificil pero si no no pasara de nivel ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Has que cada vez se ponga las flechas mas rapidas y has que el juego sea mas divertido. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Has que todas las flecha tenga la misma velocidad y has que el juego sea mas animado las flechas y que sea mas adictivo. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Quita ese boton de estar y ponlo que cuando se pulse la pantalla empieze la cuenta regresiva.
User prompt
Quita el boton de opciones has el juego mas animado quiero que este juego sea el top 1. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
añadir en el menu un sistema de opciones de subir y bajar el volumen y cosas como bajar los gráficos del juego, etc. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Cuando se pulse el boton de settingg se ponga el menu de opciones. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Sigue empezando arreglalo has el boton mas grande o pon para empieze la partida se pulse un voton en vez de la pantalla.
User prompt
Y porque sigue empezando
User prompt
¡¡Cuando se pulse el boton de opciones no debe de empezarse el juego!!
User prompt
Cuando se pulse se ponen las opciones que te dije. ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
Pon el boton mas abajo.
User prompt
Pon el boton de ajustes que se vea en la pantalla y que vaya ocultando cuando empieze el juego. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Añade al juego lo que tu quiera añade en el menu un sistema de opciones de subir y bajar el volumen y cosas como bajar los graficos del juego etc. ↪💡 Consider importing and using the following plugins: @upit/storage.v1, @upit/tween.v1
User prompt
Has que el juego sea mas divertido ponle lo que tu quieras. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Quita la particulas amarillas y azulas solo ponle major diversion al juego.
User prompt
Y el good perfect. has un sistema de combos y animaciones. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Mejora las anumaciones de good, perfect etc tambien has un poco mas pequeños los botones para que no se peguen añade cometas al fondo y has una pantalla de carga cuan se pulse pañsar para reintentar en el game over para poner el titulo de nuevo. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Esta bien pero agrega mas decoracion en el fondo como cochetes ocnnis etc. Mejora el sistema de miss de se pone fondo rojo quitalo y has una animacion de miss mejora los combos con animaciones etc ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* 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;
self.speed = baseSpeed + (level - 1) * 2;
self.hitTested = false;
self.update = function () {
self.y += self.speed;
};
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;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c2c54
});
/****
* Game Code
****/
// Game constants
var COLUMN_COUNT = 4;
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 hitsNeededForNextLevel = 10; // Hits needed to advance level
var currentLevelHits = 0; // Current hits in this level
// Level system
var level = 1;
var baseSpeed = 8;
var baseSpawnInterval = 45;
var scoresPerLevel = [0, 1000, 2500, 5000, 8000, 12000, 17000, 23000, 30000, 40000];
// Direction mapping
var directions = ['left', 'down', 'up', 'right'];
var columnPositions = [];
// 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 pulsing animation to target zones
tween(targetZone, {
scaleX: 1.1,
scaleY: 1.1,
alpha: 0.5
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(targetZone, {
scaleX: 1,
scaleY: 1,
alpha: 0.3
}, {
duration: 1000,
easing: tween.easeInOut
});
}
});
}
// 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 backgroundParticles = [];
var rockets = [];
var confetti = [];
var comets = [];
// Create floating particles
for (var i = 0; i < 15; i++) {
var particle = game.addChild(LK.getAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.2,
scaleY: 0.2,
alpha: 0.1
}));
particle.x = Math.random() * 2048;
particle.y = Math.random() * 2732;
particle.speed = 0.5 + Math.random() * 1.5;
backgroundParticles.push(particle);
}
// 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
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, 0x4ECDC4, 0x45B7D1, 0xF9CA24, 0xF0932B, 0xEB4D4B, 0x6C5CE7];
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);
// 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('HEALTH', {
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);
// 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);
}
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;
LK.getSound('hit_perfect').play();
showAccuracyText('PERFECT!', 0x00ff00);
// Extra effect for perfect hits
LK.effects.flashScreen(0x00ff00, 100);
} else if (accuracy === 'good') {
points = 50 * comboMultiplier;
LK.getSound('hit_good').play();
showAccuracyText('GOOD', 0xffff00);
}
score += points;
combo++;
// Increase health bar
healthBar = Math.min(maxHealth, healthBar + healthPerHit);
currentLevelHits++;
// Check if ready for next level
if (currentLevelHits >= hitsNeededForNextLevel) {
level++;
currentLevelHits = 0;
// Update spawn interval based on level
spawnInterval = Math.max(15, baseSpawnInterval - (level - 1) * 3);
// Show level up effect
showAccuracyText('LEVEL ' + level + '!', 0x00ffff);
LK.effects.flashScreen(0x00ffff, 500);
}
// 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);
}
// Animate combo text on milestone combos
if (combo % 10 === 0 && combo > 0) {
// Create spectacular combo effect
var comboEffect = new ComboEffect(arrow.x, arrow.y - 100, combo);
game.addChild(comboEffect);
// Enhanced combo text animation
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 >= 50) {
for (var c = 0; c < 15; c++) {
LK.setTimeout(function () {
var burstConfetti = game.addChild(LK.getAsset('hit_effect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.2,
scaleY: 0.2,
alpha: 0.8
}));
burstConfetti.x = arrow.x + (Math.random() - 0.5) * 200;
burstConfetti.y = arrow.y + (Math.random() - 0.5) * 200;
var colors = [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0xF9CA24, 0xF0932B];
burstConfetti.tint = colors[Math.floor(Math.random() * colors.length)];
tween(burstConfetti, {
y: burstConfetti.y - 300,
alpha: 0,
rotation: Math.random() * Math.PI * 2,
scaleX: 0.05,
scaleY: 0.05
}, {
duration: 1500,
easing: tween.easeOut,
onFinish: function onFinish() {
burstConfetti.destroy();
}
});
}, c * 30);
}
}
}
// Remove arrow
arrow.destroy();
var arrowIndex = arrows.indexOf(arrow);
if (arrowIndex > -1) {
arrows.splice(arrowIndex, 1);
}
updateUI();
}
function processMiss() {
combo = 0;
missCount++;
LK.getSound('miss').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.5;
accuracyTxt.scaleY = 0.5;
accuracyTxt.rotation = 0;
// Enhanced animation with scale bounce and rotation
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 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;
gameState = 'start';
gameStarted = false;
// 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;
// Update UI
updateUI();
}
});
}
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;
LK.getSound('hit_perfect').play();
showAccuracyText('PERFECT!', 0x00ff00);
// Extra effect for perfect hits
LK.effects.flashScreen(0x00ff00, 100);
} else if (accuracy === 'good') {
points = 50 * comboMultiplier;
LK.getSound('hit_good').play();
showAccuracyText('GOOD', 0xffff00);
}
score += points;
combo++;
// Increase health bar
healthBar = Math.min(maxHealth, healthBar + healthPerHit);
currentLevelHits++;
// Check if ready for next level
if (currentLevelHits >= hitsNeededForNextLevel) {
level++;
currentLevelHits = 0;
// Update spawn interval based on level
spawnInterval = Math.max(15, baseSpawnInterval - (level - 1) * 3);
// Show level up effect
showAccuracyText('LEVEL ' + level + '!', 0x00ffff);
LK.effects.flashScreen(0x00ffff, 500);
}
// 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);
}
// Animate combo text on milestone combos
if (combo % 10 === 0 && combo > 0) {
tween(comboTxt, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(comboTxt, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
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
game.down = function (x, y, obj) {
if (gameState === 'start') {
startCountdown();
} else if (gameState === 'gameover') {
restartGame();
} else if (gameState === 'playing') {
// 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 () {
// Animate background particles
for (var i = 0; i < backgroundParticles.length; i++) {
var particle = backgroundParticles[i];
particle.y -= particle.speed;
particle.rotation += 0.02;
if (particle.y < -50) {
particle.y = 2732 + 50;
particle.x = Math.random() * 2048;
}
}
// Animate rockets
for (var i = 0; i < rockets.length; i++) {
var rocket = rockets[i];
rocket.y -= rocket.speed;
rocket.rotation += 0.01;
// Add slight wobble
rocket.x += Math.sin(LK.ticks * 0.02 + i) * 0.5;
if (rocket.y < -100) {
rocket.y = 2732 + 100;
rocket.x = Math.random() * 2048;
}
}
// Animate confetti
for (var i = 0; i < confetti.length; i++) {
var piece = confetti[i];
piece.y -= piece.speed;
piece.rotation += piece.rotationSpeed;
// Add floating motion
piece.x += Math.sin(LK.ticks * 0.01 + i) * 0.3;
if (piece.y < -50) {
piece.y = 2732 + 50;
piece.x = Math.random() * 2048;
}
}
// Animate comets
for (var i = 0; i < comets.length; i++) {
var comet = comets[i];
// Move comet diagonally across screen
comet.x += Math.cos(comet.rotation) * comet.speed;
comet.y += Math.sin(comet.rotation) * comet.speed;
// Add trail effect with alpha pulsing
comet.alpha = 0.15 + 0.1 * Math.sin(LK.ticks * 0.1 + i);
// 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;
}
}
if (gameState === 'loading') {
// Animate loading text
loadingTxt.alpha = 0.7 + 0.3 * Math.sin(LK.ticks * 0.15);
return;
}
if (gameState === 'start') {
// Animate start text with rainbow effect
startTxt.alpha = 0.7 + 0.3 * Math.sin(LK.ticks * 0.1);
var colorPhase = LK.ticks * 0.05;
startTxt.fill = 0xFFFFFF;
// Animate title with floating effect
titleTxt.y = -300 + 10 * Math.sin(LK.ticks * 0.08);
titleTxt.rotation = 0.1 * Math.sin(LK.ticks * 0.06);
// Animate subtitle
subtitleTxt.alpha = 0.6 + 0.4 * Math.sin(LK.ticks * 0.12);
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
restartTxt.alpha = 0;
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
@@ -261,11 +261,11 @@
// 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 much larger for comfortable mobile tapping
-var controlZoneWidth = COLUMN_WIDTH * 1.2;
-var controlZoneHeight = 500; // Very large height for easy tapping
+// 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,
@@ -284,8 +284,9 @@
// Add decorative background elements
var backgroundParticles = [];
var rockets = [];
var confetti = [];
+var comets = [];
// Create floating particles
for (var i = 0; i < 15; i++) {
var particle = game.addChild(LK.getAsset('hit_effect', {
anchorX: 0.5,
@@ -330,8 +331,24 @@
var colors = [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0xF9CA24, 0xF0932B, 0xEB4D4B, 0x6C5CE7];
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
@@ -476,8 +493,29 @@
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);
// Functions
function spawnArrow() {
var column = Math.floor(Math.random() * COLUMN_COUNT);
var direction = directions[column];
@@ -641,13 +679,30 @@
function showAccuracyText(text, color) {
accuracyTxt.setText(text);
accuracyTxt.fill = color;
accuracyTxt.alpha = 1;
+ accuracyTxt.scaleX = 0.5;
+ accuracyTxt.scaleY = 0.5;
+ accuracyTxt.rotation = 0;
+ // Enhanced animation with scale bounce and rotation
tween(accuracyTxt, {
- alpha: 0
+ scaleX: 1.5,
+ scaleY: 1.5,
+ rotation: text === 'PERFECT!' ? 0.3 : 0.1
}, {
- duration: 1000,
- easing: tween.easeOut
+ 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);
@@ -752,51 +807,69 @@
});
}, 600);
}
function restartGame() {
- // Reset all game variables
- score = 0;
- combo = 0;
- missCount = 0;
- level = 1;
- healthBar = 50;
- currentLevelHits = 0;
- arrowSpawnTimer = 0;
- spawnInterval = 45;
- gameState = 'start';
- gameStarted = false;
- // 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);
- // Update UI
- updateUI();
+ // 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;
+ gameState = 'start';
+ gameStarted = false;
+ // 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;
+ // Update UI
+ updateUI();
+ }
+ });
}
function showGameOverScreen() {
gameState = 'gameover';
// Flash screen with dramatic effect
@@ -1013,8 +1086,28 @@
piece.y = 2732 + 50;
piece.x = Math.random() * 2048;
}
}
+ // Animate comets
+ for (var i = 0; i < comets.length; i++) {
+ var comet = comets[i];
+ // Move comet diagonally across screen
+ comet.x += Math.cos(comet.rotation) * comet.speed;
+ comet.y += Math.sin(comet.rotation) * comet.speed;
+ // Add trail effect with alpha pulsing
+ comet.alpha = 0.15 + 0.1 * Math.sin(LK.ticks * 0.1 + i);
+ // 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;
+ }
+ }
+ if (gameState === 'loading') {
+ // Animate loading text
+ loadingTxt.alpha = 0.7 + 0.3 * Math.sin(LK.ticks * 0.15);
+ return;
+ }
if (gameState === 'start') {
// Animate start text with rainbow effect
startTxt.alpha = 0.7 + 0.3 * Math.sin(LK.ticks * 0.1);
var colorPhase = LK.ticks * 0.05;