/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Barrier = Container.expand(function () { var self = Container.call(this); var barrierGraphics = self.attachAsset('barrier', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var Deer = Container.expand(function () { var self = Container.call(this); var deerGraphics = self.attachAsset('deer', { anchorX: 0.5, anchorY: 0.5 }); self.baseSpeed = 40; self.currentSpeed = self.baseSpeed; self.directionX = 1; self.directionY = 0; self.changeDirectionTimer = 0; self.evasiveness = 1; self.update = function () { // Calculate distance to truck for perception var distanceToTruck = Math.sqrt(Math.pow(truck.x - self.x, 2) + Math.pow(truck.y - self.y, 2)); var perceptionRadius = 300 + self.evasiveness * 50; // Calculate speed reduction based on truck speed - faster truck = slower deer var speedReduction = Math.max(0, (truckSpeed - 2) * 8); // Considerable reduction var adjustedBaseSpeed = Math.max(5, self.baseSpeed - speedReduction); // If truck is within perception range, flee if (distanceToTruck < perceptionRadius) { // Calculate direction away from truck var fleeX = self.x - truck.x; var fleeY = self.y - truck.y; // Normalize flee direction var fleeLength = Math.sqrt(fleeX * fleeX + fleeY * fleeY); if (fleeLength > 0) { fleeX = fleeX / fleeLength; fleeY = fleeY / fleeLength; } // Set direction to flee from truck self.directionX = fleeX; self.directionY = fleeY; // Increase speed when fleeing (but still affected by truck speed) self.currentSpeed = adjustedBaseSpeed + self.evasiveness * 2; } else { // Normal behavior when truck is far - move straight down the road self.directionX = 0; // Stay centered on road self.directionY = 1; // Move down the road self.currentSpeed = adjustedBaseSpeed + self.evasiveness * 1.5; } // Move deer self.x += self.directionX * self.currentSpeed; self.y += self.directionY * self.currentSpeed; // Keep deer on road with preference for road boundaries var roadCenterX = 1024; var roadWidth = 350; var roadLeft = roadCenterX - roadWidth / 2; var roadRight = roadCenterX + roadWidth / 2; // Boundary check with road preference if (self.x < roadLeft - 50) { self.x = roadLeft - 50; self.directionX = Math.abs(self.directionX); } if (self.x > roadRight + 50) { self.x = roadRight + 50; self.directionX = -Math.abs(self.directionX); } if (self.y < 100) { self.y = 100; self.directionY = Math.abs(self.directionY); } // Allow deer to continue past the top if (self.y < 100) { self.y = 100; self.directionY = Math.abs(self.directionY); } // Bias deer movement towards staying on road if (self.x < roadLeft || self.x > roadRight) { // If off road, guide back to road if (self.x < roadLeft) { self.directionX += 0.1; } else { self.directionX -= 0.1; } } }; self.increaseEvasiveness = function () { self.evasiveness += 0.5; self.currentSpeed = self.baseSpeed + self.evasiveness * 1.5; }; self.escape = function () { // Deer escapes by running down the road var roadCenterX = 1024; // Position deer at center of road without randomness self.x = roadCenterX; // Move further down the road by fixed amount self.y = self.y + 400; // Set direction to run straight down the road self.directionX = 0; // No horizontal movement self.directionY = 1; // Moving down the road // Flash effect when escaping LK.effects.flashObject(self, 0xffff00, 500); }; self.teleport = function () { // Store original position for tween effect var originalAlpha = self.alpha; // Fade out effect tween(self, { alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Teleport to new position ahead of truck on road var roadCenterX = 1024; self.x = roadCenterX; self.y = truck.y - 600; // Position deer ahead of truck, not at top // Reset direction to move straight down road self.directionX = 0; self.directionY = 1; // Fade back in with flash effect tween(self, { alpha: originalAlpha }, { duration: 300, easing: tween.easeIn, onFinish: function onFinish() { LK.effects.flashObject(self, 0x00ffff, 400); } }); } }); }; return self; }); var Road = Container.expand(function () { var self = Container.call(this); var roadGraphics = self.attachAsset('road', { 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: 0.5 }); return self; }); var Truck = Container.expand(function () { var self = Container.call(this); var truckGraphics = self.attachAsset('truck', { anchorX: 0.5, anchorY: 0.5 }); var personGraphics = self.attachAsset('person', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -14 }); self.speed = 100; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x228b22 }); /**** * Game Code ****/ // Game variables var truck; var deer; var roads = []; var barrier; var lastIntersecting = false; var lastBarrierIntersecting = false; var hitCount = 0; var targetScore = 0; // Create the long road system for (var r = 0; r < 7; r++) { var road = game.addChild(new Road()); road.x = 1024; // Center horizontally road.y = r * 2732; roads.push(road); } // Change background to grass game.setBackgroundColor(0x228b22); // Create score display var scoreTxt = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Create target display var targetTxt = new Text2('Target: ' + targetScore, { size: 60, fill: 0xFFFF00 }); targetTxt.anchor.set(1, 0); targetTxt.x = -20; targetTxt.y = 100; LK.gui.topRight.addChild(targetTxt); // Create speedometer display var speedometerTxt = new Text2('Speed: 100', { size: 60, fill: 0x00FF00 }); speedometerTxt.anchor.set(0, 0); speedometerTxt.x = 120; speedometerTxt.y = 20; LK.gui.topLeft.addChild(speedometerTxt); // Initialize truck at bottom of road truck = game.addChild(new Truck()); truck.x = 1024; truck.y = 2600; // Initialize deer in front of truck on road deer = game.addChild(new Deer()); deer.x = 1024; deer.y = 2200; // Position deer in front of truck but not too far ahead // Initialize barrier at top of screen barrier = game.addChild(new Barrier()); barrier.x = 1024; barrier.y = 50; // Position at very top of screen // Touch controls for acceleration var truckSpeed = 2; var maxSpeed = 8; var isAccelerating = false; game.down = function (x, y, obj) { isAccelerating = true; }; game.up = function (x, y, obj) { isAccelerating = false; }; // Main game loop game.update = function () { // Handle truck acceleration and movement if (isAccelerating && truckSpeed < maxSpeed) { truckSpeed += 0.2; } else if (!isAccelerating && truckSpeed > 2) { truckSpeed -= 0.1; } // Update speedometer display - show speed based on truck movement var displaySpeed = Math.round(100 + (truckSpeed - 2) * 25); // Base 100, increases with truck speed speedometerTxt.setText('Speed: ' + displaySpeed); // Move truck forward on road automatically truck.y -= truckSpeed; // Keep truck within road bounds horizontally var roadCenterX = 1024; var roadWidth = 350; var roadLeft = roadCenterX - roadWidth / 2; var roadRight = roadCenterX + roadWidth / 2; if (truck.x < roadLeft) truck.x = roadLeft; if (truck.x > roadRight) truck.x = roadRight; // Allow truck to continue past the top - removed boundary restriction // Keep barrier at fixed position at end of road (top of first road segment) barrier.y = 50; // Fixed position at top of road system // Maintain distance behind deer when deer teleports if (deer.y < truck.y - 1000) { // Deer has moved far ahead, adjust truck position to maintain chase truck.y = deer.y + 400; // Keep truck behind deer at reasonable distance truck.x = 1024; // Center truck on road } // Check collision between truck and deer var currentIntersecting = truck.intersects(deer); if (!lastIntersecting && currentIntersecting) { // Hit detected! hitCount++; LK.setScore(hitCount); scoreTxt.setText('Score: ' + hitCount); // Play hit sound LK.getSound('hit').play(); // Flash screen briefly LK.effects.flashScreen(0xff0000, 300); // Make deer more evasive deer.increaseEvasiveness(); // Deer escapes to new position deer.escape(); // Play escape sound LK.getSound('escape').play(); // Check win condition if (hitCount >= targetScore) { LK.showYouWin(); } } lastIntersecting = currentIntersecting; // Check collision between deer and barrier var currentBarrierIntersecting = deer.intersects(barrier); if (!lastBarrierIntersecting && currentBarrierIntersecting) { // Deer hit barrier - teleport both back to bottom with tween effect tween(deer, { alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { deer.x = 1024; deer.y = 2200; deer.directionX = 0; deer.directionY = 1; tween(deer, { alpha: 1 }, { duration: 300, easing: tween.easeIn }); } }); tween(truck, { alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { truck.x = 1024; truck.y = 2600; tween(truck, { alpha: 1 }, { duration: 300, easing: tween.easeIn }); } }); } lastBarrierIntersecting = currentBarrierIntersecting; // Check if deer is approaching the end of the road and add more road segments var lastRoad = roads[roads.length - 1]; var distanceToEnd = lastRoad.y + 1366 - deer.y; // Half road height from deer to road end if (distanceToEnd < 1000) { // When deer is within 1000 pixels of road end // Add new road segments ahead for (var i = 0; i < 3; i++) { var newRoad = game.addChild(new Road()); newRoad.x = 1024; // Center horizontally newRoad.y = roads[roads.length - 1].y + 2732; // Position after last road roads.push(newRoad); } } // Remove old road segments that are far behind to prevent memory issues for (var r = roads.length - 1; r >= 0; r--) { if (roads[r].y < deer.y - 3000) { // If road is 3000 pixels behind deer roads[r].destroy(); roads.splice(r, 1); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Barrier = Container.expand(function () {
var self = Container.call(this);
var barrierGraphics = self.attachAsset('barrier', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Deer = Container.expand(function () {
var self = Container.call(this);
var deerGraphics = self.attachAsset('deer', {
anchorX: 0.5,
anchorY: 0.5
});
self.baseSpeed = 40;
self.currentSpeed = self.baseSpeed;
self.directionX = 1;
self.directionY = 0;
self.changeDirectionTimer = 0;
self.evasiveness = 1;
self.update = function () {
// Calculate distance to truck for perception
var distanceToTruck = Math.sqrt(Math.pow(truck.x - self.x, 2) + Math.pow(truck.y - self.y, 2));
var perceptionRadius = 300 + self.evasiveness * 50;
// Calculate speed reduction based on truck speed - faster truck = slower deer
var speedReduction = Math.max(0, (truckSpeed - 2) * 8); // Considerable reduction
var adjustedBaseSpeed = Math.max(5, self.baseSpeed - speedReduction);
// If truck is within perception range, flee
if (distanceToTruck < perceptionRadius) {
// Calculate direction away from truck
var fleeX = self.x - truck.x;
var fleeY = self.y - truck.y;
// Normalize flee direction
var fleeLength = Math.sqrt(fleeX * fleeX + fleeY * fleeY);
if (fleeLength > 0) {
fleeX = fleeX / fleeLength;
fleeY = fleeY / fleeLength;
}
// Set direction to flee from truck
self.directionX = fleeX;
self.directionY = fleeY;
// Increase speed when fleeing (but still affected by truck speed)
self.currentSpeed = adjustedBaseSpeed + self.evasiveness * 2;
} else {
// Normal behavior when truck is far - move straight down the road
self.directionX = 0; // Stay centered on road
self.directionY = 1; // Move down the road
self.currentSpeed = adjustedBaseSpeed + self.evasiveness * 1.5;
}
// Move deer
self.x += self.directionX * self.currentSpeed;
self.y += self.directionY * self.currentSpeed;
// Keep deer on road with preference for road boundaries
var roadCenterX = 1024;
var roadWidth = 350;
var roadLeft = roadCenterX - roadWidth / 2;
var roadRight = roadCenterX + roadWidth / 2;
// Boundary check with road preference
if (self.x < roadLeft - 50) {
self.x = roadLeft - 50;
self.directionX = Math.abs(self.directionX);
}
if (self.x > roadRight + 50) {
self.x = roadRight + 50;
self.directionX = -Math.abs(self.directionX);
}
if (self.y < 100) {
self.y = 100;
self.directionY = Math.abs(self.directionY);
}
// Allow deer to continue past the top
if (self.y < 100) {
self.y = 100;
self.directionY = Math.abs(self.directionY);
}
// Bias deer movement towards staying on road
if (self.x < roadLeft || self.x > roadRight) {
// If off road, guide back to road
if (self.x < roadLeft) {
self.directionX += 0.1;
} else {
self.directionX -= 0.1;
}
}
};
self.increaseEvasiveness = function () {
self.evasiveness += 0.5;
self.currentSpeed = self.baseSpeed + self.evasiveness * 1.5;
};
self.escape = function () {
// Deer escapes by running down the road
var roadCenterX = 1024;
// Position deer at center of road without randomness
self.x = roadCenterX;
// Move further down the road by fixed amount
self.y = self.y + 400;
// Set direction to run straight down the road
self.directionX = 0; // No horizontal movement
self.directionY = 1; // Moving down the road
// Flash effect when escaping
LK.effects.flashObject(self, 0xffff00, 500);
};
self.teleport = function () {
// Store original position for tween effect
var originalAlpha = self.alpha;
// Fade out effect
tween(self, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Teleport to new position ahead of truck on road
var roadCenterX = 1024;
self.x = roadCenterX;
self.y = truck.y - 600; // Position deer ahead of truck, not at top
// Reset direction to move straight down road
self.directionX = 0;
self.directionY = 1;
// Fade back in with flash effect
tween(self, {
alpha: originalAlpha
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
LK.effects.flashObject(self, 0x00ffff, 400);
}
});
}
});
};
return self;
});
var Road = Container.expand(function () {
var self = Container.call(this);
var roadGraphics = self.attachAsset('road', {
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: 0.5
});
return self;
});
var Truck = Container.expand(function () {
var self = Container.call(this);
var truckGraphics = self.attachAsset('truck', {
anchorX: 0.5,
anchorY: 0.5
});
var personGraphics = self.attachAsset('person', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -14
});
self.speed = 100;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x228b22
});
/****
* Game Code
****/
// Game variables
var truck;
var deer;
var roads = [];
var barrier;
var lastIntersecting = false;
var lastBarrierIntersecting = false;
var hitCount = 0;
var targetScore = 0;
// Create the long road system
for (var r = 0; r < 7; r++) {
var road = game.addChild(new Road());
road.x = 1024; // Center horizontally
road.y = r * 2732;
roads.push(road);
}
// Change background to grass
game.setBackgroundColor(0x228b22);
// Create score display
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create target display
var targetTxt = new Text2('Target: ' + targetScore, {
size: 60,
fill: 0xFFFF00
});
targetTxt.anchor.set(1, 0);
targetTxt.x = -20;
targetTxt.y = 100;
LK.gui.topRight.addChild(targetTxt);
// Create speedometer display
var speedometerTxt = new Text2('Speed: 100', {
size: 60,
fill: 0x00FF00
});
speedometerTxt.anchor.set(0, 0);
speedometerTxt.x = 120;
speedometerTxt.y = 20;
LK.gui.topLeft.addChild(speedometerTxt);
// Initialize truck at bottom of road
truck = game.addChild(new Truck());
truck.x = 1024;
truck.y = 2600;
// Initialize deer in front of truck on road
deer = game.addChild(new Deer());
deer.x = 1024;
deer.y = 2200; // Position deer in front of truck but not too far ahead
// Initialize barrier at top of screen
barrier = game.addChild(new Barrier());
barrier.x = 1024;
barrier.y = 50; // Position at very top of screen
// Touch controls for acceleration
var truckSpeed = 2;
var maxSpeed = 8;
var isAccelerating = false;
game.down = function (x, y, obj) {
isAccelerating = true;
};
game.up = function (x, y, obj) {
isAccelerating = false;
};
// Main game loop
game.update = function () {
// Handle truck acceleration and movement
if (isAccelerating && truckSpeed < maxSpeed) {
truckSpeed += 0.2;
} else if (!isAccelerating && truckSpeed > 2) {
truckSpeed -= 0.1;
}
// Update speedometer display - show speed based on truck movement
var displaySpeed = Math.round(100 + (truckSpeed - 2) * 25); // Base 100, increases with truck speed
speedometerTxt.setText('Speed: ' + displaySpeed);
// Move truck forward on road automatically
truck.y -= truckSpeed;
// Keep truck within road bounds horizontally
var roadCenterX = 1024;
var roadWidth = 350;
var roadLeft = roadCenterX - roadWidth / 2;
var roadRight = roadCenterX + roadWidth / 2;
if (truck.x < roadLeft) truck.x = roadLeft;
if (truck.x > roadRight) truck.x = roadRight;
// Allow truck to continue past the top - removed boundary restriction
// Keep barrier at fixed position at end of road (top of first road segment)
barrier.y = 50; // Fixed position at top of road system
// Maintain distance behind deer when deer teleports
if (deer.y < truck.y - 1000) {
// Deer has moved far ahead, adjust truck position to maintain chase
truck.y = deer.y + 400; // Keep truck behind deer at reasonable distance
truck.x = 1024; // Center truck on road
}
// Check collision between truck and deer
var currentIntersecting = truck.intersects(deer);
if (!lastIntersecting && currentIntersecting) {
// Hit detected!
hitCount++;
LK.setScore(hitCount);
scoreTxt.setText('Score: ' + hitCount);
// Play hit sound
LK.getSound('hit').play();
// Flash screen briefly
LK.effects.flashScreen(0xff0000, 300);
// Make deer more evasive
deer.increaseEvasiveness();
// Deer escapes to new position
deer.escape();
// Play escape sound
LK.getSound('escape').play();
// Check win condition
if (hitCount >= targetScore) {
LK.showYouWin();
}
}
lastIntersecting = currentIntersecting;
// Check collision between deer and barrier
var currentBarrierIntersecting = deer.intersects(barrier);
if (!lastBarrierIntersecting && currentBarrierIntersecting) {
// Deer hit barrier - teleport both back to bottom with tween effect
tween(deer, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
deer.x = 1024;
deer.y = 2200;
deer.directionX = 0;
deer.directionY = 1;
tween(deer, {
alpha: 1
}, {
duration: 300,
easing: tween.easeIn
});
}
});
tween(truck, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
truck.x = 1024;
truck.y = 2600;
tween(truck, {
alpha: 1
}, {
duration: 300,
easing: tween.easeIn
});
}
});
}
lastBarrierIntersecting = currentBarrierIntersecting;
// Check if deer is approaching the end of the road and add more road segments
var lastRoad = roads[roads.length - 1];
var distanceToEnd = lastRoad.y + 1366 - deer.y; // Half road height from deer to road end
if (distanceToEnd < 1000) {
// When deer is within 1000 pixels of road end
// Add new road segments ahead
for (var i = 0; i < 3; i++) {
var newRoad = game.addChild(new Road());
newRoad.x = 1024; // Center horizontally
newRoad.y = roads[roads.length - 1].y + 2732; // Position after last road
roads.push(newRoad);
}
}
// Remove old road segments that are far behind to prevent memory issues
for (var r = roads.length - 1; r >= 0; r--) {
if (roads[r].y < deer.y - 3000) {
// If road is 3000 pixels behind deer
roads[r].destroy();
roads.splice(r, 1);
}
}
};