/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Berry = Container.expand(function () { var self = Container.call(this); var berryGraphics = self.attachAsset('berry', { anchorX: 0.5, anchorY: 0.5 }); self.collected = false; return self; }); var Creature = Container.expand(function () { var self = Container.call(this); var creatureGraphics = self.attachAsset('creature', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 1; self.direction = Math.random() * Math.PI * 2; self.changeDirectionTimer = 0; self.update = function () { self.changeDirectionTimer++; if (self.changeDirectionTimer > 120) { self.direction = Math.random() * Math.PI * 2; self.changeDirectionTimer = 0; } self.x += Math.cos(self.direction) * self.speed; self.y += Math.sin(self.direction) * self.speed; // Keep creatures in bounds if (self.x < 50 || self.x > 1998) { self.direction = Math.PI - self.direction; } if (self.y < 50 || self.y > 2682) { self.direction = -self.direction; } }; return self; }); var Crystal = Container.expand(function () { var self = Container.call(this); var crystalGraphics = self.attachAsset('crystal', { anchorX: 0.5, anchorY: 0.5 }); self.collected = false; self.glowDirection = 1; self.update = function () { if (!self.collected) { crystalGraphics.alpha += 0.02 * self.glowDirection; if (crystalGraphics.alpha >= 1) { self.glowDirection = -1; } else if (crystalGraphics.alpha <= 0.3) { self.glowDirection = 1; } } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 4; self.targetX = null; self.targetY = null; self.isMoving = false; self.moveTo = function (x, y) { self.targetX = x; self.targetY = y; self.isMoving = true; }; self.update = function () { if (self.isMoving && self.targetX !== null && self.targetY !== null) { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < self.speed) { self.x = self.targetX; self.y = self.targetY; self.isMoving = false; } else { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } } }; return self; }); var Thorn = Container.expand(function () { var self = Container.call(this); var thornGraphics = self.attachAsset('thorn', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var Tree = Container.expand(function () { var self = Container.call(this); var treeGraphics = self.attachAsset('tree', { anchorX: 0.5, anchorY: 1.0 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2d5016 }); /**** * Game Code ****/ // Game variables var player; var crystals = []; var berries = []; var trees = []; var thorns = []; var creatures = []; var areasDiscovered = 0; var itemsCollected = 0; // UI Elements var scoreTxt = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(scoreTxt); var itemsTxt = new Text2('Items: 0', { size: 60, fill: 0xFFFFFF }); itemsTxt.anchor.set(0, 0); itemsTxt.y = 100; LK.gui.topRight.addChild(itemsTxt); // Inventory button var inventoryBtn = new Text2('BAG', { size: 60, fill: 0xFFFFFF }); inventoryBtn.anchor.set(0, 0); inventoryBtn.x = 120; inventoryBtn.y = 20; LK.gui.topLeft.addChild(inventoryBtn); // Map button var mapBtn = new Text2('MAP', { size: 60, fill: 0xFFFFFF }); mapBtn.anchor.set(0, 0); mapBtn.x = 120; mapBtn.y = 90; LK.gui.topLeft.addChild(mapBtn); // Inventory state var inventoryOpen = false; var inventoryPanel = null; // Map state var mapOpen = false; var mapPanel = null; // Create ground var ground = game.addChild(LK.getAsset('ground', { anchorX: 0, anchorY: 0, x: 0, y: 0 })); // Create player player = game.addChild(new Player()); player.x = 1024; player.y = 1366; // Generate forest elements function generateForestElements() { // Create trees for (var i = 0; i < 15; i++) { var tree = new Tree(); tree.x = Math.random() * 1900 + 100; tree.y = Math.random() * 2500 + 200; trees.push(tree); game.addChild(tree); } // Create crystals for (var i = 0; i < 8; i++) { var crystal = new Crystal(); crystal.x = Math.random() * 1800 + 200; crystal.y = Math.random() * 2400 + 200; crystals.push(crystal); game.addChild(crystal); } // Create berries for (var i = 0; i < 12; i++) { var berry = new Berry(); berry.x = Math.random() * 1800 + 200; berry.y = Math.random() * 2400 + 200; berries.push(berry); game.addChild(berry); } // Create thorns for (var i = 0; i < 6; i++) { var thorn = new Thorn(); thorn.x = Math.random() * 1800 + 200; thorn.y = Math.random() * 2400 + 200; thorns.push(thorn); game.addChild(thorn); } // Create creatures for (var i = 0; i < 4; i++) { var creature = new Creature(); creature.x = Math.random() * 1600 + 300; creature.y = Math.random() * 2200 + 300; creatures.push(creature); game.addChild(creature); } } generateForestElements(); // Touch controls game.down = function (x, y, obj) { player.moveTo(x, y); }; // Inventory button click handler inventoryBtn.down = function (x, y, obj) { if (!inventoryOpen) { // Create inventory panel inventoryPanel = game.addChild(LK.getAsset('ground', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, scaleX: 0.8, scaleY: 0.6 })); inventoryPanel.tint = 0x654321; inventoryPanel.alpha = 0.9; // Add inventory title var invTitle = new Text2('INVENTORY', { size: 80, fill: 0xFFFFFF }); invTitle.anchor.set(0.5, 0); invTitle.x = 1024; invTitle.y = 900; game.addChild(invTitle); inventoryPanel.titleText = invTitle; // Add close button var closeBtn = new Text2('CLOSE', { size: 60, fill: 0xFF4444 }); closeBtn.anchor.set(0.5, 0.5); closeBtn.x = 1024; closeBtn.y = 1800; closeBtn.down = function () { inventoryPanel.destroy(); inventoryPanel.titleText.destroy(); this.destroy(); inventoryOpen = false; inventoryPanel = null; }; game.addChild(closeBtn); inventoryPanel.closeBtn = closeBtn; inventoryOpen = true; } else { // Close inventory if (inventoryPanel) { inventoryPanel.destroy(); inventoryPanel.titleText.destroy(); inventoryPanel.closeBtn.destroy(); inventoryOpen = false; inventoryPanel = null; } } }; // Map button click handler mapBtn.down = function (x, y, obj) { if (!mapOpen) { // Create map panel mapPanel = game.addChild(LK.getAsset('ground', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, scaleX: 0.9, scaleY: 0.8 })); mapPanel.tint = 0x8B4513; mapPanel.alpha = 0.95; // Add map title var mapTitle = new Text2('FOREST MAP', { size: 80, fill: 0xFFFFFF }); mapTitle.anchor.set(0.5, 0); mapTitle.x = 1024; mapTitle.y = 800; game.addChild(mapTitle); mapPanel.titleText = mapTitle; // Add player position indicator var playerDot = game.addChild(LK.getAsset('crystal', { anchorX: 0.5, anchorY: 0.5, x: 1024 + (player.x - 1024) * 0.4, y: 1366 + (player.y - 1366) * 0.3, scaleX: 0.8, scaleY: 0.8 })); playerDot.tint = 0x00FF00; mapPanel.playerDot = playerDot; // Add close button var closeMapBtn = new Text2('CLOSE', { size: 60, fill: 0xFF4444 }); closeMapBtn.anchor.set(0.5, 0.5); closeMapBtn.x = 1024; closeMapBtn.y = 1900; closeMapBtn.down = function () { mapPanel.destroy(); mapPanel.titleText.destroy(); mapPanel.playerDot.destroy(); this.destroy(); mapOpen = false; mapPanel = null; }; game.addChild(closeMapBtn); mapPanel.closeBtn = closeMapBtn; mapOpen = true; } else { // Close map if (mapPanel) { mapPanel.destroy(); mapPanel.titleText.destroy(); mapPanel.playerDot.destroy(); mapPanel.closeBtn.destroy(); mapOpen = false; mapPanel = null; } } }; // Update score display function updateScore() { scoreTxt.setText('Score: ' + LK.getScore()); itemsTxt.setText('Items: ' + itemsCollected); } // Check collisions and interactions game.update = function () { // Check crystal collection for (var i = crystals.length - 1; i >= 0; i--) { var crystal = crystals[i]; if (!crystal.collected && player.intersects(crystal)) { crystal.collected = true; crystal.alpha = 0; itemsCollected++; LK.setScore(LK.getScore() + 10); updateScore(); LK.getSound('collect').play(); crystals.splice(i, 1); crystal.destroy(); } } // Check berry collection for (var i = berries.length - 1; i >= 0; i--) { var berry = berries[i]; if (!berry.collected && player.intersects(berry)) { berry.collected = true; berry.alpha = 0; itemsCollected++; LK.setScore(LK.getScore() + 5); updateScore(); LK.getSound('collect').play(); berries.splice(i, 1); berry.destroy(); } } // Check thorn collisions for (var i = 0; i < thorns.length; i++) { var thorn = thorns[i]; if (player.intersects(thorn)) { // Push player away from thorn var dx = player.x - thorn.x; var dy = player.y - thorn.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { player.x = thorn.x + dx / distance * 60; player.y = thorn.y + dy / distance * 60; } player.isMoving = false; LK.effects.flashObject(player, 0xff0000, 500); LK.getSound('danger').play(); } } // Check creature encounters for (var i = 0; i < creatures.length; i++) { var creature = creatures[i]; if (player.intersects(creature)) { // Push player away from creature var dx = player.x - creature.x; var dy = player.y - creature.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { player.x = creature.x + dx / distance * 70; player.y = creature.y + dy / distance * 70; } player.isMoving = false; LK.effects.flashObject(player, 0x8b4513, 500); LK.setScore(Math.max(0, LK.getScore() - 2)); updateScore(); LK.getSound('danger').play(); } } // Check tree collisions (blocking) for (var i = 0; i < trees.length; i++) { var tree = trees[i]; if (player.intersects(tree)) { // Push player away from tree (account for tree anchor being at bottom center) var dx = player.x - tree.x; var dy = player.y - (tree.y - tree.height / 2); // Adjust for tree anchor point var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { // Increase push distance to ensure player stays outside tree bounds player.x = tree.x + dx / distance * (tree.width / 2 + 35); player.y = tree.y - tree.height / 2 + dy / distance * (tree.height / 2 + 35); } player.isMoving = false; } } // Keep player in bounds if (player.x < 30) player.x = 30; if (player.x > 2018) player.x = 2018; if (player.y < 30) player.y = 30; if (player.y > 2702) player.y = 2702; // Check win condition if (itemsCollected >= 15) { LK.showYouWin(); } }; // Play ambient forest music LK.playMusic('forestAmbient'); // Initialize score display updateScore();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Berry = Container.expand(function () {
var self = Container.call(this);
var berryGraphics = self.attachAsset('berry', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
return self;
});
var Creature = Container.expand(function () {
var self = Container.call(this);
var creatureGraphics = self.attachAsset('creature', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1;
self.direction = Math.random() * Math.PI * 2;
self.changeDirectionTimer = 0;
self.update = function () {
self.changeDirectionTimer++;
if (self.changeDirectionTimer > 120) {
self.direction = Math.random() * Math.PI * 2;
self.changeDirectionTimer = 0;
}
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
// Keep creatures in bounds
if (self.x < 50 || self.x > 1998) {
self.direction = Math.PI - self.direction;
}
if (self.y < 50 || self.y > 2682) {
self.direction = -self.direction;
}
};
return self;
});
var Crystal = Container.expand(function () {
var self = Container.call(this);
var crystalGraphics = self.attachAsset('crystal', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.glowDirection = 1;
self.update = function () {
if (!self.collected) {
crystalGraphics.alpha += 0.02 * self.glowDirection;
if (crystalGraphics.alpha >= 1) {
self.glowDirection = -1;
} else if (crystalGraphics.alpha <= 0.3) {
self.glowDirection = 1;
}
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.targetX = null;
self.targetY = null;
self.isMoving = false;
self.moveTo = function (x, y) {
self.targetX = x;
self.targetY = y;
self.isMoving = true;
};
self.update = function () {
if (self.isMoving && self.targetX !== null && self.targetY !== null) {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.speed) {
self.x = self.targetX;
self.y = self.targetY;
self.isMoving = false;
} else {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
}
};
return self;
});
var Thorn = Container.expand(function () {
var self = Container.call(this);
var thornGraphics = self.attachAsset('thorn', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Tree = Container.expand(function () {
var self = Container.call(this);
var treeGraphics = self.attachAsset('tree', {
anchorX: 0.5,
anchorY: 1.0
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2d5016
});
/****
* Game Code
****/
// Game variables
var player;
var crystals = [];
var berries = [];
var trees = [];
var thorns = [];
var creatures = [];
var areasDiscovered = 0;
var itemsCollected = 0;
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
var itemsTxt = new Text2('Items: 0', {
size: 60,
fill: 0xFFFFFF
});
itemsTxt.anchor.set(0, 0);
itemsTxt.y = 100;
LK.gui.topRight.addChild(itemsTxt);
// Inventory button
var inventoryBtn = new Text2('BAG', {
size: 60,
fill: 0xFFFFFF
});
inventoryBtn.anchor.set(0, 0);
inventoryBtn.x = 120;
inventoryBtn.y = 20;
LK.gui.topLeft.addChild(inventoryBtn);
// Map button
var mapBtn = new Text2('MAP', {
size: 60,
fill: 0xFFFFFF
});
mapBtn.anchor.set(0, 0);
mapBtn.x = 120;
mapBtn.y = 90;
LK.gui.topLeft.addChild(mapBtn);
// Inventory state
var inventoryOpen = false;
var inventoryPanel = null;
// Map state
var mapOpen = false;
var mapPanel = null;
// Create ground
var ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
// Create player
player = game.addChild(new Player());
player.x = 1024;
player.y = 1366;
// Generate forest elements
function generateForestElements() {
// Create trees
for (var i = 0; i < 15; i++) {
var tree = new Tree();
tree.x = Math.random() * 1900 + 100;
tree.y = Math.random() * 2500 + 200;
trees.push(tree);
game.addChild(tree);
}
// Create crystals
for (var i = 0; i < 8; i++) {
var crystal = new Crystal();
crystal.x = Math.random() * 1800 + 200;
crystal.y = Math.random() * 2400 + 200;
crystals.push(crystal);
game.addChild(crystal);
}
// Create berries
for (var i = 0; i < 12; i++) {
var berry = new Berry();
berry.x = Math.random() * 1800 + 200;
berry.y = Math.random() * 2400 + 200;
berries.push(berry);
game.addChild(berry);
}
// Create thorns
for (var i = 0; i < 6; i++) {
var thorn = new Thorn();
thorn.x = Math.random() * 1800 + 200;
thorn.y = Math.random() * 2400 + 200;
thorns.push(thorn);
game.addChild(thorn);
}
// Create creatures
for (var i = 0; i < 4; i++) {
var creature = new Creature();
creature.x = Math.random() * 1600 + 300;
creature.y = Math.random() * 2200 + 300;
creatures.push(creature);
game.addChild(creature);
}
}
generateForestElements();
// Touch controls
game.down = function (x, y, obj) {
player.moveTo(x, y);
};
// Inventory button click handler
inventoryBtn.down = function (x, y, obj) {
if (!inventoryOpen) {
// Create inventory panel
inventoryPanel = game.addChild(LK.getAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
scaleX: 0.8,
scaleY: 0.6
}));
inventoryPanel.tint = 0x654321;
inventoryPanel.alpha = 0.9;
// Add inventory title
var invTitle = new Text2('INVENTORY', {
size: 80,
fill: 0xFFFFFF
});
invTitle.anchor.set(0.5, 0);
invTitle.x = 1024;
invTitle.y = 900;
game.addChild(invTitle);
inventoryPanel.titleText = invTitle;
// Add close button
var closeBtn = new Text2('CLOSE', {
size: 60,
fill: 0xFF4444
});
closeBtn.anchor.set(0.5, 0.5);
closeBtn.x = 1024;
closeBtn.y = 1800;
closeBtn.down = function () {
inventoryPanel.destroy();
inventoryPanel.titleText.destroy();
this.destroy();
inventoryOpen = false;
inventoryPanel = null;
};
game.addChild(closeBtn);
inventoryPanel.closeBtn = closeBtn;
inventoryOpen = true;
} else {
// Close inventory
if (inventoryPanel) {
inventoryPanel.destroy();
inventoryPanel.titleText.destroy();
inventoryPanel.closeBtn.destroy();
inventoryOpen = false;
inventoryPanel = null;
}
}
};
// Map button click handler
mapBtn.down = function (x, y, obj) {
if (!mapOpen) {
// Create map panel
mapPanel = game.addChild(LK.getAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
scaleX: 0.9,
scaleY: 0.8
}));
mapPanel.tint = 0x8B4513;
mapPanel.alpha = 0.95;
// Add map title
var mapTitle = new Text2('FOREST MAP', {
size: 80,
fill: 0xFFFFFF
});
mapTitle.anchor.set(0.5, 0);
mapTitle.x = 1024;
mapTitle.y = 800;
game.addChild(mapTitle);
mapPanel.titleText = mapTitle;
// Add player position indicator
var playerDot = game.addChild(LK.getAsset('crystal', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024 + (player.x - 1024) * 0.4,
y: 1366 + (player.y - 1366) * 0.3,
scaleX: 0.8,
scaleY: 0.8
}));
playerDot.tint = 0x00FF00;
mapPanel.playerDot = playerDot;
// Add close button
var closeMapBtn = new Text2('CLOSE', {
size: 60,
fill: 0xFF4444
});
closeMapBtn.anchor.set(0.5, 0.5);
closeMapBtn.x = 1024;
closeMapBtn.y = 1900;
closeMapBtn.down = function () {
mapPanel.destroy();
mapPanel.titleText.destroy();
mapPanel.playerDot.destroy();
this.destroy();
mapOpen = false;
mapPanel = null;
};
game.addChild(closeMapBtn);
mapPanel.closeBtn = closeMapBtn;
mapOpen = true;
} else {
// Close map
if (mapPanel) {
mapPanel.destroy();
mapPanel.titleText.destroy();
mapPanel.playerDot.destroy();
mapPanel.closeBtn.destroy();
mapOpen = false;
mapPanel = null;
}
}
};
// Update score display
function updateScore() {
scoreTxt.setText('Score: ' + LK.getScore());
itemsTxt.setText('Items: ' + itemsCollected);
}
// Check collisions and interactions
game.update = function () {
// Check crystal collection
for (var i = crystals.length - 1; i >= 0; i--) {
var crystal = crystals[i];
if (!crystal.collected && player.intersects(crystal)) {
crystal.collected = true;
crystal.alpha = 0;
itemsCollected++;
LK.setScore(LK.getScore() + 10);
updateScore();
LK.getSound('collect').play();
crystals.splice(i, 1);
crystal.destroy();
}
}
// Check berry collection
for (var i = berries.length - 1; i >= 0; i--) {
var berry = berries[i];
if (!berry.collected && player.intersects(berry)) {
berry.collected = true;
berry.alpha = 0;
itemsCollected++;
LK.setScore(LK.getScore() + 5);
updateScore();
LK.getSound('collect').play();
berries.splice(i, 1);
berry.destroy();
}
}
// Check thorn collisions
for (var i = 0; i < thorns.length; i++) {
var thorn = thorns[i];
if (player.intersects(thorn)) {
// Push player away from thorn
var dx = player.x - thorn.x;
var dy = player.y - thorn.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
player.x = thorn.x + dx / distance * 60;
player.y = thorn.y + dy / distance * 60;
}
player.isMoving = false;
LK.effects.flashObject(player, 0xff0000, 500);
LK.getSound('danger').play();
}
}
// Check creature encounters
for (var i = 0; i < creatures.length; i++) {
var creature = creatures[i];
if (player.intersects(creature)) {
// Push player away from creature
var dx = player.x - creature.x;
var dy = player.y - creature.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
player.x = creature.x + dx / distance * 70;
player.y = creature.y + dy / distance * 70;
}
player.isMoving = false;
LK.effects.flashObject(player, 0x8b4513, 500);
LK.setScore(Math.max(0, LK.getScore() - 2));
updateScore();
LK.getSound('danger').play();
}
}
// Check tree collisions (blocking)
for (var i = 0; i < trees.length; i++) {
var tree = trees[i];
if (player.intersects(tree)) {
// Push player away from tree (account for tree anchor being at bottom center)
var dx = player.x - tree.x;
var dy = player.y - (tree.y - tree.height / 2); // Adjust for tree anchor point
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
// Increase push distance to ensure player stays outside tree bounds
player.x = tree.x + dx / distance * (tree.width / 2 + 35);
player.y = tree.y - tree.height / 2 + dy / distance * (tree.height / 2 + 35);
}
player.isMoving = false;
}
}
// Keep player in bounds
if (player.x < 30) player.x = 30;
if (player.x > 2018) player.x = 2018;
if (player.y < 30) player.y = 30;
if (player.y > 2702) player.y = 2702;
// Check win condition
if (itemsCollected >= 15) {
LK.showYouWin();
}
};
// Play ambient forest music
LK.playMusic('forestAmbient');
// Initialize score display
updateScore();