Code edit (3 edits merged)
Please save this source code
User prompt
add a console log when the harvestedSpiceCounter updates
User prompt
implament the harvester 'harvest' action : move to the closest spice spot, switch to harvesting Mode, and increment a harvestedSpiceCounter from 0 to 200 per spot
Code edit (10 edits merged)
Please save this source code
User prompt
in Map.render, , use cell.spiceAsset instead of creating a new terrainSpice
User prompt
in initSpiceSpots(), fill the cell.spiceAsset properties
User prompt
add a new property to cells 'spiceAsset' and set it to null in Map.init()
Code edit (1 edits merged)
Please save this source code
User prompt
At the beginning of render function, clear the screen
Code edit (1 edits merged)
Please save this source code
User prompt
In map render if spice = true for cell then add a terrainSpice on it
User prompt
In initSpiceSpots after the spice creation loop add a new property spice = true to gameMap cells based on globalTerrain values
User prompt
Spice spots are all the cells containing spice. They will be listed in spiceSpots global array. Implement initSpiceSpots to add 4 random ilots of spice on sand cells in each quarter of the map
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
in findAvailablePositionAroundRefinery, take other buildings into account
User prompt
when an Harvester is spawned on the Refinery, order it to move to the first available place around the refinery
User prompt
when a Spice Refinery is placed, automatically spawn an Harvester on it
User prompt
in spawnUnit use the playerId instead of always calling player1.addUnit()
User prompt
Fix Bug: 'Timeout.tick error: eval is not a function' in or related to this line: 'var unitClass = eval(unitInfo.className);' Line Number: 752
User prompt
in spawnUnit, user the unitInfo.className instead of calling UnitHarvester constructor
User prompt
extract the code : ``` var harvesterUnitInfo = unitRepository.getUnitInfo('unitHarvester'); var newHarvester = new UnitHarvester(rockIlot1Center.x, rockIlot1Center.y - 2, player1.playerId); gameMap.cells[rockIlot1Center.x][rockIlot1Center.y - 2].unit = newHarvester; player1.addUnit(newHarvester); game.addChild(newHarvester); ``` in a new global function spawnUnit() with all the required parameters
Code edit (15 edits merged)
Please save this source code
User prompt
update findPath to avoid buildings
Code edit (1 edits merged)
Please save this source code
===================================================================
--- original.js
+++ change.js
@@ -172,32 +172,112 @@
// Create and return the navigation mesh for pathfinding
};
self.findPath = function (start, end) {
console.log("findPath ", start, end);
- // Placeholder for pathfinding logic
- // This should be replaced with an actual pathfinding algorithm like A*
- // For now, we'll just create a direct path for demonstration purposes
+ // A* pathfinding algorithm implementation
+ // Avoid buildings by checking if the cell is occupied
+ var openSet = [];
+ var closedSet = [];
var path = [];
- var currentX = start.x;
- var currentY = start.y;
- while (currentX !== end.x || currentY !== end.y) {
- if (currentX < end.x) {
- currentX++;
- } else if (currentX > end.x) {
- currentX--;
+ var startNode = {
+ x: start.x,
+ y: start.y,
+ f: 0,
+ g: 0,
+ h: 0,
+ parent: null
+ };
+ var endNode = {
+ x: end.x,
+ y: end.y,
+ f: 0,
+ g: 0,
+ h: 0,
+ parent: null
+ };
+ openSet.push(startNode);
+ while (openSet.length > 0) {
+ var lowestIndex = 0;
+ for (var i = 0; i < openSet.length; i++) {
+ if (openSet[i].f < openSet[lowestIndex].f) {
+ lowestIndex = i;
+ }
}
- if (currentY < end.y) {
- currentY++;
- } else if (currentY > end.y) {
- currentY--;
+ var currentNode = openSet[lowestIndex];
+ if (currentNode.x === endNode.x && currentNode.y === endNode.y) {
+ var curr = currentNode;
+ while (curr.parent) {
+ path.push({
+ x: curr.x,
+ y: curr.y
+ });
+ curr = curr.parent;
+ }
+ path.reverse();
+ return path;
}
- path.push({
- x: currentX,
- y: currentY
- });
+ openSet.splice(lowestIndex, 1);
+ closedSet.push(currentNode);
+ var neighbors = getNeighbors(currentNode);
+ for (i = 0; i < neighbors.length; i++) {
+ var neighbor = neighbors[i];
+ if (closedSet.findIndex(function (node) {
+ return node.x === neighbor.x && node.y === neighbor.y;
+ }) !== -1 || self.cells[neighbor.x][neighbor.y].building) {
+ continue;
+ }
+ var gScore = currentNode.g + 1; // 1 is the distance from a node to a neighbor
+ var gScoreIsBest = false;
+ if (openSet.findIndex(function (node) {
+ return node.x === neighbor.x && node.y === neighbor.y;
+ }) === -1) {
+ gScoreIsBest = true;
+ neighbor.h = heuristic(neighbor, endNode);
+ openSet.push(neighbor);
+ } else if (gScore < neighbor.g) {
+ gScoreIsBest = true;
+ }
+ if (gScoreIsBest) {
+ neighbor.parent = currentNode;
+ neighbor.g = gScore;
+ neighbor.f = neighbor.g + neighbor.h;
+ }
+ }
}
return path;
};
+ function heuristic(node, endNode) {
+ // Use Manhattan distance as heuristic
+ return Math.abs(node.x - endNode.x) + Math.abs(node.y - endNode.y);
+ }
+ function getNeighbors(node) {
+ // Get all valid neighbors (up, down, left, right)
+ var neighbors = [];
+ var directions = [{
+ x: -1,
+ y: 0
+ }, {
+ x: 1,
+ y: 0
+ }, {
+ x: 0,
+ y: -1
+ }, {
+ x: 0,
+ y: 1
+ }];
+ directions.forEach(function (dir) {
+ var newX = node.x + dir.x;
+ var newY = node.y + dir.y;
+ if (newX >= 0 && newX < self.cells.length && newY >= 0 && newY < self.cells[0].length) {
+ neighbors.push({
+ x: newX,
+ y: newY
+ });
+ }
+ });
+ return neighbors;
+ }
self.lastInputPosition = null;
self.handleDrag = function (input) {
// Clamp the view center to the map boundaries
var targetX = Math.max(11, Math.min(self.currentViewCenter.x + input.x, mapXSize - 4));
@@ -250,10 +330,12 @@
self.alpha = 0.5;
self.visible = false;
// Initially, we display the selectionCross
self.addChild(self.selectionCross);
+ self.currentElement = null;
self.setOnElement = function (element) {
console.log('SelectionMarker setOnElement:', element);
+ self.currentElement = element;
if (!element) {
self.visible = false;
return;
}
@@ -265,10 +347,10 @@
self.selectionCross.alpha = 1;
self.selectionCircle.alpha = 0;
}
if (element.isUnit) {
- //elementDeltaX = -100;
- //elementDeltaY = -100;
+ elementDeltaX = 0;
+ elementDeltaY = 500;
self.selectionCross.alpha = 0;
self.selectionCircle.alpha = 0.9;
}
var centerDeltaX = (gameMap.currentViewCenter.x - 15) * 100;
@@ -382,19 +464,19 @@
var coords = getCoordsForUnit(self);
//console.log("self.x/y", self.x, self.y);
//console.log("asset.x/y", self.asset.x, self.asset.y);
//console.log("parent.x/y", self.parent.x, self.parent.y);
- console.log("coords", coords.x, coords.y);
- console.log("moving...", {
- x: self.cellX,
- y: self.cellY
- }, ' to ', targetCell, ' fixed :' + fixedX + ',' + fixedY);
+ //console.log("coords", coords.x, coords.y);
+ //console.log("moving...", {
+ // x: self.cellX,
+ // y: self.cellY
+ //}, ' to ', targetCell, ' fixed :' + fixedX + ',' + fixedY);
var targetCoords = getCoordsForUnit(targetCell);
- console.log("targetCoords", targetCoords.x, targetCoords.y);
+ //console.log("targetCoords", targetCoords.x, targetCoords.y);
var dx = targetCoords.x - self.x;
var dy = targetCoords.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
- console.log("distance", distance, ' / dx,dy=' + dx, ',', dy);
+ //console.log("distance", distance, ' / dx,dy=' + dx, ',', dy);
var step = self.speed * delta;
if (distance < step) {
console.log("reached step", distance);
self.x = targetCoords.x;
@@ -414,8 +496,12 @@
self.asset.rotation = angle - Math.PI / 2;
self.x += Math.cos(angle) * step;
self.y += Math.sin(angle) * step;
}
+ if (selectionMarker.currentElement == self) {
+ console.log("current selection moving...");
+ selectionMarker.setOnElement(self);
+ }
};
self.playerId = playerId;
var unitInfo = unitRepository.getUnitInfo(type);
self.name = unitInfo.name;
@@ -896,13 +982,8 @@
} else if (dragStart) {
//console.log("Drag move...");
var deltaX = currentPos.x - dragStart.x;
var deltaY = currentPos.y - dragStart.y;
- //dragStart = currentPos; // Update dragStart to the current position
- /*var inputPosition = {
- x: gameMap.currentViewCenter.x - Math.round(deltaX / 100),
- y: gameMap.currentViewCenter.y - Math.round(deltaY / 100)
- };*/
var inputPosition = {
x: Math.round(-deltaX / 100),
y: Math.round(-deltaY / 100)
};
@@ -913,11 +994,13 @@
var newCenterX = Math.round(gameMap.currentViewCenter.x + (targetX - gameMap.currentViewCenter.x) * dragSpeed);
var newCenterY = Math.round(gameMap.currentViewCenter.y + (targetY - gameMap.currentViewCenter.y) * dragSpeed);
var deltaX = gameMap.currentViewCenter.x - newCenterX;
var deltaY = gameMap.currentViewCenter.y - newCenterY;
- console.log("unit coords : " + unit.x + ',' + unit.y);
- console.log("target coords : " + targetX + ',' + targetY);
- console.log("delta coords : " + deltaX + ',' + deltaY);
+ //console.log("unit coords : " + unit.x + ',' + unit.y);
+ //console.log("target coords : " + targetX + ',' + targetY);
+ //console.log("center coords : " + gameMap.currentViewCenter.x + ',' + gameMap.currentViewCenter.y);
+ //console.log("input coords : " + inputPosition.x + ',' + inputPosition.y);
+ //console.log("delta coords : " + deltaX + ',' + deltaY);
unit.x += deltaX * 100;
unit.y += deltaY * 100;
});
gameMap.handleDrag(inputPosition);
@@ -985,8 +1068,9 @@
if (cellX >= 0 && cellX < gameMap.cells.length && cellY >= 0 && cellY < gameMap.cells[cellX].length) {
var cell = gameMap.cells[cellX][cellY];
if (!cell.building && !cell.unit && deltaToSelection > 1) {
currentSelection = null;
+ selectionMarker.setOnElement();
selectionMarker.hide();
console.log("Nothing selected at " + cellX + ',' + cellY, " deltaToSelection=" + deltaToSelection);
updateActionBoard();
} else if (cell.building) {
@@ -1275,11 +1359,11 @@
LK.on('tick', function () {
// Render the map and update unit movement each tick
if (gameIsRunning) {
gameMap.render();
- if (currentSelection && currentSelection.isUnit) {
- currentSelection.updateMovement(1 / 60); // Assuming tick operates at 60FPS
- }
+ /*if (currentSelection && currentSelection.isUnit) {
+ currentSelection.updateMovement(1 / 60); // Assuming tick operates at 60FPS
+ }*/
//game.addChild(newHarvester.asset); // TEMP DEBUG
var allUnits = player1.units.concat(player2.units);
allUnits.forEach(function (unit) {
//console.log("render unit " + unit.name, unit.x, unit.y);
@@ -1288,8 +1372,9 @@
/*if (!unit.asset.parent.parent.parent) {
console.log("First add unit !", unit.asset.parent.parent.parent);
game.addChild(unit.asset);
} else { }*/
+ unit.updateMovement(1 / 60); // Assuming tick operates at 60FPS
game.addChild(unit);
/*var screenX = (unit.cellX - 2 - gameMap.currentViewCenter.x + viewSize) * unit.asset.width;
var screenY = (unit.cellY - 3 - gameMap.currentViewCenter.y + viewSize) * unit.asset.height;
unit.x = screenX;
a tileable sand terrain tile.
A square tileable rock terrain tile WITHOUT BBORDER. Single Game Texture. In-Game asset. 2d. No shadows. No Border
Zenith view of Dune's Wind Trap power facility square fence. Ressembles a bit to Sydney's Opera. Zenith view Directly from above.
grey cancel icon. UI
thin white circle empty.
0x5e86ff
Zenith view of a white rectangular Harvester shape of a garbage truck with a triangular head. Harvesting on sand, with flowing spice in the back. inside a square fence. Zenith view. Directly overhead. Plumb view.
Minimal Ui icon of an right sign aside with an icon of a target. sand background
Minimal icon of a home with direction icon pointing to the home. sand background
3 white flat isometric concentric circles like a target.
Remove background
Gray background
Minimal Ui icon of target sign on a fire icon.. sand background
top view of an explosion effect.
Simple heavy army tank factory buiding a tank with a crane. Square fence... Zenith view Directly overhead. Plumb view.
an empty black popup UI. UI