/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Cat = Container.expand(function () {
var self = Container.call(this);
var catIdleGraphics = self.attachAsset('cat_idle', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.5,
scaleY: 1.5
});
var catWalkGraphics = self.attachAsset('cat_walk', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.5,
scaleY: 1.5
});
catWalkGraphics.visible = false;
var catEatGraphics = self.attachAsset('cat_eat', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.5,
scaleY: 1.5
});
catEatGraphics.visible = false;
var catDamageGraphics = self.attachAsset('cat_damage', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.5,
scaleY: 1.5
});
catDamageGraphics.visible = false;
var catWalkDamageGraphics = self.attachAsset('cat_walk_damage', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.5,
scaleY: 1.5
});
catWalkDamageGraphics.visible = false;
self.targetX = 1024; // Center of screen
self.speed = 15;
self.isMoving = false;
self.movementThreshold = 2;
self.facingLeft = false; // Track direction cat is facing
self.isEating = false;
self.eatingTimer = 0;
self.startEating = function () {
self.isEating = true;
self.eatingTimer = 30; // Show eating sprite for 30 frames (0.5 seconds)
// Hide other sprites and show eating sprite
catIdleGraphics.visible = false;
catWalkGraphics.visible = false;
catDamageGraphics.visible = false;
catWalkDamageGraphics.visible = false;
catEatGraphics.visible = true;
// Apply direction flip to eating sprite
if (self.facingLeft) {
catEatGraphics.scaleX = -1.5;
} else {
catEatGraphics.scaleX = 1.5;
}
};
self.switchToDamaged = function () {
// Hide all other sprites and show appropriate damaged sprite
catIdleGraphics.visible = false;
catWalkGraphics.visible = false;
catEatGraphics.visible = false;
catWalkDamageGraphics.visible = false;
if (self.isMoving) {
catWalkDamageGraphics.visible = true;
catDamageGraphics.visible = false;
} else {
catDamageGraphics.visible = true;
catWalkDamageGraphics.visible = false;
}
// Apply correct direction flip
if (self.facingLeft) {
catDamageGraphics.scaleX = -1.5;
catWalkDamageGraphics.scaleX = -1.5;
} else {
catDamageGraphics.scaleX = 1.5;
catWalkDamageGraphics.scaleX = 1.5;
}
};
self.switchToNormal = function () {
// Hide damaged sprites and restore normal sprites
catDamageGraphics.visible = false;
catWalkDamageGraphics.visible = false;
// Restore appropriate sprite based on current state
if (self.isEating) {
catEatGraphics.visible = true;
} else if (self.isMoving) {
catWalkGraphics.visible = true;
catIdleGraphics.visible = false;
} else {
catIdleGraphics.visible = true;
catWalkGraphics.visible = false;
}
};
self.update = function () {
// Smooth movement towards target position
var diff = self.targetX - self.x;
var wasMoving = self.isMoving;
var wasFacingLeft = self.facingLeft;
if (Math.abs(diff) > 5) {
self.x += diff * 0.2;
self.isMoving = Math.abs(diff) > self.movementThreshold;
// Update direction based on movement
if (diff < 0) {
self.facingLeft = true;
} else if (diff > 0) {
self.facingLeft = false;
}
} else {
self.x = self.targetX;
self.isMoving = false;
}
// Keep cat within screen bounds
var halfWidth = catIdleGraphics.width * 1.5 / 2;
if (self.x < halfWidth) {
self.x = halfWidth;
self.targetX = halfWidth;
}
if (self.x > 2048 - halfWidth) {
self.x = 2048 - halfWidth;
self.targetX = 2048 - halfWidth;
}
// Handle eating animation timer
if (self.isEating) {
self.eatingTimer--;
if (self.eatingTimer <= 0) {
self.isEating = false;
catEatGraphics.visible = false;
// Check if we should show damaged sprite
if (lives === 1) {
if (self.isMoving) {
catWalkDamageGraphics.visible = true;
catDamageGraphics.visible = false;
} else {
catDamageGraphics.visible = true;
catWalkDamageGraphics.visible = false;
}
catIdleGraphics.visible = false;
catWalkGraphics.visible = false;
} else {
// Restore appropriate sprite based on current movement state
if (self.isMoving) {
catWalkGraphics.visible = true;
catIdleGraphics.visible = false;
} else {
catIdleGraphics.visible = true;
catWalkGraphics.visible = false;
}
}
// Apply correct direction flip
if (self.facingLeft) {
catIdleGraphics.scaleX = -1.5;
catWalkGraphics.scaleX = -1.5;
catDamageGraphics.scaleX = -1.5;
catWalkDamageGraphics.scaleX = -1.5;
} else {
catIdleGraphics.scaleX = 1.5;
catWalkGraphics.scaleX = 1.5;
catDamageGraphics.scaleX = 1.5;
catWalkDamageGraphics.scaleX = 1.5;
}
}
}
// Switch sprites based on movement state or direction change (only if not eating)
if (!self.isEating && (self.isMoving !== wasMoving || self.facingLeft !== wasFacingLeft)) {
if (lives === 1) {
// Show appropriate damaged sprite based on movement
catIdleGraphics.visible = false;
catWalkGraphics.visible = false;
catEatGraphics.visible = false;
if (self.isMoving) {
catWalkDamageGraphics.visible = true;
catDamageGraphics.visible = false;
} else {
catDamageGraphics.visible = true;
catWalkDamageGraphics.visible = false;
}
} else {
// Normal sprite switching
catWalkDamageGraphics.visible = false;
if (self.isMoving) {
catIdleGraphics.visible = false;
catWalkGraphics.visible = true;
catEatGraphics.visible = false;
catDamageGraphics.visible = false;
} else {
catIdleGraphics.visible = true;
catWalkGraphics.visible = false;
catEatGraphics.visible = false;
catDamageGraphics.visible = false;
}
}
// Flip sprites based on direction
if (self.facingLeft) {
catIdleGraphics.scaleX = -1.5;
catWalkGraphics.scaleX = -1.5;
catDamageGraphics.scaleX = -1.5;
catWalkDamageGraphics.scaleX = -1.5;
} else {
catIdleGraphics.scaleX = 1.5;
catWalkGraphics.scaleX = 1.5;
catDamageGraphics.scaleX = 1.5;
catWalkDamageGraphics.scaleX = 1.5;
}
}
// Update eating sprite direction if direction changed while eating
if (self.isEating && self.facingLeft !== wasFacingLeft) {
if (self.facingLeft) {
catEatGraphics.scaleX = -1.5;
} else {
catEatGraphics.scaleX = 1.5;
}
}
// Update damaged sprite direction if direction changed
if ((catDamageGraphics.visible || catWalkDamageGraphics.visible) && self.facingLeft !== wasFacingLeft) {
if (self.facingLeft) {
catDamageGraphics.scaleX = -1.5;
catWalkDamageGraphics.scaleX = -1.5;
} else {
catDamageGraphics.scaleX = 1.5;
catWalkDamageGraphics.scaleX = 1.5;
}
}
};
return self;
});
var DialogBox = Container.expand(function () {
var self = Container.call(this);
// Create background for dialog
self.background = LK.getAsset('cat_idle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 15,
scaleY: 8
});
self.background.tint = 0x000000;
self.background.alpha = 0.8;
self.addChild(self.background);
// Create dialog text
self.dialogText = new Text2('', {
size: 60,
fill: 0xFFFFFF
});
self.dialogText.anchor.set(0.5, 0.5);
self.addChild(self.dialogText);
// Create continue button
self.continueButton = new Text2('Toca para continuar', {
size: 40,
fill: 0xFFFF00
});
self.continueButton.anchor.set(0.5, 0.5);
self.continueButton.y = 150;
self.addChild(self.continueButton);
self.setText = function (text) {
self.dialogText.setText(text);
};
self.down = function (x, y, obj) {
if (tutorialSystem && tutorialSystem.onDialogClick) {
tutorialSystem.onDialogClick();
}
};
return self;
});
var Orange = Container.expand(function () {
var self = Container.call(this);
var orangeGraphics = self.attachAsset('orange', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
var orangeDamageGraphics = self.attachAsset('orange_damage', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
orangeDamageGraphics.visible = false;
self.speed = 8;
self.lastY = 0;
self.caught = false;
self.update = function () {
if (!self.caught) {
// Increase speed when lives reach 1
var speedMultiplier = lives === 1 ? 1.5 : 1;
self.y += self.speed * speedMultiplier;
}
// Switch to damaged sprite when lives reach 1
if (lives === 1) {
orangeGraphics.visible = false;
orangeDamageGraphics.visible = true;
} else {
orangeGraphics.visible = true;
orangeDamageGraphics.visible = false;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Add background
var backgroundSprite = LK.getAsset('background', {
anchorX: 0,
anchorY: 0
});
backgroundSprite.x = 0;
backgroundSprite.y = 0;
game.addChild(backgroundSprite);
var backgroundDamageSprite = LK.getAsset('background_damage', {
anchorX: 0,
anchorY: 0
});
backgroundDamageSprite.x = 0;
backgroundDamageSprite.y = 0;
backgroundDamageSprite.visible = false;
game.addChild(backgroundDamageSprite);
var cat;
var oranges = [];
var gameSpeed = 1;
var orangeSpawnRate = 60; // frames between spawns
var frameCount = 0;
var lives = 3;
// Tutorial system variables
var tutorialSystem = null;
var gameStarted = false;
var tutorialActive = false;
// Create score display
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create lives display
var livesTxt = new Text2('Lives: 3', {
size: 60,
fill: 0xFFFFFF
});
livesTxt.anchor.set(1, 0);
livesTxt.y = 100;
LK.gui.topRight.addChild(livesTxt);
// Create heart icon for lives
var heartIcon = LK.getAsset('heart_icon', {
anchorX: 1,
anchorY: 0
});
heartIcon.x = -10; // Position relative to topRight
heartIcon.y = 170;
LK.gui.topRight.addChild(heartIcon);
// Create damaged heart icon
var heartDamageIcon = LK.getAsset('heart_damage', {
anchorX: 1,
anchorY: 0
});
heartDamageIcon.x = -10; // Position relative to topRight
heartDamageIcon.y = 170;
heartDamageIcon.visible = false;
LK.gui.topRight.addChild(heartDamageIcon);
// Create the cat
cat = game.addChild(new Cat());
cat.x = 1024; // Center horizontally
cat.y = 2600; // Near bottom of screen
// Tutorial System
tutorialSystem = {
currentStep: 0,
dialogBox: null,
tutorialOrange: null,
steps: ["¡Hola! Soy un gato azul muy hambriento 🐱", "¡Ayúdame a atrapar las naranjas que caen del cielo! 🍊", "Arrastra tu dedo por la pantalla para moverme ⬅️➡️", "¡Perfecto! Ahora atrapa esta naranja de práctica", "¡Ten cuidado! Si pierdes 3 naranjas, perderás una vida ❤️", "¡Cuando tenga solo 1 vida, todo se vuelve más intenso! ⚡", "¡Ahora estás listo! ¡A por esas naranjas! 🎯"],
init: function init() {
tutorialActive = true;
this.showDialog();
},
showDialog: function showDialog() {
if (this.currentStep >= this.steps.length) {
this.endTutorial();
return;
}
if (this.dialogBox) {
this.dialogBox.destroy();
}
this.dialogBox = new DialogBox();
this.dialogBox.x = 1024;
this.dialogBox.y = 1366;
this.dialogBox.setText(this.steps[this.currentStep]);
game.addChild(this.dialogBox);
// Animate dialog appearance
this.dialogBox.alpha = 0;
this.dialogBox.scaleX = 0.5;
this.dialogBox.scaleY = 0.5;
tween(this.dialogBox, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeOut
});
},
onDialogClick: function onDialogClick() {
this.currentStep++;
if (this.currentStep === 3) {
// Step 3: Create practice orange
this.createPracticeOrange();
} else if (this.currentStep === 4) {
// Step 4: Wait for orange to be caught
return;
} else if (this.currentStep === 5) {
// Step 5: Show lives preview
this.showLivesPreview();
} else if (this.currentStep === 6) {
// Step 6: Show hardcore mode preview
this.showHardcorePreview();
} else {
this.showDialog();
}
},
createPracticeOrange: function createPracticeOrange() {
if (this.dialogBox) {
this.dialogBox.destroy();
this.dialogBox = null;
}
this.tutorialOrange = new Orange();
this.tutorialOrange.x = 1024;
this.tutorialOrange.y = -40;
this.tutorialOrange.speed = 3; // Slower for practice
this.tutorialOrange.lastY = this.tutorialOrange.y;
game.addChild(this.tutorialOrange);
// Add arrow pointing to orange
this.createArrow();
},
createArrow: function createArrow() {
if (!tutorialActive) return;
this.arrow = new Text2('⬇️', {
size: 100,
fill: 0xFFFF00 //{4c_new}
});
this.arrow.anchor.set(0.5, 0.5);
this.arrow.x = 1024;
this.arrow.y = 200;
game.addChild(this.arrow);
// Animate arrow
tween(this.arrow, {
y: 250
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (tutorialSystem && tutorialSystem.arrow && tutorialActive) {
//{4h_new}
tween(tutorialSystem.arrow, {
y: 200
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (tutorialActive) {
tutorialSystem.createArrow();
}
}
});
}
} //{4o_new}
});
},
checkPracticeOrange: function checkPracticeOrange() {
if (this.tutorialOrange && this.tutorialOrange.caught) {
if (this.arrow) {
this.arrow.destroy();
this.arrow = null;
}
this.tutorialOrange = null;
this.currentStep++;
this.showDialog();
}
},
showLivesPreview: function showLivesPreview() {
if (this.dialogBox) {
this.dialogBox.destroy();
this.dialogBox = null;
}
// Temporarily show lives indicator
LK.effects.flashObject(heartIcon, 0xFF0000, 1000);
LK.setTimeout(function () {
tutorialSystem.showDialog();
}, 1500);
},
showHardcorePreview: function showHardcorePreview() {
if (this.dialogBox) {
this.dialogBox.destroy();
this.dialogBox = null;
}
// Briefly switch to hardcore mode visuals
var originalLives = lives;
lives = 1;
updateLives();
cat.switchToDamaged();
LK.setTimeout(function () {
lives = originalLives;
updateLives();
cat.switchToNormal();
tutorialSystem.showDialog();
}, 2000);
},
endTutorial: function endTutorial() {
tutorialActive = false;
gameStarted = true;
if (this.dialogBox) {
tween(this.dialogBox, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
tutorialSystem.dialogBox.destroy();
tutorialSystem.dialogBox = null;
}
});
}
}
};
// Start tutorial
tutorialSystem.init();
// Play tutorial music
LK.playMusic('Cool');
// Handle touch/mouse input
function handleMove(x, y, obj) {
if (cat && (gameStarted || tutorialActive && tutorialSystem.currentStep >= 2)) {
cat.targetX = x;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
handleMove(x, y, obj);
};
// Spawn oranges
function spawnOrange() {
var orange = new Orange();
orange.x = Math.random() * (2048 - 160) + 80; // Random x position within bounds
orange.y = -40; // Start above screen
orange.lastY = orange.y;
orange.speed = 6 + gameSpeed * 2; // Increase speed with game progression
oranges.push(orange);
game.addChild(orange);
}
// Update score display
function updateScore() {
scoreTxt.setText('Score: ' + LK.getScore());
}
// Update lives display
function updateLives() {
livesTxt.setText('Lives: ' + lives);
// Switch heart sprite when lives reach 1
if (lives === 1) {
heartIcon.visible = false;
heartDamageIcon.visible = true;
// Switch to hardcore music when lives reach 1
LK.playMusic('hardcore');
// Switch to damaged background
backgroundSprite.visible = false;
backgroundDamageSprite.visible = true;
} else {
heartIcon.visible = true;
heartDamageIcon.visible = false;
// Switch to normal background
backgroundSprite.visible = true;
backgroundDamageSprite.visible = false;
}
}
game.update = function () {
// Handle tutorial logic
if (tutorialActive) {
if (tutorialSystem.tutorialOrange) {
tutorialSystem.checkPracticeOrange();
if (tutorialSystem.tutorialOrange && !tutorialSystem.tutorialOrange.caught && tutorialSystem.tutorialOrange.intersects(cat)) {
tutorialSystem.tutorialOrange.caught = true;
LK.getSound('eat').play();
cat.startEating();
tween(tutorialSystem.tutorialOrange, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
if (tutorialSystem.tutorialOrange) {
tutorialSystem.tutorialOrange.destroy();
tutorialSystem.tutorialOrange = null;
} //{5i_new}
}
});
}
}
return; // Don't run normal game logic during tutorial
}
if (!gameStarted) return;
frameCount++;
// Spawn oranges
if (frameCount % Math.max(20, orangeSpawnRate - Math.floor(LK.getScore() / 5)) === 0) {
spawnOrange();
}
// Increase game speed over time
if (frameCount % 600 === 0) {
// Every 10 seconds at 60fps
gameSpeed += 0.2;
}
// Update oranges
for (var i = oranges.length - 1; i >= 0; i--) {
var orange = oranges[i];
// Check if orange went off screen (missed)
if (orange.lastY < 2732 && orange.y >= 2732 && !orange.caught) {
// Orange hit the ground - lose a life
lives--;
updateLives();
// Play fail sound
LK.getSound('fail').play();
if (lives <= 0) {
LK.showGameOver();
return;
}
orange.destroy();
oranges.splice(i, 1);
continue;
}
// Check collision with cat
if (!orange.caught && orange.intersects(cat)) {
// Orange caught!
orange.caught = true;
LK.setScore(LK.getScore() + 1);
updateScore();
// Play catch sound
LK.getSound('catch').play();
// Play eat sound
LK.getSound('eat').play();
// Flash effect on cat
LK.effects.flashObject(cat, 0xFFFFFF, 200);
// Trigger eating animation
cat.startEating();
// Animate orange being caught
tween(orange, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
orange.destroy();
}
});
oranges.splice(i, 1);
continue;
}
orange.lastY = orange.y;
}
// Check win condition (optional - high score achievement)
if (LK.getScore() >= 100) {
LK.showYouWin();
}
};
// Start energetic dance music
LK.playMusic('Fun');
// Initialize displays
updateScore();
updateLives(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Cat = Container.expand(function () {
var self = Container.call(this);
var catIdleGraphics = self.attachAsset('cat_idle', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.5,
scaleY: 1.5
});
var catWalkGraphics = self.attachAsset('cat_walk', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.5,
scaleY: 1.5
});
catWalkGraphics.visible = false;
var catEatGraphics = self.attachAsset('cat_eat', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.5,
scaleY: 1.5
});
catEatGraphics.visible = false;
var catDamageGraphics = self.attachAsset('cat_damage', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.5,
scaleY: 1.5
});
catDamageGraphics.visible = false;
var catWalkDamageGraphics = self.attachAsset('cat_walk_damage', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.5,
scaleY: 1.5
});
catWalkDamageGraphics.visible = false;
self.targetX = 1024; // Center of screen
self.speed = 15;
self.isMoving = false;
self.movementThreshold = 2;
self.facingLeft = false; // Track direction cat is facing
self.isEating = false;
self.eatingTimer = 0;
self.startEating = function () {
self.isEating = true;
self.eatingTimer = 30; // Show eating sprite for 30 frames (0.5 seconds)
// Hide other sprites and show eating sprite
catIdleGraphics.visible = false;
catWalkGraphics.visible = false;
catDamageGraphics.visible = false;
catWalkDamageGraphics.visible = false;
catEatGraphics.visible = true;
// Apply direction flip to eating sprite
if (self.facingLeft) {
catEatGraphics.scaleX = -1.5;
} else {
catEatGraphics.scaleX = 1.5;
}
};
self.switchToDamaged = function () {
// Hide all other sprites and show appropriate damaged sprite
catIdleGraphics.visible = false;
catWalkGraphics.visible = false;
catEatGraphics.visible = false;
catWalkDamageGraphics.visible = false;
if (self.isMoving) {
catWalkDamageGraphics.visible = true;
catDamageGraphics.visible = false;
} else {
catDamageGraphics.visible = true;
catWalkDamageGraphics.visible = false;
}
// Apply correct direction flip
if (self.facingLeft) {
catDamageGraphics.scaleX = -1.5;
catWalkDamageGraphics.scaleX = -1.5;
} else {
catDamageGraphics.scaleX = 1.5;
catWalkDamageGraphics.scaleX = 1.5;
}
};
self.switchToNormal = function () {
// Hide damaged sprites and restore normal sprites
catDamageGraphics.visible = false;
catWalkDamageGraphics.visible = false;
// Restore appropriate sprite based on current state
if (self.isEating) {
catEatGraphics.visible = true;
} else if (self.isMoving) {
catWalkGraphics.visible = true;
catIdleGraphics.visible = false;
} else {
catIdleGraphics.visible = true;
catWalkGraphics.visible = false;
}
};
self.update = function () {
// Smooth movement towards target position
var diff = self.targetX - self.x;
var wasMoving = self.isMoving;
var wasFacingLeft = self.facingLeft;
if (Math.abs(diff) > 5) {
self.x += diff * 0.2;
self.isMoving = Math.abs(diff) > self.movementThreshold;
// Update direction based on movement
if (diff < 0) {
self.facingLeft = true;
} else if (diff > 0) {
self.facingLeft = false;
}
} else {
self.x = self.targetX;
self.isMoving = false;
}
// Keep cat within screen bounds
var halfWidth = catIdleGraphics.width * 1.5 / 2;
if (self.x < halfWidth) {
self.x = halfWidth;
self.targetX = halfWidth;
}
if (self.x > 2048 - halfWidth) {
self.x = 2048 - halfWidth;
self.targetX = 2048 - halfWidth;
}
// Handle eating animation timer
if (self.isEating) {
self.eatingTimer--;
if (self.eatingTimer <= 0) {
self.isEating = false;
catEatGraphics.visible = false;
// Check if we should show damaged sprite
if (lives === 1) {
if (self.isMoving) {
catWalkDamageGraphics.visible = true;
catDamageGraphics.visible = false;
} else {
catDamageGraphics.visible = true;
catWalkDamageGraphics.visible = false;
}
catIdleGraphics.visible = false;
catWalkGraphics.visible = false;
} else {
// Restore appropriate sprite based on current movement state
if (self.isMoving) {
catWalkGraphics.visible = true;
catIdleGraphics.visible = false;
} else {
catIdleGraphics.visible = true;
catWalkGraphics.visible = false;
}
}
// Apply correct direction flip
if (self.facingLeft) {
catIdleGraphics.scaleX = -1.5;
catWalkGraphics.scaleX = -1.5;
catDamageGraphics.scaleX = -1.5;
catWalkDamageGraphics.scaleX = -1.5;
} else {
catIdleGraphics.scaleX = 1.5;
catWalkGraphics.scaleX = 1.5;
catDamageGraphics.scaleX = 1.5;
catWalkDamageGraphics.scaleX = 1.5;
}
}
}
// Switch sprites based on movement state or direction change (only if not eating)
if (!self.isEating && (self.isMoving !== wasMoving || self.facingLeft !== wasFacingLeft)) {
if (lives === 1) {
// Show appropriate damaged sprite based on movement
catIdleGraphics.visible = false;
catWalkGraphics.visible = false;
catEatGraphics.visible = false;
if (self.isMoving) {
catWalkDamageGraphics.visible = true;
catDamageGraphics.visible = false;
} else {
catDamageGraphics.visible = true;
catWalkDamageGraphics.visible = false;
}
} else {
// Normal sprite switching
catWalkDamageGraphics.visible = false;
if (self.isMoving) {
catIdleGraphics.visible = false;
catWalkGraphics.visible = true;
catEatGraphics.visible = false;
catDamageGraphics.visible = false;
} else {
catIdleGraphics.visible = true;
catWalkGraphics.visible = false;
catEatGraphics.visible = false;
catDamageGraphics.visible = false;
}
}
// Flip sprites based on direction
if (self.facingLeft) {
catIdleGraphics.scaleX = -1.5;
catWalkGraphics.scaleX = -1.5;
catDamageGraphics.scaleX = -1.5;
catWalkDamageGraphics.scaleX = -1.5;
} else {
catIdleGraphics.scaleX = 1.5;
catWalkGraphics.scaleX = 1.5;
catDamageGraphics.scaleX = 1.5;
catWalkDamageGraphics.scaleX = 1.5;
}
}
// Update eating sprite direction if direction changed while eating
if (self.isEating && self.facingLeft !== wasFacingLeft) {
if (self.facingLeft) {
catEatGraphics.scaleX = -1.5;
} else {
catEatGraphics.scaleX = 1.5;
}
}
// Update damaged sprite direction if direction changed
if ((catDamageGraphics.visible || catWalkDamageGraphics.visible) && self.facingLeft !== wasFacingLeft) {
if (self.facingLeft) {
catDamageGraphics.scaleX = -1.5;
catWalkDamageGraphics.scaleX = -1.5;
} else {
catDamageGraphics.scaleX = 1.5;
catWalkDamageGraphics.scaleX = 1.5;
}
}
};
return self;
});
var DialogBox = Container.expand(function () {
var self = Container.call(this);
// Create background for dialog
self.background = LK.getAsset('cat_idle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 15,
scaleY: 8
});
self.background.tint = 0x000000;
self.background.alpha = 0.8;
self.addChild(self.background);
// Create dialog text
self.dialogText = new Text2('', {
size: 60,
fill: 0xFFFFFF
});
self.dialogText.anchor.set(0.5, 0.5);
self.addChild(self.dialogText);
// Create continue button
self.continueButton = new Text2('Toca para continuar', {
size: 40,
fill: 0xFFFF00
});
self.continueButton.anchor.set(0.5, 0.5);
self.continueButton.y = 150;
self.addChild(self.continueButton);
self.setText = function (text) {
self.dialogText.setText(text);
};
self.down = function (x, y, obj) {
if (tutorialSystem && tutorialSystem.onDialogClick) {
tutorialSystem.onDialogClick();
}
};
return self;
});
var Orange = Container.expand(function () {
var self = Container.call(this);
var orangeGraphics = self.attachAsset('orange', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
var orangeDamageGraphics = self.attachAsset('orange_damage', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
orangeDamageGraphics.visible = false;
self.speed = 8;
self.lastY = 0;
self.caught = false;
self.update = function () {
if (!self.caught) {
// Increase speed when lives reach 1
var speedMultiplier = lives === 1 ? 1.5 : 1;
self.y += self.speed * speedMultiplier;
}
// Switch to damaged sprite when lives reach 1
if (lives === 1) {
orangeGraphics.visible = false;
orangeDamageGraphics.visible = true;
} else {
orangeGraphics.visible = true;
orangeDamageGraphics.visible = false;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Add background
var backgroundSprite = LK.getAsset('background', {
anchorX: 0,
anchorY: 0
});
backgroundSprite.x = 0;
backgroundSprite.y = 0;
game.addChild(backgroundSprite);
var backgroundDamageSprite = LK.getAsset('background_damage', {
anchorX: 0,
anchorY: 0
});
backgroundDamageSprite.x = 0;
backgroundDamageSprite.y = 0;
backgroundDamageSprite.visible = false;
game.addChild(backgroundDamageSprite);
var cat;
var oranges = [];
var gameSpeed = 1;
var orangeSpawnRate = 60; // frames between spawns
var frameCount = 0;
var lives = 3;
// Tutorial system variables
var tutorialSystem = null;
var gameStarted = false;
var tutorialActive = false;
// Create score display
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create lives display
var livesTxt = new Text2('Lives: 3', {
size: 60,
fill: 0xFFFFFF
});
livesTxt.anchor.set(1, 0);
livesTxt.y = 100;
LK.gui.topRight.addChild(livesTxt);
// Create heart icon for lives
var heartIcon = LK.getAsset('heart_icon', {
anchorX: 1,
anchorY: 0
});
heartIcon.x = -10; // Position relative to topRight
heartIcon.y = 170;
LK.gui.topRight.addChild(heartIcon);
// Create damaged heart icon
var heartDamageIcon = LK.getAsset('heart_damage', {
anchorX: 1,
anchorY: 0
});
heartDamageIcon.x = -10; // Position relative to topRight
heartDamageIcon.y = 170;
heartDamageIcon.visible = false;
LK.gui.topRight.addChild(heartDamageIcon);
// Create the cat
cat = game.addChild(new Cat());
cat.x = 1024; // Center horizontally
cat.y = 2600; // Near bottom of screen
// Tutorial System
tutorialSystem = {
currentStep: 0,
dialogBox: null,
tutorialOrange: null,
steps: ["¡Hola! Soy un gato azul muy hambriento 🐱", "¡Ayúdame a atrapar las naranjas que caen del cielo! 🍊", "Arrastra tu dedo por la pantalla para moverme ⬅️➡️", "¡Perfecto! Ahora atrapa esta naranja de práctica", "¡Ten cuidado! Si pierdes 3 naranjas, perderás una vida ❤️", "¡Cuando tenga solo 1 vida, todo se vuelve más intenso! ⚡", "¡Ahora estás listo! ¡A por esas naranjas! 🎯"],
init: function init() {
tutorialActive = true;
this.showDialog();
},
showDialog: function showDialog() {
if (this.currentStep >= this.steps.length) {
this.endTutorial();
return;
}
if (this.dialogBox) {
this.dialogBox.destroy();
}
this.dialogBox = new DialogBox();
this.dialogBox.x = 1024;
this.dialogBox.y = 1366;
this.dialogBox.setText(this.steps[this.currentStep]);
game.addChild(this.dialogBox);
// Animate dialog appearance
this.dialogBox.alpha = 0;
this.dialogBox.scaleX = 0.5;
this.dialogBox.scaleY = 0.5;
tween(this.dialogBox, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeOut
});
},
onDialogClick: function onDialogClick() {
this.currentStep++;
if (this.currentStep === 3) {
// Step 3: Create practice orange
this.createPracticeOrange();
} else if (this.currentStep === 4) {
// Step 4: Wait for orange to be caught
return;
} else if (this.currentStep === 5) {
// Step 5: Show lives preview
this.showLivesPreview();
} else if (this.currentStep === 6) {
// Step 6: Show hardcore mode preview
this.showHardcorePreview();
} else {
this.showDialog();
}
},
createPracticeOrange: function createPracticeOrange() {
if (this.dialogBox) {
this.dialogBox.destroy();
this.dialogBox = null;
}
this.tutorialOrange = new Orange();
this.tutorialOrange.x = 1024;
this.tutorialOrange.y = -40;
this.tutorialOrange.speed = 3; // Slower for practice
this.tutorialOrange.lastY = this.tutorialOrange.y;
game.addChild(this.tutorialOrange);
// Add arrow pointing to orange
this.createArrow();
},
createArrow: function createArrow() {
if (!tutorialActive) return;
this.arrow = new Text2('⬇️', {
size: 100,
fill: 0xFFFF00 //{4c_new}
});
this.arrow.anchor.set(0.5, 0.5);
this.arrow.x = 1024;
this.arrow.y = 200;
game.addChild(this.arrow);
// Animate arrow
tween(this.arrow, {
y: 250
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (tutorialSystem && tutorialSystem.arrow && tutorialActive) {
//{4h_new}
tween(tutorialSystem.arrow, {
y: 200
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (tutorialActive) {
tutorialSystem.createArrow();
}
}
});
}
} //{4o_new}
});
},
checkPracticeOrange: function checkPracticeOrange() {
if (this.tutorialOrange && this.tutorialOrange.caught) {
if (this.arrow) {
this.arrow.destroy();
this.arrow = null;
}
this.tutorialOrange = null;
this.currentStep++;
this.showDialog();
}
},
showLivesPreview: function showLivesPreview() {
if (this.dialogBox) {
this.dialogBox.destroy();
this.dialogBox = null;
}
// Temporarily show lives indicator
LK.effects.flashObject(heartIcon, 0xFF0000, 1000);
LK.setTimeout(function () {
tutorialSystem.showDialog();
}, 1500);
},
showHardcorePreview: function showHardcorePreview() {
if (this.dialogBox) {
this.dialogBox.destroy();
this.dialogBox = null;
}
// Briefly switch to hardcore mode visuals
var originalLives = lives;
lives = 1;
updateLives();
cat.switchToDamaged();
LK.setTimeout(function () {
lives = originalLives;
updateLives();
cat.switchToNormal();
tutorialSystem.showDialog();
}, 2000);
},
endTutorial: function endTutorial() {
tutorialActive = false;
gameStarted = true;
if (this.dialogBox) {
tween(this.dialogBox, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
tutorialSystem.dialogBox.destroy();
tutorialSystem.dialogBox = null;
}
});
}
}
};
// Start tutorial
tutorialSystem.init();
// Play tutorial music
LK.playMusic('Cool');
// Handle touch/mouse input
function handleMove(x, y, obj) {
if (cat && (gameStarted || tutorialActive && tutorialSystem.currentStep >= 2)) {
cat.targetX = x;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
handleMove(x, y, obj);
};
// Spawn oranges
function spawnOrange() {
var orange = new Orange();
orange.x = Math.random() * (2048 - 160) + 80; // Random x position within bounds
orange.y = -40; // Start above screen
orange.lastY = orange.y;
orange.speed = 6 + gameSpeed * 2; // Increase speed with game progression
oranges.push(orange);
game.addChild(orange);
}
// Update score display
function updateScore() {
scoreTxt.setText('Score: ' + LK.getScore());
}
// Update lives display
function updateLives() {
livesTxt.setText('Lives: ' + lives);
// Switch heart sprite when lives reach 1
if (lives === 1) {
heartIcon.visible = false;
heartDamageIcon.visible = true;
// Switch to hardcore music when lives reach 1
LK.playMusic('hardcore');
// Switch to damaged background
backgroundSprite.visible = false;
backgroundDamageSprite.visible = true;
} else {
heartIcon.visible = true;
heartDamageIcon.visible = false;
// Switch to normal background
backgroundSprite.visible = true;
backgroundDamageSprite.visible = false;
}
}
game.update = function () {
// Handle tutorial logic
if (tutorialActive) {
if (tutorialSystem.tutorialOrange) {
tutorialSystem.checkPracticeOrange();
if (tutorialSystem.tutorialOrange && !tutorialSystem.tutorialOrange.caught && tutorialSystem.tutorialOrange.intersects(cat)) {
tutorialSystem.tutorialOrange.caught = true;
LK.getSound('eat').play();
cat.startEating();
tween(tutorialSystem.tutorialOrange, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
if (tutorialSystem.tutorialOrange) {
tutorialSystem.tutorialOrange.destroy();
tutorialSystem.tutorialOrange = null;
} //{5i_new}
}
});
}
}
return; // Don't run normal game logic during tutorial
}
if (!gameStarted) return;
frameCount++;
// Spawn oranges
if (frameCount % Math.max(20, orangeSpawnRate - Math.floor(LK.getScore() / 5)) === 0) {
spawnOrange();
}
// Increase game speed over time
if (frameCount % 600 === 0) {
// Every 10 seconds at 60fps
gameSpeed += 0.2;
}
// Update oranges
for (var i = oranges.length - 1; i >= 0; i--) {
var orange = oranges[i];
// Check if orange went off screen (missed)
if (orange.lastY < 2732 && orange.y >= 2732 && !orange.caught) {
// Orange hit the ground - lose a life
lives--;
updateLives();
// Play fail sound
LK.getSound('fail').play();
if (lives <= 0) {
LK.showGameOver();
return;
}
orange.destroy();
oranges.splice(i, 1);
continue;
}
// Check collision with cat
if (!orange.caught && orange.intersects(cat)) {
// Orange caught!
orange.caught = true;
LK.setScore(LK.getScore() + 1);
updateScore();
// Play catch sound
LK.getSound('catch').play();
// Play eat sound
LK.getSound('eat').play();
// Flash effect on cat
LK.effects.flashObject(cat, 0xFFFFFF, 200);
// Trigger eating animation
cat.startEating();
// Animate orange being caught
tween(orange, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
orange.destroy();
}
});
oranges.splice(i, 1);
continue;
}
orange.lastY = orange.y;
}
// Check win condition (optional - high score achievement)
if (LK.getScore() >= 100) {
LK.showYouWin();
}
};
// Start energetic dance music
LK.playMusic('Fun');
// Initialize displays
updateScore();
updateLives();
Haz un sprite de un gato azul sin pupilas con la boca abierta mirando arriba. In-Game asset. 2d. High contrast. No shadows
Una naranja cute. In-Game asset. 2d. High contrast. No shadows
Un corazón roto triste cute. In-Game asset. 2d. High contrast. No shadows
Un gato azul sin pupilas preocupado. In-Game asset. 2d. High contrast. No shadows
Un gato azul sin pupilas preocupado caminando. In-Game asset. 2d. High contrast. No shadows
Naranja cute preocupada. In-Game asset. 2d. High contrast. No shadows
Un bosque quemándose D:. In-Game asset. 2d. High contrast. No shadows