User prompt
Let's make the game a bit more agar.io-style, with the courier in the center and the map scrolling. And arrows indicate the pickup and delivery points. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Let's make the game a bit more agar.io-style, with the courier in the center and the map scrolling. And arrows indicate the pickup and delivery points. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
fill all screen with shops and buildings. And change colours orders and customers. Customers colors match the their order color ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
delete gray bars on screen
User prompt
please add another ai couriers and at the start may be more than 1 customer order different foods. And fix the building and shops locations. emptied first row because player cant reach there ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Connect building entrances with buildings. Have couriers pick up and deliver packages. If couriers intersect with each other or the player, they can change their path or turn back and take an alternative route.
User prompt
Please direct the couriers' paths so they don't intersect. They also can't pick up or deliver packages. Please also adjust the height of building entrances to 1px.
User prompt
Other AI couriers are frozen. Could you please take a look at them? They are not doing their job.
User prompt
The neighborhood should be infinite, like going to the far left of the screen and reaching the far right. Like in the game Snake. Packages should keep appearing. Each time a package is completed, a new one is created.
User prompt
At the beginning of the game, there can be multiple packages at the same time, for example, 5 packages. Match the colors of these packages and the customer. Other couriers should not be chasing the same package.
User prompt
Cars should be able to enter the neighborhood. Buildings and shops should have entrances. Couriers should be required to come to the asphalt in front of the entrance to pick up and make deliveries. The red dot representing customers should be located exactly in the middle of the building.
User prompt
Other couriers can only move vertically or horizontally between buildings. They cannot travel diagonally. Their speeds also vary. They can create traffic congestion. Add cars based on the money earned outside of the couriers. Start with 10 cars and increase to 20 cars until you reach $200. Cars, couriers, and the player cannot drive over each other.
User prompt
The size of the buildings should be smaller and the roads should be wider.
User prompt
The order is completed when it arrives at the customer's premises.
User prompt
Buildings should be arranged in an orderly manner. All buildings should have roads around them and these roads should be connected to each other.
User prompt
The neighborhood layout should consist of a 4-block park in the middle and buildings arranged in a non-circular pattern around it.
User prompt
To avoid couriers getting stuck in buildings, designate wider routes and have couriers follow them to reach the customer. They should choose which route to use. However, they must be able to reach the customer. Furthermore, if a package arrives anywhere in the store, it should be picked up and delivered to the customer's location within the building.
User prompt
Couriers do not wander around randomly, they just follow the routes and pick up and deliver the package.
User prompt
The purpose of other couriers is to pick up the order and deliver it to the customer.
User prompt
Customers should only be visible when the order arrives. If the courier doesn't pick up the order, it should disappear after a while. And then there will be new orders and new customers at different locations. Other couriers will be randomly passing through the streets, and they will be competing with us.
User prompt
The package's time starts when the courier receives the package.
User prompt
Please have buildings and shops line up in a circle. Layer by layer, covering the entire screen, with these circles gradually taking on more of the screen shape with each layer. Roads should be asphalt-colored, with no buildings overlapping. Shops and houses should change with each new game.
User prompt
the shops are need to be in a row as circular. And every new game will be changed shops and houses randomly.
User prompt
okay, we need to change the map. I want to make a neighbourhood. Middle of the screen have a park. And houses like a circular plan. and 1 outer layer is circular and have another houses and shops randomly. And i dont want to see gray squares on the screen.
User prompt
please show buildings are with dark blue, shops are orange, order is yellow. And customers must be in buildings. And please allow minimum 25 seconds per order completing.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var AICourier = Container.expand(function () {
var self = Container.call(this);
var courierGraphics = self.attachAsset('courier', {
anchorX: 0.5,
anchorY: 0.5
});
courierGraphics.tint = 0xff4444; // Red tint to distinguish from player
self.speed = 6;
self.targetX = 1024;
self.targetY = 1366;
self.changeTargetTimer = 0;
self.hasOrder = false;
self.targetRestaurant = null;
self.targetCustomer = null;
self.currentWaypoint = 0;
self.routeWaypoints = [];
self.currentPath = [];
self.pathIndex = 0;
self.update = function () {
// Check for orders to pick up if not carrying one
if (!self.hasOrder && currentOrder && !courier.hasOrder && gameState === 'pickup') {
// Check if can pick up from restaurant area (wider pickup zone)
var restaurant = currentOrder.restaurant;
var restaurantDistance = Math.sqrt(Math.pow(restaurant.x - self.x, 2) + Math.pow(restaurant.y - self.y, 2));
if (restaurantDistance < 80) {
// Pick up the order
self.hasOrder = true;
self.targetCustomer = currentOrder.customer;
self.targetRestaurant = currentOrder.restaurant;
// Start the package timer
currentOrder.timerStarted = true;
// Move order with AI courier
currentOrder.x = self.x;
currentOrder.y = self.y - 40;
gameState = 'delivery';
// Clear current path and find new path to customer
self.currentPath = findPath(self.x, self.y, self.targetCustomer.x, self.targetCustomer.y);
self.pathIndex = 0;
} else {
// Find path to restaurant if don't have one or reached end
if (self.currentPath.length === 0 || self.pathIndex >= self.currentPath.length) {
self.currentPath = findPath(self.x, self.y, restaurant.x, restaurant.y);
self.pathIndex = 0;
}
}
} else if (self.hasOrder && self.targetCustomer && currentOrder) {
// AI courier is delivering - check if reached customer building
var customerDistance = Math.sqrt(Math.pow(self.targetCustomer.x - self.x, 2) + Math.pow(self.targetCustomer.y - self.y, 2));
if (customerDistance < 70) {
// Deliver the order
LK.getSound('delivery').play();
self.hasOrder = false;
self.targetCustomer = null;
self.targetRestaurant = null;
self.currentPath = [];
self.pathIndex = 0;
// Complete the delivery (similar to player delivery)
if (currentOrder) {
// Order completed successfully - AI gets the delivery done
var deliveryTime = currentOrder.timeLimit - currentOrder.timeRemaining;
if (currentOrder.timeRemaining > 0) {
// Successful delivery by AI courier
var timeBonus = Math.floor(currentOrder.timeRemaining / 1000);
var bonus = 5 + timeBonus; // AI gets smaller bonus than player
money += bonus;
}
currentOrder.restaurant.hasOrder = false;
currentOrder.customer.waitingForOrder = false;
currentOrder.customer.visible = false;
if (currentOrder.customer.deliveryTarget) {
tween.stop(currentOrder.customer.deliveryTarget);
currentOrder.customer.deliveryTarget.destroy();
currentOrder.customer.deliveryTarget = null;
}
currentOrder.destroy();
for (var i = orders.length - 1; i >= 0; i--) {
if (orders[i] === currentOrder) {
orders.splice(i, 1);
break;
}
}
currentOrder = null;
gameState = 'pickup';
// Create new order after delivery
LK.setTimeout(function () {
createNewOrder();
}, 1000);
}
} else {
// Find path to customer if don't have one or reached end
if (self.currentPath.length === 0 || self.pathIndex >= self.currentPath.length) {
self.currentPath = findPath(self.x, self.y, self.targetCustomer.x, self.targetCustomer.y);
self.pathIndex = 0;
}
}
} else {
// When not carrying order, patrol using route network
if (self.currentPath.length === 0 || self.pathIndex >= self.currentPath.length) {
// Pick a random route node to patrol to
if (routeNodes.length > 0) {
var randomNode = routeNodes[Math.floor(Math.random() * routeNodes.length)];
self.currentPath = findPath(self.x, self.y, randomNode.x, randomNode.y);
self.pathIndex = 0;
}
}
}
// Follow current path
if (self.currentPath.length > 0 && self.pathIndex < self.currentPath.length) {
var targetNode = self.currentPath[self.pathIndex];
self.targetX = targetNode.x;
self.targetY = targetNode.y;
// Check if reached current path node
var nodeDistance = Math.sqrt(Math.pow(targetNode.x - self.x, 2) + Math.pow(targetNode.y - self.y, 2));
if (nodeDistance < 60) {
self.pathIndex++;
}
} else {
// No path or reached end - stay in place
self.targetX = self.x;
self.targetY = self.y;
}
// Move toward target using simple movement with collision detection
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 10) {
var newX = self.x + dx / distance * self.speed;
var newY = self.y + dy / distance * self.speed;
// Check collisions before moving
var canMove = true;
// Check collision with cars
for (var i = 0; i < cars.length; i++) {
var carDx = Math.abs(newX - cars[i].x);
var carDy = Math.abs(newY - cars[i].y);
if (carDx < 50 && carDy < 50) {
canMove = false;
break;
}
}
// Check collision with player courier
var playerDx = Math.abs(newX - courier.x);
var playerDy = Math.abs(newY - courier.y);
if (playerDx < 50 && playerDy < 50) {
canMove = false;
}
// Check collision with other AI couriers
for (var i = 0; i < aiCouriers.length; i++) {
if (aiCouriers[i] === self) continue;
var aiDx = Math.abs(newX - aiCouriers[i].x);
var aiDy = Math.abs(newY - aiCouriers[i].y);
if (aiDx < 50 && aiDy < 50) {
canMove = false;
break;
}
}
if (canMove) {
self.x = newX;
self.y = newY;
}
}
// Update order position if carrying one
if (self.hasOrder && currentOrder) {
currentOrder.x = self.x;
currentOrder.y = self.y - 40;
}
};
return self;
});
var Car = Container.expand(function () {
var self = Container.call(this);
var carGraphics = self.attachAsset('courier', {
anchorX: 0.5,
anchorY: 0.5
});
carGraphics.tint = 0x333333; // Dark gray for cars
carGraphics.scaleX = 0.8;
carGraphics.scaleY = 0.8;
self.speed = 2 + Math.random() * 4; // Speed between 2-6
self.direction = Math.random() < 0.5 ? 'horizontal' : 'vertical';
self.movingPositive = Math.random() < 0.5; // true = right/down, false = left/up
self.targetX = self.x;
self.targetY = self.y;
self.stuckTimer = 0;
self.maxStuckTime = 2000; // 2 seconds before finding new path
self.update = function () {
var oldX = self.x;
var oldY = self.y;
// Move only horizontally or vertically
if (self.direction === 'horizontal') {
if (self.movingPositive) {
self.targetX = self.x + self.speed;
} else {
self.targetX = self.x - self.speed;
}
// Reverse direction at boundaries
if (self.x > 1900 || self.x < 148) {
self.movingPositive = !self.movingPositive;
}
} else {
if (self.movingPositive) {
self.targetY = self.y + self.speed;
} else {
self.targetY = self.y - self.speed;
}
// Reverse direction at boundaries
if (self.y > 2550 || self.y < 182) {
self.movingPositive = !self.movingPositive;
}
}
// Check for collisions before moving
var canMove = true;
var testX = self.targetX;
var testY = self.targetY;
// Check collision with other cars
for (var i = 0; i < cars.length; i++) {
if (cars[i] === self) continue;
var dx = Math.abs(testX - cars[i].x);
var dy = Math.abs(testY - cars[i].y);
if (dx < 50 && dy < 50) {
canMove = false;
break;
}
}
// Check collision with couriers
var courierDx = Math.abs(testX - courier.x);
var courierDy = Math.abs(testY - courier.y);
if (courierDx < 50 && courierDy < 50) {
canMove = false;
}
// Check collision with AI couriers
for (var i = 0; i < aiCouriers.length; i++) {
var aiDx = Math.abs(testX - aiCouriers[i].x);
var aiDy = Math.abs(testY - aiCouriers[i].y);
if (aiDx < 50 && aiDy < 50) {
canMove = false;
break;
}
}
if (canMove) {
self.x = testX;
self.y = testY;
self.stuckTimer = 0;
} else {
// If stuck for too long, change direction
self.stuckTimer += 16.67;
if (self.stuckTimer >= self.maxStuckTime) {
self.movingPositive = !self.movingPositive;
self.stuckTimer = 0;
}
}
};
return self;
});
var Courier = Container.expand(function () {
var self = Container.call(this);
var courierGraphics = self.attachAsset('courier', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.hasOrder = false;
self.targetRestaurant = null;
self.targetCustomer = null;
self.currentPath = [];
self.pathIndex = 0;
self.lastTargetX = 0;
self.lastTargetY = 0;
self.moveToward = function (targetX, targetY) {
// Check if target changed significantly - recalculate path
var targetChanged = Math.abs(targetX - self.lastTargetX) > 50 || Math.abs(targetY - self.lastTargetY) > 50;
if (targetChanged || self.currentPath.length === 0 || self.pathIndex >= self.currentPath.length) {
self.currentPath = findPath(self.x, self.y, targetX, targetY);
self.pathIndex = 0;
self.lastTargetX = targetX;
self.lastTargetY = targetY;
}
// Follow path if available
if (self.currentPath.length > 0 && self.pathIndex < self.currentPath.length) {
var pathTarget = self.currentPath[self.pathIndex];
var dx = pathTarget.x - self.x;
var dy = pathTarget.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Check if reached current path node
if (distance < 60) {
self.pathIndex++;
if (self.pathIndex < self.currentPath.length) {
pathTarget = self.currentPath[self.pathIndex];
dx = pathTarget.x - self.x;
dy = pathTarget.y - self.y;
distance = Math.sqrt(dx * dx + dy * dy);
}
}
if (distance > 10 && self.pathIndex < self.currentPath.length) {
var newX = self.x + dx / distance * self.speed;
var newY = self.y + dy / distance * self.speed;
// Check collisions before moving
var canMove = true;
// Check collision with cars
for (var i = 0; i < cars.length; i++) {
var carDx = Math.abs(newX - cars[i].x);
var carDy = Math.abs(newY - cars[i].y);
if (carDx < 50 && carDy < 50) {
canMove = false;
break;
}
}
// Check collision with AI couriers
for (var i = 0; i < aiCouriers.length; i++) {
var aiDx = Math.abs(newX - aiCouriers[i].x);
var aiDy = Math.abs(newY - aiCouriers[i].y);
if (aiDx < 50 && aiDy < 50) {
canMove = false;
break;
}
}
if (canMove) {
self.x = newX;
self.y = newY;
}
}
} else {
// Direct movement as fallback
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 10) {
var newX = self.x + dx / distance * self.speed;
var newY = self.y + dy / distance * self.speed;
// Check collisions before moving
var canMove = true;
// Check collision with cars
for (var i = 0; i < cars.length; i++) {
var carDx = Math.abs(newX - cars[i].x);
var carDy = Math.abs(newY - cars[i].y);
if (carDx < 50 && carDy < 50) {
canMove = false;
break;
}
}
// Check collision with AI couriers
for (var i = 0; i < aiCouriers.length; i++) {
var aiDx = Math.abs(newX - aiCouriers[i].x);
var aiDy = Math.abs(newY - aiCouriers[i].y);
if (aiDx < 50 && aiDy < 50) {
canMove = false;
break;
}
}
if (canMove) {
self.x = newX;
self.y = newY;
}
}
}
};
return self;
});
var Customer = Container.expand(function () {
var self = Container.call(this);
var customerGraphics = self.attachAsset('customer', {
anchorX: 0.5,
anchorY: 0.5
});
self.waitingForOrder = false;
self.orderTime = 0;
self.maxWaitTime = 10000; // 10 seconds
self.deliveryTarget = null;
self.visible = false; // Start invisible
self.update = function () {
if (self.waitingForOrder) {
self.orderTime += 16.67; // Approximate ms per frame at 60fps
}
};
return self;
});
var Order = Container.expand(function () {
var self = Container.call(this);
var orderGraphics = self.attachAsset('order', {
anchorX: 0.5,
anchorY: 0.5
});
self.restaurant = null;
self.customer = null;
self.timeLimit = 25000; // 25 seconds
self.timeRemaining = self.timeLimit;
self.timerStarted = false; // Timer doesn't start until courier picks up
self.lifeTime = 0; // Track how long order has existed
self.maxLifeTime = 15000; // Order expires after 15 seconds if not picked up
self.update = function () {
if (self.timerStarted && self.timeRemaining > 0) {
self.timeRemaining -= 16.67;
}
// Track order lifetime for auto-expiry
if (!self.timerStarted) {
self.lifeTime += 16.67;
}
};
return self;
});
var PowerUp = Container.expand(function (type) {
var self = Container.call(this);
var powerupGraphics = self.attachAsset(type === 'health' ? 'healthPowerup' : 'timePowerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = type;
self.lifeTime = 0;
self.maxLifeTime = 8000; // 8 seconds
self.update = function () {
self.lifeTime += 16.67;
// Pulse animation
var pulse = 1 + 0.2 * Math.sin(self.lifeTime * 0.01);
powerupGraphics.scaleX = pulse;
powerupGraphics.scaleY = pulse;
};
return self;
});
var Restaurant = Container.expand(function () {
var self = Container.call(this);
var restaurantGraphics = self.attachAsset('restaurant', {
anchorX: 0.5,
anchorY: 0.5
});
self.hasOrder = false;
self.orderReady = false;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x8BC34A
});
/****
* Game Code
****/
// Game variables
var courier;
var aiCouriers = [];
var cars = [];
var restaurants = [];
var customers = [];
var orders = [];
var powerUps = [];
var buildings = [];
var health = 100;
var money = 0;
var currentOrder = null;
var gameState = 'pickup'; // 'pickup', 'delivery'
var timeFreezeActive = false;
var timeFreezeRemaining = 0;
// UI Elements
var healthBar = new Text2('Health: 100', {
size: 60,
fill: 0xFF0000
});
healthBar.anchor.set(0, 0);
LK.gui.topLeft.addChild(healthBar);
healthBar.x = 120;
healthBar.y = 20;
var moneyText = new Text2('$0', {
size: 60,
fill: 0x00FF00
});
moneyText.anchor.set(1, 0);
LK.gui.topRight.addChild(moneyText);
moneyText.x = -20;
moneyText.y = 20;
var orderTimer = new Text2('', {
size: 50,
fill: 0xFFFF00
});
orderTimer.anchor.set(0.5, 0);
LK.gui.top.addChild(orderTimer);
orderTimer.y = 100;
// Game-wide route system
var routes = [];
var routeNodes = [];
// Create neighborhood layout
function createNeighborhood() {
// Center coordinates
var centerX = 1024;
var centerY = 1366;
// Create orderly grid layout with proper roads
var blockSize = 200; // Distance between blocks
var roadWidth = 120; // Width of roads (increased from 80)
var buildingSize = 80; // Size of buildings (reduced from 120)
// Create 4-block central park (2x2 grid of park blocks)
var parkSize = blockSize;
var parkPositions = [{
x: centerX - parkSize / 2,
y: centerY - parkSize / 2
},
// Top-left
{
x: centerX + parkSize / 2,
y: centerY - parkSize / 2
},
// Top-right
{
x: centerX - parkSize / 2,
y: centerY + parkSize / 2
},
// Bottom-left
{
x: centerX + parkSize / 2,
y: centerY + parkSize / 2
} // Bottom-right
];
// Create the 4 park blocks
for (var i = 0; i < parkPositions.length; i++) {
var park = game.addChild(LK.getAsset('building', {
anchorX: 0.5,
anchorY: 0.5,
x: parkPositions[i].x,
y: parkPositions[i].y
}));
park.tint = 0x4CAF50; // Green color for park
park.scaleX = 1.6;
park.scaleY = 1.6;
}
// Define grid layout for city blocks around the park
var gridRows = 8;
var gridCols = 6;
var startX = centerX - gridCols * blockSize / 2;
var startY = centerY - gridRows * blockSize / 2;
// Create horizontal roads
for (var row = 0; row <= gridRows; row++) {
var roadY = startY + row * blockSize;
if (roadY > 150 && roadY < 2582) {
var road = game.addChild(LK.getAsset('road', {
anchorX: 0.5,
anchorY: 0.5,
x: centerX,
y: roadY
}));
road.scaleX = 15; // Make road span full width
road.scaleY = roadWidth / 80;
}
}
// Create vertical roads
for (var col = 0; col <= gridCols; col++) {
var roadX = startX + col * blockSize;
if (roadX > 150 && roadX < 1898) {
var road = game.addChild(LK.getAsset('road', {
anchorX: 0.5,
anchorY: 0.5,
x: roadX,
y: centerY
}));
road.scaleX = roadWidth / 100;
road.scaleY = 20; // Make road span full height
}
}
// Store all building and restaurant positions
var allBuildingPositions = [];
var allRestaurantPositions = [];
// Generate building positions in the center of each block
for (var row = 0; row < gridRows; row++) {
for (var col = 0; col < gridCols; col++) {
var blockCenterX = startX + col * blockSize + blockSize / 2;
var blockCenterY = startY + row * blockSize + blockSize / 2;
// Skip blocks that overlap with the central park
var distanceToCenter = Math.sqrt(Math.pow(blockCenterX - centerX, 2) + Math.pow(blockCenterY - centerY, 2));
if (distanceToCenter < parkSize * 1.2) continue;
// Only add positions within game bounds
if (blockCenterX > 200 && blockCenterX < 1848 && blockCenterY > 250 && blockCenterY < 2482) {
// Randomly assign as building or restaurant
if (Math.random() < 0.3) {
// 30% chance for restaurant
allRestaurantPositions.push({
x: blockCenterX,
y: blockCenterY
});
} else {
// 70% chance for building
allBuildingPositions.push({
x: blockCenterX,
y: blockCenterY
});
}
}
}
}
// Create buildings at calculated positions
for (var i = 0; i < allBuildingPositions.length; i++) {
var building = game.addChild(LK.getAsset('building', {
anchorX: 0.5,
anchorY: 0.5,
x: allBuildingPositions[i].x,
y: allBuildingPositions[i].y
}));
buildings.push(building);
}
// Create restaurants at calculated positions
for (var i = 0; i < allRestaurantPositions.length; i++) {
var restaurant = game.addChild(new Restaurant());
restaurant.x = allRestaurantPositions[i].x;
restaurant.y = allRestaurantPositions[i].y;
restaurants.push(restaurant);
}
// Create customers - place them inside buildings
var customerCount = Math.min(buildings.length, 20);
for (var i = 0; i < customerCount; i++) {
var customer = game.addChild(new Customer());
// Place customer at same position as building
customer.x = buildings[i].x;
customer.y = buildings[i].y;
customers.push(customer);
}
// Create route network after building placement
createRouteNetwork();
}
// Create a network of route nodes for pathfinding
function createRouteNetwork() {
routeNodes = [];
routes = [];
var centerX = 1024;
var centerY = 1366;
var blockSize = 200;
var gridRows = 8;
var gridCols = 6;
var startX = centerX - gridCols * blockSize / 2;
var startY = centerY - gridRows * blockSize / 2;
// Create route nodes at road intersections
for (var row = 0; row <= gridRows; row++) {
for (var col = 0; col <= gridCols; col++) {
var nodeX = startX + col * blockSize;
var nodeY = startY + row * blockSize;
// Only add nodes within game bounds
if (nodeX > 150 && nodeX < 1898 && nodeY > 150 && nodeY < 2582) {
routeNodes.push({
x: nodeX,
y: nodeY,
connections: [],
isIntersection: true
});
}
}
}
// Add route nodes at the center of each road segment for better pathfinding
// Horizontal road segments
for (var row = 0; row <= gridRows; row++) {
for (var col = 0; col < gridCols; col++) {
var nodeX = startX + col * blockSize + blockSize / 2;
var nodeY = startY + row * blockSize;
if (nodeX > 150 && nodeX < 1898 && nodeY > 150 && nodeY < 2582) {
routeNodes.push({
x: nodeX,
y: nodeY,
connections: []
});
}
}
}
// Vertical road segments
for (var row = 0; row < gridRows; row++) {
for (var col = 0; col <= gridCols; col++) {
var nodeX = startX + col * blockSize;
var nodeY = startY + row * blockSize + blockSize / 2;
if (nodeX > 150 && nodeX < 1898 && nodeY > 150 && nodeY < 2582) {
routeNodes.push({
x: nodeX,
y: nodeY,
connections: []
});
}
}
}
// Add building access nodes near each building and restaurant
for (var i = 0; i < buildings.length; i++) {
var building = buildings[i];
// Add access nodes on the roads around the building
var accessNodes = [{
x: building.x,
y: building.y - blockSize / 2
},
// North road
{
x: building.x,
y: building.y + blockSize / 2
},
// South road
{
x: building.x - blockSize / 2,
y: building.y
},
// West road
{
x: building.x + blockSize / 2,
y: building.y
} // East road
];
for (var j = 0; j < accessNodes.length; j++) {
var accessNode = accessNodes[j];
if (accessNode.x > 150 && accessNode.x < 1898 && accessNode.y > 150 && accessNode.y < 2582) {
routeNodes.push({
x: accessNode.x,
y: accessNode.y,
connections: [],
buildingAccess: i
});
}
}
}
for (var i = 0; i < restaurants.length; i++) {
var restaurant = restaurants[i];
// Add access nodes on the roads around the restaurant
var accessNodes = [{
x: restaurant.x,
y: restaurant.y - blockSize / 2
},
// North road
{
x: restaurant.x,
y: restaurant.y + blockSize / 2
},
// South road
{
x: restaurant.x - blockSize / 2,
y: restaurant.y
},
// West road
{
x: restaurant.x + blockSize / 2,
y: restaurant.y
} // East road
];
for (var j = 0; j < accessNodes.length; j++) {
var accessNode = accessNodes[j];
if (accessNode.x > 150 && accessNode.x < 1898 && accessNode.y > 150 && accessNode.y < 2582) {
routeNodes.push({
x: accessNode.x,
y: accessNode.y,
connections: [],
restaurantAccess: i
});
}
}
}
// Connect route nodes - connect nodes that are on the same road
for (var i = 0; i < routeNodes.length; i++) {
for (var j = i + 1; j < routeNodes.length; j++) {
var distance = getDistance(routeNodes[i], routeNodes[j]);
var node1 = routeNodes[i];
var node2 = routeNodes[j];
// Connect nodes if they're on the same horizontal or vertical road
var sameHorizontalRoad = Math.abs(node1.y - node2.y) < 20 && distance < blockSize + 50;
var sameVerticalRoad = Math.abs(node1.x - node2.x) < 20 && distance < blockSize + 50;
if ((sameHorizontalRoad || sameVerticalRoad) && distance > 10) {
routeNodes[i].connections.push(j);
routeNodes[j].connections.push(i);
}
}
}
}
// Find closest route node to a position
function findClosestRouteNode(x, y) {
var closestIndex = -1;
var closestDistance = Infinity;
for (var i = 0; i < routeNodes.length; i++) {
var distance = getDistance({
x: x,
y: y
}, routeNodes[i]);
if (distance < closestDistance) {
closestDistance = distance;
closestIndex = i;
}
}
return closestIndex;
}
// Check if path between two nodes is clear of buildings
function isPathClear(node1, node2) {
var steps = 10;
var stepX = (node2.x - node1.x) / steps;
var stepY = (node2.y - node1.y) / steps;
for (var step = 0; step <= steps; step++) {
var checkX = node1.x + stepX * step;
var checkY = node1.y + stepY * step;
// Check if this point intersects with any building
for (var i = 0; i < buildings.length; i++) {
var building = buildings[i];
var dx = Math.abs(checkX - building.x);
var dy = Math.abs(checkY - building.y);
if (dx < building.width / 2 + 30 && dy < building.height / 2 + 30) {
return false;
}
}
}
return true;
}
// Get distance between two points
function getDistance(point1, point2) {
var dx = point1.x - point2.x;
var dy = point1.y - point2.y;
return Math.sqrt(dx * dx + dy * dy);
}
// Find path between two positions using A* pathfinding
function findPath(startX, startY, endX, endY) {
var startNode = findClosestRouteNode(startX, startY);
var endNode = findClosestRouteNode(endX, endY);
if (startNode === -1 || endNode === -1) return [];
if (startNode === endNode) return [routeNodes[endNode]];
// Simple A* implementation
var openSet = [{
index: startNode,
g: 0,
h: getDistance(routeNodes[startNode], routeNodes[endNode]),
parent: null
}];
var closedSet = [];
var visited = [];
while (openSet.length > 0) {
// Find node with lowest f score
var current = openSet[0];
var currentIndex = 0;
for (var i = 1; i < openSet.length; i++) {
if (openSet[i].g + openSet[i].h < current.g + current.h) {
current = openSet[i];
currentIndex = i;
}
}
// Move current from open to closed
openSet.splice(currentIndex, 1);
closedSet.push(current);
visited.push(current.index);
// Check if we reached the goal
if (current.index === endNode) {
var path = [];
var pathNode = current;
while (pathNode) {
path.unshift(routeNodes[pathNode.index]);
pathNode = pathNode.parent;
}
return path;
}
// Check all neighbors
var connections = routeNodes[current.index].connections;
for (var i = 0; i < connections.length; i++) {
var neighborIndex = connections[i];
// Skip if already visited
if (visited.indexOf(neighborIndex) !== -1) continue;
var g = current.g + getDistance(routeNodes[current.index], routeNodes[neighborIndex]);
var h = getDistance(routeNodes[neighborIndex], routeNodes[endNode]);
// Check if this path to neighbor is better
var existingOpen = null;
for (var j = 0; j < openSet.length; j++) {
if (openSet[j].index === neighborIndex) {
existingOpen = openSet[j];
break;
}
}
if (!existingOpen || g < existingOpen.g) {
var neighbor = {
index: neighborIndex,
g: g,
h: h,
parent: current
};
if (existingOpen) {
openSet[j] = neighbor;
} else {
openSet.push(neighbor);
}
}
}
}
return []; // No path found
}
function createNewOrder() {
if (currentOrder) return;
var availableRestaurants = restaurants.filter(function (r) {
return !r.hasOrder;
});
if (availableRestaurants.length === 0) return;
// Select random restaurant and building for new customer
var restaurant = availableRestaurants[Math.floor(Math.random() * availableRestaurants.length)];
var availableBuildings = buildings.filter(function (b) {
// Don't use buildings that already have visible customers
for (var i = 0; i < customers.length; i++) {
if (customers[i].visible && customers[i].x === b.x && customers[i].y === b.y) {
return false;
}
}
return true;
});
if (availableBuildings.length === 0) return;
var selectedBuilding = availableBuildings[Math.floor(Math.random() * availableBuildings.length)];
// Find or create customer at selected building
var customer = null;
for (var i = 0; i < customers.length; i++) {
if (!customers[i].waitingForOrder && customers[i].x === selectedBuilding.x && customers[i].y === selectedBuilding.y) {
customer = customers[i];
break;
}
}
// If no customer at this building, create one
if (!customer) {
customer = game.addChild(new Customer());
customer.x = selectedBuilding.x;
customer.y = selectedBuilding.y;
customers.push(customer);
}
var order = game.addChild(new Order());
order.x = restaurant.x;
order.y = restaurant.y - 60;
order.restaurant = restaurant;
order.customer = customer;
restaurant.hasOrder = true;
restaurant.orderReady = true;
customer.waitingForOrder = true;
customer.visible = true; // Make customer visible when order arrives
customer.orderTime = 0;
// Create delivery target indicator
var deliveryTarget = game.addChild(LK.getAsset('deliveryTarget', {
anchorX: 0.5,
anchorY: 0.5,
x: customer.x,
y: customer.y - 50
}));
customer.deliveryTarget = deliveryTarget;
// Start flashing animation
tween(deliveryTarget, {
alpha: 0.3
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(deliveryTarget, {
alpha: 1
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (deliveryTarget.parent) {
tween(deliveryTarget, {
alpha: 0.3
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(deliveryTarget, {
alpha: 1
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
}
}
});
}
});
currentOrder = order;
orders.push(order);
gameState = 'pickup';
}
function createCars() {
var targetCarCount = 10; // Start with 10 cars
if (money >= 200) {
targetCarCount = 20; // Max 20 cars at $200
} else if (money > 0) {
// Gradually increase from 10 to 20 based on money
targetCarCount = 10 + Math.floor(money / 200 * 10);
}
// Add cars if we need more
while (cars.length < targetCarCount) {
var car = game.addChild(new Car());
// Place cars on roads
if (Math.random() < 0.5) {
// Place on horizontal road
car.x = Math.random() * 1800 + 124;
car.y = 1366 + (Math.floor(Math.random() * 8) - 4) * 200; // Various horizontal roads
} else {
// Place on vertical road
car.x = 1024 + (Math.floor(Math.random() * 6) - 3) * 200; // Various vertical roads
car.y = Math.random() * 2400 + 166;
}
cars.push(car);
}
// Remove excess cars if money decreased (shouldn't happen but safety check)
while (cars.length > targetCarCount) {
var removedCar = cars.pop();
removedCar.destroy();
}
}
function spawnPowerUp() {
if (powerUps.length >= 3) return;
var type = Math.random() < 0.6 ? 'health' : 'time';
var powerUp = game.addChild(new PowerUp(type));
powerUp.x = Math.random() * 1800 + 124;
powerUp.y = Math.random() * 2400 + 166;
powerUps.push(powerUp);
}
function updateUI() {
healthBar.setText('Health: ' + Math.floor(health));
moneyText.setText('$' + money);
if (currentOrder && gameState === 'delivery') {
var timeLeft = Math.max(0, currentOrder.timeRemaining / 1000);
orderTimer.setText('Deliver in: ' + timeLeft.toFixed(1) + 's');
} else {
orderTimer.setText('');
}
}
function checkCollisions() {
// Check courier-restaurant collision for pickup (wider area)
if (gameState === 'pickup' && currentOrder) {
var restaurant = currentOrder.restaurant;
var pickupDistance = Math.sqrt(Math.pow(restaurant.x - courier.x, 2) + Math.pow(restaurant.y - courier.y, 2));
if (pickupDistance < 80) {
// Wider pickup area
// Pick up order
LK.getSound('pickup').play();
courier.hasOrder = true;
gameState = 'delivery';
currentOrder.x = courier.x;
currentOrder.y = courier.y - 40;
// Start the package timer when courier receives the package
currentOrder.timerStarted = true;
}
}
// Check courier-customer collision for delivery (building area)
if (gameState === 'delivery' && currentOrder && courier.hasOrder) {
var customer = currentOrder.customer;
var deliveryDistance = Math.sqrt(Math.pow(customer.x - courier.x, 2) + Math.pow(customer.y - courier.y, 2));
if (deliveryDistance < 70) {
// Wider delivery area for building
// Deliver order
LK.getSound('delivery').play();
completeDelivery();
}
}
// Check courier-powerup collisions
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
if (courier.intersects(powerUp)) {
LK.getSound('powerup').play();
if (powerUp.type === 'health') {
health = Math.min(100, health + 25);
} else if (powerUp.type === 'time') {
timeFreezeActive = true;
timeFreezeRemaining = 3000; // 3 seconds
}
powerUp.destroy();
powerUps.splice(i, 1);
}
}
}
function completeDelivery() {
if (!currentOrder) return;
var deliveryTime = currentOrder.timeLimit - currentOrder.timeRemaining;
var bonus = 0;
if (currentOrder.timeRemaining > 0) {
// Successful delivery
var timeBonus = Math.floor(currentOrder.timeRemaining / 1000);
bonus = 10 + timeBonus;
money += bonus;
// Flash green for success
LK.effects.flashObject(courier, 0x00ff00, 500);
} else {
// Late delivery - health penalty
health -= 20;
LK.effects.flashObject(courier, 0xff0000, 1000);
if (health <= 0) {
LK.showGameOver();
return;
}
}
// Clean up order
currentOrder.restaurant.hasOrder = false;
currentOrder.customer.waitingForOrder = false;
currentOrder.customer.visible = false; // Hide customer after delivery
// Remove delivery target indicator
if (currentOrder.customer.deliveryTarget) {
tween.stop(currentOrder.customer.deliveryTarget);
currentOrder.customer.deliveryTarget.destroy();
currentOrder.customer.deliveryTarget = null;
}
currentOrder.destroy();
for (var i = orders.length - 1; i >= 0; i--) {
if (orders[i] === currentOrder) {
orders.splice(i, 1);
break;
}
}
currentOrder = null;
courier.hasOrder = false;
gameState = 'pickup';
// Create new order after short delay
LK.setTimeout(function () {
createNewOrder();
}, 1000);
}
// Initialize game elements
createNeighborhood();
// Create courier
courier = game.addChild(new Courier());
courier.x = 1024;
courier.y = 1366;
// Initialize cars
createCars();
// Create AI couriers
for (var i = 0; i < 3; i++) {
var aiCourier = game.addChild(new AICourier());
aiCourier.x = Math.random() * 1800 + 124;
aiCourier.y = Math.random() * 2400 + 166;
// Create route waypoints based on restaurant and road positions
aiCourier.routeWaypoints = [];
// Add restaurant positions as waypoints
for (var j = 0; j < restaurants.length; j++) {
aiCourier.routeWaypoints.push({
x: restaurants[j].x,
y: restaurants[j].y
});
}
// Add some road intersection points as additional waypoints
var centerX = 1024;
var centerY = 1366;
var roadRadii = [450, 750]; // Road layer radii
for (var r = 0; r < roadRadii.length; r++) {
for (var angle = 0; angle < Math.PI * 2; angle += Math.PI / 4) {
var roadX = centerX + Math.cos(angle) * roadRadii[r];
var roadY = centerY + Math.sin(angle) * roadRadii[r];
if (roadX > 100 && roadX < 1948 && roadY > 100 && roadY < 2632) {
aiCourier.routeWaypoints.push({
x: roadX,
y: roadY
});
}
}
}
aiCouriers.push(aiCourier);
}
// Touch controls
var targetX = courier.x;
var targetY = courier.y;
game.down = function (x, y, obj) {
targetX = x;
targetY = y;
};
game.move = function (x, y, obj) {
targetX = x;
targetY = y;
};
// Create first order
createNewOrder();
// Spawn initial power-up
LK.setTimeout(function () {
spawnPowerUp();
}, 3000);
game.update = function () {
// Move courier toward target
courier.moveToward(targetX, targetY);
// Update time freeze
if (timeFreezeActive) {
timeFreezeRemaining -= 16.67;
if (timeFreezeRemaining <= 0) {
timeFreezeActive = false;
}
}
// Update current order timer (if not frozen)
if (currentOrder && !timeFreezeActive) {
currentOrder.update();
// Check if order expired before pickup
if (!currentOrder.timerStarted && currentOrder.lifeTime >= currentOrder.maxLifeTime) {
// Order expired - clean up and create new one
currentOrder.restaurant.hasOrder = false;
currentOrder.customer.waitingForOrder = false;
currentOrder.customer.visible = false; // Hide customer
if (currentOrder.customer.deliveryTarget) {
tween.stop(currentOrder.customer.deliveryTarget);
currentOrder.customer.deliveryTarget.destroy();
currentOrder.customer.deliveryTarget = null;
}
currentOrder.destroy();
for (var i = orders.length - 1; i >= 0; i--) {
if (orders[i] === currentOrder) {
orders.splice(i, 1);
break;
}
}
currentOrder = null;
gameState = 'pickup';
// Create new order immediately
LK.setTimeout(function () {
createNewOrder();
}, 500);
} else {
// Move order with courier if picked up
if (courier.hasOrder && gameState === 'delivery') {
currentOrder.x = courier.x;
currentOrder.y = courier.y - 40;
}
// Maintain delivery target flashing
if (gameState === 'delivery' && currentOrder.customer.deliveryTarget) {
var target = currentOrder.customer.deliveryTarget;
if (!target.isFlashing) {
var _flashTarget = function flashTarget() {
if (target.parent) {
tween(target, {
alpha: 0.3
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (target.parent) {
tween(target, {
alpha: 1
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: _flashTarget
});
}
}
});
}
};
target.isFlashing = true;
_flashTarget();
}
}
// Check for failed delivery
if (currentOrder.timeRemaining <= 0 && gameState === 'delivery') {
completeDelivery();
}
}
}
// Update car count based on money
createCars();
// Update cars
for (var i = 0; i < cars.length; i++) {
cars[i].update();
}
// Update AI couriers
for (var i = 0; i < aiCouriers.length; i++) {
aiCouriers[i].update();
}
// Update customers
for (var i = 0; i < customers.length; i++) {
customers[i].update();
}
// Update power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
powerUp.update();
if (powerUp.lifeTime >= powerUp.maxLifeTime) {
powerUp.destroy();
powerUps.splice(i, 1);
}
}
// Spawn new power-ups occasionally
if (LK.ticks % 600 === 0) {
// Every 10 seconds
spawnPowerUp();
}
// Check collisions
checkCollisions();
// Update UI
updateUI();
// Win condition (optional - could be score based)
if (money >= 200) {
LK.showYouWin();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -126,15 +126,46 @@
// No path or reached end - stay in place
self.targetX = self.x;
self.targetY = self.y;
}
- // Move toward target using simple movement
+ // Move toward target using simple movement with collision detection
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 10) {
- self.x += dx / distance * self.speed;
- self.y += dy / distance * self.speed;
+ var newX = self.x + dx / distance * self.speed;
+ var newY = self.y + dy / distance * self.speed;
+ // Check collisions before moving
+ var canMove = true;
+ // Check collision with cars
+ for (var i = 0; i < cars.length; i++) {
+ var carDx = Math.abs(newX - cars[i].x);
+ var carDy = Math.abs(newY - cars[i].y);
+ if (carDx < 50 && carDy < 50) {
+ canMove = false;
+ break;
+ }
+ }
+ // Check collision with player courier
+ var playerDx = Math.abs(newX - courier.x);
+ var playerDy = Math.abs(newY - courier.y);
+ if (playerDx < 50 && playerDy < 50) {
+ canMove = false;
+ }
+ // Check collision with other AI couriers
+ for (var i = 0; i < aiCouriers.length; i++) {
+ if (aiCouriers[i] === self) continue;
+ var aiDx = Math.abs(newX - aiCouriers[i].x);
+ var aiDy = Math.abs(newY - aiCouriers[i].y);
+ if (aiDx < 50 && aiDy < 50) {
+ canMove = false;
+ break;
+ }
+ }
+ if (canMove) {
+ self.x = newX;
+ self.y = newY;
+ }
}
// Update order position if carrying one
if (self.hasOrder && currentOrder) {
currentOrder.x = self.x;
@@ -142,8 +173,93 @@
}
};
return self;
});
+var Car = Container.expand(function () {
+ var self = Container.call(this);
+ var carGraphics = self.attachAsset('courier', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ carGraphics.tint = 0x333333; // Dark gray for cars
+ carGraphics.scaleX = 0.8;
+ carGraphics.scaleY = 0.8;
+ self.speed = 2 + Math.random() * 4; // Speed between 2-6
+ self.direction = Math.random() < 0.5 ? 'horizontal' : 'vertical';
+ self.movingPositive = Math.random() < 0.5; // true = right/down, false = left/up
+ self.targetX = self.x;
+ self.targetY = self.y;
+ self.stuckTimer = 0;
+ self.maxStuckTime = 2000; // 2 seconds before finding new path
+ self.update = function () {
+ var oldX = self.x;
+ var oldY = self.y;
+ // Move only horizontally or vertically
+ if (self.direction === 'horizontal') {
+ if (self.movingPositive) {
+ self.targetX = self.x + self.speed;
+ } else {
+ self.targetX = self.x - self.speed;
+ }
+ // Reverse direction at boundaries
+ if (self.x > 1900 || self.x < 148) {
+ self.movingPositive = !self.movingPositive;
+ }
+ } else {
+ if (self.movingPositive) {
+ self.targetY = self.y + self.speed;
+ } else {
+ self.targetY = self.y - self.speed;
+ }
+ // Reverse direction at boundaries
+ if (self.y > 2550 || self.y < 182) {
+ self.movingPositive = !self.movingPositive;
+ }
+ }
+ // Check for collisions before moving
+ var canMove = true;
+ var testX = self.targetX;
+ var testY = self.targetY;
+ // Check collision with other cars
+ for (var i = 0; i < cars.length; i++) {
+ if (cars[i] === self) continue;
+ var dx = Math.abs(testX - cars[i].x);
+ var dy = Math.abs(testY - cars[i].y);
+ if (dx < 50 && dy < 50) {
+ canMove = false;
+ break;
+ }
+ }
+ // Check collision with couriers
+ var courierDx = Math.abs(testX - courier.x);
+ var courierDy = Math.abs(testY - courier.y);
+ if (courierDx < 50 && courierDy < 50) {
+ canMove = false;
+ }
+ // Check collision with AI couriers
+ for (var i = 0; i < aiCouriers.length; i++) {
+ var aiDx = Math.abs(testX - aiCouriers[i].x);
+ var aiDy = Math.abs(testY - aiCouriers[i].y);
+ if (aiDx < 50 && aiDy < 50) {
+ canMove = false;
+ break;
+ }
+ }
+ if (canMove) {
+ self.x = testX;
+ self.y = testY;
+ self.stuckTimer = 0;
+ } else {
+ // If stuck for too long, change direction
+ self.stuckTimer += 16.67;
+ if (self.stuckTimer >= self.maxStuckTime) {
+ self.movingPositive = !self.movingPositive;
+ self.stuckTimer = 0;
+ }
+ }
+ };
+ return self;
+});
var Courier = Container.expand(function () {
var self = Container.call(this);
var courierGraphics = self.attachAsset('courier', {
anchorX: 0.5,
@@ -182,19 +298,67 @@
distance = Math.sqrt(dx * dx + dy * dy);
}
}
if (distance > 10 && self.pathIndex < self.currentPath.length) {
- self.x += dx / distance * self.speed;
- self.y += dy / distance * self.speed;
+ var newX = self.x + dx / distance * self.speed;
+ var newY = self.y + dy / distance * self.speed;
+ // Check collisions before moving
+ var canMove = true;
+ // Check collision with cars
+ for (var i = 0; i < cars.length; i++) {
+ var carDx = Math.abs(newX - cars[i].x);
+ var carDy = Math.abs(newY - cars[i].y);
+ if (carDx < 50 && carDy < 50) {
+ canMove = false;
+ break;
+ }
+ }
+ // Check collision with AI couriers
+ for (var i = 0; i < aiCouriers.length; i++) {
+ var aiDx = Math.abs(newX - aiCouriers[i].x);
+ var aiDy = Math.abs(newY - aiCouriers[i].y);
+ if (aiDx < 50 && aiDy < 50) {
+ canMove = false;
+ break;
+ }
+ }
+ if (canMove) {
+ self.x = newX;
+ self.y = newY;
+ }
}
} else {
// Direct movement as fallback
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 10) {
- self.x += dx / distance * self.speed;
- self.y += dy / distance * self.speed;
+ var newX = self.x + dx / distance * self.speed;
+ var newY = self.y + dy / distance * self.speed;
+ // Check collisions before moving
+ var canMove = true;
+ // Check collision with cars
+ for (var i = 0; i < cars.length; i++) {
+ var carDx = Math.abs(newX - cars[i].x);
+ var carDy = Math.abs(newY - cars[i].y);
+ if (carDx < 50 && carDy < 50) {
+ canMove = false;
+ break;
+ }
+ }
+ // Check collision with AI couriers
+ for (var i = 0; i < aiCouriers.length; i++) {
+ var aiDx = Math.abs(newX - aiCouriers[i].x);
+ var aiDy = Math.abs(newY - aiCouriers[i].y);
+ if (aiDx < 50 && aiDy < 50) {
+ canMove = false;
+ break;
+ }
+ }
+ if (canMove) {
+ self.x = newX;
+ self.y = newY;
+ }
}
}
};
return self;
@@ -282,8 +446,9 @@
****/
// Game variables
var courier;
var aiCouriers = [];
+var cars = [];
var restaurants = [];
var customers = [];
var orders = [];
var powerUps = [];
@@ -801,8 +966,37 @@
currentOrder = order;
orders.push(order);
gameState = 'pickup';
}
+function createCars() {
+ var targetCarCount = 10; // Start with 10 cars
+ if (money >= 200) {
+ targetCarCount = 20; // Max 20 cars at $200
+ } else if (money > 0) {
+ // Gradually increase from 10 to 20 based on money
+ targetCarCount = 10 + Math.floor(money / 200 * 10);
+ }
+ // Add cars if we need more
+ while (cars.length < targetCarCount) {
+ var car = game.addChild(new Car());
+ // Place cars on roads
+ if (Math.random() < 0.5) {
+ // Place on horizontal road
+ car.x = Math.random() * 1800 + 124;
+ car.y = 1366 + (Math.floor(Math.random() * 8) - 4) * 200; // Various horizontal roads
+ } else {
+ // Place on vertical road
+ car.x = 1024 + (Math.floor(Math.random() * 6) - 3) * 200; // Various vertical roads
+ car.y = Math.random() * 2400 + 166;
+ }
+ cars.push(car);
+ }
+ // Remove excess cars if money decreased (shouldn't happen but safety check)
+ while (cars.length > targetCarCount) {
+ var removedCar = cars.pop();
+ removedCar.destroy();
+ }
+}
function spawnPowerUp() {
if (powerUps.length >= 3) return;
var type = Math.random() < 0.6 ? 'health' : 'time';
var powerUp = game.addChild(new PowerUp(type));
@@ -914,8 +1108,10 @@
// Create courier
courier = game.addChild(new Courier());
courier.x = 1024;
courier.y = 1366;
+// Initialize cars
+createCars();
// Create AI couriers
for (var i = 0; i < 3; i++) {
var aiCourier = game.addChild(new AICourier());
aiCourier.x = Math.random() * 1800 + 124;
@@ -1041,8 +1237,14 @@
completeDelivery();
}
}
}
+ // Update car count based on money
+ createCars();
+ // Update cars
+ for (var i = 0; i < cars.length; i++) {
+ cars[i].update();
+ }
// Update AI couriers
for (var i = 0; i < aiCouriers.length; i++) {
aiCouriers[i].update();
}
ıts a courier scooter its looking behind . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
police car with flashing lights. In-Game asset. 2d. High contrast. No shadows
vandal riding dirt bike. In-Game asset. High contrast. No shadows
health powerup. In-Game asset. 2d. High contrast. No shadows
pizza boxes. In-Game asset. 2d. High contrast. No shadows
extra time powerup. In-Game asset. 2d. High contrast. No shadows
restaurant shop. In-Game asset. High contrast. No shadows
town house. In-Game asset. 2d. High contrast. No shadows
a man waiting outside. In-Game asset. 2d. High contrast. No shadows
arrow. In-Game asset. 2d. High contrast. No shadows
fence. In-Game asset. 2d. High contrast. No shadows