/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Animal = Container.expand(function (type, barnArea) {
var self = Container.call(this);
self.type = type; // 'cow', 'sheep', 'chicken'
self.barnArea = barnArea;
self.hunger = 100; // 0-100, decreases over time
self.thirst = 100; // 0-100, decreases over time
self.happiness = 100; // 0-100, affected by care
self.lastCareTime = Date.now();
// Visual representation
var animalGraphic = null;
if (type === 'cow') {
animalGraphic = self.attachAsset('cow', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
} else if (type === 'sheep') {
animalGraphic = self.attachAsset('sheep', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
} else if (type === 'chicken') {
animalGraphic = self.attachAsset('chicken', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
}
// Random wandering
self.targetX = self.x;
self.targetY = self.y;
self.speed = 1.0;
self.setRandomTarget = function () {
self.targetX = barnArea.x + Math.random() * barnArea.width;
self.targetY = barnArea.y + Math.random() * barnArea.height;
};
self.feed = function () {
if (self.hunger < 100) {
self.hunger = Math.min(100, self.hunger + 30);
self.happiness = Math.min(100, self.happiness + 10);
coins += 5; // Reward for caring
score += 5;
updateUI();
// Visual feedback
tween(animalGraphic, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
onFinish: function onFinish() {
tween(animalGraphic, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
}
};
self.giveWater = function () {
if (self.thirst < 100) {
self.thirst = Math.min(100, self.thirst + 40);
self.happiness = Math.min(100, self.happiness + 15);
coins += 3;
score += 3;
updateUI();
// Visual feedback
tween(animalGraphic, {
tint: 0x87CEEB
}, {
duration: 300,
onFinish: function onFinish() {
tween(animalGraphic, {
tint: 0xFFFFFF
}, {
duration: 300
});
}
});
}
};
self.update = function () {
var now = Date.now();
// Decrease needs over time
if (now - self.lastCareTime > 10000) {
// Every 10 seconds
self.hunger = Math.max(0, self.hunger - 2);
self.thirst = Math.max(0, self.thirst - 3);
if (self.hunger < 50 || self.thirst < 50) {
self.happiness = Math.max(0, self.happiness - 1);
}
self.lastCareTime = now;
}
// Random wandering
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 5 || Math.random() < 0.01) {
self.setRandomTarget();
} else {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Visual indicators for needs
if (self.hunger < 30) {
animalGraphic.tint = 0xFF9999; // Reddish when hungry
} else if (self.thirst < 30) {
animalGraphic.tint = 0x9999FF; // Bluish when thirsty
} else {
animalGraphic.tint = 0xFFFFFF; // Normal color
}
};
self.down = function (x, y, obj) {
// Cycle through care actions on tap
if (self.hunger < 80) {
self.feed();
} else if (self.thirst < 80) {
self.giveWater();
} else {
// Pet the animal for happiness
self.happiness = Math.min(100, self.happiness + 20);
tween(animalGraphic, {
rotation: 0.2
}, {
duration: 150,
onFinish: function onFinish() {
tween(animalGraphic, {
rotation: 0
}, {
duration: 150
});
}
});
}
};
return self;
});
var Barn = Container.expand(function () {
var self = Container.call(this);
// Barn background
var barnBg = self.attachAsset('barnBackground', {
anchorX: 0.5,
anchorY: 0.5
});
self.animals = [];
self.barnArea = {
x: -600,
y: -600,
width: 1200,
height: 1200
};
self.fox = null;
self.lastFoxSpawn = Date.now();
self.foxSpawnInterval = 60000; // Fox appears every 60 seconds
self.addAnimal = function (type) {
var animal = new Animal(type, self.barnArea);
animal.x = self.barnArea.x + Math.random() * self.barnArea.width;
animal.y = self.barnArea.y + Math.random() * self.barnArea.height;
animal.setRandomTarget();
self.animals.push(animal);
self.addChild(animal);
return animal;
};
self.update = function () {
for (var i = 0; i < self.animals.length; i++) {
self.animals[i].update();
}
// Save animal states periodically
if (LK.ticks % 60 === 0) {
self.saveAnimals();
}
// Fox spawning logic
var now = Date.now();
if (!self.fox && now - self.lastFoxSpawn > self.foxSpawnInterval && self.animals.length > 0) {
// Spawn a new fox
self.fox = new Fox(self.barnArea, self.animals);
self.addChild(self.fox);
self.lastFoxSpawn = now;
}
// Update fox if it exists
if (self.fox) {
self.fox.update();
// Check if fox was destroyed (escaped or attacked)
if (self.fox.destroyed) {
self.fox = null;
self.saveAnimals(); // Save when animals are removed by fox
}
}
};
self.saveAnimals = function () {
// Save animal count and individual animal properties as separate storage keys
storage.animalCount = self.animals.length;
for (var i = 0; i < self.animals.length; i++) {
var animal = self.animals[i];
var prefix = 'animal_' + i + '_';
storage[prefix + 'type'] = animal.type;
storage[prefix + 'x'] = animal.x;
storage[prefix + 'y'] = animal.y;
storage[prefix + 'hunger'] = animal.hunger;
storage[prefix + 'thirst'] = animal.thirst;
storage[prefix + 'happiness'] = animal.happiness;
}
};
self.loadAnimals = function () {
var animalCount = storage.animalCount || 0;
for (var i = 0; i < animalCount; i++) {
var prefix = 'animal_' + i + '_';
var animalType = storage[prefix + 'type'];
if (animalType) {
var animal = self.addAnimal(animalType);
animal.x = storage[prefix + 'x'] || animal.x;
animal.y = storage[prefix + 'y'] || animal.y;
animal.hunger = storage[prefix + 'hunger'] || 100;
animal.thirst = storage[prefix + 'thirst'] || 100;
animal.happiness = storage[prefix + 'happiness'] || 100;
}
}
};
return self;
});
var Fox = Container.expand(function (barnArea, animals) {
var self = Container.call(this);
self.barnArea = barnArea;
self.animals = animals;
self.spawnTime = Date.now();
self.attackTime = 30000; // 30 seconds before attacking
self.hasAttacked = false;
self.speed = 1.0;
self.barkDuration = 5000; // Bark for 5 seconds
self.isBarking = true;
self.barkSound = null;
// Visual representation
var foxGraphic = self.attachAsset('fox', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
// Set random position in barn area
self.x = barnArea.x + Math.random() * barnArea.width;
self.y = barnArea.y + Math.random() * barnArea.height;
// Random wandering target
self.targetX = self.x;
self.targetY = self.y;
self.setRandomTarget = function () {
self.targetX = barnArea.x + Math.random() * barnArea.width;
self.targetY = barnArea.y + Math.random() * barnArea.height;
};
self.attack = function () {
if (self.animals.length > 0 && !self.hasAttacked) {
// Kill a random animal
var randomIndex = Math.floor(Math.random() * self.animals.length);
var targetAnimal = self.animals[randomIndex];
// Remove animal from barn
targetAnimal.destroy();
self.animals.splice(randomIndex, 1);
self.hasAttacked = true;
// Fox leaves after attack
self.escape();
}
};
self.escape = function () {
// Stop barking sound if still playing
if (self.barkSound) {
self.barkSound.stop();
self.barkSound = null;
}
self.isBarking = false;
// Tween fox out of the barn area quickly
tween(self, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 500,
onFinish: function onFinish() {
self.destroy();
}
});
};
self.update = function () {
var elapsed = Date.now() - self.spawnTime;
// Handle barking sound for first 5 seconds
if (self.isBarking) {
if (elapsed < self.barkDuration) {
// Start barking if not already started
if (!self.barkSound) {
self.barkSound = LK.getSound('bark');
self.barkSound.play();
}
} else {
// Stop barking after 5 seconds
self.isBarking = false;
if (self.barkSound) {
self.barkSound.stop();
self.barkSound = null;
}
}
}
// Attack after 30 seconds if still alive
if (elapsed >= self.attackTime && !self.hasAttacked) {
self.attack();
return;
}
// Random wandering behavior
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 5 || Math.random() < 0.02) {
self.setRandomTarget();
} else {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Visual threat indication (red tint gets stronger over time)
var threatLevel = Math.min(1, elapsed / self.attackTime);
var redTint = 0xFF0000;
var whiteTint = 0xFFFFFF;
// Interpolate between white and red based on threat level
var r = 255;
var g = Math.floor(255 * (1 - threatLevel));
var b = Math.floor(255 * (1 - threatLevel));
foxGraphic.tint = r << 16 | g << 8 | b;
};
self.down = function (x, y, obj) {
// Player clicked the fox - it escapes immediately
self.escape();
};
return self;
});
var Plot = Container.expand(function (row, col) {
var self = Container.call(this);
// Plot properties
self.row = row;
self.col = col;
self.state = 'empty'; // empty, planted, growing, ready
self.plantTime = 0;
self.growthDuration = 180000; // 3 minutes
self.cropValue = 10;
// Visual elements
var soil = self.attachAsset('soilPlot', {
anchorX: 0.5,
anchorY: 0.5
});
var plantGraphics = null;
self.plant = function () {
if (self.state === 'empty' && coins >= 5) {
coins -= 5;
self.state = 'planted';
self.plantTime = Date.now();
plantGraphics = self.addChild(LK.getAsset('seed', {
anchorX: 0.5,
anchorY: 0.5
}));
LK.getSound('plant').play();
updateUI();
}
};
self.harvest = function () {
if (self.state === 'ready') {
coins += self.cropValue;
score += self.cropValue;
self.state = 'empty';
if (plantGraphics) {
plantGraphics.destroy();
plantGraphics = null;
}
// Harvest effect
var coinEffect = self.addChild(LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
y: -60
}));
tween(coinEffect, {
y: -120,
alpha: 0
}, {
duration: 800,
onFinish: function onFinish() {
coinEffect.destroy();
}
});
LK.getSound('harvest').play();
updateUI();
}
};
self.update = function () {
if (self.state === 'planted' || self.state === 'growing') {
var elapsed = Date.now() - self.plantTime;
var progress = elapsed / self.growthDuration;
if (progress >= 1) {
// Fully grown
self.state = 'ready';
if (plantGraphics) {
plantGraphics.destroy();
plantGraphics = self.addChild(LK.getAsset('crop', {
anchorX: 0.5,
anchorY: 1,
y: 60
}));
}
} else if (progress >= 0.5 && self.state === 'planted') {
// Growing stage
self.state = 'growing';
if (plantGraphics) {
plantGraphics.destroy();
plantGraphics = self.addChild(LK.getAsset('sprout', {
anchorX: 0.5,
anchorY: 1,
y: 40
}));
}
}
}
// Save plot states to storage
self.saveState();
};
self.saveState = function () {
var plotKey = 'plot_' + self.row + '_' + self.col;
storage[plotKey] = {
state: self.state,
plantTime: self.plantTime
};
};
self.loadState = function () {
var plotKey = 'plot_' + self.row + '_' + self.col;
var savedState = storage[plotKey];
if (savedState) {
self.state = savedState.state;
self.plantTime = savedState.plantTime || 0;
// Restore visual state based on saved data
if (self.state === 'planted' || self.state === 'growing' || self.state === 'ready') {
var elapsed = Date.now() - self.plantTime;
var progress = elapsed / self.growthDuration;
if (progress >= 1) {
self.state = 'ready';
plantGraphics = self.addChild(LK.getAsset('crop', {
anchorX: 0.5,
anchorY: 1,
y: 60
}));
} else if (progress >= 0.5) {
self.state = 'growing';
plantGraphics = self.addChild(LK.getAsset('sprout', {
anchorX: 0.5,
anchorY: 1,
y: 40
}));
} else {
plantGraphics = self.addChild(LK.getAsset('seed', {
anchorX: 0.5,
anchorY: 0.5
}));
}
}
}
};
self.down = function (x, y, obj) {
if (self.state === 'empty') {
self.plant();
} else if (self.state === 'ready') {
self.harvest();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables - load from storage with defaults
var coins = storage.coins || 25;
var score = storage.score || 0;
var plots = [];
var gridRows = 4;
var gridCols = 6;
var plotSize = 200;
// Loan system variables
var loanActive = storage.loanActive || false;
var loanStartTime = storage.loanStartTime || 0;
var loanDuration = 60 * 60 * 1000; // 60 minutes in milliseconds
var loanAmount = 2000;
// UI elements
var coinsText = new Text2('Coins: 25', {
size: 60,
fill: 0xFFFFFF
});
coinsText.anchor.set(0, 0);
LK.gui.topLeft.addChild(coinsText);
coinsText.x = 120;
coinsText.y = 20;
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.y = 20;
// Credit button (bottom-left)
var creditButton = new Text2('KREDI\n2000', {
size: 45,
fill: 0xFFFFFF
});
creditButton.anchor.set(0, 1);
creditButton.x = 20;
creditButton.y = -20;
LK.gui.bottomLeft.addChild(creditButton);
// Loan timer display (only visible when loan is active)
var loanTimerText = new Text2('', {
size: 40,
fill: 0xFF0000
});
loanTimerText.anchor.set(0, 1);
loanTimerText.x = 20;
loanTimerText.y = -120;
LK.gui.bottomLeft.addChild(loanTimerText);
function updateUI() {
coinsText.setText('Coins: ' + coins);
scoreText.setText('Score: ' + score);
// Save game state to storage
storage.coins = coins;
storage.score = score;
updateButtonStates();
updateLoanUI();
// Game continues endlessly - no win condition
}
function updateLoanUI() {
if (loanActive) {
var now = Date.now();
var timeLeft = loanDuration - (now - loanStartTime);
if (timeLeft > 0) {
// Show remaining time
var minutesLeft = Math.ceil(timeLeft / (60 * 1000));
loanTimerText.setText('Kredi: ' + minutesLeft + ' dk');
loanTimerText.alpha = 1;
creditButton.alpha = 0.5;
creditButton.tint = 0x888888;
} else {
// Time is up - check if player has enough coins
if (coins >= loanAmount) {
// Player can pay back - deduct coins and clear loan
coins -= loanAmount;
loanActive = false;
loanStartTime = 0;
storage.loanActive = false;
storage.loanStartTime = 0;
loanTimerText.alpha = 0;
creditButton.alpha = 1.0;
creditButton.tint = 0xFFFFFF;
updateUI();
} else {
// Player doesn't have enough - game over
LK.showGameOver();
}
}
} else {
loanTimerText.alpha = 0;
creditButton.alpha = 1.0;
creditButton.tint = 0xFFFFFF;
}
}
// Create farm grid (moved to upper portion)
var farmStartX = (2048 - gridCols * plotSize) / 2;
var farmStartY = 200;
for (var row = 0; row < gridRows; row++) {
plots[row] = [];
for (var col = 0; col < gridCols; col++) {
var plot = new Plot(row, col);
plot.x = farmStartX + col * plotSize + plotSize / 2;
plot.y = farmStartY + row * plotSize + plotSize / 2;
plots[row][col] = plot;
// Load saved plot state
plot.loadState();
game.addChild(plot);
}
}
// Instructions text
var instructionsText = new Text2('Tap empty plots to plant (5 coins)\nTap crops to harvest\nTap animals to care for them', {
size: 40,
fill: 0x333333
});
instructionsText.anchor.set(0.5, 0);
instructionsText.x = 1024;
instructionsText.y = 120;
game.addChild(instructionsText);
// Buy animal buttons (bottom-right)
var sheepButton = LK.getAsset('sheep', {
anchorX: 1,
anchorY: 1,
scaleX: 1.0,
scaleY: 1.0
});
sheepButton.x = -120;
sheepButton.y = -200;
LK.gui.bottomRight.addChild(sheepButton);
// Sheep price text
var sheepPriceText = new Text2('50', {
size: 40,
fill: 0xFFFFFF
});
sheepPriceText.anchor.set(1, 1);
sheepPriceText.x = -20;
sheepPriceText.y = -200;
LK.gui.bottomRight.addChild(sheepPriceText);
var cowButton = LK.getAsset('cow', {
anchorX: 1,
anchorY: 1,
scaleX: 0.8,
scaleY: 0.8
});
cowButton.x = -120;
cowButton.y = -120;
LK.gui.bottomRight.addChild(cowButton);
// Cow price text
var cowPriceText = new Text2('75', {
size: 40,
fill: 0xFFFFFF
});
cowPriceText.anchor.set(1, 1);
cowPriceText.x = -20;
cowPriceText.y = -120;
LK.gui.bottomRight.addChild(cowPriceText);
var chickenButton = LK.getAsset('chicken', {
anchorX: 1,
anchorY: 1,
scaleX: 1.0,
scaleY: 1.0
});
chickenButton.x = -120;
chickenButton.y = -40;
LK.gui.bottomRight.addChild(chickenButton);
// Chicken price text
var chickenPriceText = new Text2('25', {
size: 40,
fill: 0xFFFFFF
});
chickenPriceText.anchor.set(1, 1);
chickenPriceText.x = -20;
chickenPriceText.y = -40;
LK.gui.bottomRight.addChild(chickenPriceText);
// Button click handlers
sheepButton.down = function (x, y, obj) {
if (coins >= 50) {
coins -= 50;
barn.addAnimal('sheep');
updateUI();
// Visual feedback
tween(sheepButton, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
onFinish: function onFinish() {
tween(sheepButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150
});
}
});
}
};
cowButton.down = function (x, y, obj) {
if (coins >= 75) {
coins -= 75;
barn.addAnimal('cow');
updateUI();
// Visual feedback
tween(cowButton, {
scaleX: 0.96,
scaleY: 0.96
}, {
duration: 150,
onFinish: function onFinish() {
tween(cowButton, {
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 150
});
}
});
}
};
chickenButton.down = function (x, y, obj) {
if (coins >= 25) {
coins -= 25;
barn.addAnimal('chicken');
updateUI();
// Visual feedback
tween(chickenButton, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
onFinish: function onFinish() {
tween(chickenButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150
});
}
});
}
};
// Credit button click handler
creditButton.down = function (x, y, obj) {
if (!loanActive) {
// Take the loan
coins += loanAmount;
loanActive = true;
loanStartTime = Date.now();
// Save to storage
storage.loanActive = loanActive;
storage.loanStartTime = loanStartTime;
updateUI();
// Visual feedback
tween(creditButton, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
onFinish: function onFinish() {
tween(creditButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150
});
}
});
}
};
// Update button appearance based on coin availability
function updateButtonStates() {
// Chicken button (25 coins)
if (coins >= 25) {
chickenButton.tint = 0xFFFFFF;
chickenButton.alpha = 1.0;
chickenPriceText.tint = 0xFFFFFF;
} else {
chickenButton.tint = 0x888888;
chickenButton.alpha = 0.6;
chickenPriceText.tint = 0x888888;
}
// Sheep button (50 coins)
if (coins >= 50) {
sheepButton.tint = 0xFFFFFF;
sheepButton.alpha = 1.0;
sheepPriceText.tint = 0xFFFFFF;
} else {
sheepButton.tint = 0x888888;
sheepButton.alpha = 0.6;
sheepPriceText.tint = 0x888888;
}
// Cow button (75 coins)
if (coins >= 75) {
cowButton.tint = 0xFFFFFF;
cowButton.alpha = 1.0;
cowPriceText.tint = 0xFFFFFF;
} else {
cowButton.tint = 0x888888;
cowButton.alpha = 0.6;
cowPriceText.tint = 0x888888;
}
}
// Create barn in lower portion
var barn = new Barn();
barn.x = 1024; // Center horizontally
barn.y = 2200; // Lower portion of screen
game.addChild(barn);
// Load saved animals or add initial ones if no save data
if (storage.animalCount && storage.animalCount > 0) {
barn.loadAnimals();
} else {
// Add some initial animals
barn.addAnimal('cow');
barn.addAnimal('cow');
barn.addAnimal('sheep');
barn.addAnimal('sheep');
barn.addAnimal('chicken');
barn.addAnimal('chicken');
barn.addAnimal('chicken');
}
game.update = function () {
// Update all plots
for (var row = 0; row < gridRows; row++) {
for (var col = 0; col < gridCols; col++) {
plots[row][col].update();
}
}
// Update barn and animals
barn.update();
// Check loan status every frame
if (loanActive) {
updateLoanUI();
}
// Game continues endlessly - no game over condition
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Animal = Container.expand(function (type, barnArea) {
var self = Container.call(this);
self.type = type; // 'cow', 'sheep', 'chicken'
self.barnArea = barnArea;
self.hunger = 100; // 0-100, decreases over time
self.thirst = 100; // 0-100, decreases over time
self.happiness = 100; // 0-100, affected by care
self.lastCareTime = Date.now();
// Visual representation
var animalGraphic = null;
if (type === 'cow') {
animalGraphic = self.attachAsset('cow', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
} else if (type === 'sheep') {
animalGraphic = self.attachAsset('sheep', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
} else if (type === 'chicken') {
animalGraphic = self.attachAsset('chicken', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
}
// Random wandering
self.targetX = self.x;
self.targetY = self.y;
self.speed = 1.0;
self.setRandomTarget = function () {
self.targetX = barnArea.x + Math.random() * barnArea.width;
self.targetY = barnArea.y + Math.random() * barnArea.height;
};
self.feed = function () {
if (self.hunger < 100) {
self.hunger = Math.min(100, self.hunger + 30);
self.happiness = Math.min(100, self.happiness + 10);
coins += 5; // Reward for caring
score += 5;
updateUI();
// Visual feedback
tween(animalGraphic, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
onFinish: function onFinish() {
tween(animalGraphic, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
}
};
self.giveWater = function () {
if (self.thirst < 100) {
self.thirst = Math.min(100, self.thirst + 40);
self.happiness = Math.min(100, self.happiness + 15);
coins += 3;
score += 3;
updateUI();
// Visual feedback
tween(animalGraphic, {
tint: 0x87CEEB
}, {
duration: 300,
onFinish: function onFinish() {
tween(animalGraphic, {
tint: 0xFFFFFF
}, {
duration: 300
});
}
});
}
};
self.update = function () {
var now = Date.now();
// Decrease needs over time
if (now - self.lastCareTime > 10000) {
// Every 10 seconds
self.hunger = Math.max(0, self.hunger - 2);
self.thirst = Math.max(0, self.thirst - 3);
if (self.hunger < 50 || self.thirst < 50) {
self.happiness = Math.max(0, self.happiness - 1);
}
self.lastCareTime = now;
}
// Random wandering
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 5 || Math.random() < 0.01) {
self.setRandomTarget();
} else {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Visual indicators for needs
if (self.hunger < 30) {
animalGraphic.tint = 0xFF9999; // Reddish when hungry
} else if (self.thirst < 30) {
animalGraphic.tint = 0x9999FF; // Bluish when thirsty
} else {
animalGraphic.tint = 0xFFFFFF; // Normal color
}
};
self.down = function (x, y, obj) {
// Cycle through care actions on tap
if (self.hunger < 80) {
self.feed();
} else if (self.thirst < 80) {
self.giveWater();
} else {
// Pet the animal for happiness
self.happiness = Math.min(100, self.happiness + 20);
tween(animalGraphic, {
rotation: 0.2
}, {
duration: 150,
onFinish: function onFinish() {
tween(animalGraphic, {
rotation: 0
}, {
duration: 150
});
}
});
}
};
return self;
});
var Barn = Container.expand(function () {
var self = Container.call(this);
// Barn background
var barnBg = self.attachAsset('barnBackground', {
anchorX: 0.5,
anchorY: 0.5
});
self.animals = [];
self.barnArea = {
x: -600,
y: -600,
width: 1200,
height: 1200
};
self.fox = null;
self.lastFoxSpawn = Date.now();
self.foxSpawnInterval = 60000; // Fox appears every 60 seconds
self.addAnimal = function (type) {
var animal = new Animal(type, self.barnArea);
animal.x = self.barnArea.x + Math.random() * self.barnArea.width;
animal.y = self.barnArea.y + Math.random() * self.barnArea.height;
animal.setRandomTarget();
self.animals.push(animal);
self.addChild(animal);
return animal;
};
self.update = function () {
for (var i = 0; i < self.animals.length; i++) {
self.animals[i].update();
}
// Save animal states periodically
if (LK.ticks % 60 === 0) {
self.saveAnimals();
}
// Fox spawning logic
var now = Date.now();
if (!self.fox && now - self.lastFoxSpawn > self.foxSpawnInterval && self.animals.length > 0) {
// Spawn a new fox
self.fox = new Fox(self.barnArea, self.animals);
self.addChild(self.fox);
self.lastFoxSpawn = now;
}
// Update fox if it exists
if (self.fox) {
self.fox.update();
// Check if fox was destroyed (escaped or attacked)
if (self.fox.destroyed) {
self.fox = null;
self.saveAnimals(); // Save when animals are removed by fox
}
}
};
self.saveAnimals = function () {
// Save animal count and individual animal properties as separate storage keys
storage.animalCount = self.animals.length;
for (var i = 0; i < self.animals.length; i++) {
var animal = self.animals[i];
var prefix = 'animal_' + i + '_';
storage[prefix + 'type'] = animal.type;
storage[prefix + 'x'] = animal.x;
storage[prefix + 'y'] = animal.y;
storage[prefix + 'hunger'] = animal.hunger;
storage[prefix + 'thirst'] = animal.thirst;
storage[prefix + 'happiness'] = animal.happiness;
}
};
self.loadAnimals = function () {
var animalCount = storage.animalCount || 0;
for (var i = 0; i < animalCount; i++) {
var prefix = 'animal_' + i + '_';
var animalType = storage[prefix + 'type'];
if (animalType) {
var animal = self.addAnimal(animalType);
animal.x = storage[prefix + 'x'] || animal.x;
animal.y = storage[prefix + 'y'] || animal.y;
animal.hunger = storage[prefix + 'hunger'] || 100;
animal.thirst = storage[prefix + 'thirst'] || 100;
animal.happiness = storage[prefix + 'happiness'] || 100;
}
}
};
return self;
});
var Fox = Container.expand(function (barnArea, animals) {
var self = Container.call(this);
self.barnArea = barnArea;
self.animals = animals;
self.spawnTime = Date.now();
self.attackTime = 30000; // 30 seconds before attacking
self.hasAttacked = false;
self.speed = 1.0;
self.barkDuration = 5000; // Bark for 5 seconds
self.isBarking = true;
self.barkSound = null;
// Visual representation
var foxGraphic = self.attachAsset('fox', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
// Set random position in barn area
self.x = barnArea.x + Math.random() * barnArea.width;
self.y = barnArea.y + Math.random() * barnArea.height;
// Random wandering target
self.targetX = self.x;
self.targetY = self.y;
self.setRandomTarget = function () {
self.targetX = barnArea.x + Math.random() * barnArea.width;
self.targetY = barnArea.y + Math.random() * barnArea.height;
};
self.attack = function () {
if (self.animals.length > 0 && !self.hasAttacked) {
// Kill a random animal
var randomIndex = Math.floor(Math.random() * self.animals.length);
var targetAnimal = self.animals[randomIndex];
// Remove animal from barn
targetAnimal.destroy();
self.animals.splice(randomIndex, 1);
self.hasAttacked = true;
// Fox leaves after attack
self.escape();
}
};
self.escape = function () {
// Stop barking sound if still playing
if (self.barkSound) {
self.barkSound.stop();
self.barkSound = null;
}
self.isBarking = false;
// Tween fox out of the barn area quickly
tween(self, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 500,
onFinish: function onFinish() {
self.destroy();
}
});
};
self.update = function () {
var elapsed = Date.now() - self.spawnTime;
// Handle barking sound for first 5 seconds
if (self.isBarking) {
if (elapsed < self.barkDuration) {
// Start barking if not already started
if (!self.barkSound) {
self.barkSound = LK.getSound('bark');
self.barkSound.play();
}
} else {
// Stop barking after 5 seconds
self.isBarking = false;
if (self.barkSound) {
self.barkSound.stop();
self.barkSound = null;
}
}
}
// Attack after 30 seconds if still alive
if (elapsed >= self.attackTime && !self.hasAttacked) {
self.attack();
return;
}
// Random wandering behavior
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 5 || Math.random() < 0.02) {
self.setRandomTarget();
} else {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Visual threat indication (red tint gets stronger over time)
var threatLevel = Math.min(1, elapsed / self.attackTime);
var redTint = 0xFF0000;
var whiteTint = 0xFFFFFF;
// Interpolate between white and red based on threat level
var r = 255;
var g = Math.floor(255 * (1 - threatLevel));
var b = Math.floor(255 * (1 - threatLevel));
foxGraphic.tint = r << 16 | g << 8 | b;
};
self.down = function (x, y, obj) {
// Player clicked the fox - it escapes immediately
self.escape();
};
return self;
});
var Plot = Container.expand(function (row, col) {
var self = Container.call(this);
// Plot properties
self.row = row;
self.col = col;
self.state = 'empty'; // empty, planted, growing, ready
self.plantTime = 0;
self.growthDuration = 180000; // 3 minutes
self.cropValue = 10;
// Visual elements
var soil = self.attachAsset('soilPlot', {
anchorX: 0.5,
anchorY: 0.5
});
var plantGraphics = null;
self.plant = function () {
if (self.state === 'empty' && coins >= 5) {
coins -= 5;
self.state = 'planted';
self.plantTime = Date.now();
plantGraphics = self.addChild(LK.getAsset('seed', {
anchorX: 0.5,
anchorY: 0.5
}));
LK.getSound('plant').play();
updateUI();
}
};
self.harvest = function () {
if (self.state === 'ready') {
coins += self.cropValue;
score += self.cropValue;
self.state = 'empty';
if (plantGraphics) {
plantGraphics.destroy();
plantGraphics = null;
}
// Harvest effect
var coinEffect = self.addChild(LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
y: -60
}));
tween(coinEffect, {
y: -120,
alpha: 0
}, {
duration: 800,
onFinish: function onFinish() {
coinEffect.destroy();
}
});
LK.getSound('harvest').play();
updateUI();
}
};
self.update = function () {
if (self.state === 'planted' || self.state === 'growing') {
var elapsed = Date.now() - self.plantTime;
var progress = elapsed / self.growthDuration;
if (progress >= 1) {
// Fully grown
self.state = 'ready';
if (plantGraphics) {
plantGraphics.destroy();
plantGraphics = self.addChild(LK.getAsset('crop', {
anchorX: 0.5,
anchorY: 1,
y: 60
}));
}
} else if (progress >= 0.5 && self.state === 'planted') {
// Growing stage
self.state = 'growing';
if (plantGraphics) {
plantGraphics.destroy();
plantGraphics = self.addChild(LK.getAsset('sprout', {
anchorX: 0.5,
anchorY: 1,
y: 40
}));
}
}
}
// Save plot states to storage
self.saveState();
};
self.saveState = function () {
var plotKey = 'plot_' + self.row + '_' + self.col;
storage[plotKey] = {
state: self.state,
plantTime: self.plantTime
};
};
self.loadState = function () {
var plotKey = 'plot_' + self.row + '_' + self.col;
var savedState = storage[plotKey];
if (savedState) {
self.state = savedState.state;
self.plantTime = savedState.plantTime || 0;
// Restore visual state based on saved data
if (self.state === 'planted' || self.state === 'growing' || self.state === 'ready') {
var elapsed = Date.now() - self.plantTime;
var progress = elapsed / self.growthDuration;
if (progress >= 1) {
self.state = 'ready';
plantGraphics = self.addChild(LK.getAsset('crop', {
anchorX: 0.5,
anchorY: 1,
y: 60
}));
} else if (progress >= 0.5) {
self.state = 'growing';
plantGraphics = self.addChild(LK.getAsset('sprout', {
anchorX: 0.5,
anchorY: 1,
y: 40
}));
} else {
plantGraphics = self.addChild(LK.getAsset('seed', {
anchorX: 0.5,
anchorY: 0.5
}));
}
}
}
};
self.down = function (x, y, obj) {
if (self.state === 'empty') {
self.plant();
} else if (self.state === 'ready') {
self.harvest();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables - load from storage with defaults
var coins = storage.coins || 25;
var score = storage.score || 0;
var plots = [];
var gridRows = 4;
var gridCols = 6;
var plotSize = 200;
// Loan system variables
var loanActive = storage.loanActive || false;
var loanStartTime = storage.loanStartTime || 0;
var loanDuration = 60 * 60 * 1000; // 60 minutes in milliseconds
var loanAmount = 2000;
// UI elements
var coinsText = new Text2('Coins: 25', {
size: 60,
fill: 0xFFFFFF
});
coinsText.anchor.set(0, 0);
LK.gui.topLeft.addChild(coinsText);
coinsText.x = 120;
coinsText.y = 20;
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.y = 20;
// Credit button (bottom-left)
var creditButton = new Text2('KREDI\n2000', {
size: 45,
fill: 0xFFFFFF
});
creditButton.anchor.set(0, 1);
creditButton.x = 20;
creditButton.y = -20;
LK.gui.bottomLeft.addChild(creditButton);
// Loan timer display (only visible when loan is active)
var loanTimerText = new Text2('', {
size: 40,
fill: 0xFF0000
});
loanTimerText.anchor.set(0, 1);
loanTimerText.x = 20;
loanTimerText.y = -120;
LK.gui.bottomLeft.addChild(loanTimerText);
function updateUI() {
coinsText.setText('Coins: ' + coins);
scoreText.setText('Score: ' + score);
// Save game state to storage
storage.coins = coins;
storage.score = score;
updateButtonStates();
updateLoanUI();
// Game continues endlessly - no win condition
}
function updateLoanUI() {
if (loanActive) {
var now = Date.now();
var timeLeft = loanDuration - (now - loanStartTime);
if (timeLeft > 0) {
// Show remaining time
var minutesLeft = Math.ceil(timeLeft / (60 * 1000));
loanTimerText.setText('Kredi: ' + minutesLeft + ' dk');
loanTimerText.alpha = 1;
creditButton.alpha = 0.5;
creditButton.tint = 0x888888;
} else {
// Time is up - check if player has enough coins
if (coins >= loanAmount) {
// Player can pay back - deduct coins and clear loan
coins -= loanAmount;
loanActive = false;
loanStartTime = 0;
storage.loanActive = false;
storage.loanStartTime = 0;
loanTimerText.alpha = 0;
creditButton.alpha = 1.0;
creditButton.tint = 0xFFFFFF;
updateUI();
} else {
// Player doesn't have enough - game over
LK.showGameOver();
}
}
} else {
loanTimerText.alpha = 0;
creditButton.alpha = 1.0;
creditButton.tint = 0xFFFFFF;
}
}
// Create farm grid (moved to upper portion)
var farmStartX = (2048 - gridCols * plotSize) / 2;
var farmStartY = 200;
for (var row = 0; row < gridRows; row++) {
plots[row] = [];
for (var col = 0; col < gridCols; col++) {
var plot = new Plot(row, col);
plot.x = farmStartX + col * plotSize + plotSize / 2;
plot.y = farmStartY + row * plotSize + plotSize / 2;
plots[row][col] = plot;
// Load saved plot state
plot.loadState();
game.addChild(plot);
}
}
// Instructions text
var instructionsText = new Text2('Tap empty plots to plant (5 coins)\nTap crops to harvest\nTap animals to care for them', {
size: 40,
fill: 0x333333
});
instructionsText.anchor.set(0.5, 0);
instructionsText.x = 1024;
instructionsText.y = 120;
game.addChild(instructionsText);
// Buy animal buttons (bottom-right)
var sheepButton = LK.getAsset('sheep', {
anchorX: 1,
anchorY: 1,
scaleX: 1.0,
scaleY: 1.0
});
sheepButton.x = -120;
sheepButton.y = -200;
LK.gui.bottomRight.addChild(sheepButton);
// Sheep price text
var sheepPriceText = new Text2('50', {
size: 40,
fill: 0xFFFFFF
});
sheepPriceText.anchor.set(1, 1);
sheepPriceText.x = -20;
sheepPriceText.y = -200;
LK.gui.bottomRight.addChild(sheepPriceText);
var cowButton = LK.getAsset('cow', {
anchorX: 1,
anchorY: 1,
scaleX: 0.8,
scaleY: 0.8
});
cowButton.x = -120;
cowButton.y = -120;
LK.gui.bottomRight.addChild(cowButton);
// Cow price text
var cowPriceText = new Text2('75', {
size: 40,
fill: 0xFFFFFF
});
cowPriceText.anchor.set(1, 1);
cowPriceText.x = -20;
cowPriceText.y = -120;
LK.gui.bottomRight.addChild(cowPriceText);
var chickenButton = LK.getAsset('chicken', {
anchorX: 1,
anchorY: 1,
scaleX: 1.0,
scaleY: 1.0
});
chickenButton.x = -120;
chickenButton.y = -40;
LK.gui.bottomRight.addChild(chickenButton);
// Chicken price text
var chickenPriceText = new Text2('25', {
size: 40,
fill: 0xFFFFFF
});
chickenPriceText.anchor.set(1, 1);
chickenPriceText.x = -20;
chickenPriceText.y = -40;
LK.gui.bottomRight.addChild(chickenPriceText);
// Button click handlers
sheepButton.down = function (x, y, obj) {
if (coins >= 50) {
coins -= 50;
barn.addAnimal('sheep');
updateUI();
// Visual feedback
tween(sheepButton, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
onFinish: function onFinish() {
tween(sheepButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150
});
}
});
}
};
cowButton.down = function (x, y, obj) {
if (coins >= 75) {
coins -= 75;
barn.addAnimal('cow');
updateUI();
// Visual feedback
tween(cowButton, {
scaleX: 0.96,
scaleY: 0.96
}, {
duration: 150,
onFinish: function onFinish() {
tween(cowButton, {
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 150
});
}
});
}
};
chickenButton.down = function (x, y, obj) {
if (coins >= 25) {
coins -= 25;
barn.addAnimal('chicken');
updateUI();
// Visual feedback
tween(chickenButton, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
onFinish: function onFinish() {
tween(chickenButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150
});
}
});
}
};
// Credit button click handler
creditButton.down = function (x, y, obj) {
if (!loanActive) {
// Take the loan
coins += loanAmount;
loanActive = true;
loanStartTime = Date.now();
// Save to storage
storage.loanActive = loanActive;
storage.loanStartTime = loanStartTime;
updateUI();
// Visual feedback
tween(creditButton, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
onFinish: function onFinish() {
tween(creditButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150
});
}
});
}
};
// Update button appearance based on coin availability
function updateButtonStates() {
// Chicken button (25 coins)
if (coins >= 25) {
chickenButton.tint = 0xFFFFFF;
chickenButton.alpha = 1.0;
chickenPriceText.tint = 0xFFFFFF;
} else {
chickenButton.tint = 0x888888;
chickenButton.alpha = 0.6;
chickenPriceText.tint = 0x888888;
}
// Sheep button (50 coins)
if (coins >= 50) {
sheepButton.tint = 0xFFFFFF;
sheepButton.alpha = 1.0;
sheepPriceText.tint = 0xFFFFFF;
} else {
sheepButton.tint = 0x888888;
sheepButton.alpha = 0.6;
sheepPriceText.tint = 0x888888;
}
// Cow button (75 coins)
if (coins >= 75) {
cowButton.tint = 0xFFFFFF;
cowButton.alpha = 1.0;
cowPriceText.tint = 0xFFFFFF;
} else {
cowButton.tint = 0x888888;
cowButton.alpha = 0.6;
cowPriceText.tint = 0x888888;
}
}
// Create barn in lower portion
var barn = new Barn();
barn.x = 1024; // Center horizontally
barn.y = 2200; // Lower portion of screen
game.addChild(barn);
// Load saved animals or add initial ones if no save data
if (storage.animalCount && storage.animalCount > 0) {
barn.loadAnimals();
} else {
// Add some initial animals
barn.addAnimal('cow');
barn.addAnimal('cow');
barn.addAnimal('sheep');
barn.addAnimal('sheep');
barn.addAnimal('chicken');
barn.addAnimal('chicken');
barn.addAnimal('chicken');
}
game.update = function () {
// Update all plots
for (var row = 0; row < gridRows; row++) {
for (var col = 0; col < gridCols; col++) {
plots[row][col].update();
}
}
// Update barn and animals
barn.update();
// Check loan status every frame
if (loanActive) {
updateLoanUI();
}
// Game continues endlessly - no game over condition
};
plant seed. In-Game asset. High contrast. No shadows. 2d pixel art
newly sprouted plant. In-Game asset. 2d. High contrast. No shadows. pixel
fully grown tomato sprouts. In-Game asset. 2d. High contrast. No shadows. pixel
square soil texture. In-Game asset. 2d. High contrast. No shadows. pixel
coin. In-Game asset. 2d. High contrast. No shadows
pixel art cow. In-Game asset. 2d. High contrast. No shadows
pixel chicken. In-Game asset. 2d. High contrast. No shadows
Sheep. In-Game asset. 2d. High contrast. No shadows. Pixel
Fox. In-Game asset. 2d. High contrast. No shadows. Pixel