User prompt
Make the player shoot auto when the dog is following the animal
User prompt
Make the ammo inf
Code edit (1 edits merged)
Please save this source code
User prompt
Add Diffrent seasons and diffrent dogs with diffrent ablities every season change ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
Make The Player not able to go in the ponds
User prompt
Create Small Ponds in the map and add Ducks in to the ponds Make Sure the dogs go slower in the pond ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add More Sounds
User prompt
Modify dog to only follow one animal at a time by setting single target priority ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
while the animal is running form the dog it cannot turn invis
User prompt
Make the dog go after the animal untill it is shot ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Remove the stamina bar and replace it with an ammo
User prompt
Make the dog walk animation ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make Sure the dog follows the animal to the player to shoot easier ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make The Dog follow footprints and find the animal ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Animals go slower than the dog
User prompt
After the dog stops barking make it come backt to the player ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make the animals invis after some time that dog sees them ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Remove The animal hiding under trees
User prompt
Make the dog go after the animals ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make The Footprints Almost invis to the player and make it so you cant shoot trough trees
User prompt
Make the animals hide under trees and bushes after beeing Seen By The Dog
User prompt
Make the animals invis untill the dog sees them,Make The Dog Follow animal footprints ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make an hunting dog ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make More Maps
User prompt
Shop Does not oppen
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Animal = Container.expand(function (animalType) {
var self = Container.call(this);
self.animalType = animalType || 'deer';
self.graphics = self.attachAsset(self.animalType, {
anchorX: 0.5,
anchorY: 0.5
});
// Animal properties
self.health = 100;
self.alertLevel = 0;
self.speed = 0.5 + Math.random() * 1.5;
self.direction = Math.random() * Math.PI * 2;
self.isAlive = true;
self.detectionRadius = 150 + Math.random() * 100;
self.lastX = self.x;
self.lastY = self.y;
// Visibility properties for dog tracking system
self.isDiscoveredByDog = false;
self.graphics.visible = false; // Start invisible
self.visibilityTimer = 0; // Timer for how long animal has been visible
self.maxVisibilityTime = 300; // 5 seconds at 60fps before going invisible
self.isFadingOut = false; // Flag to prevent multiple fade animations
// Movement timer
self.moveTimer = 0;
self.moveChangeInterval = 60 + Math.random() * 120;
self.update = function () {
if (!self.isAlive) return;
// Random movement behavior
self.moveTimer++;
if (self.moveTimer >= self.moveChangeInterval) {
self.direction += (Math.random() - 0.5) * 0.5;
self.moveTimer = 0;
self.moveChangeInterval = 60 + Math.random() * 120;
}
// Move animal
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
// Keep within bounds
if (self.x < 50) {
self.x = 50;
self.direction = Math.random() * Math.PI * 2;
}
if (self.x > 1998) {
self.x = 1998;
self.direction = Math.random() * Math.PI * 2;
}
if (self.y < 50) {
self.y = 50;
self.direction = Math.random() * Math.PI * 2;
}
if (self.y > 2682) {
self.y = 2682;
self.direction = Math.random() * Math.PI * 2;
}
// Dog and player detection behavior
var distanceToDog = Math.sqrt(Math.pow(self.x - huntingDog.x, 2) + Math.pow(self.y - huntingDog.y, 2));
var distanceToPlayer = Math.sqrt(Math.pow(self.x - hunter.x, 2) + Math.pow(self.y - hunter.y, 2));
// If discovered by dog, flee from dog
if (self.isDiscoveredByDog && distanceToDog < 300) {
// Flee from dog
var fleeFromDogAngle = Math.atan2(self.y - huntingDog.y, self.x - huntingDog.x);
self.direction = fleeFromDogAngle;
self.speed = Math.min(4, self.speed + 0.15);
self.graphics.alpha = 1.0;
} else if (distanceToPlayer < self.detectionRadius) {
// Normal player detection behavior
self.alertLevel = Math.min(100, self.alertLevel + 2);
// Flee from player
var fleeAngle = Math.atan2(self.y - hunter.y, self.x - hunter.x);
self.direction = fleeAngle;
self.speed = Math.min(4, self.speed + 0.1);
self.graphics.alpha = 1.0; // Fully visible when fleeing from player
} else {
self.alertLevel = Math.max(0, self.alertLevel - 1);
self.speed = Math.max(1, self.speed - 0.05);
self.graphics.alpha = 1.0; // Fully visible when calm
}
// Handle visibility timer - make animal invisible after being seen for some time
if (self.isDiscoveredByDog && self.graphics.visible) {
self.visibilityTimer++;
// Start fading out when timer reaches max visibility time
if (self.visibilityTimer >= self.maxVisibilityTime && !self.isFadingOut) {
self.isFadingOut = true;
// Use tween to fade out the animal
tween(self.graphics, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
self.graphics.visible = false;
self.isDiscoveredByDog = false;
self.visibilityTimer = 0;
self.isFadingOut = false;
self.graphics.alpha = 1.0; // Reset alpha for next discovery
}
});
}
}
// Create footprints occasionally - more frequent when fleeing
var footprintChance = 0.02;
if (self.alertLevel > 50 || self.isDiscoveredByDog) {
footprintChance = 0.08; // More footprints when scared or being chased
}
if (Math.random() < footprintChance) {
createFootprint(self.x, self.y);
}
};
return self;
});
var Footprint = Container.expand(function () {
var self = Container.call(this);
self.graphics = self.attachAsset('footprint', {
anchorX: 0.5,
anchorY: 0.5
});
self.graphics.alpha = 0.1;
self.lifetime = 600; // 10 seconds at 60fps
self.update = function () {
self.lifetime--;
self.graphics.alpha = self.lifetime / 600 * 0.1;
if (self.lifetime <= 0) {
self.destroy();
for (var i = footprints.length - 1; i >= 0; i--) {
if (footprints[i] === self) {
footprints.splice(i, 1);
break;
}
}
}
};
return self;
});
// Game variables
var Hunter = Container.expand(function () {
var self = Container.call(this);
self.graphics = self.attachAsset('hunter', {
anchorX: 0.5,
anchorY: 0.5
});
self.rifle = self.addChild(LK.getAsset('rifle', {
anchorX: 0,
anchorY: 0.5
}));
self.rifle.x = 30;
self.rifle.y = 0;
// Hunter stats
self.stamina = 100;
self.hunger = 100;
self.accuracy = 50;
self.stealth = 50;
self.tracking = 50;
self.isMoving = false;
self.lastMoveTime = 0;
return self;
});
var HuntingDog = Container.expand(function () {
var self = Container.call(this);
self.graphics = self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5
});
// Dog properties
self.energy = 100;
self.loyalty = 80;
self.tracking = 60;
self.speed = 2.5;
self.followDistance = 80;
self.detectionRadius = 200;
self.isFollowing = true;
self.targetAnimal = null;
self.alertCooldown = 0;
self.wasChasing = false; // Track if dog was previously chasing
// Movement properties
self.targetX = 0;
self.targetY = 0;
self.lastX = self.x;
self.lastY = self.y;
// Walking animation properties
self.isWalking = false;
self.walkAnimationOffset = 0;
self.walkAnimationSpeed = 0.2;
self.update = function () {
if (self.energy <= 0) return;
// Check for nearby animals to chase
var closestAnimal = null;
var closestAnimalDistance = Infinity;
for (var a = 0; a < animals.length; a++) {
var animal = animals[a];
if (!animal.isAlive || !animal.isDiscoveredByDog) continue;
var animalDistance = Math.sqrt(Math.pow(self.x - animal.x, 2) + Math.pow(self.y - animal.y, 2));
if (animalDistance < 250 && animalDistance < closestAnimalDistance) {
closestAnimal = animal;
closestAnimalDistance = animalDistance;
}
}
// Chase behavior - prioritize chasing animals over following hunter
if (closestAnimal && closestAnimalDistance < 250) {
// Set chasing flag
self.wasChasing = true;
// Stop any existing return tween
tween.stop(self, {
x: true,
y: true
});
// Strategic herding behavior to drive animal toward player
var animalToHunterAngle = Math.atan2(hunter.y - closestAnimal.y, hunter.x - closestAnimal.x);
var dogToAnimalAngle = Math.atan2(closestAnimal.y - self.y, closestAnimal.x - self.x);
var animalToHunterDistance = Math.sqrt(Math.pow(closestAnimal.x - hunter.x, 2) + Math.pow(closestAnimal.y - hunter.y, 2));
// Position dog on the opposite side of animal from hunter to herd it toward player
var herdingAngle = animalToHunterAngle + Math.PI; // Opposite direction from hunter
var optimalDistance = 80; // Distance to maintain from animal while herding
// Calculate where dog should be to herd animal toward hunter
var targetHerdX = closestAnimal.x + Math.cos(herdingAngle) * optimalDistance;
var targetHerdY = closestAnimal.y + Math.sin(herdingAngle) * optimalDistance;
// Move toward herding position
var moveToHerdAngle = Math.atan2(targetHerdY - self.y, targetHerdX - self.x);
var distanceToHerdPosition = Math.sqrt(Math.pow(targetHerdX - self.x, 2) + Math.pow(targetHerdY - self.y, 2));
// If dog is far from optimal herding position, move toward it
if (distanceToHerdPosition > 30) {
self.x += Math.cos(moveToHerdAngle) * self.speed * 1.3;
self.y += Math.sin(moveToHerdAngle) * self.speed * 1.3;
} else {
// If in good herding position, apply pressure to drive animal toward hunter
var pressureAngle = Math.atan2(closestAnimal.y - self.y, closestAnimal.x - self.x);
self.x += Math.cos(pressureAngle) * self.speed * 0.8; // Slower, controlled approach
self.y += Math.sin(pressureAngle) * self.speed * 0.8;
}
// Point towards the animal being herded
self.graphics.rotation = dogToAnimalAngle;
// Bark more frequently when herding toward player (closer to hunter)
var barkFrequency = animalToHunterDistance < 200 ? 60 : 90; // More frequent barking when close to hunter
if (LK.ticks % barkFrequency === 0) {
LK.getSound('bark').play();
}
// Consume more energy while chasing
if (LK.ticks % 15 === 0) {
self.energy = Math.max(0, self.energy - 0.5);
}
// Flash the dog to show it's in chase mode - green flash when successfully herding toward player
if (LK.ticks % 30 === 0) {
var flashColor = animalToHunterDistance < 150 ? 0x44FF44 : 0xFF4444; // Green when close to hunter, red otherwise
LK.effects.flashObject(self, flashColor, 150);
}
} else if (self.isFollowing) {
// Follow footprints or hunter when not chasing
var distanceToHunter = Math.sqrt(Math.pow(self.x - hunter.x, 2) + Math.pow(self.y - hunter.y, 2));
// If dog was chasing but now stopped, smoothly return to player using tween
if (self.wasChasing && !closestAnimal) {
self.wasChasing = false;
// Use tween to smoothly move dog back to hunter
tween(self, {
x: hunter.x + self.followDistance * 0.6,
y: hunter.y + self.followDistance * 0.4
}, {
duration: 1500,
easing: tween.easeOut,
onFinish: function onFinish() {
// Dog has returned to player
LK.effects.flashObject(self, 0x00FF00, 300);
}
});
return; // Skip normal movement while tweening back
}
// Check for nearby footprints to follow and find hidden animals
var nearestFootprint = null;
var nearestFootprintDistance = Infinity;
var footprintTrail = []; // Store footprints for trail following
for (var f = 0; f < footprints.length; f++) {
var footprint = footprints[f];
var footprintDistance = Math.sqrt(Math.pow(self.x - footprint.x, 2) + Math.pow(self.y - footprint.y, 2));
if (footprintDistance < 150) {
footprintTrail.push({
footprint: footprint,
distance: footprintDistance
});
}
if (footprintDistance < nearestFootprintDistance) {
nearestFootprint = footprint;
nearestFootprintDistance = footprintDistance;
}
}
// Sort footprint trail by distance for better pathfinding
footprintTrail.sort(function (a, b) {
return a.distance - b.distance;
});
// Follow footprints if found, otherwise follow hunter
if (nearestFootprint && nearestFootprintDistance < 80) {
// Move towards footprint
var angle = Math.atan2(nearestFootprint.y - self.y, nearestFootprint.x - self.x);
self.x += Math.cos(angle) * self.speed * 0.9; // Slightly faster when tracking
self.y += Math.sin(angle) * self.speed * 0.9;
// Flash footprint when following it
if (LK.ticks % 60 === 0) {
LK.effects.flashObject(nearestFootprint, 0xFFFF00, 200);
}
// When close to footprint, search for nearby hidden animals
if (nearestFootprintDistance < 30) {
for (var a = 0; a < animals.length; a++) {
var animal = animals[a];
if (!animal.isAlive || animal.isDiscoveredByDog) continue;
var animalToFootprintDistance = Math.sqrt(Math.pow(animal.x - nearestFootprint.x, 2) + Math.pow(animal.y - nearestFootprint.y, 2));
var animalToDogDistance = Math.sqrt(Math.pow(animal.x - self.x, 2) + Math.pow(animal.y - self.y, 2));
// If animal is near this footprint and dog is close, discover it
if (animalToFootprintDistance < 100 && animalToDogDistance < self.detectionRadius * 1.2) {
animal.isDiscoveredByDog = true;
animal.graphics.visible = true;
animal.visibilityTimer = 0;
animal.isFadingOut = false;
animal.graphics.alpha = 1.0;
// Special effect for footprint-based discovery
LK.effects.flashObject(animal, 0x00FFFF, 1000); // Cyan flash for trail discovery
LK.effects.flashObject(nearestFootprint, 0x00FFFF, 500);
// Play bark sound for discovery
if (LK.ticks % 30 === 0) {
LK.getSound('bark').play();
}
// Point dog towards discovered animal
var discoveryAngle = Math.atan2(animal.y - self.y, animal.x - self.x);
self.graphics.rotation = discoveryAngle;
break;
}
}
}
// Consume energy while tracking
if (LK.ticks % 25 === 0) {
self.energy = Math.max(0, self.energy - 0.2);
}
} else if (distanceToHunter > self.followDistance) {
// Move towards hunter
var angle = Math.atan2(hunter.y - self.y, hunter.x - self.x);
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
// Consume energy while moving
if (LK.ticks % 20 === 0) {
self.energy = Math.max(0, self.energy - 0.3);
}
}
}
// Scan for animals and make them visible when detected
self.alertCooldown = Math.max(0, self.alertCooldown - 1);
for (var i = 0; i < animals.length; i++) {
var animal = animals[i];
if (!animal.isAlive) continue;
var distance = Math.sqrt(Math.pow(self.x - animal.x, 2) + Math.pow(self.y - animal.y, 2));
// Make animal visible if dog detects it
if (distance < self.detectionRadius && !animal.isDiscoveredByDog) {
animal.isDiscoveredByDog = true;
animal.graphics.visible = true;
animal.visibilityTimer = 0; // Reset visibility timer
animal.isFadingOut = false; // Reset fading flag
animal.graphics.alpha = 1.0; // Ensure full visibility
// Flash the animal when first discovered
LK.effects.flashObject(animal, 0x00FF00, 800);
}
}
// Alert to closest animal
if (self.alertCooldown === 0) {
var closestAnimal = null;
var closestDistance = Infinity;
for (var i = 0; i < animals.length; i++) {
var animal = animals[i];
if (!animal.isAlive || !animal.isDiscoveredByDog) continue;
var distance = Math.sqrt(Math.pow(self.x - animal.x, 2) + Math.pow(self.y - animal.y, 2));
if (distance < self.detectionRadius && distance < closestDistance) {
closestAnimal = animal;
closestDistance = distance;
}
}
if (closestAnimal && closestAnimal !== self.targetAnimal) {
self.targetAnimal = closestAnimal;
self.alertToAnimal();
self.alertCooldown = 180; // 3 seconds cooldown
}
}
// Regenerate energy when not moving much
var movement = Math.sqrt(Math.pow(self.x - self.lastX, 2) + Math.pow(self.y - self.lastY, 2));
if (movement < 1 && self.energy < 100) {
self.energy += 0.15;
}
// Walking animation logic
var currentlyWalking = movement > 0.5; // Dog is walking if movement is significant
// Start walking animation when movement begins
if (!self.isWalking && currentlyWalking) {
self.isWalking = true;
self.startWalkAnimation();
}
// Stop walking animation when movement stops
else if (self.isWalking && !currentlyWalking) {
self.isWalking = false;
self.stopWalkAnimation();
}
self.lastX = self.x;
self.lastY = self.y;
};
self.alertToAnimal = function () {
// Visual alert - flash the dog
LK.effects.flashObject(self, 0xFFFF00, 500);
// Point towards the animal
if (self.targetAnimal) {
var angle = Math.atan2(self.targetAnimal.y - self.y, self.targetAnimal.x - self.x);
self.graphics.rotation = angle;
// Play bark sound
LK.getSound('bark').play();
// Create tracking bonus for player - larger bonus if found via footprints
var trackingBonus = 5;
// Check if there are recent footprints nearby (indicating trail-based discovery)
for (var f = 0; f < footprints.length; f++) {
var footprint = footprints[f];
var footprintToAnimalDistance = Math.sqrt(Math.pow(self.targetAnimal.x - footprint.x, 2) + Math.pow(self.targetAnimal.y - footprint.y, 2));
if (footprintToAnimalDistance < 80) {
trackingBonus = 10; // Double bonus for footprint-based discovery
break;
}
}
hunter.tracking = Math.min(100, hunter.tracking + trackingBonus);
}
};
self.rest = function () {
// Dog rests and recovers energy faster
self.energy = Math.min(100, self.energy + 2);
};
self.startWalkAnimation = function () {
// Create a continuous bobbing animation while walking
self.walkAnimationLoop();
};
self.stopWalkAnimation = function () {
// Stop the walking animation and return to normal position
tween.stop(self.graphics, {
y: true,
scaleY: true
});
tween(self.graphics, {
y: 0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeOut
});
};
self.walkAnimationLoop = function () {
if (!self.isWalking) return; // Stop if no longer walking
// Create bobbing motion with slight scale changes to simulate walking
tween(self.graphics, {
y: -3,
scaleY: 0.95
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (self.isWalking) {
// Bounce back down
tween(self.graphics, {
y: 0,
scaleY: 1.05
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Continue the loop if still walking
if (self.isWalking) {
self.walkAnimationLoop();
}
}
});
}
}
});
};
return self;
});
var Shop = Container.expand(function () {
var self = Container.call(this);
self.isOpen = false;
// Shop background panel
self.background = self.addChild(LK.getAsset('shop_panel', {
anchorX: 0.5,
anchorY: 0.5
}));
self.background.scaleX = 1.2;
self.background.scaleY = 1.5;
// Shop title
self.title = self.addChild(new Text2('HUNTING SHOP', {
size: 32,
fill: 0xFFFFFF
}));
self.title.anchor.set(0.5, 0);
self.title.y = -450;
// Close button
self.closeButton = self.addChild(LK.getAsset('buy_button', {
anchorX: 0.5,
anchorY: 0.5
}));
self.closeButton.y = 420;
self.closeButton.tint = 0xFF4444;
self.closeText = self.addChild(new Text2('CLOSE', {
size: 18,
fill: 0xFFFFFF
}));
self.closeText.anchor.set(0.5, 0.5);
self.closeText.y = 420;
// Shop items
self.items = [];
self.itemsContainer = self.addChild(new Container());
self.itemsContainer.y = -350;
self.open = function () {
self.isOpen = true;
self.visible = true;
self.setupItems();
// Bring shop to front
if (self.parent) {
self.parent.removeChild(self);
self.parent.addChild(self);
}
};
self.close = function () {
self.isOpen = false;
self.visible = false;
};
self.setupItems = function () {
// Clear existing items
for (var i = 0; i < self.items.length; i++) {
if (self.items[i].parent) {
self.items[i].destroy();
}
}
self.items = [];
// Add shop items
var yOffset = 0;
for (var i = 0; i < shopItemsData.length; i++) {
var item = self.itemsContainer.addChild(new ShopItem(shopItemsData[i]));
item.y = yOffset;
item.x = -200; // Center the items
self.items.push(item);
yOffset += 100;
}
};
self.down = function (x, y, obj) {
if (!self.isOpen) return;
// Check close button
if (x >= -60 && x <= 60 && y >= 400 && y <= 440) {
self.close();
}
};
// Initially hidden
self.visible = false;
return self;
});
var ShopItem = Container.expand(function (itemData) {
var self = Container.call(this);
self.itemData = itemData;
self.name = itemData.name;
self.price = itemData.price;
self.description = itemData.description;
self.type = itemData.type;
self.effect = itemData.effect;
// Create item display
self.panel = self.addChild(LK.getAsset('shop_panel', {
anchorX: 0,
anchorY: 0
}));
self.panel.scaleX = 0.8;
self.panel.scaleY = 0.3;
// Item name
self.nameText = self.addChild(new Text2(self.name, {
size: 24,
fill: 0xFFFFFF
}));
self.nameText.anchor.set(0, 0);
self.nameText.x = 10;
self.nameText.y = 10;
// Item price
self.priceText = self.addChild(new Text2('$' + self.price, {
size: 20,
fill: 0xFFD700
}));
self.priceText.anchor.set(0, 0);
self.priceText.x = 10;
self.priceText.y = 35;
// Description
self.descText = self.addChild(new Text2(self.description, {
size: 16,
fill: 0xCCCCCC
}));
self.descText.anchor.set(0, 0);
self.descText.x = 10;
self.descText.y = 60;
// Buy button
self.buyButton = self.addChild(LK.getAsset('buy_button', {
anchorX: 0,
anchorY: 0
}));
self.buyButton.x = 250;
self.buyButton.y = 30;
self.buyText = self.addChild(new Text2('BUY', {
size: 18,
fill: 0xFFFFFF
}));
self.buyText.anchor.set(0.5, 0.5);
self.buyText.x = 310;
self.buyText.y = 50;
self.down = function (x, y, obj) {
// Check if click is on buy button
if (x >= 250 && x <= 370 && y >= 30 && y <= 70) {
if (playerCoins >= self.price) {
playerCoins -= self.price;
applyItemEffect(self);
coinText.setText('Coins: ' + playerCoins);
// Visual feedback
LK.effects.flashObject(self.buyButton, 0x00FF00, 300);
} else {
// Not enough coins
LK.effects.flashObject(self.buyButton, 0xFF0000, 300);
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F4F2F // Dark forest green
});
/****
* Game Code
****/
// Game variables
// Hunter and equipment
// Animals
// Environment
// UI elements
// Sounds
var hunter;
var huntingDog;
var animals = [];
var trees = [];
var footprints = [];
var gameScore = 0;
var dayTime = 0; // 0-1440 (24 hours in minutes)
var isAiming = false;
// Shop system variables
var playerCoins = 100; // Starting coins
var shop;
var shopButton;
var coinText;
// Map system variables
var currentMap = 0; // 0=Forest, 1=Desert, 2=Arctic
var mapButton;
var mapText;
var maps = [{
name: 'Forest',
backgroundColor: 0x2F4F2F,
animals: ['deer', 'rabbit', 'boar', 'wolf'],
treeCount: 30,
bushCount: 50,
animalCount: 15,
visibility: 1.0
}, {
name: 'Desert',
backgroundColor: 0x8B7355,
animals: ['rabbit', 'boar'],
treeCount: 5,
bushCount: 20,
animalCount: 8,
visibility: 0.7
}, {
name: 'Arctic',
backgroundColor: 0xE6F3FF,
animals: ['deer', 'wolf'],
treeCount: 15,
bushCount: 10,
animalCount: 6,
visibility: 0.5
}];
// Shop items data
var shopItemsData = [{
name: 'Better Rifle',
price: 150,
description: 'Increases accuracy by 20%',
type: 'weapon',
effect: 'accuracy'
}, {
name: 'Camouflage Gear',
price: 100,
description: 'Improves stealth by 25%',
type: 'equipment',
effect: 'stealth'
}, {
name: 'Tracking Boots',
price: 80,
description: 'Better tracking skills +15%',
type: 'equipment',
effect: 'tracking'
}, {
name: 'Energy Drink',
price: 50,
description: 'Restores stamina to full',
type: 'consumable',
effect: 'stamina'
}, {
name: 'Food Rations',
price: 30,
description: 'Restores hunger to full',
type: 'consumable',
effect: 'hunger'
}];
// UI elements
var staminaBar, hungerBar, scoreText, timeText;
// Initialize hunter
hunter = game.addChild(new Hunter());
hunter.x = 1024;
hunter.y = 1366;
// Initialize hunting dog
huntingDog = game.addChild(new HuntingDog());
huntingDog.x = hunter.x + 50;
huntingDog.y = hunter.y + 30;
// Initialize first map
createMapEnvironment(maps[currentMap]);
// Create UI
staminaBar = LK.getAsset('stamina_bar', {
anchorX: 0,
anchorY: 0
});
LK.gui.topLeft.addChild(staminaBar);
staminaBar.x = 120;
staminaBar.y = 20;
hungerBar = LK.getAsset('hunger_bar', {
anchorX: 0,
anchorY: 0
});
LK.gui.topLeft.addChild(hungerBar);
hungerBar.x = 120;
hungerBar.y = 50;
// Dog energy bar
var dogEnergyBar = LK.getAsset('stamina_bar', {
anchorX: 0,
anchorY: 0
});
LK.gui.topLeft.addChild(dogEnergyBar);
dogEnergyBar.x = 120;
dogEnergyBar.y = 80;
dogEnergyBar.tint = 0xFFD700; // Golden color for dog
// Dog energy label
var dogEnergyText = new Text2('Dog Energy', {
size: 16,
fill: 0xFFFFFF
});
dogEnergyText.anchor.set(0, 0);
LK.gui.topLeft.addChild(dogEnergyText);
dogEnergyText.x = 120;
dogEnergyText.y = 105;
scoreText = new Text2('Score: 0', {
size: 40,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.x = -200;
scoreText.y = 20;
timeText = new Text2('Dawn', {
size: 35,
fill: 0xFFD700
});
timeText.anchor.set(0.5, 0);
LK.gui.top.addChild(timeText);
timeText.y = 20;
// Coin display
coinText = new Text2('Coins: ' + playerCoins, {
size: 40,
fill: 0xFFD700
});
coinText.anchor.set(1, 0);
LK.gui.topRight.addChild(coinText);
coinText.x = -10;
coinText.y = 60;
// Shop button
shopButton = LK.getAsset('shop_button', {
anchorX: 0.5,
anchorY: 0.5
});
LK.gui.bottomRight.addChild(shopButton);
shopButton.x = -100;
shopButton.y = -50;
var shopButtonText = new Text2('SHOP', {
size: 24,
fill: 0xFFFFFF
});
shopButtonText.anchor.set(0.5, 0.5);
LK.gui.bottomRight.addChild(shopButtonText);
shopButtonText.x = -100;
shopButtonText.y = -50;
// Initialize shop
shop = game.addChild(new Shop());
shop.x = 1024;
shop.y = 1366;
shop.visible = false;
// Map button
mapButton = LK.getAsset('shop_button', {
anchorX: 0.5,
anchorY: 0.5
});
LK.gui.bottomLeft.addChild(mapButton);
mapButton.x = 100;
mapButton.y = -50;
mapText = new Text2('MAP: ' + maps[currentMap].name, {
size: 20,
fill: 0xFFFFFF
});
mapText.anchor.set(0.5, 0.5);
LK.gui.bottomLeft.addChild(mapText);
mapText.x = 100;
mapText.y = -50;
// Create footprint function
function createFootprint(x, y) {
var footprint = game.addChild(new Footprint());
footprint.x = x;
footprint.y = y;
footprints.push(footprint);
}
// Function to switch maps
function switchToMap(mapIndex) {
currentMap = mapIndex;
var mapData = maps[currentMap];
// Update background color
game.setBackgroundColor(mapData.backgroundColor);
// Clear existing environment
for (var i = trees.length - 1; i >= 0; i--) {
if (trees[i].parent) {
trees[i].destroy();
}
}
trees = [];
// Clear existing animals
for (var i = animals.length - 1; i >= 0; i--) {
if (animals[i].parent) {
animals[i].destroy();
}
}
animals = [];
// Clear footprints
for (var i = footprints.length - 1; i >= 0; i--) {
if (footprints[i].parent) {
footprints[i].destroy();
}
}
footprints = [];
// Create new environment
createMapEnvironment(mapData);
// Update UI
mapText.setText('MAP: ' + mapData.name);
// Reset hunter position
hunter.x = 1024;
hunter.y = 1366;
// Reset dog position near hunter
if (huntingDog) {
huntingDog.x = hunter.x + 50;
huntingDog.y = hunter.y + 30;
huntingDog.energy = 100;
huntingDog.targetAnimal = null;
}
}
// Function to create environment for current map
function createMapEnvironment(mapData) {
// Create trees
for (var i = 0; i < mapData.treeCount; i++) {
var tree = game.addChild(LK.getAsset('tree', {
anchorX: 0.5,
anchorY: 1.0
}));
tree.x = Math.random() * 1948 + 50;
tree.y = Math.random() * 2582 + 100;
// Apply map-specific tinting
if (currentMap === 1) {
// Desert
tree.tint = 0xD2B48C; // Sandy brown
} else if (currentMap === 2) {
// Arctic
tree.tint = 0xC0C0C0; // Silver/white
}
trees.push(tree);
}
// Add bushes
for (var i = 0; i < mapData.bushCount; i++) {
var bush = game.addChild(LK.getAsset('bush', {
anchorX: 0.5,
anchorY: 0.5
}));
bush.x = Math.random() * 1948 + 50;
bush.y = Math.random() * 2582 + 100;
// Apply map-specific tinting
if (currentMap === 1) {
// Desert
bush.tint = 0xDAA520; // Golden rod
} else if (currentMap === 2) {
// Arctic
bush.tint = 0xF0F8FF; // Alice blue
}
}
// Spawn animals for this map
for (var i = 0; i < mapData.animalCount; i++) {
var animalType = mapData.animals[Math.floor(Math.random() * mapData.animals.length)];
var animal = game.addChild(new Animal(animalType));
animal.x = Math.random() * 1848 + 100;
animal.y = Math.random() * 2482 + 100;
// Reset visibility for new map
animal.isDiscoveredByDog = false;
animal.graphics.visible = false;
animal.graphics.alpha = 1.0; // Reset transparency
animal.visibilityTimer = 0; // Reset visibility timer
animal.isFadingOut = false; // Reset fading flag
animals.push(animal);
}
}
// Shop item effects function
function applyItemEffect(shopItem) {
var effect = shopItem.effect;
var type = shopItem.type;
if (type === 'consumable') {
if (effect === 'stamina') {
hunter.stamina = 100;
} else if (effect === 'hunger') {
hunter.hunger = 100;
}
} else if (type === 'equipment' || type === 'weapon') {
if (effect === 'accuracy') {
hunter.accuracy = Math.min(100, hunter.accuracy + 20);
} else if (effect === 'stealth') {
hunter.stealth = Math.min(100, hunter.stealth + 25);
} else if (effect === 'tracking') {
hunter.tracking = Math.min(100, hunter.tracking + 15);
}
}
}
// Function to award coins for hunting
function awardCoins(animalType) {
var coinReward = 5;
if (animalType === 'deer') coinReward = 10;else if (animalType === 'boar') coinReward = 15;else if (animalType === 'wolf') coinReward = 25;
playerCoins += coinReward;
coinText.setText('Coins: ' + playerCoins);
// Create coin visual effect
var coinEffect = game.addChild(LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
}));
coinEffect.x = hunter.x;
coinEffect.y = hunter.y - 50;
// Animate coin moving up and fading
tween(coinEffect, {
y: coinEffect.y - 100,
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
if (coinEffect.parent) {
coinEffect.destroy();
}
}
});
}
// Shooting function
function shootAtTarget(targetX, targetY) {
if (hunter.stamina < 10) return;
hunter.stamina -= 10;
LK.getSound('gunshot').play();
// Check if shot is blocked by trees
var shotBlocked = false;
for (var t = 0; t < trees.length; t++) {
var tree = trees[t];
// Calculate if the shot line intersects with the tree
var dx = targetX - hunter.x;
var dy = targetY - hunter.y;
var shotLength = Math.sqrt(dx * dx + dy * dy);
// Normalize the shot direction
var shotDirX = dx / shotLength;
var shotDirY = dy / shotLength;
// Check multiple points along the shot path
for (var step = 0; step < shotLength; step += 10) {
var checkX = hunter.x + shotDirX * step;
var checkY = hunter.y + shotDirY * step;
var treeDistance = Math.sqrt(Math.pow(checkX - tree.x, 2) + Math.pow(checkY - tree.y, 2));
if (treeDistance < 50) {
// Tree collision radius
shotBlocked = true;
break;
}
}
if (shotBlocked) break;
}
// If shot is blocked, don't check for animal hits
if (shotBlocked) {
return;
}
// Check if we hit any animals
for (var i = animals.length - 1; i >= 0; i--) {
var animal = animals[i];
var distance = Math.sqrt(Math.pow(animal.x - targetX, 2) + Math.pow(animal.y - targetY, 2));
if (distance < 60) {
// Hit!
animal.isAlive = false;
animal.graphics.alpha = 0.5;
// Award points based on animal type
var points = 10;
if (animal.animalType === 'deer') points = 20;else if (animal.animalType === 'boar') points = 30;else if (animal.animalType === 'wolf') points = 50;
gameScore += points;
LK.setScore(gameScore);
scoreText.setText('Score: ' + gameScore);
// Award coins
awardCoins(animal.animalType);
// Flash effect
LK.effects.flashObject(animal, 0xff0000, 500);
// Remove animal after delay
LK.setTimeout(function () {
if (animal.parent) {
animal.destroy();
for (var j = animals.length - 1; j >= 0; j--) {
if (animals[j] === animal) {
animals.splice(j, 1);
break;
}
}
}
}, 1000);
break;
}
}
}
// Movement handling
var targetX = hunter.x;
var targetY = hunter.y;
var isMovingToTarget = false;
function handleMove(x, y, obj) {
targetX = x;
targetY = y;
isMovingToTarget = true;
}
game.move = handleMove;
game.down = function (x, y, obj) {
// Convert to GUI coordinates for shop button check - with null check
if (obj && obj.parent && obj.position) {
var guiPos = LK.gui.bottomRight.toLocal(obj.parent.toGlobal(obj.position));
// Check if shop button was clicked
if (guiPos.x >= -175 && guiPos.x <= -25 && guiPos.y >= -75 && guiPos.y <= -25) {
console.log("Shop button clicked!");
if (!shop.isOpen) {
shop.open();
console.log("Shop opened, visible:", shop.visible);
}
return;
}
// Check if map button was clicked
var mapGuiPos = LK.gui.bottomLeft.toLocal(obj.parent.toGlobal(obj.position));
if (mapGuiPos.x >= 25 && mapGuiPos.x <= 175 && mapGuiPos.y >= -75 && mapGuiPos.y <= -25) {
console.log("Map button clicked!");
currentMap = (currentMap + 1) % maps.length;
switchToMap(currentMap);
LK.effects.flashObject(mapButton, 0x00FF00, 300);
return;
}
}
// Check if clicking on the dog to give it rest command
var dogDistance = Math.sqrt(Math.pow(huntingDog.x - x, 2) + Math.pow(huntingDog.y - y, 2));
if (dogDistance < 60) {
huntingDog.rest();
LK.effects.flashObject(huntingDog, 0x00FF00, 300);
return;
}
if (isAiming) {
shootAtTarget(x, y);
isAiming = false;
} else {
isAiming = true;
LK.setTimeout(function () {
isAiming = false;
}, 2000);
}
};
// Main game update loop
game.update = function () {
// Update day/night cycle
dayTime += 0.5; // 0.5 minutes per frame at 60fps = 48 minutes real time for full day
if (dayTime >= 1440) dayTime = 0;
// Update time display
var hour = Math.floor(dayTime / 60);
var timeOfDay = '';
if (hour >= 5 && hour < 12) timeOfDay = 'Morning';else if (hour >= 12 && hour < 18) timeOfDay = 'Afternoon';else if (hour >= 18 && hour < 21) timeOfDay = 'Evening';else timeOfDay = 'Night';
timeText.setText(timeOfDay + ' (' + hour + ':' + Math.floor(dayTime % 60).toString().padStart(2, '0') + ')');
// Move hunter towards target
if (isMovingToTarget) {
var dx = targetX - hunter.x;
var dy = targetY - hunter.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
var moveSpeed = 3;
hunter.x += dx / distance * moveSpeed;
hunter.y += dy / distance * moveSpeed;
// Consume stamina while moving
if (LK.ticks % 10 === 0) {
hunter.stamina = Math.max(0, hunter.stamina - 0.5);
hunter.hunger = Math.max(0, hunter.hunger - 0.1);
}
// Play footstep sound occasionally
if (LK.ticks % 30 === 0) {
LK.getSound('footstep').play();
}
} else {
isMovingToTarget = false;
}
}
// Regenerate stamina when not moving
if (!isMovingToTarget && hunter.stamina < 100) {
hunter.stamina += 0.2;
}
// Update UI bars
staminaBar.scaleX = hunter.stamina / 100;
hungerBar.scaleX = hunter.hunger / 100;
dogEnergyBar.scaleX = huntingDog.energy / 100;
// Update hunting dog
if (huntingDog) {
huntingDog.update();
}
// Update animals
for (var i = 0; i < animals.length; i++) {
animals[i].update();
}
// Update footprints
for (var i = 0; i < footprints.length; i++) {
footprints[i].update();
}
// Spawn new animals occasionally
var mapData = maps[currentMap];
if (animals.length < mapData.animalCount && LK.ticks % 600 === 0) {
var animalType = mapData.animals[Math.floor(Math.random() * mapData.animals.length)];
var animal = game.addChild(new Animal(animalType));
animal.x = Math.random() * 1848 + 100;
animal.y = Math.random() * 2482 + 100;
// Start new animals as invisible until dog finds them
animal.isDiscoveredByDog = false;
animal.graphics.visible = false;
animal.graphics.alpha = 1.0; // Reset transparency
animal.visibilityTimer = 0; // Reset visibility timer
animal.isFadingOut = false; // Reset fading flag
animals.push(animal);
}
// Game over condition - if hunter runs out of stamina and hunger
if (hunter.stamina <= 0 && hunter.hunger <= 0) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -183,8 +183,12 @@
self.targetX = 0;
self.targetY = 0;
self.lastX = self.x;
self.lastY = self.y;
+ // Walking animation properties
+ self.isWalking = false;
+ self.walkAnimationOffset = 0;
+ self.walkAnimationSpeed = 0.2;
self.update = function () {
if (self.energy <= 0) return;
// Check for nearby animals to chase
var closestAnimal = null;
@@ -381,8 +385,20 @@
var movement = Math.sqrt(Math.pow(self.x - self.lastX, 2) + Math.pow(self.y - self.lastY, 2));
if (movement < 1 && self.energy < 100) {
self.energy += 0.15;
}
+ // Walking animation logic
+ var currentlyWalking = movement > 0.5; // Dog is walking if movement is significant
+ // Start walking animation when movement begins
+ if (!self.isWalking && currentlyWalking) {
+ self.isWalking = true;
+ self.startWalkAnimation();
+ }
+ // Stop walking animation when movement stops
+ else if (self.isWalking && !currentlyWalking) {
+ self.isWalking = false;
+ self.stopWalkAnimation();
+ }
self.lastX = self.x;
self.lastY = self.y;
};
self.alertToAnimal = function () {
@@ -411,8 +427,55 @@
self.rest = function () {
// Dog rests and recovers energy faster
self.energy = Math.min(100, self.energy + 2);
};
+ self.startWalkAnimation = function () {
+ // Create a continuous bobbing animation while walking
+ self.walkAnimationLoop();
+ };
+ self.stopWalkAnimation = function () {
+ // Stop the walking animation and return to normal position
+ tween.stop(self.graphics, {
+ y: true,
+ scaleY: true
+ });
+ tween(self.graphics, {
+ y: 0,
+ scaleY: 1.0
+ }, {
+ duration: 200,
+ easing: tween.easeOut
+ });
+ };
+ self.walkAnimationLoop = function () {
+ if (!self.isWalking) return; // Stop if no longer walking
+ // Create bobbing motion with slight scale changes to simulate walking
+ tween(self.graphics, {
+ y: -3,
+ scaleY: 0.95
+ }, {
+ duration: 300,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ if (self.isWalking) {
+ // Bounce back down
+ tween(self.graphics, {
+ y: 0,
+ scaleY: 1.05
+ }, {
+ duration: 300,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ // Continue the loop if still walking
+ if (self.isWalking) {
+ self.walkAnimationLoop();
+ }
+ }
+ });
+ }
+ }
+ });
+ };
return self;
});
var Shop = Container.expand(function () {
var self = Container.call(this);
Wild Boar. In-Game asset. 2d. High contrast. No shadows
Bush. In-Game asset. 2d. High contrast. No shadows
Tree. In-Game asset. 2d. High contrast. No shadows
Deer. In-Game asset. 2d. High contrast. No shadows
Hunter. In-Game asset. 2d. High contrast. No shadows
Rifle. In-Game asset. 2d. High contrast. No shadows
Wolf. In-Game asset. 2d. High contrast. No shadows
Rabbit. High contrast. No shadows
Coin. In-Game asset. 2d. High contrast. No shadows
Animal Footprint. High contrast. No shadows
Shop Button. In-Game asset. 2d. High contrast. No shadows
Duck Flying. In-Game asset. 2d. No shadows