User prompt
fix the roads wo show properly road intersections and regular roads with correct orientation
User prompt
rotate road again when only have road neighbors up and down, create an asset for road intersections
User prompt
rotate road asset when right or left nieghbor road assets are next to them ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
fix the cars to move in sttight line trying to follow the path ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
remove the street block that is below the houses
User prompt
add the street blocks below each house, the road assets fix it to make it look like it where different roads, add some street block to make it more City alike
User prompt
create the asset for street block
User prompt
create blocks where the houses spawn, cars only spawn on road asset and cann not get inside of the street block
User prompt
create a life counter of 3 lifes, game over when lifes end or time runs out, add another power up for 1+ life ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
create different assets for each power up
User prompt
prevent the splayer to spawn overlaping a house
User prompt
make 15% bigger every asset ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
link each package to an especific house, only picking up the correct package to be delivered
User prompt
orientate player sprite to right and left acording mouse direction
User prompt
create different objects for powerups, temporal shield, temporal speed upgrade, add 10 seconds to clock ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
I belive the issue is the house collider is not alowing to player to interact with house and recognizing as delivery succesful
User prompt
player is not being able to deliver package to the house that the arrow points to go, fix that
User prompt
be sure to score and make the delivery succesful when player collide with the correct house
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Arrow = Container.expand(function (targetType) {
var self = Container.call(this);
var arrowGraphics = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 0.5
});
// Set color based on target type
if (targetType === 'pickup') {
arrowGraphics.tint = 0x00ff00; // Green for package pickup
} else if (targetType === 'delivery') {
arrowGraphics.tint = 0xff0000; // Red for delivery house
}
self.targetType = targetType;
self.target = null;
self.update = function () {
if (self.target && player) {
// Calculate direction to target
var dx = self.target.x - player.x;
var dy = self.target.y - player.y;
var angle = Math.atan2(dy, dx);
// Position arrow around player
var radius = 80;
self.x = player.x + Math.cos(angle) * radius;
self.y = player.y + Math.sin(angle) * radius;
// Rotate arrow to point towards target
arrowGraphics.rotation = angle + Math.PI / 2;
// Pulse animation using tween
if (!self.tweening) {
self.tweening = true;
tween(self, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.tweening = false;
}
});
}
});
}
}
};
return self;
});
var Car = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('car', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = (Math.random() - 0.5) * 4;
self.speedY = (Math.random() - 0.5) * 4;
self.update = function () {
var oldX = self.x;
var oldY = self.y;
self.x += self.speedX;
self.y += self.speedY;
// Calculate rotation based on movement direction
// Front of sprite is left side, so 0 rotation = moving left
var targetRotation = Math.atan2(self.speedY, self.speedX) + Math.PI;
// Smooth rotation using tween
tween.stop(carGraphics, {
rotation: true
});
tween(carGraphics, {
rotation: targetRotation
}, {
duration: 200,
easing: tween.easeOut
});
// Check collision with houses
var hitHouse = false;
for (var h = 0; h < houses.length; h++) {
if (self.intersects(houses[h])) {
hitHouse = true;
break;
}
}
// If hit house, revert movement and bounce
if (hitHouse) {
self.x = oldX;
self.y = oldY;
self.speedX *= -1;
self.speedY *= -1;
}
// Bounce off edges
if (self.x < 40 || self.x > 2008) {
self.speedX *= -1;
}
if (self.y < 40 || self.y > 2692) {
self.speedY *= -1;
}
// Keep in bounds
self.x = Math.max(40, Math.min(2008, self.x));
self.y = Math.max(40, Math.min(2692, self.y));
};
return self;
});
var Dog = Container.expand(function () {
var self = Container.call(this);
var dogGraphics = self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.direction = Math.random() * Math.PI * 2;
self.update = function () {
// Check distance to player
var dx = player.x - self.x;
var dy = player.y - self.y;
var distanceToPlayer = Math.sqrt(dx * dx + dy * dy);
var detectionRange = 150;
if (distanceToPlayer < detectionRange && player) {
// Follow player behavior
var angleToPlayer = Math.atan2(dy, dx);
self.direction = angleToPlayer;
self.speed = 2.5; // Slightly faster when chasing
} else {
// Simple AI - change direction occasionally
if (Math.random() < 0.02) {
self.direction = Math.random() * Math.PI * 2;
}
self.speed = 2; // Normal speed when wandering
}
var oldX = self.x;
var oldY = self.y;
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
// Check collision with houses
var hitHouse = false;
for (var h = 0; h < houses.length; h++) {
if (self.intersects(houses[h])) {
hitHouse = true;
break;
}
}
// If hit house, revert movement and change direction
if (hitHouse) {
self.x = oldX;
self.y = oldY;
self.direction = Math.random() * Math.PI * 2;
}
// Bounce off edges
if (self.x < 15 || self.x > 2033) {
self.direction = Math.PI - self.direction;
}
if (self.y < 15 || self.y > 2717) {
self.direction = -self.direction;
}
// Keep in bounds
self.x = Math.max(15, Math.min(2033, self.x));
self.y = Math.max(15, Math.min(2717, self.y));
};
return self;
});
var House = Container.expand(function (houseId) {
var self = Container.call(this);
var houseGraphics = self.attachAsset('house', {
anchorX: 0.5,
anchorY: 0.5
});
self.houseId = houseId;
self.hasDelivery = false;
self.down = function (x, y, obj) {
if (player.hasPackage && self.distanceTo(player) < 80) {
if (player.targetHouse === self.houseId) {
// Correct delivery
LK.setScore(LK.getScore() + 100);
player.hasPackage = false;
player.targetHouse = null;
self.hasDelivery = true;
packagesDelivered++;
// Visual feedback
tween(self, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 200,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
LK.getSound('delivery').play();
scoreText.setText(LK.getScore());
// Remove delivery arrow
if (deliveryArrow) {
deliveryArrow.destroy();
deliveryArrow = null;
}
// Create pickup arrow for next available package
if (packages.length > 0) {
pickupArrow = game.addChild(new Arrow('pickup'));
pickupArrow.target = packages[0];
}
// Check win condition
if (packagesDelivered >= totalPackages) {
if (currentLevel < 4) {
currentLevel++;
startLevel();
} else {
LK.showYouWin();
}
}
} else {
// Wrong delivery
LK.setScore(Math.max(0, LK.getScore() - 50));
scoreText.setText(LK.getScore());
LK.effects.flashObject(self, 0xff0000, 500);
}
}
};
self.distanceTo = function (other) {
var dx = self.x - other.x;
var dy = self.y - other.y;
return Math.sqrt(dx * dx + dy * dy);
};
return self;
});
var Package = Container.expand(function (targetHouseId) {
var self = Container.call(this);
var packageGraphics = self.attachAsset('package', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.targetHouseId = targetHouseId; // Link package to specific house
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 = 5;
self.hasPackage = false;
self.targetHouse = null;
return self;
});
var PowerUp = Container.expand(function (type) {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = type; // 'time', 'speed', 'shield'
self.collected = false;
// Set different colors for different types
if (type === 'time') {
powerupGraphics.tint = 0x00FF00;
} else if (type === 'speed') {
powerupGraphics.tint = 0x0080FF;
} else if (type === 'shield') {
powerupGraphics.tint = 0xFFFF00;
}
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x228B22
});
/****
* Game Code
****/
// Game variables
var player;
var packages = [];
var houses = [];
var cars = [];
var dogs = [];
var powerups = [];
var currentLevel = 1;
var totalPackages = 3;
var packagesDelivered = 0;
var gameTime = 60000; // 60 seconds
var timeRemaining = gameTime;
var dragNode = null;
var lastCollisionCheck = {};
var targetX = null;
var targetY = null;
var isMoving = false;
var pickupArrow = null;
var deliveryArrow = null;
// UI elements
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var timeText = new Text2('Time: 60', {
size: 60,
fill: 0xFFFFFF
});
timeText.anchor.set(1, 0);
LK.gui.topRight.addChild(timeText);
var levelText = new Text2('Level 1', {
size: 60,
fill: 0xFFFFFF
});
levelText.anchor.set(0, 0);
LK.gui.topLeft.addChild(levelText);
// Create road background
for (var i = 0; i < 18; i++) {
for (var j = 0; j < 24; j++) {
var road = LK.getAsset('road', {
x: i * 115,
y: j * 115,
anchorX: 0,
anchorY: 0
});
game.addChild(road);
}
}
function startLevel() {
// Clear existing game objects
for (var i = packages.length - 1; i >= 0; i--) {
packages[i].destroy();
}
for (var i = houses.length - 1; i >= 0; i--) {
houses[i].destroy();
}
for (var i = cars.length - 1; i >= 0; i--) {
cars[i].destroy();
}
for (var i = dogs.length - 1; i >= 0; i--) {
dogs[i].destroy();
}
for (var i = powerups.length - 1; i >= 0; i--) {
powerups[i].destroy();
}
// Clear arrow indicators
if (pickupArrow) {
pickupArrow.destroy();
pickupArrow = null;
}
if (deliveryArrow) {
deliveryArrow.destroy();
deliveryArrow = null;
}
packages = [];
houses = [];
cars = [];
dogs = [];
powerups = [];
packagesDelivered = 0;
// Reset time
timeRemaining = gameTime;
// Update UI
levelText.setText('Level ' + currentLevel);
// Create player if not exists
if (!player) {
player = game.addChild(new Player());
player.x = 1024;
player.y = 2366;
}
player.hasPackage = false;
player.targetHouse = null;
player.hasShield = false;
// Helper function to check if position overlaps with existing houses
function isPositionClear(x, y, minDistance) {
for (var j = 0; j < houses.length; j++) {
var dx = x - houses[j].x;
var dy = y - houses[j].y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance) {
return false;
}
}
return true;
}
// Create packages and houses
totalPackages = 2 + currentLevel;
for (var i = 0; i < totalPackages; i++) {
// Create package with specific target house ID
var pkg = new Package(i);
pkg.x = 200 + Math.random() * 1600;
pkg.y = 200 + Math.random() * 1200;
packages.push(pkg);
game.addChild(pkg);
}
// Create corresponding house with overlap prevention
// Create pickup arrow indicator pointing to first available package
if (packages.length > 0) {
pickupArrow = game.addChild(new Arrow('pickup'));
pickupArrow.target = packages[0];
}
// Create packages and houses
for (var i = 0; i < totalPackages; i++) {
var house = new House(i);
var attempts = 0;
var maxAttempts = 50;
var minHouseDistance = 200; // Minimum distance between houses
do {
house.x = 200 + Math.random() * 1600;
house.y = 1500 + Math.random() * 1000;
attempts++;
} while (!isPositionClear(house.x, house.y, minHouseDistance) && attempts < maxAttempts);
houses.push(house);
game.addChild(house);
}
// Create cars (more with each level)
var numCars = currentLevel + 1;
for (var i = 0; i < numCars; i++) {
var car = new Car();
car.x = Math.random() * 2048;
car.y = Math.random() * 2732;
cars.push(car);
game.addChild(car);
}
// Create dogs
var numDogs = Math.floor(currentLevel / 2) + 1;
for (var i = 0; i < numDogs; i++) {
var dog = new Dog();
dog.x = Math.random() * 2048;
dog.y = Math.random() * 2732;
dogs.push(dog);
game.addChild(dog);
}
// Create power-ups
var powerupTypes = ['time', 'speed', 'shield'];
for (var i = 0; i < 2; i++) {
var powerup = new PowerUp(powerupTypes[Math.floor(Math.random() * powerupTypes.length)]);
powerup.x = Math.random() * 2048;
powerup.y = Math.random() * 2732;
powerups.push(powerup);
game.addChild(powerup);
}
}
function handleMove(x, y, obj) {
// Set target position for smooth movement
targetX = Math.max(30, Math.min(2018, x));
targetY = Math.max(30, Math.min(2702, y));
isMoving = true;
// Orient player sprite based on mouse direction
if (player) {
var dx = targetX - player.x;
if (dx > 0) {
// Moving right - face right (normal orientation)
player.scaleX = 1;
} else if (dx < 0) {
// Moving left - face left (flip horizontally)
player.scaleX = -1;
}
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
// Check if clicking on package to pick up
for (var i = 0; i < packages.length; i++) {
var pkg = packages[i];
if (!pkg.collected && pkg.intersects && player.intersects(pkg)) {
if (!player.hasPackage) {
pkg.collected = true;
pkg.destroy();
packages.splice(i, 1);
player.hasPackage = true;
// Use the package's assigned target house
player.targetHouse = pkg.targetHouseId;
LK.getSound('pickup').play();
// Remove pickup arrow and create delivery arrow
if (pickupArrow) {
pickupArrow.destroy();
pickupArrow = null;
}
// Create delivery arrow pointing to target house
if (player.targetHouse !== null && player.targetHouse < houses.length) {
deliveryArrow = game.addChild(new Arrow('delivery'));
deliveryArrow.target = houses[player.targetHouse];
}
return;
}
}
}
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
// Mouse up - no action needed for smooth movement
};
game.update = function () {
// Smooth player movement towards target
if (isMoving && targetX !== null && targetY !== null) {
var dx = targetX - player.x;
var dy = targetY - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
// Move towards target with player speed
var moveX = dx / distance * player.speed;
var moveY = dy / distance * player.speed;
var oldX = player.x;
var oldY = player.y;
player.x += moveX;
player.y += moveY;
// Check collision with houses
var hitHouse = false;
var hitTargetHouse = false;
for (var h = 0; h < houses.length; h++) {
if (player.intersects(houses[h])) {
hitHouse = true;
// Check if this is the target house for delivery
if (player.hasPackage && player.targetHouse === h) {
hitTargetHouse = true;
}
break;
}
}
// If hit house, revert movement unless it's the target house for delivery
if (hitHouse && !hitTargetHouse) {
player.x = oldX;
player.y = oldY;
isMoving = false; // Stop movement when hitting house
}
} else {
// Close enough to target, stop moving
player.x = targetX;
player.y = targetY;
isMoving = false;
}
}
// Update time
timeRemaining -= 16.67; // Approximate 60fps
var seconds = Math.ceil(timeRemaining / 1000);
timeText.setText('Time: ' + Math.max(0, seconds));
// Check time up
if (timeRemaining <= 0) {
LK.showGameOver();
return;
}
// Check package pickup
for (var i = packages.length - 1; i >= 0; i--) {
var pkg = packages[i];
if (!pkg.collected && player.intersects(pkg)) {
if (!player.hasPackage) {
pkg.collected = true;
pkg.destroy();
packages.splice(i, 1);
player.hasPackage = true;
// Use the package's assigned target house
player.targetHouse = pkg.targetHouseId;
LK.getSound('pickup').play();
// Remove pickup arrow and create delivery arrow
if (pickupArrow) {
pickupArrow.destroy();
pickupArrow = null;
}
// Create delivery arrow pointing to target house
if (player.targetHouse !== null && player.targetHouse < houses.length) {
deliveryArrow = game.addChild(new Arrow('delivery'));
deliveryArrow.target = houses[player.targetHouse];
}
}
}
}
// Check package delivery when player collides with house
if (player.hasPackage && player.targetHouse !== null) {
for (var h = 0; h < houses.length; h++) {
var house = houses[h];
var houseKey = 'house_delivery_' + h;
var currentCollision = player.intersects(house);
if (!lastCollisionCheck[houseKey] && currentCollision) {
// Just started colliding with house
if (player.targetHouse === h) {
// Correct delivery
LK.setScore(LK.getScore() + 100);
player.hasPackage = false;
player.targetHouse = null;
house.hasDelivery = true;
packagesDelivered++;
// Visual feedback
tween(house, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 200,
onFinish: function onFinish() {
tween(house, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
LK.getSound('delivery').play();
scoreText.setText(LK.getScore());
// Remove delivery arrow
if (deliveryArrow) {
deliveryArrow.destroy();
deliveryArrow = null;
}
// Create pickup arrow for next available package
if (packages.length > 0) {
pickupArrow = game.addChild(new Arrow('pickup'));
pickupArrow.target = packages[0];
}
// Check win condition
if (packagesDelivered >= totalPackages) {
if (currentLevel < 4) {
currentLevel++;
startLevel();
} else {
LK.showYouWin();
}
}
break; // Exit loop after successful delivery
} else {
// Wrong delivery
LK.setScore(Math.max(0, LK.getScore() - 50));
scoreText.setText(LK.getScore());
LK.effects.flashObject(house, 0xff0000, 500);
}
}
lastCollisionCheck[houseKey] = currentCollision;
}
}
// Check powerup collection
for (var i = powerups.length - 1; i >= 0; i--) {
var powerup = powerups[i];
if (!powerup.collected && player.intersects(powerup)) {
powerup.collected = true;
powerup.destroy();
powerups.splice(i, 1);
if (powerup.type === 'time') {
timeRemaining += 10000; // Add 10 seconds
} else if (powerup.type === 'speed') {
player.speed = 8;
LK.setTimeout(function () {
player.speed = 5;
}, 5000);
} else if (powerup.type === 'shield') {
player.hasShield = true;
// Visual shield effect
tween(player, {
tint: 0x00FFFF
}, {
duration: 200
});
LK.setTimeout(function () {
player.hasShield = false;
tween(player, {
tint: 0xFFFFFF
}, {
duration: 200
});
}, 8000); // Shield lasts 8 seconds
}
LK.getSound('powerup').play();
LK.setScore(LK.getScore() + 25);
scoreText.setText(LK.getScore());
}
}
// Check collisions with obstacles
for (var i = 0; i < cars.length; i++) {
var car = cars[i];
var carKey = 'car_' + i;
var currentCollision = player.intersects(car);
if (!lastCollisionCheck[carKey] && currentCollision) {
// Just started colliding
if (!player.hasShield) {
LK.setScore(Math.max(0, LK.getScore() - 25));
scoreText.setText(LK.getScore());
LK.effects.flashObject(player, 0xff0000, 500);
}
}
lastCollisionCheck[carKey] = currentCollision;
}
for (var i = 0; i < dogs.length; i++) {
var dog = dogs[i];
var dogKey = 'dog_' + i;
var currentCollision = player.intersects(dog);
if (!lastCollisionCheck[dogKey] && currentCollision) {
// Just started colliding
if (!player.hasShield) {
LK.setScore(Math.max(0, LK.getScore() - 15));
scoreText.setText(LK.getScore());
LK.effects.flashObject(player, 0xff0000, 300);
}
}
lastCollisionCheck[dogKey] = currentCollision;
}
};
// Start the first level
startLevel();
// Play background music
LK.playMusic('bgmusic'); ===================================================================
--- original.js
+++ change.js
@@ -326,13 +326,13 @@
});
levelText.anchor.set(0, 0);
LK.gui.topLeft.addChild(levelText);
// Create road background
-for (var i = 0; i < 21; i++) {
- for (var j = 0; j < 28; j++) {
+for (var i = 0; i < 18; i++) {
+ for (var j = 0; j < 24; j++) {
var road = LK.getAsset('road', {
- x: i * 100,
- y: j * 100,
+ x: i * 115,
+ y: j * 115,
anchorX: 0,
anchorY: 0
});
game.addChild(road);
shield icon inside of a blue energy bubble. In-Game asset. 2d. High contrast. No shadows
1+ up heart icon. In-Game asset. 2d. High contrast. No shadows
fast foward icon. In-Game asset. 2d. High contrast. No shadows
+10 inside of a clock icon. In-Game asset. 2d. High contrast. No shadows
Street block, garden with concrete walkway on the border. In-Game asset. 2d. High contrast. No shadows