User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'toGlobal')' in or related to this line: 'var guiPos = LK.gui.bottom.toLocal(obj.parent.toGlobal(obj.position));' Line Number: 574
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'toGlobal')' in or related to this line: 'var guiPos = LK.gui.bottom.toLocal(obj.parent.toGlobal(obj.position));' Line Number: 574
User prompt
Three button also a sprint,attack and walk
Code edit (1 edits merged)
Please save this source code
User prompt
Lost Pup Journey
Initial prompt
A 3d realistic game in which a dog is lost from his home for 6 days and he got 5 level in between
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Car = Container.expand(function () {
var self = Container.call(this);
var carBody = self.attachAsset('car', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.direction = 1; // 1 for right, -1 for left
self.update = function () {
self.x += self.speed * self.direction;
// Remove car when off screen
if (self.x > 2200 || self.x < -200) {
self.destroy();
cars.splice(cars.indexOf(self), 1);
}
};
return self;
});
var Dog = Container.expand(function () {
var self = Container.call(this);
// Create dog visual
var dogBody = self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5
});
var dogTail = self.attachAsset('dogTail', {
anchorX: 0.5,
anchorY: 0.5,
x: -40,
y: 10
});
// Dog stats
self.energy = 100;
self.hunger = 100;
self.thirst = 100;
self.speed = 3;
self.baseSpeed = 3;
// Animation
self.tailWagTime = 0;
self.update = function () {
// Tail wagging animation
self.tailWagTime += 0.3;
dogTail.rotation = Math.sin(self.tailWagTime) * 0.5;
// Decrease stats over time
if (LK.ticks % 180 === 0) {
// Every 3 seconds
self.hunger = Math.max(0, self.hunger - 1);
self.thirst = Math.max(0, self.thirst - 1);
self.energy = Math.max(0, self.energy - 0.5);
}
// Speed based on stats
var avgStat = (self.energy + self.hunger + self.thirst) / 3;
self.speed = self.baseSpeed * (avgStat / 100);
// Visual feedback for low stats and movement mode
if (avgStat < 30) {
dogBody.alpha = 0.7;
} else {
dogBody.alpha = 1.0;
}
// Movement mode visual effects
if (movementMode === 'sprint') {
// Sprint mode - slight blue tint and faster tail wag
dogBody.tint = 0xccccff;
self.tailWagTime += 0.1; // Extra tail wag speed
} else if (movementMode === 'attack') {
// Attack mode - slight red tint and aggressive posture
dogBody.tint = 0xffcccc;
dogBody.scaleX = 1.1;
dogBody.scaleY = 0.9; // Lower stance
} else {
// Walk mode - normal appearance
dogBody.tint = 0xffffff;
dogBody.scaleX = 1.0;
dogBody.scaleY = 1.0;
}
};
self.eat = function () {
self.hunger = Math.min(100, self.hunger + 30);
self.energy = Math.min(100, self.energy + 10);
LK.getSound('eating').play();
};
self.drink = function () {
self.thirst = Math.min(100, self.thirst + 40);
self.energy = Math.min(100, self.energy + 5);
LK.getSound('drinking').play();
};
self.bark = function () {
LK.getSound('bark').play();
// Bark animation
tween(dogBody, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut
});
tween(dogBody, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeIn
});
};
return self;
});
var Food = Container.expand(function () {
var self = Container.call(this);
var foodGraphic = self.attachAsset('food', {
anchorX: 0.5,
anchorY: 0.5
});
// Gentle pulsing animation
self.pulseTime = 0;
self.update = function () {
self.pulseTime += 0.1;
var scale = 1 + Math.sin(self.pulseTime) * 0.1;
foodGraphic.scaleX = scale;
foodGraphic.scaleY = scale;
};
return self;
});
var Obstacle = Container.expand(function (assetId) {
var self = Container.call(this);
var obstacleGraphic = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Water = Container.expand(function () {
var self = Container.call(this);
var waterGraphic = self.attachAsset('water', {
anchorX: 0.5,
anchorY: 0.5
});
// Shimmer animation
self.shimmerTime = 0;
self.update = function () {
self.shimmerTime += 0.15;
waterGraphic.alpha = 0.8 + Math.sin(self.shimmerTime) * 0.2;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB // Sky blue
});
/****
* Game Code
****/
// Game state
// Dog sprite - main character
// Environment elements
// UI elements
// Sounds
var currentLevel = storage.currentLevel || 1;
var maxLevel = storage.maxLevel || 1;
var gameState = 'playing'; // playing, paused, levelComplete
// Game objects
var dog = null;
var cars = [];
var foods = [];
var waters = [];
var obstacles = [];
// Level data
var levelData = {
1: {
name: "Day 1: City Streets",
backgroundColor: 0x87CEEB,
carSpawnRate: 120,
foodCount: 3,
waterCount: 2,
obstacleCount: 5,
targetX: 1800,
targetY: 2400
},
2: {
name: "Day 2: City Outskirts",
backgroundColor: 0x90EE90,
carSpawnRate: 90,
foodCount: 2,
waterCount: 3,
obstacleCount: 7,
targetX: 1900,
targetY: 2500
},
3: {
name: "Day 3: Forest",
backgroundColor: 0x228B22,
carSpawnRate: 0,
foodCount: 4,
waterCount: 4,
obstacleCount: 10,
targetX: 1700,
targetY: 2600
},
4: {
name: "Day 4: Suburbs",
backgroundColor: 0xF0E68C,
carSpawnRate: 150,
foodCount: 3,
waterCount: 2,
obstacleCount: 8,
targetX: 1600,
targetY: 2400
},
5: {
name: "Day 5: Industrial Area",
backgroundColor: 0x696969,
carSpawnRate: 60,
foodCount: 2,
waterCount: 1,
obstacleCount: 12,
targetX: 1500,
targetY: 2300
}
};
// UI elements
var levelText = new Text2("", {
size: 60,
fill: 0xFFFFFF
});
// Control buttons
var walkButton = new Text2("WALK", {
size: 40,
fill: 0xFFFFFF
});
var sprintButton = new Text2("SPRINT", {
size: 40,
fill: 0xFFFFFF
});
var attackButton = new Text2("ATTACK", {
size: 40,
fill: 0xFFFFFF
});
// Movement mode
var movementMode = 'walk'; // walk, sprint, attack
var energyBarBg = LK.getAsset('energyBar', {
anchorX: 0,
anchorY: 0,
scaleX: 1,
scaleY: 1
});
var energyBarFill = LK.getAsset('energyBar', {
anchorX: 0,
anchorY: 0,
scaleX: 1,
scaleY: 1
});
var hungerBarBg = LK.getAsset('hungerBar', {
anchorX: 0,
anchorY: 0,
scaleX: 1,
scaleY: 1
});
var hungerBarFill = LK.getAsset('hungerBar', {
anchorX: 0,
anchorY: 0,
scaleX: 1,
scaleY: 1
});
var thirstBarBg = LK.getAsset('thirstBar', {
anchorX: 0,
anchorY: 0,
scaleX: 1,
scaleY: 1
});
var thirstBarFill = LK.getAsset('thirstBar', {
anchorX: 0,
anchorY: 0,
scaleX: 1,
scaleY: 1
});
// Home marker
var homeMarker = null;
// Initialize UI
function initializeUI() {
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
levelText.y = 50;
// Energy bar
energyBarBg.alpha = 0.3;
energyBarFill.tint = 0x32CD32;
LK.gui.topLeft.addChild(energyBarBg);
LK.gui.topLeft.addChild(energyBarFill);
energyBarBg.x = 120;
energyBarBg.y = 50;
energyBarFill.x = 120;
energyBarFill.y = 50;
// Hunger bar
hungerBarBg.alpha = 0.3;
hungerBarFill.tint = 0xFF4500;
LK.gui.topLeft.addChild(hungerBarBg);
LK.gui.topLeft.addChild(hungerBarFill);
hungerBarBg.x = 120;
hungerBarBg.y = 80;
hungerBarFill.x = 120;
hungerBarFill.y = 80;
// Thirst bar
thirstBarBg.alpha = 0.3;
thirstBarFill.tint = 0x4169E1;
LK.gui.topLeft.addChild(thirstBarBg);
LK.gui.topLeft.addChild(thirstBarFill);
thirstBarBg.x = 120;
thirstBarBg.y = 110;
thirstBarFill.x = 120;
thirstBarFill.y = 110;
// Add control buttons
walkButton.anchor.set(0.5, 0.5);
sprintButton.anchor.set(0.5, 0.5);
attackButton.anchor.set(0.5, 0.5);
LK.gui.bottom.addChild(walkButton);
LK.gui.bottom.addChild(sprintButton);
LK.gui.bottom.addChild(attackButton);
walkButton.x = -200;
walkButton.y = -100;
sprintButton.x = 0;
sprintButton.y = -100;
attackButton.x = 200;
attackButton.y = -100;
// Set initial button states
updateButtonStates();
}
// Initialize level
function initializeLevel(levelNum) {
// Clear existing objects
cars = [];
foods = [];
waters = [];
obstacles = [];
// Remove existing game objects
while (game.children.length > 0) {
game.removeChild(game.children[0]);
}
var level = levelData[levelNum];
if (!level) return;
game.setBackgroundColor(level.backgroundColor);
levelText.setText(level.name);
// Create dog
dog = new Dog();
dog.x = 100;
dog.y = 2400;
game.addChild(dog);
// Create food items
for (var i = 0; i < level.foodCount; i++) {
var food = new Food();
food.x = 200 + Math.random() * 1600;
food.y = 300 + Math.random() * 2000;
foods.push(food);
game.addChild(food);
}
// Create water items
for (var i = 0; i < level.waterCount; i++) {
var water = new Water();
water.x = 200 + Math.random() * 1600;
water.y = 300 + Math.random() * 2000;
waters.push(water);
game.addChild(water);
}
// Create obstacles
var obstacleAsset = levelNum === 3 ? 'tree' : 'house';
for (var i = 0; i < level.obstacleCount; i++) {
var obstacle = new Obstacle(obstacleAsset);
obstacle.x = 200 + Math.random() * 1600;
obstacle.y = 300 + Math.random() * 2000;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Create home marker
homeMarker = new Obstacle('home');
homeMarker.x = level.targetX;
homeMarker.y = level.targetY;
game.addChild(homeMarker);
// Flash effect for level start
LK.effects.flashScreen(0xFFFFFF, 500);
}
// Update button visual states
function updateButtonStates() {
// Reset all buttons
walkButton.alpha = 0.6;
sprintButton.alpha = 0.6;
attackButton.alpha = 0.6;
// Highlight active button
if (movementMode === 'walk') {
walkButton.alpha = 1.0;
} else if (movementMode === 'sprint') {
sprintButton.alpha = 1.0;
} else if (movementMode === 'attack') {
attackButton.alpha = 1.0;
}
}
// Game logic
function updateUI() {
if (!dog) return;
// Update stat bars
energyBarFill.scaleX = dog.energy / 100;
hungerBarFill.scaleX = dog.hunger / 100;
thirstBarFill.scaleX = dog.thirst / 100;
}
function checkCollisions() {
if (!dog) return;
// Check food collisions
for (var i = foods.length - 1; i >= 0; i--) {
var food = foods[i];
if (dog.intersects(food)) {
dog.eat();
food.destroy();
foods.splice(i, 1);
LK.setScore(LK.getScore() + 10);
}
}
// Check water collisions
for (var i = waters.length - 1; i >= 0; i--) {
var water = waters[i];
if (dog.intersects(water)) {
dog.drink();
water.destroy();
waters.splice(i, 1);
LK.setScore(LK.getScore() + 10);
}
}
// Check car collisions
for (var i = 0; i < cars.length; i++) {
var car = cars[i];
if (dog.intersects(car)) {
// Game over
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
return;
}
}
// Check if dog reached home
if (homeMarker && dog.intersects(homeMarker)) {
// Level complete
currentLevel++;
storage.currentLevel = currentLevel;
storage.maxLevel = Math.max(storage.maxLevel || 1, currentLevel);
if (currentLevel > 5) {
// Game complete
LK.showYouWin();
} else {
// Next level
LK.effects.flashScreen(0x00FF00, 1000);
LK.setTimeout(function () {
initializeLevel(currentLevel);
}, 1000);
}
}
}
function spawnCar() {
var level = levelData[currentLevel];
if (!level || level.carSpawnRate === 0) return;
if (LK.ticks % level.carSpawnRate === 0) {
var car = new Car();
car.y = 800 + Math.random() * 1000;
if (Math.random() < 0.5) {
car.x = -100;
car.direction = 1;
} else {
car.x = 2148;
car.direction = -1;
}
cars.push(car);
game.addChild(car);
// Honk sound
if (Math.random() < 0.3) {
LK.getSound('carHonk').play();
}
}
}
function checkGameOver() {
if (!dog) return;
if (dog.energy <= 0 || dog.hunger <= 0 || dog.thirst <= 0) {
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
}
}
// Movement
var dragNode = null;
function handleMove(x, y, obj) {
if (dragNode && dragNode === dog) {
// Calculate movement distance based on mode
var moveSpeed = 1;
if (movementMode === 'sprint') {
moveSpeed = 2;
// Sprint drains energy faster
if (LK.ticks % 10 === 0) {
dog.energy = Math.max(0, dog.energy - 1);
}
} else if (movementMode === 'attack') {
moveSpeed = 0.8;
// Attack mode is slower but more aggressive
}
// Apply movement with speed modifier
var deltaX = (x - dog.x) * moveSpeed * 0.1;
var deltaY = (y - dog.y) * moveSpeed * 0.1;
var newX = Math.max(40, Math.min(2008, dog.x + deltaX));
var newY = Math.max(40, Math.min(2692, dog.y + deltaY));
dog.x = newX;
dog.y = newY;
// Different behaviors based on mode
if (movementMode === 'attack') {
// Attack mode - bark more often and scare away some cars
if (Math.random() < 0.01) {
dog.bark();
// Scare away nearby cars
for (var i = 0; i < cars.length; i++) {
var car = cars[i];
var distance = Math.sqrt(Math.pow(car.x - dog.x, 2) + Math.pow(car.y - dog.y, 2));
if (distance < 150) {
car.speed *= 1.5; // Make car go faster away
}
}
}
} else if (movementMode === 'sprint') {
// Sprint mode - occasional panting sound
if (Math.random() < 0.005) {
dog.bark(); // Use bark as panting sound
}
} else {
// Walk mode - normal bark occasionally
if (Math.random() < 0.001) {
dog.bark();
}
}
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
// Convert to GUI coordinates for button checking - safely handle obj.parent
var guiPos;
if (obj && obj.parent && obj.parent.toGlobal) {
guiPos = LK.gui.bottom.toLocal(obj.parent.toGlobal(obj.position));
} else {
// Fallback to using x,y directly converted to GUI coordinates
guiPos = LK.gui.bottom.toLocal({
x: x,
y: y
});
}
// Check button presses
if (Math.abs(guiPos.x - walkButton.x) < 80 && Math.abs(guiPos.y - walkButton.y) < 30) {
movementMode = 'walk';
updateButtonStates();
return;
}
if (Math.abs(guiPos.x - sprintButton.x) < 80 && Math.abs(guiPos.y - sprintButton.y) < 30) {
movementMode = 'sprint';
updateButtonStates();
return;
}
if (Math.abs(guiPos.x - attackButton.x) < 80 && Math.abs(guiPos.y - attackButton.y) < 30) {
movementMode = 'attack';
updateButtonStates();
return;
}
if (dog) {
dragNode = dog;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game loop
game.update = function () {
if (gameState !== 'playing') return;
updateUI();
checkCollisions();
spawnCar();
checkGameOver();
};
// Initialize game
initializeUI();
initializeLevel(currentLevel); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Car = Container.expand(function () {
var self = Container.call(this);
var carBody = self.attachAsset('car', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.direction = 1; // 1 for right, -1 for left
self.update = function () {
self.x += self.speed * self.direction;
// Remove car when off screen
if (self.x > 2200 || self.x < -200) {
self.destroy();
cars.splice(cars.indexOf(self), 1);
}
};
return self;
});
var Dog = Container.expand(function () {
var self = Container.call(this);
// Create dog visual
var dogBody = self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5
});
var dogTail = self.attachAsset('dogTail', {
anchorX: 0.5,
anchorY: 0.5,
x: -40,
y: 10
});
// Dog stats
self.energy = 100;
self.hunger = 100;
self.thirst = 100;
self.speed = 3;
self.baseSpeed = 3;
// Animation
self.tailWagTime = 0;
self.update = function () {
// Tail wagging animation
self.tailWagTime += 0.3;
dogTail.rotation = Math.sin(self.tailWagTime) * 0.5;
// Decrease stats over time
if (LK.ticks % 180 === 0) {
// Every 3 seconds
self.hunger = Math.max(0, self.hunger - 1);
self.thirst = Math.max(0, self.thirst - 1);
self.energy = Math.max(0, self.energy - 0.5);
}
// Speed based on stats
var avgStat = (self.energy + self.hunger + self.thirst) / 3;
self.speed = self.baseSpeed * (avgStat / 100);
// Visual feedback for low stats and movement mode
if (avgStat < 30) {
dogBody.alpha = 0.7;
} else {
dogBody.alpha = 1.0;
}
// Movement mode visual effects
if (movementMode === 'sprint') {
// Sprint mode - slight blue tint and faster tail wag
dogBody.tint = 0xccccff;
self.tailWagTime += 0.1; // Extra tail wag speed
} else if (movementMode === 'attack') {
// Attack mode - slight red tint and aggressive posture
dogBody.tint = 0xffcccc;
dogBody.scaleX = 1.1;
dogBody.scaleY = 0.9; // Lower stance
} else {
// Walk mode - normal appearance
dogBody.tint = 0xffffff;
dogBody.scaleX = 1.0;
dogBody.scaleY = 1.0;
}
};
self.eat = function () {
self.hunger = Math.min(100, self.hunger + 30);
self.energy = Math.min(100, self.energy + 10);
LK.getSound('eating').play();
};
self.drink = function () {
self.thirst = Math.min(100, self.thirst + 40);
self.energy = Math.min(100, self.energy + 5);
LK.getSound('drinking').play();
};
self.bark = function () {
LK.getSound('bark').play();
// Bark animation
tween(dogBody, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut
});
tween(dogBody, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeIn
});
};
return self;
});
var Food = Container.expand(function () {
var self = Container.call(this);
var foodGraphic = self.attachAsset('food', {
anchorX: 0.5,
anchorY: 0.5
});
// Gentle pulsing animation
self.pulseTime = 0;
self.update = function () {
self.pulseTime += 0.1;
var scale = 1 + Math.sin(self.pulseTime) * 0.1;
foodGraphic.scaleX = scale;
foodGraphic.scaleY = scale;
};
return self;
});
var Obstacle = Container.expand(function (assetId) {
var self = Container.call(this);
var obstacleGraphic = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Water = Container.expand(function () {
var self = Container.call(this);
var waterGraphic = self.attachAsset('water', {
anchorX: 0.5,
anchorY: 0.5
});
// Shimmer animation
self.shimmerTime = 0;
self.update = function () {
self.shimmerTime += 0.15;
waterGraphic.alpha = 0.8 + Math.sin(self.shimmerTime) * 0.2;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB // Sky blue
});
/****
* Game Code
****/
// Game state
// Dog sprite - main character
// Environment elements
// UI elements
// Sounds
var currentLevel = storage.currentLevel || 1;
var maxLevel = storage.maxLevel || 1;
var gameState = 'playing'; // playing, paused, levelComplete
// Game objects
var dog = null;
var cars = [];
var foods = [];
var waters = [];
var obstacles = [];
// Level data
var levelData = {
1: {
name: "Day 1: City Streets",
backgroundColor: 0x87CEEB,
carSpawnRate: 120,
foodCount: 3,
waterCount: 2,
obstacleCount: 5,
targetX: 1800,
targetY: 2400
},
2: {
name: "Day 2: City Outskirts",
backgroundColor: 0x90EE90,
carSpawnRate: 90,
foodCount: 2,
waterCount: 3,
obstacleCount: 7,
targetX: 1900,
targetY: 2500
},
3: {
name: "Day 3: Forest",
backgroundColor: 0x228B22,
carSpawnRate: 0,
foodCount: 4,
waterCount: 4,
obstacleCount: 10,
targetX: 1700,
targetY: 2600
},
4: {
name: "Day 4: Suburbs",
backgroundColor: 0xF0E68C,
carSpawnRate: 150,
foodCount: 3,
waterCount: 2,
obstacleCount: 8,
targetX: 1600,
targetY: 2400
},
5: {
name: "Day 5: Industrial Area",
backgroundColor: 0x696969,
carSpawnRate: 60,
foodCount: 2,
waterCount: 1,
obstacleCount: 12,
targetX: 1500,
targetY: 2300
}
};
// UI elements
var levelText = new Text2("", {
size: 60,
fill: 0xFFFFFF
});
// Control buttons
var walkButton = new Text2("WALK", {
size: 40,
fill: 0xFFFFFF
});
var sprintButton = new Text2("SPRINT", {
size: 40,
fill: 0xFFFFFF
});
var attackButton = new Text2("ATTACK", {
size: 40,
fill: 0xFFFFFF
});
// Movement mode
var movementMode = 'walk'; // walk, sprint, attack
var energyBarBg = LK.getAsset('energyBar', {
anchorX: 0,
anchorY: 0,
scaleX: 1,
scaleY: 1
});
var energyBarFill = LK.getAsset('energyBar', {
anchorX: 0,
anchorY: 0,
scaleX: 1,
scaleY: 1
});
var hungerBarBg = LK.getAsset('hungerBar', {
anchorX: 0,
anchorY: 0,
scaleX: 1,
scaleY: 1
});
var hungerBarFill = LK.getAsset('hungerBar', {
anchorX: 0,
anchorY: 0,
scaleX: 1,
scaleY: 1
});
var thirstBarBg = LK.getAsset('thirstBar', {
anchorX: 0,
anchorY: 0,
scaleX: 1,
scaleY: 1
});
var thirstBarFill = LK.getAsset('thirstBar', {
anchorX: 0,
anchorY: 0,
scaleX: 1,
scaleY: 1
});
// Home marker
var homeMarker = null;
// Initialize UI
function initializeUI() {
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
levelText.y = 50;
// Energy bar
energyBarBg.alpha = 0.3;
energyBarFill.tint = 0x32CD32;
LK.gui.topLeft.addChild(energyBarBg);
LK.gui.topLeft.addChild(energyBarFill);
energyBarBg.x = 120;
energyBarBg.y = 50;
energyBarFill.x = 120;
energyBarFill.y = 50;
// Hunger bar
hungerBarBg.alpha = 0.3;
hungerBarFill.tint = 0xFF4500;
LK.gui.topLeft.addChild(hungerBarBg);
LK.gui.topLeft.addChild(hungerBarFill);
hungerBarBg.x = 120;
hungerBarBg.y = 80;
hungerBarFill.x = 120;
hungerBarFill.y = 80;
// Thirst bar
thirstBarBg.alpha = 0.3;
thirstBarFill.tint = 0x4169E1;
LK.gui.topLeft.addChild(thirstBarBg);
LK.gui.topLeft.addChild(thirstBarFill);
thirstBarBg.x = 120;
thirstBarBg.y = 110;
thirstBarFill.x = 120;
thirstBarFill.y = 110;
// Add control buttons
walkButton.anchor.set(0.5, 0.5);
sprintButton.anchor.set(0.5, 0.5);
attackButton.anchor.set(0.5, 0.5);
LK.gui.bottom.addChild(walkButton);
LK.gui.bottom.addChild(sprintButton);
LK.gui.bottom.addChild(attackButton);
walkButton.x = -200;
walkButton.y = -100;
sprintButton.x = 0;
sprintButton.y = -100;
attackButton.x = 200;
attackButton.y = -100;
// Set initial button states
updateButtonStates();
}
// Initialize level
function initializeLevel(levelNum) {
// Clear existing objects
cars = [];
foods = [];
waters = [];
obstacles = [];
// Remove existing game objects
while (game.children.length > 0) {
game.removeChild(game.children[0]);
}
var level = levelData[levelNum];
if (!level) return;
game.setBackgroundColor(level.backgroundColor);
levelText.setText(level.name);
// Create dog
dog = new Dog();
dog.x = 100;
dog.y = 2400;
game.addChild(dog);
// Create food items
for (var i = 0; i < level.foodCount; i++) {
var food = new Food();
food.x = 200 + Math.random() * 1600;
food.y = 300 + Math.random() * 2000;
foods.push(food);
game.addChild(food);
}
// Create water items
for (var i = 0; i < level.waterCount; i++) {
var water = new Water();
water.x = 200 + Math.random() * 1600;
water.y = 300 + Math.random() * 2000;
waters.push(water);
game.addChild(water);
}
// Create obstacles
var obstacleAsset = levelNum === 3 ? 'tree' : 'house';
for (var i = 0; i < level.obstacleCount; i++) {
var obstacle = new Obstacle(obstacleAsset);
obstacle.x = 200 + Math.random() * 1600;
obstacle.y = 300 + Math.random() * 2000;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Create home marker
homeMarker = new Obstacle('home');
homeMarker.x = level.targetX;
homeMarker.y = level.targetY;
game.addChild(homeMarker);
// Flash effect for level start
LK.effects.flashScreen(0xFFFFFF, 500);
}
// Update button visual states
function updateButtonStates() {
// Reset all buttons
walkButton.alpha = 0.6;
sprintButton.alpha = 0.6;
attackButton.alpha = 0.6;
// Highlight active button
if (movementMode === 'walk') {
walkButton.alpha = 1.0;
} else if (movementMode === 'sprint') {
sprintButton.alpha = 1.0;
} else if (movementMode === 'attack') {
attackButton.alpha = 1.0;
}
}
// Game logic
function updateUI() {
if (!dog) return;
// Update stat bars
energyBarFill.scaleX = dog.energy / 100;
hungerBarFill.scaleX = dog.hunger / 100;
thirstBarFill.scaleX = dog.thirst / 100;
}
function checkCollisions() {
if (!dog) return;
// Check food collisions
for (var i = foods.length - 1; i >= 0; i--) {
var food = foods[i];
if (dog.intersects(food)) {
dog.eat();
food.destroy();
foods.splice(i, 1);
LK.setScore(LK.getScore() + 10);
}
}
// Check water collisions
for (var i = waters.length - 1; i >= 0; i--) {
var water = waters[i];
if (dog.intersects(water)) {
dog.drink();
water.destroy();
waters.splice(i, 1);
LK.setScore(LK.getScore() + 10);
}
}
// Check car collisions
for (var i = 0; i < cars.length; i++) {
var car = cars[i];
if (dog.intersects(car)) {
// Game over
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
return;
}
}
// Check if dog reached home
if (homeMarker && dog.intersects(homeMarker)) {
// Level complete
currentLevel++;
storage.currentLevel = currentLevel;
storage.maxLevel = Math.max(storage.maxLevel || 1, currentLevel);
if (currentLevel > 5) {
// Game complete
LK.showYouWin();
} else {
// Next level
LK.effects.flashScreen(0x00FF00, 1000);
LK.setTimeout(function () {
initializeLevel(currentLevel);
}, 1000);
}
}
}
function spawnCar() {
var level = levelData[currentLevel];
if (!level || level.carSpawnRate === 0) return;
if (LK.ticks % level.carSpawnRate === 0) {
var car = new Car();
car.y = 800 + Math.random() * 1000;
if (Math.random() < 0.5) {
car.x = -100;
car.direction = 1;
} else {
car.x = 2148;
car.direction = -1;
}
cars.push(car);
game.addChild(car);
// Honk sound
if (Math.random() < 0.3) {
LK.getSound('carHonk').play();
}
}
}
function checkGameOver() {
if (!dog) return;
if (dog.energy <= 0 || dog.hunger <= 0 || dog.thirst <= 0) {
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
}
}
// Movement
var dragNode = null;
function handleMove(x, y, obj) {
if (dragNode && dragNode === dog) {
// Calculate movement distance based on mode
var moveSpeed = 1;
if (movementMode === 'sprint') {
moveSpeed = 2;
// Sprint drains energy faster
if (LK.ticks % 10 === 0) {
dog.energy = Math.max(0, dog.energy - 1);
}
} else if (movementMode === 'attack') {
moveSpeed = 0.8;
// Attack mode is slower but more aggressive
}
// Apply movement with speed modifier
var deltaX = (x - dog.x) * moveSpeed * 0.1;
var deltaY = (y - dog.y) * moveSpeed * 0.1;
var newX = Math.max(40, Math.min(2008, dog.x + deltaX));
var newY = Math.max(40, Math.min(2692, dog.y + deltaY));
dog.x = newX;
dog.y = newY;
// Different behaviors based on mode
if (movementMode === 'attack') {
// Attack mode - bark more often and scare away some cars
if (Math.random() < 0.01) {
dog.bark();
// Scare away nearby cars
for (var i = 0; i < cars.length; i++) {
var car = cars[i];
var distance = Math.sqrt(Math.pow(car.x - dog.x, 2) + Math.pow(car.y - dog.y, 2));
if (distance < 150) {
car.speed *= 1.5; // Make car go faster away
}
}
}
} else if (movementMode === 'sprint') {
// Sprint mode - occasional panting sound
if (Math.random() < 0.005) {
dog.bark(); // Use bark as panting sound
}
} else {
// Walk mode - normal bark occasionally
if (Math.random() < 0.001) {
dog.bark();
}
}
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
// Convert to GUI coordinates for button checking - safely handle obj.parent
var guiPos;
if (obj && obj.parent && obj.parent.toGlobal) {
guiPos = LK.gui.bottom.toLocal(obj.parent.toGlobal(obj.position));
} else {
// Fallback to using x,y directly converted to GUI coordinates
guiPos = LK.gui.bottom.toLocal({
x: x,
y: y
});
}
// Check button presses
if (Math.abs(guiPos.x - walkButton.x) < 80 && Math.abs(guiPos.y - walkButton.y) < 30) {
movementMode = 'walk';
updateButtonStates();
return;
}
if (Math.abs(guiPos.x - sprintButton.x) < 80 && Math.abs(guiPos.y - sprintButton.y) < 30) {
movementMode = 'sprint';
updateButtonStates();
return;
}
if (Math.abs(guiPos.x - attackButton.x) < 80 && Math.abs(guiPos.y - attackButton.y) < 30) {
movementMode = 'attack';
updateButtonStates();
return;
}
if (dog) {
dragNode = dog;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game loop
game.update = function () {
if (gameState !== 'playing') return;
updateUI();
checkCollisions();
spawnCar();
checkGameOver();
};
// Initialize game
initializeUI();
initializeLevel(currentLevel);
A realistic brown dog. In-Game asset. 2d. High contrast. No shadows
A realistic bmw car. In-Game asset. 2d. High contrast. No shadows
A realistic house with owner. In-Game asset. 2d. High contrast. No shadows
A realistic tree. In-Game asset. 2d. High contrast. No shadows
A realistic brown dog tail. In-Game asset. 2d. High contrast. No shadows
a realistic pizza. In-Game asset. 2d. High contrast. No shadows
A realistic water. In-Game asset. 2d. High contrast. No shadows
A realistic sweet home with owner. In-Game asset. 2d. High contrast. No shadows