User prompt
Make the message big and easy to read. If using percentages for size is not possible, just make it large enough to be clear.
User prompt
I want to show a bold and highlighted message on the right side of the screen for 30 seconds. The message will say: "Game controls: Use mouse to move. For mobile, tap to move."
User prompt
I want to show a text on the right side of the screen. It will be an information message and it should stay for 30 seconds.
User prompt
Place "Animal Right" a bit lower at the bottom right of the screen.
User prompt
Place "Animal Right" at the bottom right of the screen.
User prompt
The chicken should move from left to right. When it reaches the right side, it should disappear. After 40 seconds, it should appear again and repeat the same movement.
User prompt
When the chicken reaches the left side, it should disappear. After 40 seconds, it should appear again and repeat the same movement.
User prompt
The chicken should move from left to right, then go back from right to left. It should move very slowly.
User prompt
The chicken should move from right to left, then go back from left to right. It should move very slowly.
User prompt
The chicken should only move from the bottom to the top, in the middle of the screen.
User prompt
Make the rooster move very slowly.
User prompt
Create a new asset named "Rooster". The rooster will have 4 different images (assets). It should start with the 1st image and start walking. The rooster will walk around the entire screen. While walking, it will show images in this order: 1, 2, 3, 4, then back to 1, and repeat. I will add the images myself. Please set the timing between images smoothly.
User prompt
Create a new asset named "Rooster". The rooster will have 4 different images (assets). When the rooster moves, it will show the images in this order: 1st image, then 2nd, then 3rd, then 4th, then go back to the 1st image and repeat the cycle. I will add the images myself. Please set the timing between images smoothly.
User prompt
The bird should start flying 1 minute after the player enters the game. Then it should appear every 1 minute in a loop.
User prompt
The bird should fly across the screen every 1 minute.
User prompt
The clouds should always go all the way to the end.
User prompt
After 40 seconds, it should start again in a loop.,
User prompt
Start the bird at the top of the screen. When it reaches the end, it should disappear. Then it should start again in a loop.
User prompt
I want a bird that flies across the middle of the map, like clouds. I will add the bird's image myself. Please link the bird as an asset called "bird".
User prompt
I want a bird that flies across the middle of the map, like clouds.
User prompt
Please arrange it based on the center of the screen. Below the center, place 4 blocks (squares) for houses. I want to add images inside these blocks.
User prompt
I want to add a house to my game. Add 4 squares near the bottom of the screen. I want to put images inside these squares. The images should be placed at the bottom center of the screen.
User prompt
I want to add a bird to my game. It will appear at the bottom, on the left side at the start. The bird will move a little to the right, then a little to the left. It should flap its wings while moving. I will add the wing flap images myself. The bird should switch between these images to create the wing flap animation. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
I want to add a windmill to my game. It should be below the center of the screen. The windmill will have a simple rotating animation. Only the first image will move. The image behind it will stay still. Name it "Windmill". Also, it should be customizable.
User prompt
I want to add a windmill to my game. It will be placed at the top, centered in the middle. The windmill will have a simple rotating animation. Name it "Windmill". Also, it should be customizable. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Animal = Container.expand(function () {
var self = Container.call(this);
self.animalAsset = null;
self.setAnimalImage = function (imageId) {
if (self.animalAsset) {
self.animalAsset.destroy();
}
self.animalAsset = self.attachAsset(imageId, {
anchorX: 0.5,
anchorY: 0.5
});
};
return self;
});
// Bird class
var Bird = Container.expand(function () {
var self = Container.call(this);
// Create the bird asset
var birdAsset = self.attachAsset('Bird', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 1,
scaleX: 0.8,
scaleY: 0.8
});
// Variables for movement
self.speed = 1.0; // Faster than clouds
self.lifeTime = 3000; // 50 seconds at 60fps
self.lifeCounter = 0; // Track how long bird has been visible
self.flyHeight = 0; // Vertical position offset for flying pattern
// Initialize bird
self.init = function () {
self.lifeCounter = 0;
self.alpha = 1;
// Start movement animation using tween
self.startMoving();
};
// Start the left to right movement with slight up/down wave pattern
self.startMoving = function () {
// Move bird to the right side of screen
var targetX = 2048 + birdAsset.width / 2; // Move past right edge
// Create the movement tween
tween(self, {
x: targetX
}, {
duration: 20000,
// Faster than clouds - 20 seconds to cross screen
easing: tween.linear
});
};
// Update function called every frame
self.update = function () {
// Increment life counter
self.lifeCounter++;
// Create a small wavy flight pattern
self.y = self.y + Math.sin(self.lifeCounter * 0.03) * 1.5;
// If bird has reached the right edge of the screen
if (self.x >= 2048 + birdAsset.width / 2) {
// Stop any existing tweens on this bird
tween.stop(self);
// Fade out animation
tween(self, {
alpha: 0
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
// Remove bird from game
self.destroy();
}
});
}
};
return self;
});
// CarrotSlot class for area 2
var CarrotSlot = Container.expand(function () {
var self = Container.call(this);
self.slotAsset = self.attachAsset('carrot', {
anchorX: 0.5,
anchorY: 1
});
var sproutAsset = self.attachAsset('sprout', {
anchorX: 0.5,
anchorY: 1,
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
});
self.harvested = false;
self.regrowTime = 1800; // 30 seconds at 60fps
self.regrowCounter = 0;
self.fieldIndex = 1; // Area 2
self.regrowing = false;
// Show/hide carrot and handle regrow animation
self.setHarvested = function (harvested) {
self.harvested = harvested;
if (harvested) {
// Hide carrot with animation
tween(self.slotAsset, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
easing: tween.easeOut
});
// Show sprout with animation
sproutAsset.alpha = 1;
sproutAsset.scaleX = 0.1;
sproutAsset.scaleY = 0.1;
// Animate sprout appearing
tween(sproutAsset, {
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
easing: tween.easeOut
});
self.regrowCounter = self.regrowTime;
self.regrowing = true;
} else {
// Show carrot with animation
tween(self.slotAsset, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeIn
});
// Hide sprout with animation
tween(sproutAsset, {
alpha: 0
}, {
duration: 300,
easing: tween.easeIn
});
self.regrowing = false;
}
};
// Regrow logic
self.update = function () {
if (self.harvested && self.regrowing) {
if (self.regrowCounter > 0) {
// Animate sprout growing to carrot size
var t = 1 - self.regrowCounter / self.regrowTime;
sproutAsset.scaleX = 0.5 + 0.5 * t;
sproutAsset.scaleY = 0.5 + 0.5 * t;
self.regrowCounter--;
}
if (self.regrowCounter <= 0) {
// Sprout is now full size, switch back to carrot and allow harvest again
sproutAsset.scaleX = 1;
sproutAsset.scaleY = 1;
self.setHarvested(false);
}
}
};
// For hit detection
self.isHarvestable = function () {
return !self.harvested;
};
return self;
});
// Cloud class
var Cloud = Container.expand(function () {
var self = Container.call(this);
// Create the cloud asset
var cloudAsset = self.attachAsset('cloud', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8 // Semi-transparent clouds
});
// Variables for movement
self.speed = 0.2; // Very slow speed for smooth movement
self.lifeTime = 6000; // 100 seconds at 60fps - longer lifetime
self.lifeCounter = 0; // Track how long cloud has been visible
self.layer = 0; // Layer for visual depth (0 = front, 1 = back)
// Initialize cloud
self.init = function () {
self.lifeCounter = 0;
self.alpha = 1;
// Apply layer-specific settings
if (self.layer === 1) {
// Back layer cloud (slightly smaller and more transparent)
self.scale.set(0.8, 0.8);
self.alpha = 0.7;
}
// Start movement animation using tween
self.startMoving();
};
// Start the left to right movement only
self.startMoving = function () {
// Move cloud to the right side of screen
var targetX = 2048 + cloudAsset.width / 2; // Move past right edge
// Create the movement tween
tween(self, {
x: targetX
}, {
duration: 60000,
// Slower movement - 60 seconds to cross screen
easing: tween.linear
});
};
// Update function called every frame
self.update = function () {
// Increment life counter
self.lifeCounter++;
// Track lastX for edge detection
if (typeof self.lastX === "undefined") self.lastX = self.x;
// If cloud has just reached the right edge of the screen (crossed this frame)
if (self.lastX < 2048 + cloudAsset.width / 2 && self.x >= 2048 + cloudAsset.width / 2) {
// Stop any existing tweens on this cloud
tween.stop(self);
// Fade out animation
tween(self, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Remove cloud from game
self.destroy();
}
});
}
// Update lastX for next frame
self.lastX = self.x;
};
return self;
});
// EggplantSlot class for area 4
var EggplantSlot = Container.expand(function () {
var self = Container.call(this);
self.slotAsset = self.attachAsset('eggplant', {
anchorX: 0.5,
anchorY: 1
});
var sproutAsset = self.attachAsset('sprout', {
anchorX: 0.5,
anchorY: 1,
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
});
self.harvested = false;
self.regrowTime = 1800; // 30 seconds at 60fps
self.regrowCounter = 0;
self.fieldIndex = 3; // Area 4
self.regrowing = false;
// Show/hide eggplant and handle regrow animation
self.setHarvested = function (harvested) {
self.harvested = harvested;
if (harvested) {
// Hide eggplant with animation
tween(self.slotAsset, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
easing: tween.easeOut
});
// Show sprout with animation
sproutAsset.alpha = 1;
sproutAsset.scaleX = 0.1;
sproutAsset.scaleY = 0.1;
// Animate sprout appearing
tween(sproutAsset, {
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
easing: tween.easeOut
});
self.regrowCounter = self.regrowTime;
self.regrowing = true;
} else {
// Show eggplant with animation
tween(self.slotAsset, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeIn
});
// Hide sprout with animation
tween(sproutAsset, {
alpha: 0
}, {
duration: 300,
easing: tween.easeIn
});
self.regrowing = false;
}
};
// Regrow logic
self.update = function () {
if (self.harvested && self.regrowing) {
if (self.regrowCounter > 0) {
// Animate sprout growing to eggplant size
var t = 1 - self.regrowCounter / self.regrowTime;
sproutAsset.scaleX = 0.5 + 0.5 * t;
sproutAsset.scaleY = 0.5 + 0.5 * t;
self.regrowCounter--;
}
if (self.regrowCounter <= 0) {
// Sprout is now full size, switch back to eggplant and allow harvest again
sproutAsset.scaleX = 1;
sproutAsset.scaleY = 1;
self.setHarvested(false);
}
}
};
// For hit detection
self.isHarvestable = function () {
return !self.harvested;
};
return self;
});
// Farmer class
var Farmer = Container.expand(function () {
var self = Container.call(this);
// Create animation frames
var idleFrame = self.attachAsset('farmer', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 1
});
// Frame 2 (running)
var runningFrame = self.attachAsset('farmer_walk', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
// Frame 3 (right step)
var rightStepFrame = self.attachAsset('farmer_walk', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0,
rotation: 0.1
});
self.speed = 18; // px per move
self.targetX = self.x;
self.targetY = self.y;
self.moving = false;
self.lastMoving = false;
self.animationTimer = 0;
self.animationFrame = 0;
self.frameTime = 18; // 0.3 seconds at 60fps
// Animation frame switching
self.switchToFrame = function (frameNum) {
idleFrame.alpha = 0;
runningFrame.alpha = 0;
rightStepFrame.alpha = 0;
if (frameNum === 0) {
// Idle
idleFrame.alpha = 1;
} else if (frameNum === 1) {
// Running
runningFrame.alpha = 1;
} else if (frameNum === 2) {
// Right step
rightStepFrame.alpha = 1;
}
};
// Move farmer towards target
self.update = function () {
// Track movement direction and update image
if (self.moving) {
var dx = self.targetX - self.x;
// Check if moving right or left
if (dx > 0) {
// Moving right - use player_right asset
idleFrame.scaleX = 1;
runningFrame.scaleX = 1;
rightStepFrame.scaleX = 1;
// Switch to player_right image
if (self.currentAsset !== idleFrame || idleFrame.texture !== LK.getAsset('player_right', {}).texture) {
if (self.currentAsset) {
self.currentAsset.alpha = 0;
}
var rightAsset = LK.getAsset('player_right', {
anchorX: 0.5,
anchorY: 0.5
});
rightAsset.alpha = 1;
self.addChild(rightAsset);
self.currentAsset = rightAsset;
}
} else if (dx < 0) {
// Moving left - use player_left asset
idleFrame.scaleX = -1;
runningFrame.scaleX = -1;
rightStepFrame.scaleX = -1;
// Switch to player_left image
if (self.currentAsset !== idleFrame || idleFrame.texture !== LK.getAsset('player_left', {}).texture) {
if (self.currentAsset) {
self.currentAsset.alpha = 0;
}
var leftAsset = LK.getAsset('player_left', {
anchorX: 0.5,
anchorY: 0.5
});
leftAsset.alpha = 1;
self.addChild(leftAsset);
self.currentAsset = leftAsset;
}
}
// Animation handling
self.animationTimer++;
if (self.animationTimer >= self.frameTime) {
self.animationTimer = 0;
self.animationFrame = self.animationFrame === 1 ? 2 : 1; // Toggle between frames 1 and 2
self.switchToFrame(self.animationFrame);
}
} else if (!self.moving && self.lastMoving) {
// Just stopped moving - switch to idle
self.switchToFrame(0);
}
self.lastMoving = self.moving;
if (!self.moving) return;
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < self.speed) {
self.x = self.targetX;
self.y = self.targetY;
self.moving = false;
// Switch to idle frame when stopping
self.switchToFrame(0);
} else {
self.x += self.speed * dx / dist;
self.y += self.speed * dy / dist;
}
};
// Set movement target
self.moveTo = function (x, y) {
self.targetX = x;
self.targetY = y;
// Start movement
if (!self.moving) {
self.moving = true;
self.animationFrame = 1;
self.animationTimer = 0;
self.switchToFrame(self.animationFrame);
}
};
return self;
});
// Field class
var Field = Container.expand(function () {
var self = Container.call(this);
self.index = 0; // 0-3
self.locked = false;
self.lockCost = 0;
self.lockNode = null;
self.fenceNodes = [];
self.wheats = [];
self.unlockBtn = null;
// Draw fences - Empty implementation to eliminate fences
self.drawFences = function (x, y, w, h) {
self.fenceNodes = [];
// No fences or gates are created
};
// Place wheat
self.placeWheats = function (x, y, w, h, count) {
self.wheats = [];
// Define grid size
var rows = 5;
var cols = 10;
// Choose vegetable asset per area
var vegAssetId = 'wheat';
if (self.index === 1) vegAssetId = 'carrot';
if (self.index === 2) vegAssetId = 'tomato';
if (self.index === 3) vegAssetId = 'eggplant';
// Fallback if asset not found, use wheat
if (!LK.assets || !LK.assets[vegAssetId]) vegAssetId = 'wheat';
// Calculate asset size for spacing (use wheat size as reference for all)
var vegAsset = LK.getAsset('wheat', {
anchorX: 0.5,
anchorY: 1
});
var wheatW = vegAsset.width;
var wheatH = vegAsset.height;
// Padding from fences
var padX = 60;
var padY = 60;
// Compute available area for wheat grid
var gridW = w - 2 * padX;
var gridH = h - 2 * padY;
// Compute spacing between wheat plants
var spacingX = (gridW - wheatW) / (cols - 1);
var spacingY = (gridH - wheatH) / (rows - 1);
// Place appropriate vegetable in grid based on field index
for (var row = 0; row < rows; ++row) {
for (var col = 0; col < cols; ++col) {
var wx = x + padX + col * spacingX + wheatW / 2;
var wy = y + padY + row * spacingY + wheatH;
var veg;
// Create appropriate vegetable based on area/field index
if (self.index === 1) {
veg = new CarrotSlot();
} else if (self.index === 2) {
veg = new TomatoSlot();
} else if (self.index === 3) {
veg = new EggplantSlot();
} else {
veg = new Wheat();
veg.fieldIndex = self.index;
veg.vegAssetId = vegAssetId;
veg.setVegAsset && veg.setVegAsset(vegAssetId);
}
veg.x = wx;
veg.y = wy;
self.addChild(veg);
self.wheats.push(veg);
}
}
};
// Lock overlay
self.showLock = function (centerX, centerY) {
if (self.lockNode) return;
self.lockNode = LK.getAsset('lock', {
anchorX: 0.5,
anchorY: 0.5,
x: centerX,
y: centerY
});
self.addChild(self.lockNode);
// Unlock text
var unlockTxt = new Text2('Unlock\n$' + self.lockCost, {
size: 60,
fill: "#fff"
});
unlockTxt.anchor.set(0.5, 0.5);
unlockTxt.x = centerX;
unlockTxt.y = centerY + 70;
self.unlockBtn = unlockTxt;
self.addChild(unlockTxt);
};
self.hideLock = function () {
if (self.lockNode) {
self.lockNode.destroy();
self.lockNode = null;
}
if (self.unlockBtn) {
self.unlockBtn.destroy();
self.unlockBtn = null;
}
};
return self;
});
// Rooster class with 4-frame animation cycling smoothly
var Rooster = Container.expand(function () {
var self = Container.call(this);
// Animation frame asset ids
var frameIds = ['rooster_1', 'rooster_2', 'rooster_3', 'rooster_4'];
self.roosterFrames = [];
self.currentFrame = 0;
self.frameTimer = 0;
self.frameInterval = 10; // ~0.16s per frame at 60fps (smooth)
// Attach all frames, only show the first
for (var i = 0; i < frameIds.length; ++i) {
var frame = self.attachAsset(frameIds[i], {
anchorX: 0.5,
anchorY: 0.5,
alpha: i === 0 ? 1 : 0
});
self.roosterFrames.push(frame);
}
// Animation update
self.update = function () {
self.frameTimer++;
if (self.frameTimer >= self.frameInterval) {
// Hide current frame
self.roosterFrames[self.currentFrame].alpha = 0;
// Advance to next frame
self.currentFrame = (self.currentFrame + 1) % self.roosterFrames.length;
// Show new frame
self.roosterFrames[self.currentFrame].alpha = 1;
self.frameTimer = 0;
}
};
return self;
});
// TomatoSlot class for area 3
var TomatoSlot = Container.expand(function () {
var self = Container.call(this);
self.slotAsset = self.attachAsset('tomato', {
anchorX: 0.5,
anchorY: 1
});
var sproutAsset = self.attachAsset('sprout', {
anchorX: 0.5,
anchorY: 1,
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
});
self.harvested = false;
self.regrowTime = 1800; // 30 seconds at 60fps
self.regrowCounter = 0;
self.fieldIndex = 2; // Area 3
self.regrowing = false;
// Show/hide tomato and handle regrow animation
self.setHarvested = function (harvested) {
self.harvested = harvested;
if (harvested) {
// Hide tomato with animation
tween(self.slotAsset, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
easing: tween.easeOut
});
// Show sprout with animation
sproutAsset.alpha = 1;
sproutAsset.scaleX = 0.1;
sproutAsset.scaleY = 0.1;
// Animate sprout appearing
tween(sproutAsset, {
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
easing: tween.easeOut
});
self.regrowCounter = self.regrowTime;
self.regrowing = true;
} else {
// Show tomato with animation
tween(self.slotAsset, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeIn
});
// Hide sprout with animation
tween(sproutAsset, {
alpha: 0
}, {
duration: 300,
easing: tween.easeIn
});
self.regrowing = false;
}
};
// Regrow logic
self.update = function () {
if (self.harvested && self.regrowing) {
if (self.regrowCounter > 0) {
// Animate sprout growing to tomato size
var t = 1 - self.regrowCounter / self.regrowTime;
sproutAsset.scaleX = 0.5 + 0.5 * t;
sproutAsset.scaleY = 0.5 + 0.5 * t;
self.regrowCounter--;
}
if (self.regrowCounter <= 0) {
// Sprout is now full size, switch back to tomato and allow harvest again
sproutAsset.scaleX = 1;
sproutAsset.scaleY = 1;
self.setHarvested(false);
}
}
};
// For hit detection
self.isHarvestable = function () {
return !self.harvested;
};
return self;
});
// Wheat class
var Wheat = Container.expand(function () {
var self = Container.call(this);
self.vegAssetId = 'wheat';
self.wheatAsset = self.attachAsset('wheat', {
anchorX: 0.5,
anchorY: 1
});
var sproutAsset = self.attachAsset('sprout', {
anchorX: 0.5,
anchorY: 1,
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
});
self.harvested = false;
self.regrowTime = 1800; // 30 seconds at 60fps
self.regrowCounter = 0;
self.fieldIndex = 0; // which field this wheat belongs to
self.regrowing = false;
self.removeAfter = 0;
// Change vegetable asset if needed
self.setVegAsset = function (assetId) {
if (self.wheatAsset) {
self.wheatAsset.destroy();
}
self.vegAssetId = assetId || 'wheat';
// Only allow wheat, carrot, tomato, eggplant
var validAssets = {
wheat: 1,
carrot: 1,
tomato: 1,
eggplant: 1
};
if (!validAssets[self.vegAssetId]) self.vegAssetId = 'wheat';
self.wheatAsset = self.attachAsset(self.vegAssetId, {
anchorX: 0.5,
anchorY: 1
});
// Make sure sprout is on top
self.removeChild(sproutAsset);
self.addChild(sproutAsset);
};
// Show/hide wheat and handle regrow animation
self.setHarvested = function (harvested) {
self.harvested = harvested;
if (harvested) {
// Hide wheat, show sprout
if (self.wheatAsset) {
// Animate wheat harvesting with tween
tween(self.wheatAsset, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
easing: tween.easeOut
});
}
// Show and animate sprout growing from nothing
sproutAsset.alpha = 1;
sproutAsset.scaleX = 0.1;
sproutAsset.scaleY = 0.1;
// Animate sprout appearing
tween(sproutAsset, {
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
easing: tween.easeOut
});
self.regrowCounter = self.regrowTime;
self.regrowing = true;
} else {
// Show wheat/veg, hide sprout with animation
if (self.wheatAsset) {
tween(self.wheatAsset, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeIn
});
}
// Fade out sprout
tween(sproutAsset, {
alpha: 0
}, {
duration: 300,
easing: tween.easeIn
});
self.regrowing = false;
}
};
// Regrow logic and removal after 5 seconds
self.update = function () {
if (self.harvested && self.regrowing) {
if (self.regrowCounter > 0) {
// Animate sprout growing to wheat/veg size
var t = 1 - self.regrowCounter / self.regrowTime;
sproutAsset.scaleX = 0.5 + 0.5 * t;
sproutAsset.scaleY = 0.5 + 0.5 * t;
self.regrowCounter--;
}
if (self.regrowCounter <= 0) {
// Sprout is now full size, switch back to wheat/veg and allow harvest again
sproutAsset.scaleX = 1;
sproutAsset.scaleY = 1;
self.setHarvested(false);
}
}
};
// For hit detection
self.isHarvestable = function () {
return !self.harvested;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x4caf50 // Grass green
});
/****
* Game Code
****/
// Rooster animation frames (replace id values with your own image ids)
// --- Game constants ---
// Field fence (rectangle)
// Wheat (ellipse)
// Farmer (box)
// House (box)
// Sickle (ellipse, yellow)
// Lock icon (ellipse, gray)
// Area 2
// Area 3
// Area 4
var FIELD_W = 900;
var FIELD_H = 900;
var FIELD_GAP = 120; // Increased gap to move fences further from center
var FIELD_COUNT = 4;
var WHEAT_PER_FIELD = 10;
// Area unlock prices and reward multipliers
var FIELD_LOCK_COSTS = [0, 20000, 40000, 60000]; // Area 1 open, others locked
var FIELD_REWARD_MULT = [1, 2, 3, 4]; // Area 1=1x, 2=2x, 3=3x, 4=4x
// --- Area constants ---
// Define the distance from center for all areas (equal distance)
var AREA_DISTANCE = 600;
// Create an array to hold the areas
var areas = [];
var animals = [];
// --- Game state ---
var fields = [];
var farmer = null;
var money = 0;
var moneyTxt = null;
var sickle = null;
var dragging = false;
var dragOffsetX = 0;
var dragOffsetY = 0;
var unlockFieldIndex = -1;
var playerMovementBlockedByUIClick = false; // Flag to indicate UI handled the click
// --- Layout calculation ---
// Fields: 2x2 grid, with house in center
// [0][1]
// [2][3]
var fieldPositions = [{
x: 0,
y: 0
},
// top-left
{
x: FIELD_W + FIELD_GAP,
y: 0
},
// top-right
{
x: 0,
y: FIELD_H + FIELD_GAP
},
// bottom-left
{
x: FIELD_W + FIELD_GAP,
y: FIELD_H + FIELD_GAP
} // bottom-right
];
// Center everything in game area
var totalW = FIELD_W * 2 + FIELD_GAP;
var totalH = FIELD_H * 2 + FIELD_GAP;
var offsetX = Math.floor((2048 - totalW) / 2);
var offsetY = Math.floor((2732 - totalH) / 2);
// --- Create fields ---
for (var i = 0; i < FIELD_COUNT; ++i) {
var f = new Field();
f.index = i;
f.locked = FIELD_LOCK_COSTS[i] > 0;
f.lockCost = FIELD_LOCK_COSTS[i];
var pos = fieldPositions[i];
var fx = offsetX + pos.x;
var fy = offsetY + pos.y;
// Skip drawing fences
f.placeWheats(fx, fy, FIELD_W, FIELD_H, WHEAT_PER_FIELD);
if (f.locked) {
// Center of field
f.showLock(fx + FIELD_W / 2, fy + FIELD_H / 2);
}
game.addChild(f);
fields.push(f);
}
// Center reference point for positions
var centerX = offsetX + FIELD_W;
var centerY = offsetY + FIELD_H - 250;
// --- Create farmer ---
farmer = new Farmer();
farmer.x = centerX;
farmer.y = centerY - 120; // Start at center area
game.addChild(farmer);
// --- Create sickle (attached to farmer's hand) ---
sickle = LK.getAsset('sickle', {
anchorX: 0.2,
// hand position, left side of ellipse
anchorY: 0.7,
// slightly below center
x: 0,
y: 30
});
sickle.alpha = 1;
// --- Money display ---
moneyTxt = new Text2('$0', {
size: 100,
fill: "#fff"
});
moneyTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(moneyTxt);
// --- Controls message on right side ---
// Create the controls message text
var controlsMsgTxt = new Text2("Game controls: Use mouse to move.\nFor mobile, tap to move.", {
size: 180,
// Much larger for easy reading
fill: 0xFFF700,
fontWeight: "bold",
stroke: "#000",
strokeThickness: 16,
// Thicker outline for contrast
font: "bold 180px Arial, sans-serif"
});
controlsMsgTxt.anchor.set(1, 0.5); // Right align, vertically centered
// Position at right side, vertically centered (avoid top 100px for menu)
controlsMsgTxt.x = 2048 - 40; // 40px padding from right edge
controlsMsgTxt.y = 2732 / 2;
game.addChild(controlsMsgTxt);
// Hide after 30 seconds (30000 ms)
LK.setTimeout(function () {
if (controlsMsgTxt && controlsMsgTxt.parent) {
controlsMsgTxt.destroy();
}
}, 30000);
// --- Helper: update money display ---
function updateMoneyDisplay() {
moneyTxt.setText('$' + money);
}
// --- Helper: unlock field if enough money ---
function tryUnlockField(fieldIdx) {
var f = fields[fieldIdx];
if (!f.locked) return;
if (money >= f.lockCost) {
money -= f.lockCost;
updateMoneyDisplay();
f.locked = false;
f.hideLock();
// Flash field green
for (var i = 0; i < f.fenceNodes.length; ++i) {
LK.effects.flashObject(f.fenceNodes[i], 0x00ff00, 600);
}
} else {
// Not enough money, flash red
LK.effects.flashScreen(0xff0000, 400);
}
}
// --- Touch/mouse handling ---
var lastDownX = 0,
lastDownY = 0;
var harvestMode = false;
var harvestWheat = null;
// Helper: find harvestable vegetable under (x, y) in unlocked fields
function findHarvestableWheat(x, y) {
for (var i = 0; i < fields.length; ++i) {
var f = fields[i];
if (f.locked) continue;
for (var j = 0; j < f.wheats.length; ++j) {
var w = f.wheats[j];
if (w.isHarvestable()) {
// Use bounding box for hit
var wx = w.x,
wy = w.y;
var ww = 60,
wh = 80;
if (x >= wx - ww / 2 && x <= wx + ww / 2 && y >= wy - wh && y <= wy) {
return w;
}
}
}
}
return null;
}
// Helper: find locked field under (x, y)
function findLockedField(x, y) {
for (var i = 0; i < fields.length; ++i) {
var f = fields[i];
if (!f.locked) continue;
// Use field area
var pos = fieldPositions[i];
var fx = offsetX + pos.x;
var fy = offsetY + pos.y;
if (x >= fx && x <= fx + FIELD_W && y >= fy && y <= fy + FIELD_H) {
return i;
}
}
return -1;
}
// --- Game event handlers ---
// Move farmer or harvest wheat
game.down = function (x, y, obj) {
// If UI handled this click, do nothing for game movement.
if (playerMovementBlockedByUIClick) {
playerMovementBlockedByUIClick = false; // Reset flag for next input
return;
}
// Shop system completely removed
// No shopButton references needed anymore
// Continue with normal game control flow
// No shop button checks needed
//
lastDownX = x;
lastDownY = y;
// Check if tapping on locked field unlock button
var lockedIdx = findLockedField(x, y);
if (lockedIdx >= 0) {
var f = fields[lockedIdx];
// If tap is near lock icon or unlock text
var centerX = offsetX + fieldPositions[lockedIdx].x + FIELD_W / 2;
var centerY = offsetY + fieldPositions[lockedIdx].y + FIELD_H / 2;
var dist = Math.sqrt((x - centerX) * (x - centerX) + (y - centerY) * (y - centerY));
if (dist < 120) {
tryUnlockField(lockedIdx);
return;
}
}
// Check for wheat
var w = findHarvestableWheat(x, y);
if (w) {
harvestMode = true;
harvestWheat = w;
// Change player to face forward during harvest
// Switch to player_down for harvesting
if (farmer.currentAsset) {
farmer.currentAsset.alpha = 0;
}
var playerDown = LK.getAsset('player_down', {
anchorX: 0.5,
anchorY: 0.5
});
playerDown.alpha = 1;
farmer.addChild(playerDown);
farmer.currentAsset = playerDown;
// Animate sickle (in farmer's hand)
tween(sickle, {
rotation: Math.PI * 2
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
sickle.rotation = 0;
// Show harvest animation effect
var harvestEffect = LK.getAsset('sprout', {
anchorX: 0.5,
anchorY: 0.5,
x: w.x,
y: w.y - 50,
alpha: 0.8,
scaleX: 2,
scaleY: 2
});
game.addChild(harvestEffect);
// Animate the harvest effect
tween(harvestEffect, {
alpha: 0,
y: harvestEffect.y - 100
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
harvestEffect.destroy();
}
});
}
});
// Harvest
w.setHarvested(true);
var reward = 100 * (FIELD_REWARD_MULT[w.fieldIndex] || 1);
money += reward;
updateMoneyDisplay();
// Flash wheat
LK.effects.flashObject(w, 0xffff00, 300);
// No setHarvested(false) here; regrow/removal handled in Wheat.update
harvestMode = false;
harvestWheat = null;
return;
}
// Move farmer with animation
farmer.moveTo(x, y);
dragging = true;
dragOffsetX = x - farmer.x;
dragOffsetY = y - farmer.y;
};
// Drag farmer
game.move = function (x, y, obj) {
// If UI interaction blocked the start of a drag, this helps.
if (playerMovementBlockedByUIClick) {
// Flag will be reset by the next 'down' event, or could be reset here if necessary,
// but typically 'move' follows a 'down' that wasn't blocked.
return;
}
// Shop system completely removed
//
if (dragging) {
farmer.moveTo(x - dragOffsetX, y - dragOffsetY);
}
if (harvestMode && harvestWheat) {
sickle.x = x;
sickle.y = y;
}
};
// End drag/harvest
game.up = function (x, y, obj) {
// If UI interaction blocked the 'down' event, 'up' should also be controlled.
if (playerMovementBlockedByUIClick) {
playerMovementBlockedByUIClick = false; // Reset flag here as well
return;
}
// Shop system completely removed
//
//
dragging = false;
harvestMode = false;
harvestWheat = null;
};
// --- Main update loop ---
game.update = function () {
// Update farmer
farmer.update();
// Update wheat regrow
for (var i = 0; i < fields.length; ++i) {
var f = fields[i];
for (var j = 0; j < f.wheats.length; ++j) {
f.wheats[j].update();
}
}
// Update clouds
for (var i = 0; i < clouds.length; i++) {
if (clouds[i] && clouds[i].parent) {
clouds[i].update();
}
}
// Update birds
for (var i = 0; i < birds.length; i++) {
if (birds[i] && birds[i].parent) {
birds[i].update();
}
}
};
// --- Create areas and place animals ---
// Calculate center of game screen
var gameWidth = 2048;
var gameHeight = 2732;
var gameCenterX = gameWidth / 2;
var gameCenterY = gameHeight / 2;
// Create the four areas at equal distances from center
// Area_Left
var areaLeft = new Container();
areaLeft.x = gameCenterX - AREA_DISTANCE;
areaLeft.y = gameCenterY;
areaLeft.name = "Area_Left";
game.addChild(areaLeft);
areas.push(areaLeft);
// Area_Right
var areaRight = new Container();
areaRight.x = gameCenterX + AREA_DISTANCE;
areaRight.y = gameCenterY;
areaRight.name = "Area_Right";
game.addChild(areaRight);
areas.push(areaRight);
// Area_Top
var areaTop = new Container();
areaTop.x = gameCenterX;
areaTop.y = gameCenterY - AREA_DISTANCE;
areaTop.name = "Area_Top";
game.addChild(areaTop);
areas.push(areaTop);
// Area_Bottom
var areaBottom = new Container();
areaBottom.x = gameCenterX;
areaBottom.y = gameCenterY + AREA_DISTANCE;
areaBottom.name = "Area_Bottom";
game.addChild(areaBottom);
areas.push(areaBottom);
// Place animals in the areas
// Animal_Right at bottom right of screen
var animalRight = new Animal();
animalRight.setAnimalImage('animal_right');
animalRight.name = "Animal_Right";
// Place at bottom right, accounting for anchor (0.5, 0.5) and asset size
var animalRightAsset = LK.getAsset('animal_right', {
anchorX: 0.5,
anchorY: 0.5
});
animalRight.x = gameWidth - animalRightAsset.width / 2 - 10; // 10px padding from right
animalRight.y = gameHeight - animalRightAsset.height / 2 - 10; // 10px padding from bottom
game.addChild(animalRight);
animals.push(animalRight);
// Area_Bottom has no animal
// --- Create clouds ---
var clouds = [];
// Create two clouds at different positions
function createClouds() {
// Remove any existing clouds
for (var i = 0; i < clouds.length; i++) {
if (clouds[i] && clouds[i].parent) {
clouds[i].destroy();
}
}
clouds = [];
// Cloud width for calculations
var cloudWidth = 500;
// Create first cloud (front layer)
var cloud1 = new Cloud();
cloud1.x = -cloudWidth / 2; // Start from off-screen left
cloud1.y = 180; // Higher position near the top
cloud1.layer = 0; // Front layer - this will be in front
cloud1.init(); // Initialize movement and timing
game.addChild(cloud1);
clouds.push(cloud1);
// Create second cloud (back layer)
var cloud2 = new Cloud();
cloud2.x = -cloudWidth / 2 - 200; // Start more separated from first cloud
cloud2.y = 280; // Position below first cloud with more separation
cloud2.layer = 1; // Back layer - this will be behind
cloud2.init(); // Initialize movement and timing
game.addChild(cloud2);
clouds.push(cloud2);
// Schedule creation of new clouds after these disappear
LK.setTimeout(createClouds, 61000); // 61 seconds to ensure smooth transition
}
// Start creating clouds
createClouds();
// Shop system completely removed
// --- Create birds ---
var birds = [];
// Create a bird that starts at the top, flies across, disappears, and restarts in a loop
function createBird() {
// Remove any existing birds that might be stuck
for (var i = 0; i < birds.length; i++) {
if (birds[i] && birds[i].parent) {
birds[i].destroy();
}
}
birds = [];
// Bird asset for size
var tempBirdAsset = LK.getAsset('Bird', {
anchorX: 0.5,
anchorY: 0.5
});
var birdWidth = tempBirdAsset.width;
var birdHeight = tempBirdAsset.height;
// Start at the top of the screen, just off the left edge
var bird = new Bird();
bird.x = -birdWidth / 2;
bird.y = birdHeight / 2 + 20; // 20px padding from the very top
bird.init();
game.addChild(bird);
birds.push(bird);
// Set up a watcher to restart the bird after 60 seconds (3600 ticks at 60fps)
bird._birdLoopCheck = function () {
// Only restart if bird is gone (destroyed)
if (!bird.parent) {
LK.setTimeout(createBird, 60000); // 60 seconds delay before next bird
} else {
LK.setTimeout(bird._birdLoopCheck, 200); // Check again in 200ms
}
};
LK.setTimeout(bird._birdLoopCheck, 200);
}
// Start creating birds after 1 minute (60000 ms)
LK.setTimeout(createBird, 60000);
// --- Initial money display ---
updateMoneyDisplay();
// --- Place trees at corners ---
// Tree size
var treeWidth = 400;
var treeHeight = 532;
// Top left corner tree
var topLeftTree = LK.getAsset('tree', {
anchorX: 0.5,
anchorY: 0.5,
x: offsetX / 2,
y: offsetY / 2
});
game.addChild(topLeftTree);
// Top right corner tree
var topRightTree = LK.getAsset('tree', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 - offsetX / 2,
y: offsetY / 2
});
game.addChild(topRightTree);
// Bottom left corner tree
var bottomLeftTree = LK.getAsset('tree', {
anchorX: 0.5,
anchorY: 0.5,
x: offsetX / 2,
y: 2732 - offsetY / 2
});
game.addChild(bottomLeftTree);
// Bottom right corner tree
var bottomRightTree = LK.getAsset('tree', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 - offsetX / 2,
y: 2732 - offsetY / 2
});
game.addChild(bottomRightTree);
// --- Place trees at middle sides aligned with corner trees ---
// Tree to the left of center
var leftCenterTree = LK.getAsset('tree', {
anchorX: 0.5,
anchorY: 0.5,
x: offsetX / 2,
y: topRightTree.y
});
game.addChild(leftCenterTree);
// Tree to the right of center
var rightCenterTree = LK.getAsset('tree', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 - offsetX / 2,
y: topRightTree.y
});
game.addChild(rightCenterTree);
// --- Add Rooster that moves left-to-right, disappears at right edge, reappears after 40s and repeats ---
var rooster = null;
var roosterTimeout = null;
function spawnRooster() {
// Remove any existing rooster
if (rooster && rooster.parent) {
rooster.destroy();
}
rooster = new Rooster();
// Start at the left center of the screen
rooster.y = 2732 / 2;
rooster.x = rooster.roosterFrames[0].width / 2 + 10;
game.addChild(rooster);
// Rooster path: left-to-right, horizontally centered
var roosterStartX = rooster.roosterFrames[0].width / 2 + 10;
var roosterEndX = 2048 - rooster.roosterFrames[0].width / 2 - 10;
var roosterSpeed = 1; // px per frame, very slow movement
rooster.targetX = roosterEndX;
rooster.direction = 1; // 1: moving right
rooster.updateRoosterMovement = function () {
// Track lastX for edge detection
if (typeof rooster.lastX === "undefined") rooster.lastX = rooster.x;
// Move only horizontally in the center
var dx = rooster.targetX - rooster.x;
var dist = Math.abs(dx);
if (dist < roosterSpeed) {
rooster.x = rooster.targetX;
} else {
rooster.x += roosterSpeed * (dx > 0 ? 1 : -1);
}
// Call animation update
if (typeof rooster.update === "function") {
rooster.update();
}
// Check if rooster just reached the right edge (disappear trigger)
if (rooster.lastX < roosterEndX && rooster.x >= roosterEndX) {
// Fade out and destroy, then respawn after 40s
tween(rooster, {
alpha: 0
}, {
duration: 600,
easing: tween.easeOut,
onFinish: function onFinish() {
if (rooster && rooster.parent) {
rooster.destroy();
}
roosterTimeout = LK.setTimeout(spawnRooster, 40000); // 40 seconds
}
});
}
// Update lastX for next frame
rooster.lastX = rooster.x;
};
}
// Add rooster update to main game loop
var oldGameUpdate = game.update;
game.update = function () {
if (typeof oldGameUpdate === "function") oldGameUpdate();
if (rooster && rooster.parent && typeof rooster.updateRoosterMovement === "function") {
rooster.updateRoosterMovement();
}
};
// Start the first rooster
spawnRooster(); ===================================================================
--- original.js
+++ change.js
@@ -924,15 +924,16 @@
LK.gui.top.addChild(moneyTxt);
// --- Controls message on right side ---
// Create the controls message text
var controlsMsgTxt = new Text2("Game controls: Use mouse to move.\nFor mobile, tap to move.", {
- size: 90,
+ size: 180,
+ // Much larger for easy reading
fill: 0xFFF700,
- // Bright yellow for highlight
fontWeight: "bold",
stroke: "#000",
- strokeThickness: 8,
- font: "bold 90px Arial, sans-serif"
+ strokeThickness: 16,
+ // Thicker outline for contrast
+ font: "bold 180px Arial, sans-serif"
});
controlsMsgTxt.anchor.set(1, 0.5); // Right align, vertically centered
// Position at right side, vertically centered (avoid top 100px for menu)
controlsMsgTxt.x = 2048 - 40; // 40px padding from right edge