如何实现满足条件的卡车向目标站点移动的逻辑?
Got it, let's break down how to implement this truck dispatch system step by step. I’ll walk you through each part with code snippets and explanations that fit your exact requirements.
1. 核心思路梳理
First, let's align on the key requirements we're building for:
- Manage 2 (scalable) trucks using an array for easy bulk operations
- Spawn new stations every time the user clicks the screen
- Use 3 custom conditions to pick the right truck for each new station
2. Initialize the Truck Array
We’ll start by defining truck objects with critical properties (status, position, target) and store them in an array. This makes it trivial to add more trucks later.
// Define the concrete plant's starting position const concretePlant = { x: 50, y: 50 }; // Initialize our truck fleet (easily add more trucks here later) let trucks = [ { id: 1, status: 'idle', currentPos: { ...concretePlant }, targetPos: null }, { id: 2, status: 'idle', currentPos: { ...concretePlant }, targetPos: null } ];
3. Spawn Stations on Click
Bind a click event to create new stations, then trigger the dispatch logic immediately after each new station is added.
// Array to track all active stations let stations = []; // Bind click event (browser environment example) document.addEventListener('click', (e) => { // Create a new station with the click coordinates const newStation = { id: stations.length + 1, pos: { x: e.clientX, y: e.clientY }, isServed: false // Mark if a truck has been assigned }; stations.push(newStation); // Kick off the truck dispatch logic for this new station dispatchTruckToStation(newStation); });
4. Core: Conditional Truck Dispatch Logic
You mentioned 3 conditions—let’s use practical example conditions (swap these out with your actual rules):
- Prioritize idle trucks first
- Among idle trucks, pick the one closest to the new station
- If all trucks are busy, assign the truck that will finish its current task the fastest
function dispatchTruckToStation(targetStation) { // Filter to get only idle trucks const idleTrucks = trucks.filter(truck => truck.status === 'idle'); if (idleTrucks.length > 0) { // Condition 2: Pick the idle truck closest to the station const closestTruck = idleTrucks.reduce((prev, curr) => { const prevDist = calculateDistance(prev.currentPos, targetStation.pos); const currDist = calculateDistance(curr.currentPos, targetStation.pos); return prevDist < currDist ? prev : curr; }); // Assign the truck to the station assignTruck(closestTruck, targetStation); } else { // Condition 3: All trucks busy—pick the one finishing soonest (using distance as proxy for time) const soonestFreeTruck = trucks.reduce((prev, curr) => { const prevRemainingTime = calculateDistance(prev.currentPos, prev.targetPos); const currRemainingTime = calculateDistance(curr.currentPos, curr.targetPos); return prevRemainingTime < currRemainingTime ? prev : curr; }); // Log and set up a callback for when the truck is free (adjust this logic as needed) console.log(`Truck ${soonestFreeTruck.id} will head to Station ${targetStation.id} once it finishes its current trip`); // You could also bind an event listener here to trigger dispatch when the truck goes idle } } // Helper: Calculate Euclidean distance between two points function calculateDistance(pos1, pos2) { return Math.sqrt(Math.pow(pos2.x - pos1.x, 2) + Math.pow(pos2.y - pos1.y, 2)); } // Helper: Update truck and station statuses, kick off movement function assignTruck(truck, station) { truck.status = 'busy'; truck.targetPos = station.pos; station.isServed = true; console.log(`Dispatched Truck ${truck.id} to Station ${station.id}`); // Start the truck's movement to the station startTruckMovement(truck); }
5. Simulate Truck Movement
Add logic to make the truck move incrementally toward its target, then reset to idle once it arrives.
function startTruckMovement(truck) { // Move the truck every 50ms (adjust speed as needed) const moveInterval = setInterval(() => { // Move 1 unit at a time toward the target if (truck.currentPos.x < truck.targetPos.x) truck.currentPos.x += 1; else if (truck.currentPos.x > truck.targetPos.x) truck.currentPos.x -= 1; if (truck.currentPos.y < truck.targetPos.y) truck.currentPos.y += 1; else if (truck.currentPos.y > truck.targetPos.y) truck.currentPos.y -= 1; // Check if the truck has reached its target if (truck.currentPos.x === truck.targetPos.x && truck.currentPos.y === truck.targetPos.y) { clearInterval(moveInterval); // Reset truck to idle (optional: send it back to the concrete plant) truck.status = 'idle'; truck.targetPos = null; console.log(`Truck ${truck.id} arrived at Station! Now returning to concrete plant.`); } }, 50); }
Quick Expansion Tips
- To add more trucks, just push new objects to the
trucksarray—no changes needed to the dispatch logic - Swap out the example conditions with your actual rules (e.g., prioritize high-priority stations, consider truck capacity)
- Add a visual layer using Canvas or DOM elements to draw trucks/stations and show movement in real time
内容的提问来源于stack exchange,提问作者Lilly

