User prompt
el logo debe aparecer gradualmente y venir lentamente desde el fondo ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
en la intro tambien debe aparecer el logo del juego
User prompt
pero el efecto de estrellas en la intro debera ocupar toda la pantalla ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
agrega al fondo de la intro el efecto de estrellas que usamos para la noche en el juego ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
en la intro agregar un fondo color negro directamente
User prompt
cambiar el TEXTO DE SALTAR INTRO POR TOXIK STUDIO Games
User prompt
esta perfecto pero deben estar mas claras las casas cuando es de dia las veo oscurecidad deberian estar mas claras ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
la luminosidad y el oscurecer debe aplicarse a TODAS LAS CASAS Y ARBOLES del juego ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
EL BOTON SALTAR INTRO TIENE QUE APARECER EN EL MEDIO DE LA PANTALLA, cambia la luminosidad de las casas de dia a un 70% cambia la oscuridad de las casas de noche a un 70% ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
cuando este el video no debe verse las vidass ni la velocidad ni apagar musica en pantalla, la musica del juego comienza recien luego de la intro, debe verse la imagen del boton PLAY EN EL CENTRO DE LA MITAD INFERIOR DE LA PANTALLA
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'video')' in or related to this line: 'LK.init.video('introVideo', {' Line Number: 514
User prompt
entonces agrega como intro un video de 10 segundos podras poner la opcion de salta intro tambien un boton sobre el video que diga comenzar pasado los 10 segundos
User prompt
sube la opacidad de casas y arboles, de dia sube su luminosidad al 50% de noche oscurece las imagenes un 50% ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
quita todas las sombras, las casas y arboles deben tener su opacidad total todas, puedes subirle la luminosidad para que constraste con los personajes
User prompt
la sombra el cubo flotante debe reflejarse siempre en el suelo, la sombra de todos los el obstaculo jelly tambien tiene su sombrapersonajes siempre se refleja en el suelo, ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
el cubo flotante debe tener tambien sombra, la sombra al saltar el personaje se reduce solo un poco, la sombra del murcielago no cambia de tamaño ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
el cubo flotante tambien debe tener sombra, el murcielago se agranda su sombra al acercarse al suelo, el personaje se achica su sombra al saltar ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
al perder una vida comienza de nuevo pero sin perder sus puntos
User prompt
repara el sonido
User prompt
elimina el boton de hwo to play ya que aparece cuando comeniza el juego solo una vez, quiero que el personaje tenga 3 vidas y luego vuelve a comenzar
User prompt
para evitar errores quita la pausa, el tutorial aparecera antes de comenzar el juego,
User prompt
Please fix the bug: 'Uncaught TypeError: LK.pause is not a function' in or related to this line: 'LK.pause();' Line Number: 1250
User prompt
el personaje principal se balancea levemente al andar para que sea mas dinamico, pero solo levemente, los personajes deberan reflejar las sombras en el suelo de dia ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
debe pausar totalmente el juego la opcion, el sonido aparece tachado cuando se apaga y normal prendido tachado conn una x roja pero sin cambiar el color
User prompt
cuando tocas las instrucciones se pone en pausa, las intrucciones en ingles
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var AirCube = Container.expand(function () {
var self = Container.call(this);
// Create floating cube obstacle
var cubeGraphics = self.attachAsset('airCube', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
self.speed = 0;
self.passed = false;
self.floatOffset = Math.random() * Math.PI * 2;
self.baseY = 0; // Will be set when spawned
self.update = function () {
self.x -= self.speed;
// Gentle floating animation
self.y = self.baseY + Math.sin(LK.ticks * 0.04 + self.floatOffset) * 8;
// Subtle rotation
cubeGraphics.rotation = Math.sin(LK.ticks * 0.03) * 0.1;
};
return self;
});
var BackgroundElement = Container.expand(function () {
var self = Container.call(this);
// Create different types of background elements with all 10 house and 10 tree varieties
var elementTypes = ['house1', 'house2', 'house3', 'house4', 'house5', 'house6', 'house7', 'house8', 'house9', 'house10', 'tree', 'tree2', 'tree3', 'tree4', 'tree5', 'tree6', 'tree7', 'tree8', 'tree9', 'tree10'];
var elementType = elementTypes[Math.floor(Math.random() * elementTypes.length)];
// Create depth-based layering for background elements
var isBackground = Math.random() < 0.5; // 50% chance to be background (far)
// Determine element size, alpha, and speed based on depth
var elementScale;
var alpha;
var speed;
if (isBackground) {
// Far background elements - smaller, slower, more transparent
elementScale = 0.4 + Math.random() * 0.3; // 0.4 to 0.7
alpha = 0.4 + Math.random() * 0.3; // 0.4 to 0.7
speed = 0.8 + Math.random() * 0.7; // 0.8 to 1.5
} else {
// Near background elements - larger, faster, more opaque
elementScale = 0.8 + Math.random() * 0.4; // 0.8 to 1.2
alpha = 0.6 + Math.random() * 0.3; // 0.6 to 0.9
speed = 1.5 + Math.random() * 1.0; // 1.5 to 2.5
}
// Create background element graphics
var elementGraphics = self.attachAsset(elementType, {
anchorX: 0.5,
anchorY: 1.0,
// Anchor at bottom for ground placement
scaleX: elementScale,
scaleY: elementScale,
alpha: alpha
});
// Apply slight tint variation for more natural look
var tintVariations = [0xffffff, 0xf8f8ff, 0xf0f8ff, 0xe6e6fa];
elementGraphics.tint = tintVariations[Math.floor(Math.random() * tintVariations.length)];
self.speed = speed;
self.elementType = elementType;
self.elementScale = elementScale;
self.update = function () {
self.x -= self.speed;
};
return self;
});
var Cloud = Container.expand(function () {
var self = Container.call(this);
// Choose cloud type (0, 1, or 2)
var cloudType = Math.floor(Math.random() * 3);
// Create depth-based layering for clouds
var isBackground = Math.random() < 0.4; // 40% chance to be background (far)
var isMidground = !isBackground && Math.random() < 0.6; // 60% of remaining are midground
// Determine cloud size, alpha, and speed based on depth
var cloudScale;
var alpha;
var speed;
if (isBackground) {
// Far clouds - smallest, slowest, most transparent
cloudScale = 0.3 + Math.random() * 0.2; // 0.3 to 0.5
alpha = 0.3 + Math.random() * 0.2; // 0.3 to 0.5
speed = 0.5 + Math.random() * 0.5; // 0.5 to 1.0
} else if (isMidground) {
// Mid clouds - medium size, speed, and alpha
cloudScale = 0.6 + Math.random() * 0.3; // 0.6 to 0.9
alpha = 0.5 + Math.random() * 0.2; // 0.5 to 0.7
speed = 1.2 + Math.random() * 0.6; // 1.2 to 1.8
} else {
// Near clouds - largest, fastest, most opaque
cloudScale = 1.0 + Math.random() * 0.4; // 1.0 to 1.4
alpha = 0.7 + Math.random() * 0.2; // 0.7 to 0.9
speed = 2.0 + Math.random() * 1.0; // 2.0 to 3.0
}
// Choose cloud asset based on type
var cloudAssetId;
if (cloudType === 0) {
cloudAssetId = 'cloud1';
} else if (cloudType === 1) {
cloudAssetId = 'cloud2';
} else {
cloudAssetId = 'cloud3';
}
// Create single cloud image with proper scaling
var cloudGraphics = self.attachAsset(cloudAssetId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: cloudScale,
scaleY: cloudScale,
alpha: alpha
});
// Apply slight tint variation for more natural look
var tintVariations = [0xffffff, 0xf8f8ff, 0xf0f8ff, 0xfafaff];
cloudGraphics.tint = tintVariations[Math.floor(Math.random() * tintVariations.length)];
self.speed = speed;
self.cloudScale = cloudScale;
self.cloudType = cloudType;
self.update = function () {
self.x -= self.speed;
};
return self;
});
var Fluffball = Container.expand(function () {
var self = Container.call(this);
var fluffballGraphics = self.attachAsset('fluffball', {
anchorX: 0.5,
anchorY: 0.5
});
// Create shadow for character
var shadowGraphics = self.attachAsset('characterShadow', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3,
y: 80 // Position shadow at character's feet
});
self.shadowGraphics = shadowGraphics;
self.velocityY = 0;
self.isJumping = false;
self.isDucking = false;
self.groundY = 0;
self.jumpPower = -35;
self.gravity = 0.8;
self.duckScale = 0.6;
self.normalScale = 1.0;
self.canDoubleJump = false;
self.hasDoubleJumped = false;
self.blinkTimer = 0;
self.isBlinking = false;
self.nextBlinkTime = 180; // Blink every 3 seconds (180 ticks at 60fps)
self.jump = function () {
if (!self.isJumping) {
self.velocityY = self.jumpPower;
self.isJumping = true;
self.canDoubleJump = true;
self.hasDoubleJumped = false;
LK.getSound('jump').play();
// Rotate backward during jump
tween(fluffballGraphics, {
rotation: -0.5
}, {
duration: 200,
easing: tween.easeOut
});
} else if (self.canDoubleJump && !self.hasDoubleJumped) {
// Double jump
self.velocityY = self.jumpPower * 0.8; // Slightly weaker second jump
self.hasDoubleJumped = true;
self.canDoubleJump = false;
LK.getSound('jump').play();
// Extra rotation for double jump
tween(fluffballGraphics, {
rotation: -0.8
}, {
duration: 150,
easing: tween.easeOut
});
}
};
self.startDuck = function () {
if (!self.isJumping) {
self.isDucking = true;
tween(fluffballGraphics, {
scaleY: self.duckScale
}, {
duration: 100
});
}
};
self.stopDuck = function () {
self.isDucking = false;
tween(fluffballGraphics, {
scaleY: self.normalScale
}, {
duration: 100
});
};
self.update = function () {
if (self.isJumping) {
self.velocityY += self.gravity;
self.y += self.velocityY;
// Rotate forward when falling (positive velocity)
if (self.velocityY > 5) {
tween(fluffballGraphics, {
rotation: 0.3
}, {
duration: 150,
easing: tween.easeIn
});
}
if (self.y >= self.groundY) {
self.y = self.groundY;
self.velocityY = 0;
self.isJumping = false;
self.canDoubleJump = false;
self.hasDoubleJumped = false;
// Return to original rotation when landing
tween(fluffballGraphics, {
rotation: 0
}, {
duration: 200,
easing: tween.easeOut
});
}
} else {
// Add subtle swaying animation when walking (not jumping)
var swayAmount = Math.sin(LK.ticks * 0.15) * 0.08; // Very subtle sway
fluffballGraphics.rotation = swayAmount;
// Add slight vertical bob while walking
var bobAmount = Math.sin(LK.ticks * 0.2) * 2; // Small vertical movement
fluffballGraphics.y = bobAmount;
}
// Blinking animation
self.blinkTimer++;
if (self.blinkTimer >= self.nextBlinkTime && !self.isBlinking) {
self.isBlinking = true;
self.blinkTimer = 0;
self.nextBlinkTime = 180; // Reset timer for next blink (3 seconds)
// Remove current graphics and add blinking graphics
self.removeChild(fluffballGraphics);
fluffballGraphics = self.attachAsset('fluffballBlink', {
anchorX: 0.5,
anchorY: 0.5
});
// Switch back after blink duration
LK.setTimeout(function () {
if (self.isBlinking) {
// Remove blinking graphics and restore normal graphics
self.removeChild(fluffballGraphics);
fluffballGraphics = self.attachAsset('fluffball', {
anchorX: 0.5,
anchorY: 0.5
});
self.isBlinking = false;
}
}, 250); // Blink duration of 250ms (0.25 seconds)
}
// Update shadow visibility based on theme and jumping state
if (self.shadowGraphics) {
// Show shadow during day theme, hide during night
self.shadowGraphics.alpha = currentTheme === 'day' ? 0.3 : 0;
// Adjust shadow size based on jumping height (perspective effect)
if (self.isJumping) {
var jumpHeight = self.groundY - self.y;
var shadowScale = Math.max(0.3, 1 - jumpHeight * 0.002); // Shadow gets smaller when higher
self.shadowGraphics.scaleX = shadowScale;
self.shadowGraphics.scaleY = shadowScale * 0.5; // Flatter when higher
self.shadowGraphics.alpha = currentTheme === 'day' ? 0.3 * shadowScale : 0;
} else {
self.shadowGraphics.scaleX = 1;
self.shadowGraphics.scaleY = 1;
}
}
// Bounce animation
if (!self.isJumping && LK.ticks % 30 == 0) {
tween(fluffballGraphics, {
scaleY: 1.1
}, {
duration: 150,
easing: tween.easeOut
});
tween(fluffballGraphics, {
scaleY: 1.0
}, {
duration: 150,
easing: tween.easeIn
});
}
};
return self;
});
var GummyBee = Container.expand(function () {
var self = Container.call(this);
var beeGraphics = self.attachAsset('gummyBee', {
anchorX: 0.5,
anchorY: 0.5
});
// Create shadow for bee
var shadowGraphics = self.attachAsset('beeShadow', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.2
});
self.shadowGraphics = shadowGraphics;
self.speed = 0;
self.passed = false;
self.bobOffset = Math.random() * Math.PI * 2;
self.baseY = 0; // Will be set when spawned
self.verticalRange = 25 + Math.random() * 30; // Reduced vertical movement range
self.verticalSpeed = 0.08 + Math.random() * 0.05; // Variable vertical speed
self.lastY = 0;
self.update = function () {
self.x -= self.speed;
// Initialize lastY if not set
if (self.lastY === undefined) self.lastY = self.y;
// Varied flight pattern - some bees fly high (requiring jumps), others fly low (safe at ground)
var verticalOffset = Math.sin(LK.ticks * self.verticalSpeed + self.bobOffset) * self.verticalRange;
self.y = self.baseY + verticalOffset;
// Wing rotation animation
beeGraphics.rotation = Math.sin(LK.ticks * 0.1) * 0.2;
// Scale animation for wing flapping
beeGraphics.scaleY = 1.0 + Math.sin(LK.ticks * 0.3) * 0.1;
// Update shadow position and visibility
if (self.shadowGraphics) {
// Position shadow on ground directly below bee
var groundDistance = groundY - self.y;
self.shadowGraphics.y = groundDistance;
// Adjust shadow properties based on height and theme
var heightFactor = Math.max(0.1, 1 - groundDistance * 0.001);
self.shadowGraphics.scaleX = heightFactor;
self.shadowGraphics.scaleY = heightFactor * 0.6;
self.shadowGraphics.alpha = currentTheme === 'day' ? 0.2 * heightFactor : 0;
}
// Update lastY
self.lastY = self.y;
};
return self;
});
var JellyObstacle = Container.expand(function () {
var self = Container.call(this);
var jellyGraphics = self.attachAsset('jellyObstacle', {
anchorX: 0.5,
anchorY: 1.0
});
self.speed = 0;
self.passed = false;
self.update = function () {
self.x -= self.speed;
// Wobble animation
jellyGraphics.scaleX = 1 + Math.sin(LK.ticks * 0.1) * 0.1;
jellyGraphics.scaleY = 1 + Math.cos(LK.ticks * 0.08) * 0.05;
};
return self;
});
var ShadowBat = Container.expand(function () {
var self = Container.call(this);
var batGraphics = self.attachAsset('shadowBat', {
anchorX: 0.5,
anchorY: 0.5
});
// Create shadow for bat
var shadowGraphics = self.attachAsset('batShadow', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.25
});
self.shadowGraphics = shadowGraphics;
self.speed = 0;
self.passed = false;
self.zigzagDirection = 1; // 1 for up, -1 for down
self.zigzagSpeed = 6; // Increased vertical movement speed for faster zigzag
self.zigzagRange = 150; // How far up/down to move
self.startY = 0; // Starting Y position
self.lastY = 0;
self.update = function () {
self.x -= self.speed;
// Initialize lastY if not set
if (self.lastY === undefined) self.lastY = self.y;
// Initialize startY if not set
if (self.startY === 0) self.startY = self.y;
// Enhanced zigzag movement - goes much closer to ground with faster movement
self.y += self.zigzagDirection * self.zigzagSpeed;
// Calculate ground proximity - bat can get within 120px of ground
var maxGroundApproach = self.groundY - 120;
// Change direction when reaching limits - goes closer to ground now
if (self.y <= self.startY - self.zigzagRange) {
self.zigzagDirection = 1; // Change to downward
} else if (self.y >= maxGroundApproach) {
self.zigzagDirection = -1; // Change to upward - return to original position
}
// More pronounced wing animation for faster zigzag effect
batGraphics.rotation = Math.sin(LK.ticks * 0.4) * 0.15; // More visible rotation for zigzag effect
// Update shadow position and visibility
if (self.shadowGraphics) {
// Position shadow on ground directly below bat
var groundDistance = self.groundY - self.y;
self.shadowGraphics.y = groundDistance;
// Adjust shadow properties based on height and theme
var heightFactor = Math.max(0.1, 1 - groundDistance * 0.0008);
self.shadowGraphics.scaleX = heightFactor;
self.shadowGraphics.scaleY = heightFactor * 0.5;
self.shadowGraphics.alpha = currentTheme === 'day' ? 0.25 * heightFactor : 0;
}
// Update lastY
self.lastY = self.y;
};
return self;
});
var SparkleGem = Container.expand(function () {
var self = Container.call(this);
var gemGraphics = self.attachAsset('sparkleGem', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0;
self.collected = false;
self.update = function () {
self.x -= self.speed;
// Sparkle animation
gemGraphics.rotation += 0.1;
gemGraphics.scaleX = 1 + Math.sin(LK.ticks * 0.2) * 0.3;
gemGraphics.scaleY = 1 + Math.cos(LK.ticks * 0.2) * 0.3;
};
return self;
});
var Star = Container.expand(function () {
var self = Container.call(this);
var starGraphics = self.attachAsset('star', {
anchorX: 0.5,
anchorY: 0.5
});
self.twinkleSpeed = 0.02 + Math.random() * 0.03;
self.twinkleOffset = Math.random() * Math.PI * 2;
self.minAlpha = 0.3;
self.maxAlpha = 1.0;
self.minScale = 0.3;
self.maxScale = 1.5;
self.scaleSpeed = 0.01 + Math.random() * 0.02;
self.scaleOffset = Math.random() * Math.PI * 2;
self.disappearTimer = Math.random() * 600 + 300; // Random time between 5-15 seconds
self.isDisappearing = false;
self.disappearDuration = 0;
self.reappearDelay = 0;
self.update = function () {
// Create twinkling effect with random timing
var twinkle = Math.sin(LK.ticks * self.twinkleSpeed + self.twinkleOffset);
starGraphics.alpha = self.minAlpha + (self.maxAlpha - self.minAlpha) * (twinkle + 1) / 2;
// Dynamic scale changes
var scaleVariation = Math.sin(LK.ticks * self.scaleSpeed + self.scaleOffset);
var targetScale = self.minScale + (self.maxScale - self.minScale) * (scaleVariation + 1) / 2;
starGraphics.scaleX = targetScale;
starGraphics.scaleY = targetScale;
// Disappear and reappear cycle
self.disappearTimer--;
if (self.disappearTimer <= 0 && !self.isDisappearing) {
self.isDisappearing = true;
self.disappearDuration = Math.random() * 120 + 60; // Disappear for 1-3 seconds
self.reappearDelay = Math.random() * 300 + 180; // Reappear after 3-8 seconds
// Fade out
tween(starGraphics, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 500 + Math.random() * 1000,
easing: tween.easeOut
});
}
if (self.isDisappearing) {
self.disappearDuration--;
if (self.disappearDuration <= 0) {
self.reappearDelay--;
if (self.reappearDelay <= 0) {
// Reset star state and fade back in
self.isDisappearing = false;
self.disappearTimer = Math.random() * 900 + 600; // Next disappear cycle
// Fade in with new random properties
self.twinkleSpeed = 0.02 + Math.random() * 0.03;
self.scaleSpeed = 0.01 + Math.random() * 0.02;
tween(starGraphics, {
alpha: self.maxAlpha,
scaleX: 1,
scaleY: 1
}, {
duration: 800 + Math.random() * 1200,
easing: tween.easeIn
});
}
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
// Game variables
var gameSpeed = 6;
var speedIncrement = 0.002;
var maxSpeed = 12;
var isGameRunning = true;
var perfectPassBonus = 10;
var gemValue = 5;
// Background variables
var currentTheme = 'day';
var isTransitioning = false;
var stars = [];
var starsContainer;
// Background setup
var dayBg = game.addChild(LK.getAsset('dayBackground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
var nightBg = game.addChild(LK.getAsset('nightBackground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
alpha: 0
}));
// Ground setup
var groundY = 2732 - 500;
var ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: groundY
}));
// Underground brown rectangle
var underground = game.addChild(LK.getAsset('underground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: groundY + 200
}));
// Create stars container for night theme
starsContainer = game.addChild(new Container());
starsContainer.alpha = 0;
// Generate twinkling stars
for (var i = 0; i < 150; i++) {
var star = starsContainer.addChild(new Star());
star.x = Math.random() * 2048;
star.y = Math.random() * (2732 * 0.6); // Stars only in upper 60% of screen
stars.push(star);
}
// Create clouds container for day theme (before player)
var cloudsContainer = game.addChild(new Container());
// Create background elements container (behind character)
var backgroundElementsContainer = game.addChild(new Container());
// Player setup
var fluffball = game.addChild(new Fluffball());
fluffball.scaleX = 1.2;
fluffball.scaleY = 1.2;
fluffball.x = 300;
fluffball.y = groundY - 80;
fluffball.groundY = groundY - 80;
// Arrays for game objects
var jellyObstacles = [];
var gummyBees = [];
var sparkleGems = [];
var shadowBats = [];
var airCubes = [];
var clouds = [];
var backgroundElements = [];
// Timers for spawning
var obstacleSpawnTimer = 0;
var gemSpawnTimer = 0;
// Input tracking
var isHolding = false;
var lastClickTime = 0;
var doubleClickDelay = 300; // Maximum time between clicks for double click (ms)
// Score display
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 8,
font: "'Arial Black', 'Helvetica', sans-serif"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 100;
// Speed display
var speedTxt = new Text2('SPEED: 1x', {
size: 40,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
speedTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(speedTxt);
speedTxt.x = -50;
speedTxt.y = 50;
// Functions
function spawnJellyObstacle() {
var obstacle = game.addChild(new JellyObstacle());
obstacle.scaleX = 1.3;
obstacle.scaleY = 1.3;
obstacle.x = 2048 + 100;
obstacle.y = groundY;
obstacle.speed = gameSpeed;
jellyObstacles.push(obstacle);
}
function spawnGummyBee() {
var bee = game.addChild(new GummyBee());
bee.scaleX = 1.3;
bee.scaleY = 1.3;
bee.x = 2048 + 100;
// Create varied flight patterns - some high (requiring jumps), some low (safe at ground)
var flightType = Math.random();
if (flightType < 0.4) {
// High flying bees that require jumping (40% chance)
var baseHeight = groundY - 250 - Math.random() * 150;
bee.verticalRange = 15 + Math.random() * 20; // Much smaller range for high flyers
} else {
// Low flying bees that are safe when character is on ground (60% chance)
var baseHeight = groundY - 150 - Math.random() * 100;
bee.verticalRange = 20 + Math.random() * 30; // Reduced range for low flyers
}
bee.y = baseHeight;
bee.baseY = baseHeight;
bee.speed = gameSpeed;
gummyBees.push(bee);
}
function spawnSparkleGem() {
var gem = game.addChild(new SparkleGem());
gem.scaleX = 1.2;
gem.scaleY = 1.2;
gem.x = 2048 + 100;
gem.y = groundY - 150 - Math.random() * 350;
gem.speed = gameSpeed;
sparkleGems.push(gem);
}
function spawnShadowBat() {
var bat = game.addChild(new ShadowBat());
bat.x = 2048 + 100;
bat.y = groundY - 350 - Math.random() * 200;
bat.speed = gameSpeed;
bat.groundY = groundY; // Set ground reference for diving
bat.zigzagRange = 200 + Math.random() * 100; // Increased range for more dramatic movement
bat.zigzagSpeed = 4 + Math.random() * 2; // Slightly faster zigzag
shadowBats.push(bat);
}
function spawnAirCube() {
var cube = game.addChild(new AirCube());
cube.x = 2048 + 100;
cube.y = groundY - 280; // Much higher position for character to pass underneath
cube.baseY = groundY - 280;
cube.speed = gameSpeed;
airCubes.push(cube);
}
function spawnCloud() {
var cloud = cloudsContainer.addChild(new Cloud());
cloud.x = 2048 + 200;
cloud.y = 200 + Math.random() * 800; // Clouds in upper portion of sky
clouds.push(cloud);
}
function spawnBackgroundElement() {
var element = backgroundElementsContainer.addChild(new BackgroundElement());
element.x = 2048 + 300;
element.y = groundY; // Position at ground level
backgroundElements.push(element);
}
function transitionBackground(newTheme) {
if (isTransitioning || currentTheme === newTheme) return;
isTransitioning = true;
if (newTheme === 'night') {
// Transition to night
tween(dayBg, {
alpha: 0
}, {
duration: 2000,
easing: tween.easeInOut
});
tween(nightBg, {
alpha: 1
}, {
duration: 2000,
easing: tween.easeInOut
});
// Show twinkling stars during night
tween(starsContainer, {
alpha: 1
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
currentTheme = 'night';
isTransitioning = false;
}
});
// Hide clouds during night
tween(cloudsContainer, {
alpha: 0
}, {
duration: 2000,
easing: tween.easeInOut
});
} else {
// Transition to day
tween(nightBg, {
alpha: 0
}, {
duration: 2000,
easing: tween.easeInOut
});
tween(dayBg, {
alpha: 1
}, {
duration: 2000,
easing: tween.easeInOut
});
// Hide twinkling stars during day
tween(starsContainer, {
alpha: 0
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
currentTheme = 'day';
isTransitioning = false;
}
});
// Show clouds during day
tween(cloudsContainer, {
alpha: 1
}, {
duration: 2000,
easing: tween.easeInOut
});
}
}
function checkCollisions() {
// Check jelly obstacles
for (var i = jellyObstacles.length - 1; i >= 0; i--) {
var obstacle = jellyObstacles[i];
// Initialize last intersection state if not set
if (obstacle.lastIntersecting === undefined) {
obstacle.lastIntersecting = false;
}
var currentIntersecting = fluffball.intersects(obstacle);
// Only trigger collision on the exact frame when intersection starts
if (!obstacle.lastIntersecting && currentIntersecting) {
// Game over
LK.getSound('hit').play();
LK.effects.flashScreen(0xff0000, 500);
LK.showGameOver();
return;
}
// Update last intersection state
obstacle.lastIntersecting = currentIntersecting;
// Perfect pass bonus
if (!obstacle.passed && obstacle.x < fluffball.x - 50) {
obstacle.passed = true;
LK.setScore(LK.getScore() + perfectPassBonus);
// Animate score text
tween(scoreTxt, {
tint: 0xFF0000,
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(scoreTxt, {
tint: 0xFFFFFF,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150,
easing: tween.easeIn
});
}
});
}
// Remove off-screen obstacles
if (obstacle.x < -100) {
obstacle.destroy();
jellyObstacles.splice(i, 1);
}
}
// Check gummy bees
for (var i = gummyBees.length - 1; i >= 0; i--) {
var bee = gummyBees[i];
var canCollide = true;
// If fluffball is on ground, prevent collision with bees flying too high
if (!fluffball.isJumping) {
// Character collision area when on ground - extends from feet to head
var fluffballTop = fluffball.y - 80; // Top of character
var fluffballBottom = fluffball.y + 80; // Bottom of character
// Only collide if bee is within the character's ground-level collision zone
if (bee.y < fluffballTop - 20) {
// Bee is too high above character when on ground - no collision
canCollide = false;
}
}
// Initialize last intersection state if not set
if (bee.lastIntersecting === undefined) {
bee.lastIntersecting = false;
}
var currentIntersecting = fluffball.intersects(bee) && canCollide;
// Only trigger collision on the exact frame when intersection starts
if (!bee.lastIntersecting && currentIntersecting) {
// Game over
LK.getSound('hit').play();
LK.effects.flashScreen(0xff0000, 500);
LK.showGameOver();
return;
}
// Update last intersection state
bee.lastIntersecting = currentIntersecting;
// Perfect pass bonus
if (!bee.passed && bee.x < fluffball.x - 50) {
bee.passed = true;
LK.setScore(LK.getScore() + perfectPassBonus);
// Animate score text
tween(scoreTxt, {
tint: 0xFF0000,
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(scoreTxt, {
tint: 0xFFFFFF,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150,
easing: tween.easeIn
});
}
});
}
// Remove off-screen bees
if (bee.x < -100) {
bee.destroy();
gummyBees.splice(i, 1);
}
}
// Check sparkle gems
for (var i = sparkleGems.length - 1; i >= 0; i--) {
var gem = sparkleGems[i];
// Initialize last intersection state if not set
if (gem.lastIntersecting === undefined) {
gem.lastIntersecting = false;
}
var currentIntersecting = fluffball.intersects(gem) && !gem.collected;
// Only trigger collection on the exact frame when intersection starts
if (!gem.lastIntersecting && currentIntersecting) {
gem.collected = true;
LK.setScore(LK.getScore() + gemValue);
LK.getSound('collect').play();
LK.effects.flashObject(gem, 0xffffff, 200);
// Animate score text
tween(scoreTxt, {
tint: 0xFF0000,
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(scoreTxt, {
tint: 0xFFFFFF,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150,
easing: tween.easeIn
});
}
});
// Remove gem with tween
tween(gem, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 200,
onFinish: function onFinish() {
gem.destroy();
}
});
sparkleGems.splice(i, 1);
} else if (gem.x < -100) {
gem.destroy();
sparkleGems.splice(i, 1);
}
// Update last intersection state
gem.lastIntersecting = currentIntersecting;
}
// Check shadow bats
for (var i = shadowBats.length - 1; i >= 0; i--) {
var bat = shadowBats[i];
// Initialize last intersection state if not set
if (bat.lastIntersecting === undefined) {
bat.lastIntersecting = false;
}
var currentIntersecting = fluffball.intersects(bat);
// Only trigger collision on the exact frame when intersection starts
if (!bat.lastIntersecting && currentIntersecting) {
// Game over
LK.getSound('hit').play();
LK.effects.flashScreen(0xff0000, 500);
LK.showGameOver();
return;
}
// Update last intersection state
bat.lastIntersecting = currentIntersecting;
// Perfect pass bonus
if (!bat.passed && bat.x < fluffball.x - 50) {
bat.passed = true;
LK.setScore(LK.getScore() + perfectPassBonus);
// Animate score text
tween(scoreTxt, {
tint: 0xFF0000,
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(scoreTxt, {
tint: 0xFFFFFF,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150,
easing: tween.easeIn
});
}
});
}
// Remove off-screen bats
if (bat.x < -100) {
bat.destroy();
shadowBats.splice(i, 1);
}
}
// Check air cubes - with collision detection enabled
for (var i = airCubes.length - 1; i >= 0; i--) {
var cube = airCubes[i];
// Initialize last intersection state if not set
if (cube.lastIntersecting === undefined) {
cube.lastIntersecting = false;
}
var currentIntersecting = fluffball.intersects(cube);
// Only trigger collision on the exact frame when intersection starts
if (!cube.lastIntersecting && currentIntersecting) {
// Game over
LK.getSound('hit').play();
LK.effects.flashScreen(0xff0000, 500);
LK.showGameOver();
return;
}
// Update last intersection state
cube.lastIntersecting = currentIntersecting;
// Perfect pass bonus
if (!cube.passed && cube.x < fluffball.x - 50) {
cube.passed = true;
LK.setScore(LK.getScore() + perfectPassBonus);
// Animate score text
tween(scoreTxt, {
tint: 0xFF0000,
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(scoreTxt, {
tint: 0xFFFFFF,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150,
easing: tween.easeIn
});
}
});
}
// Remove off-screen cubes
if (cube.x < -100) {
cube.destroy();
airCubes.splice(i, 1);
}
}
}
// Input handlers
game.down = function (x, y, obj) {
if (isGameRunning) {
var currentTime = Date.now();
var timeSinceLastClick = currentTime - lastClickTime;
// Check for double click
if (timeSinceLastClick < doubleClickDelay) {
// Double click detected - trigger double jump immediately
fluffball.jump();
} else {
// Single click - trigger jump immediately
fluffball.jump();
}
lastClickTime = currentTime;
isHolding = true;
// Start ducking after a short delay if still holding
LK.setTimeout(function () {
if (isHolding) {
fluffball.startDuck();
}
}, 200);
}
};
game.up = function (x, y, obj) {
isHolding = false;
fluffball.stopDuck();
};
// Main game loop
game.update = function () {
if (!isGameRunning) return;
// Increase speed gradually
if (gameSpeed < maxSpeed) {
gameSpeed += speedIncrement;
}
// Update speed display
var speedMultiplier = Math.floor(gameSpeed / 6 * 10) / 10;
speedTxt.setText('SPEED: ' + speedMultiplier + 'x');
// Update score display
scoreTxt.setText(LK.getScore().toString());
// Spawn obstacles with increased spacing
obstacleSpawnTimer++;
if (obstacleSpawnTimer > 160 - gameSpeed * 4) {
obstacleSpawnTimer = 0;
var randomValue = Math.random();
if (randomValue < 0.4) {
spawnJellyObstacle();
} else if (randomValue < 0.75) {
spawnGummyBee();
} else if (randomValue < 0.9) {
spawnShadowBat();
} else {
spawnAirCube();
}
}
// Spawn gems with increased spacing
gemSpawnTimer++;
if (gemSpawnTimer > 220) {
gemSpawnTimer = 0;
if (Math.random() < 0.4) {
spawnSparkleGem();
}
}
// Update all objects speeds
for (var i = 0; i < jellyObstacles.length; i++) {
jellyObstacles[i].speed = gameSpeed;
}
for (var i = 0; i < gummyBees.length; i++) {
gummyBees[i].speed = gameSpeed;
}
for (var i = 0; i < sparkleGems.length; i++) {
sparkleGems[i].speed = gameSpeed;
}
for (var i = 0; i < shadowBats.length; i++) {
shadowBats[i].speed = gameSpeed;
}
for (var i = 0; i < airCubes.length; i++) {
airCubes[i].speed = gameSpeed;
}
// Spawn clouds only during day theme
if (currentTheme === 'day' && Math.random() < 0.005) {
// Low spawn rate for decoration
spawnCloud();
}
// Spawn background elements at ground level
if (Math.random() < 0.008) {
// Spawn rate for ground-level scenery
spawnBackgroundElement();
}
// Update and manage clouds
for (var i = clouds.length - 1; i >= 0; i--) {
var cloud = clouds[i];
if (cloud.x < -300) {
// Remove off-screen clouds
cloud.destroy();
clouds.splice(i, 1);
}
}
// Update and manage background elements
for (var i = backgroundElements.length - 1; i >= 0; i--) {
var element = backgroundElements[i];
if (element.x < -400) {
// Remove off-screen background elements
element.destroy();
backgroundElements.splice(i, 1);
}
}
// Check collisions
checkCollisions();
// Background transition based on score every 100 points
var score = LK.getScore();
var scoreThreshold = Math.floor(score / 100);
if (scoreThreshold % 2 === 1) {
// Odd hundreds (100, 300, 500...) = night
transitionBackground('night');
} else {
// Even hundreds (0, 200, 400...) = day
transitionBackground('day');
}
};
// Game logo setup
var gameLogo = game.addChild(LK.getAsset('gameLogo', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 800,
alpha: 0.7,
scaleX: 0.6,
scaleY: 0.6
}));
// Start breathing animation for logo
function startLogoBreathing() {
tween(gameLogo, {
scaleX: 1.02,
scaleY: 1.02
}, {
duration: 1200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(gameLogo, {
scaleX: 0.98,
scaleY: 0.98
}, {
duration: 1200,
easing: tween.easeInOut,
onFinish: function onFinish() {
startLogoBreathing(); // Loop the animation
}
});
}
});
}
// Start the breathing animation
startLogoBreathing();
// Initialize music state from storage (default to true if not set)
var isMusicEnabled = storage.musicEnabled !== undefined ? storage.musicEnabled : true;
// Tutorial button
var tutorialBtn = new Text2('?', {
size: 60,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 4,
font: "'Arial Black', 'Helvetica', sans-serif"
});
tutorialBtn.anchor.set(0.5, 0.5);
LK.gui.topRight.addChild(tutorialBtn);
tutorialBtn.x = -150;
tutorialBtn.y = 120;
// Music control button
var musicBtn = new Text2(isMusicEnabled ? '♪' : '♪✗', {
size: 50,
fill: isMusicEnabled ? 0x00FF00 : 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3,
font: "'Arial Black', 'Helvetica', sans-serif"
});
musicBtn.anchor.set(0.5, 0.5);
LK.gui.topRight.addChild(musicBtn);
musicBtn.x = -200;
musicBtn.y = 120;
// Show tutorial at game start
isGameRunning = false; // Start with game paused
// Create tutorial overlay
var tutorialOverlay = game.addChild(new Container());
// Semi-transparent background
var overlayBg = tutorialOverlay.attachAsset('underground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732,
alpha: 0.8,
scaleX: 1,
scaleY: 5.464
});
overlayBg.tint = 0x000000;
// Tutorial title
var titleText = new Text2('HOW TO PLAY', {
size: 80,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 6,
font: "'Arial Black', 'Helvetica', sans-serif"
});
titleText.anchor.set(0.5, 0.5);
tutorialOverlay.addChild(titleText);
titleText.x = 1024;
titleText.y = 400;
// Tutorial instructions in English
var instructionTexts = ['TAP TO JUMP', 'HOLD TO DUCK', 'DOUBLE TAP FOR DOUBLE JUMP', 'AVOID OBSTACLES', 'COLLECT GEMS ✦', 'PASS CLOSE TO ENEMIES = +10 POINTS'];
for (var i = 0; i < instructionTexts.length; i++) {
var instructText = new Text2(instructionTexts[i], {
size: 50,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3,
font: "'Arial Black', 'Helvetica', sans-serif"
});
instructText.anchor.set(0.5, 0.5);
tutorialOverlay.addChild(instructText);
instructText.x = 1024;
instructText.y = 600 + i * 80;
}
// Start game button
var startBtn = new Text2('START GAME', {
size: 60,
fill: 0x00FF00,
stroke: 0x000000,
strokeThickness: 4,
font: "'Arial Black', 'Helvetica', sans-serif"
});
startBtn.anchor.set(0.5, 0.5);
tutorialOverlay.addChild(startBtn);
startBtn.x = 1024;
startBtn.y = 1200;
// Start button interaction
startBtn.down = function () {
LK.effects.flashObject(startBtn, 0xFFFFFF, 200);
// Start the game
isGameRunning = true;
// Fade out and remove tutorial
tween(tutorialOverlay, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
tutorialOverlay.destroy();
}
});
};
// Allow starting by tapping background
overlayBg.down = function () {
// Start the game
isGameRunning = true;
tween(tutorialOverlay, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
tutorialOverlay.destroy();
}
});
};
// Fade in tutorial
tutorialOverlay.alpha = 0;
tween(tutorialOverlay, {
alpha: 1
}, {
duration: 300
});
// Tutorial button interaction - now just shows instructions again
tutorialBtn.down = function (x, y, obj) {
// Flash button to show it was pressed
LK.effects.flashObject(tutorialBtn, 0xFFFF00, 300);
// Create simple instruction display without pausing
var instructionOverlay = game.addChild(new Container());
// Semi-transparent background
var instructBg = instructionOverlay.attachAsset('underground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732,
alpha: 0.6,
scaleX: 1,
scaleY: 5.464
});
instructBg.tint = 0x000000;
// Instructions text
var quickInstructions = new Text2('TAP TO JUMP • HOLD TO DUCK\nDOUBLE TAP FOR DOUBLE JUMP\nAVOID OBSTACLES • COLLECT GEMS', {
size: 50,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3,
font: "'Arial Black', 'Helvetica', sans-serif"
});
quickInstructions.anchor.set(0.5, 0.5);
instructionOverlay.addChild(quickInstructions);
quickInstructions.x = 1024;
quickInstructions.y = 1366;
// Auto-remove after 3 seconds
LK.setTimeout(function () {
tween(instructionOverlay, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
instructionOverlay.destroy();
}
});
}, 3000);
// Allow manual close by tapping
instructBg.down = function () {
tween(instructionOverlay, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
instructionOverlay.destroy();
}
});
};
};
// Music button interaction
musicBtn.down = function (x, y, obj) {
// Toggle music state
isMusicEnabled = !isMusicEnabled;
// Save to storage
storage.musicEnabled = isMusicEnabled;
// Update button appearance and text
musicBtn.setText(isMusicEnabled ? '♪' : '♪✗');
musicBtn.fill = isMusicEnabled ? 0x00FF00 : 0xFFFFFF;
// Flash button to show it was pressed
LK.effects.flashObject(musicBtn, 0xFFFF00, 300);
// Control music playback
if (isMusicEnabled) {
LK.playMusic('backgroundMusic');
} else {
LK.stopMusic();
}
};
// Start background music if enabled
if (isMusicEnabled) {
LK.playMusic('backgroundMusic');
}
;
; ===================================================================
--- original.js
+++ change.js
@@ -1181,103 +1181,152 @@
musicBtn.anchor.set(0.5, 0.5);
LK.gui.topRight.addChild(musicBtn);
musicBtn.x = -200;
musicBtn.y = 120;
-// Tutorial button interaction
+// Show tutorial at game start
+isGameRunning = false; // Start with game paused
+// Create tutorial overlay
+var tutorialOverlay = game.addChild(new Container());
+// Semi-transparent background
+var overlayBg = tutorialOverlay.attachAsset('underground', {
+ anchorX: 0,
+ anchorY: 0,
+ x: 0,
+ y: 0,
+ width: 2048,
+ height: 2732,
+ alpha: 0.8,
+ scaleX: 1,
+ scaleY: 5.464
+});
+overlayBg.tint = 0x000000;
+// Tutorial title
+var titleText = new Text2('HOW TO PLAY', {
+ size: 80,
+ fill: 0xFFFFFF,
+ stroke: 0x000000,
+ strokeThickness: 6,
+ font: "'Arial Black', 'Helvetica', sans-serif"
+});
+titleText.anchor.set(0.5, 0.5);
+tutorialOverlay.addChild(titleText);
+titleText.x = 1024;
+titleText.y = 400;
+// Tutorial instructions in English
+var instructionTexts = ['TAP TO JUMP', 'HOLD TO DUCK', 'DOUBLE TAP FOR DOUBLE JUMP', 'AVOID OBSTACLES', 'COLLECT GEMS ✦', 'PASS CLOSE TO ENEMIES = +10 POINTS'];
+for (var i = 0; i < instructionTexts.length; i++) {
+ var instructText = new Text2(instructionTexts[i], {
+ size: 50,
+ fill: 0xFFFFFF,
+ stroke: 0x000000,
+ strokeThickness: 3,
+ font: "'Arial Black', 'Helvetica', sans-serif"
+ });
+ instructText.anchor.set(0.5, 0.5);
+ tutorialOverlay.addChild(instructText);
+ instructText.x = 1024;
+ instructText.y = 600 + i * 80;
+}
+// Start game button
+var startBtn = new Text2('START GAME', {
+ size: 60,
+ fill: 0x00FF00,
+ stroke: 0x000000,
+ strokeThickness: 4,
+ font: "'Arial Black', 'Helvetica', sans-serif"
+});
+startBtn.anchor.set(0.5, 0.5);
+tutorialOverlay.addChild(startBtn);
+startBtn.x = 1024;
+startBtn.y = 1200;
+// Start button interaction
+startBtn.down = function () {
+ LK.effects.flashObject(startBtn, 0xFFFFFF, 200);
+ // Start the game
+ isGameRunning = true;
+ // Fade out and remove tutorial
+ tween(tutorialOverlay, {
+ alpha: 0
+ }, {
+ duration: 300,
+ onFinish: function onFinish() {
+ tutorialOverlay.destroy();
+ }
+ });
+};
+// Allow starting by tapping background
+overlayBg.down = function () {
+ // Start the game
+ isGameRunning = true;
+ tween(tutorialOverlay, {
+ alpha: 0
+ }, {
+ duration: 300,
+ onFinish: function onFinish() {
+ tutorialOverlay.destroy();
+ }
+ });
+};
+// Fade in tutorial
+tutorialOverlay.alpha = 0;
+tween(tutorialOverlay, {
+ alpha: 1
+}, {
+ duration: 300
+});
+// Tutorial button interaction - now just shows instructions again
tutorialBtn.down = function (x, y, obj) {
// Flash button to show it was pressed
LK.effects.flashObject(tutorialBtn, 0xFFFF00, 300);
- // Pause the game completely
- isGameRunning = false;
- // Create tutorial overlay
- var tutorialOverlay = game.addChild(new Container());
+ // Create simple instruction display without pausing
+ var instructionOverlay = game.addChild(new Container());
// Semi-transparent background
- var overlayBg = tutorialOverlay.attachAsset('underground', {
+ var instructBg = instructionOverlay.attachAsset('underground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732,
- alpha: 0.8,
+ alpha: 0.6,
scaleX: 1,
scaleY: 5.464
});
- overlayBg.tint = 0x000000;
- // Tutorial title
- var titleText = new Text2('HOW TO PLAY', {
- size: 80,
+ instructBg.tint = 0x000000;
+ // Instructions text
+ var quickInstructions = new Text2('TAP TO JUMP • HOLD TO DUCK\nDOUBLE TAP FOR DOUBLE JUMP\nAVOID OBSTACLES • COLLECT GEMS', {
+ size: 50,
fill: 0xFFFFFF,
stroke: 0x000000,
- strokeThickness: 6,
+ strokeThickness: 3,
font: "'Arial Black', 'Helvetica', sans-serif"
});
- titleText.anchor.set(0.5, 0.5);
- tutorialOverlay.addChild(titleText);
- titleText.x = 1024;
- titleText.y = 400;
- // Tutorial instructions in English
- var instructionTexts = ['TAP TO JUMP', 'HOLD TO DUCK', 'DOUBLE TAP FOR DOUBLE JUMP', 'AVOID OBSTACLES', 'COLLECT GEMS ✦', 'PASS CLOSE TO ENEMIES = +10 POINTS'];
- for (var i = 0; i < instructionTexts.length; i++) {
- var instructText = new Text2(instructionTexts[i], {
- size: 50,
- fill: 0xFFFFFF,
- stroke: 0x000000,
- strokeThickness: 3,
- font: "'Arial Black', 'Helvetica', sans-serif"
- });
- instructText.anchor.set(0.5, 0.5);
- tutorialOverlay.addChild(instructText);
- instructText.x = 1024;
- instructText.y = 600 + i * 80;
- }
- // Close button
- var closeBtn = new Text2('CLOSE', {
- size: 60,
- fill: 0xFF4444,
- stroke: 0x000000,
- strokeThickness: 4,
- font: "'Arial Black', 'Helvetica', sans-serif"
- });
- closeBtn.anchor.set(0.5, 0.5);
- tutorialOverlay.addChild(closeBtn);
- closeBtn.x = 1024;
- closeBtn.y = 1200;
- // Close button interaction
- closeBtn.down = function () {
- LK.effects.flashObject(closeBtn, 0xFFFFFF, 200);
- // Resume the game
- isGameRunning = true;
- // Fade out and remove tutorial
- tween(tutorialOverlay, {
+ quickInstructions.anchor.set(0.5, 0.5);
+ instructionOverlay.addChild(quickInstructions);
+ quickInstructions.x = 1024;
+ quickInstructions.y = 1366;
+ // Auto-remove after 3 seconds
+ LK.setTimeout(function () {
+ tween(instructionOverlay, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
- tutorialOverlay.destroy();
+ instructionOverlay.destroy();
}
});
- };
- // Allow closing by tapping background
- overlayBg.down = function () {
- // Resume the game
- isGameRunning = true;
- tween(tutorialOverlay, {
+ }, 3000);
+ // Allow manual close by tapping
+ instructBg.down = function () {
+ tween(instructionOverlay, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
- tutorialOverlay.destroy();
+ instructionOverlay.destroy();
}
});
};
- // Fade in tutorial
- tutorialOverlay.alpha = 0;
- tween(tutorialOverlay, {
- alpha: 1
- }, {
- duration: 300
- });
};
// Music button interaction
musicBtn.down = function (x, y, obj) {
// Toggle music state
Chibi style, incredibly cute, perfectly round, puffy creature. **It has no visible legs or limbs, appearing as a soft, adorable ball with a friendly, expressive face (big, innocent eyes and a small smile).** Implied motion is a gentle bounce or glide. Predominant color: light pink with subtle fluffy texture. Minimalist, clean lines, vibrant colors. Solid light blue background. Mobile game character asset, running/gliding animation frame.. In-Game asset. 2d. High contrast. No shadows
ojos cerrados
Kawaii, cute, pink logo for 'Fluffball's Endless Adventure'. The design should feature a whimsical, bubbly, and rounded font for the text, with soft, sweet aesthetics and subtle playful elements integrated into the typography itself (e.g., tiny sparkles, soft gradients, or a slight bouncy feel to the letters). No character or drawing should be included, only the stylized text.. In-Game asset. 2d. High contrast. No shadows
nube blanca sin bordes minimalista, silueta unica y original. In-Game asset. 2d. High contrast. No shadows
circulo blanco sin bordes. In-Game asset. 2d. High contrast. No shadows
kawaii shadown bat de lado. In-Game asset. 2d. High contrast. No shadows
pink cute rec tangle kawaii. In-Game asset. 2d. High contrast. No shadows
a single simple kawaii tree without outlines and no face, for a non-distracting game background. In-Game asset. 2d. High contrast. No shadows
a single simple kawaii house without outlines and no face, for a non-distracting game background. In-Game asset. 2d. High contrast. No shadows
a single simple kawaii house without outlines and no face, for a non-distracting game background. In-Game asset. 2d. High contrast. No shadows
a single simple kawaii house without outlines and no face, for a non-distracting game background. In-Game asset. 2d. High contrast. No shadows