User prompt
Create start screen image
User prompt
Add start screen images
User prompt
Add game start screen
User prompt
I cant go through houses
User prompt
Add to world house not to screen
User prompt
Add houses to random places on the map
User prompt
Please fix the bug: 'Can't find variable: shops' in or related to this line: 'if (isPositionClear(x, y, minDistance, [villagers, houses, shops, trees])) {' Line Number: 247
User prompt
Add house
User prompt
Add background image
User prompt
Start button move the screen middle
User prompt
Add start button
User prompt
Add house
User prompt
Block me house and tree
User prompt
Add viliger house and tree
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'obj.event.preventDefault();' Line Number: 543
User prompt
The game pauses when I press the movement keys
User prompt
Please fix the bug: 'shops is not defined' in or related to this line: 'if (isPositionClear(x, y, minDistance, [villagers, houses, shops, trees])) {' Line Number: 344
User prompt
add village houses and trees
User prompt
remove objects such as houses and shop stands
User prompt
Remove all objects and replace them with houses and trees.
User prompt
Enlarge the movement keys. I can create my own pictures of objects like houses.
User prompt
Spacing the movement keys
User prompt
Let's not pass through objects
User prompt
add more villagers. increase the diversity of the village by adding objects such as houses and shop stands
User prompt
Move the movement keys a little higher. Put the execution key in the bottom left corner of the screen.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // D-Pad Button class var DPadButton = Container.expand(function () { var self = Container.call(this); self.bg = self.attachAsset('dpadBtn', { anchorX: 0.5, anchorY: 0.5 }); self.bg.alpha = 0.7; self.icon = null; // Will be set by game code return self; }); // Execute Button class var ExecuteButton = Container.expand(function () { var self = Container.call(this); self.bg = self.attachAsset('executeBtn', { anchorX: 0.5, anchorY: 0.5 }); self.bg.alpha = 0.92; self.label = new Text2('EXECUTE', { size: 60, fill: "#fff" }); self.label.anchor.set(0.5, 0.5); self.addChild(self.label); self.visible = false; return self; }); // House class var House = Container.expand(function () { var self = Container.call(this); // Create house body self.body = new Container(); self.addChild(self.body); // House base self.base = self.body.attachAsset('Sickvligers', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.6, scaleY: 2.8 }); self.base.tint = 0x8B4513; // Brown color for house // House roof self.roof = new Container(); self.roof.y = -self.base.height * 0.4; self.body.addChild(self.roof); self.roofAsset = self.roof.attachAsset('Sickvligers', { anchorX: 0.5, anchorY: 0.5, scaleX: 4.0, scaleY: 1.6 }); self.roofAsset.tint = 0xA52A2A; // Dark red for roof // Door self.door = self.body.attachAsset('Sickvligers', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 1.4, y: self.base.height * 0.15 }); self.door.tint = 0x4B2F17; // Dark wood door // Window self.window = self.body.attachAsset('Sickvligers', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8, x: self.base.width * 0.25, y: -self.base.height * 0.1 }); self.window.tint = 0xADD8E6; // Light blue window return self; }); // Plague Doctor (player) class var PlagueDoctor = Container.expand(function () { var self = Container.call(this); var doctorSprite = self.attachAsset('plagueDoctor', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 18; // Movement speed per tick // For collision box, use the asset's width/height self.getBounds = function () { return { x: self.x - doctorSprite.width / 2, y: self.y - doctorSprite.height / 2, width: doctorSprite.width, height: doctorSprite.height }; }; return self; }); // Shop Stand class var ShopStand = Container.expand(function () { var self = Container.call(this); // Shop stand base self.base = self.attachAsset('Sickvligers', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.6, scaleY: 1.4 }); self.base.tint = 0x8B4513; // Brown wood // Shop stand canopy self.canopy = self.attachAsset('Sickvligers', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.0, scaleY: 0.8, y: -self.base.height * 0.7 }); self.canopy.tint = 0xE34234; // Red canopy // Shop items (fruits/goods) for (var i = 0; i < 3; i++) { var item = self.attachAsset('Sickvligers', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, x: (i - 1) * 40, y: -20 }); // Random item colors var colors = [0xFFFF00, 0xFF0000, 0x00FF00]; // Yellow, red, green item.tint = colors[i]; } return self; }); // Tree class var Tree = Container.expand(function () { var self = Container.call(this); // Tree trunk self.trunk = self.attachAsset('Sickvligers', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 2.0 }); self.trunk.tint = 0x8B4513; // Brown // Tree foliage self.foliage = self.attachAsset('Sickvligers', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.4, scaleY: 2.4, y: -80 }); self.foliage.tint = 0x228B22; // Forest green return self; }); // Villager class var Villager = Container.expand(function () { var self = Container.call(this); self.isSick = false; self.isAlive = true; self.init = function (isSick) { self.isSick = isSick; self.isAlive = true; self.removeChildren(); var assetId = isSick ? 'villagerSick' : 'villagerHealthy'; self.sprite = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); }; self.getBounds = function () { return { x: self.x - self.sprite.width / 2, y: self.y - self.sprite.height / 2, width: self.sprite.width, height: self.sprite.height }; }; self.execute = function () { self.isAlive = false; // Animate fade out and shrink tween(self.sprite, { alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 400, easing: tween.cubicIn, onFinish: function onFinish() { self.visible = false; } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xf2e5bc }); /**** * Game Code ****/ // D-pad buttons // "Execute" button // Sick villager // Healthy villager // Plague Doctor (player) // --- Game constants --- var VILLAGE_WIDTH = 6144; // Expanded map width (3x standard screen width) var VILLAGE_HEIGHT = 4096; // Expanded map height (2x standard screen height) var NUM_VILLAGERS = 40; // More villagers for the larger map var NUM_SICK = 15; // More sick villagers var VILLAGER_MIN_DIST = 220; // Minimum distance between villagers var NUM_HOUSES = 15; // Number of houses to place var NUM_SHOPS = 10; // Number of shop stands var NUM_TREES = 25; // Number of trees // --- Game state --- var player; var villagers = []; var houses = []; var shops = []; var trees = []; var sickLeft = NUM_SICK; var executeBtn; var dpadBtns = {}; var dpadState = { up: false, down: false, left: false, right: false }; var cameraX = 0; // For horizontal scrolling var cameraY = 0; // For vertical scrolling var playerWorldX = 0; // Player's true position in world coordinates var playerWorldY = 0; // Player's true position in world coordinates var draggingDPad = null; var canExecuteVillager = null; // Reference to sick villager in range // --- GUI elements --- var sickLeftTxt = new Text2('Sick left: ' + sickLeft, { size: 90, fill: 0xB16262 }); sickLeftTxt.anchor.set(0.5, 0); // Place at top center, but not in top 100px LK.gui.top.addChild(sickLeftTxt); sickLeftTxt.y = 110; // --- Helper functions --- function clamp(val, min, max) { if (val < min) return min; if (val > max) return max; return val; } // Axis-aligned bounding box collision function aabbIntersect(a, b) { return a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y; } // --- Map and villagers setup --- // Starting position is the center of the map (no offset needed for scrolling map) var mapCenterX = VILLAGE_WIDTH / 2; var mapCenterY = VILLAGE_HEIGHT / 2; // Check if a position is clear for placing objects (no collision with existing objects) function isPositionClear(x, y, radius, objectArrays) { // Check distance from map center (player start) if (Math.abs(x - mapCenterX) < 300 && Math.abs(y - mapCenterY) < 300) { return false; } // Check distance from existing objects for (var i = 0; i < objectArrays.length; i++) { var objects = objectArrays[i]; for (var j = 0; j < objects.length; j++) { var obj = objects[j]; var dx = x - obj.x; var dy = y - obj.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < radius) { return false; } } } return true; } // Place objects randomly on the map function placeObjects(objectClass, count, minDistance, container) { for (var i = 0; i < count; i++) { var object = new objectClass(); // Try to find a valid position var x, y; var attempts = 0; var placed = false; while (!placed && attempts < 50) { // Random position with padding from edges x = 200 + Math.random() * (VILLAGE_WIDTH - 400); y = 200 + Math.random() * (VILLAGE_HEIGHT - 400); if (isPositionClear(x, y, minDistance, [villagers, houses, shops, trees])) { object.x = x; object.y = y; // Store original position for camera calculations object.x0 = x; object.y0 = y; game.addChild(object); container.push(object); placed = true; } attempts++; } } } // Place villagers randomly, but not too close to each other or the player start function placeVillagers() { villagers = []; var placed = 0; var sickPlaced = 0; while (placed < NUM_VILLAGERS) { var isSick = sickPlaced < NUM_SICK ? true : false; var villager = new Villager(); villager.init(isSick); // Random position in map bounds with padding from edges var x = 200 + Math.random() * (VILLAGE_WIDTH - 400); var y = 200 + Math.random() * (VILLAGE_HEIGHT - 400); if (isPositionClear(x, y, VILLAGER_MIN_DIST, [villagers, houses, shops, trees])) { villager.x = x; villager.y = y; // Store original position for camera calculations villager.x0 = x; villager.y0 = y; game.addChild(villager); villagers.push(villager); if (isSick) sickPlaced++; placed++; } } } // --- Player setup --- player = new PlagueDoctor(); playerWorldX = mapCenterX; // Initialize player world coordinates at map center playerWorldY = mapCenterY; // Initialize player world coordinates at map center player.x = mapCenterX; // Start player at map center player.y = mapCenterY; // Start player at map center game.addChild(player); // --- Place village objects --- // Place houses, shops and trees first placeObjects(House, NUM_HOUSES, 400, houses); placeObjects(ShopStand, NUM_SHOPS, 320, shops); placeObjects(Tree, NUM_TREES, 200, trees); // --- Villagers --- placeVillagers(); // --- Execute Button --- // Place execute button in the bottom left corner of the screen executeBtn = new ExecuteButton(); executeBtn.x = executeBtn.width * 0.7; // Position with some padding from left edge executeBtn.y = LK.gui.bottomLeft.height - executeBtn.height * 0.7; // Position with some padding from bottom LK.gui.bottomLeft.addChild(executeBtn); // --- D-Pad Controls (fit to screen, always visible in bottom middle using LK.gui.bottom) --- var dpadSize = Math.floor(LK.gui.bottom.width * 0.18); // Responsive size, ~18% of gui width if (dpadSize < 90) dpadSize = 90; if (dpadSize > 180) dpadSize = 180; // Further increase margin for even more space between keys var dpadMargin = Math.floor(dpadSize * 1.5); // Open up spacing between keys even more // Place the D-pad cluster in the bottom middle of the screen, moved higher up var dpadCenterX = LK.gui.bottom.width / 2; // Center horizontally var dpadCenterY = LK.gui.bottom.height - dpadSize * 3.5; // Position higher above bottom function createDPadBtns() { // Up var btnUp = new DPadButton(); btnUp.x = dpadCenterX; btnUp.y = dpadCenterY - dpadMargin; btnUp.icon = new Text2('▲', { size: Math.floor(dpadSize * 0.38), fill: "#222" }); btnUp.icon.anchor.set(0.5, 0.5); btnUp.addChild(btnUp.icon); LK.gui.bottom.addChild(btnUp); dpadBtns['up'] = btnUp; // Down var btnDown = new DPadButton(); btnDown.x = dpadCenterX; btnDown.y = dpadCenterY + dpadMargin; btnDown.icon = new Text2('▼', { size: Math.floor(dpadSize * 0.38), fill: "#222" }); btnDown.icon.anchor.set(0.5, 0.5); btnDown.addChild(btnDown.icon); LK.gui.bottom.addChild(btnDown); dpadBtns['down'] = btnDown; // Left var btnLeft = new DPadButton(); btnLeft.x = dpadCenterX - dpadMargin; btnLeft.y = dpadCenterY; btnLeft.icon = new Text2('◀', { size: Math.floor(dpadSize * 0.38), fill: "#222" }); btnLeft.icon.anchor.set(0.5, 0.5); btnLeft.addChild(btnLeft.icon); LK.gui.bottom.addChild(btnLeft); dpadBtns['left'] = btnLeft; // Right var btnRight = new DPadButton(); btnRight.x = dpadCenterX + dpadMargin; btnRight.y = dpadCenterY; btnRight.icon = new Text2('▶', { size: Math.floor(dpadSize * 0.38), fill: "#222" }); btnRight.icon.anchor.set(0.5, 0.5); btnRight.addChild(btnRight.icon); LK.gui.bottom.addChild(btnRight); dpadBtns['right'] = btnRight; } createDPadBtns(); // --- D-Pad event handling --- function dpadBtnForPos(x, y) { var r = dpadSize / 2; for (var dir in dpadBtns) { var btn = dpadBtns[dir]; var bx = btn.x; var by = btn.y; if ((x - bx) * (x - bx) + (y - by) * (y - by) < r * r) { return dir; } } return null; } // D-Pad touch/mouse down LK.gui.bottom.down = function (x, y, obj) { var dir = dpadBtnForPos(x, y); if (dir) { dpadState[dir] = true; draggingDPad = dir; tween(dpadBtns[dir].bg, { alpha: 1 }, { duration: 80 }); } }; // D-Pad touch/mouse up LK.gui.bottom.up = function (x, y, obj) { if (draggingDPad) { dpadState[draggingDPad] = false; tween(dpadBtns[draggingDPad].bg, { alpha: 0.7 }, { duration: 120 }); draggingDPad = null; } }; // D-Pad move (drag) LK.gui.bottom.move = function (x, y, obj) { if (draggingDPad) { var dir = dpadBtnForPos(x, y); if (dir === draggingDPad) { if (!dpadState[dir]) { dpadState[dir] = true; tween(dpadBtns[dir].bg, { alpha: 1 }, { duration: 80 }); } } else { if (dpadState[draggingDPad]) { dpadState[draggingDPad] = false; tween(dpadBtns[draggingDPad].bg, { alpha: 0.7 }, { duration: 120 }); } } } }; // --- Execute Button event handling --- LK.gui.bottomLeft.down = function (x, y, obj) { // Check if the click is within the execute button bounds if (executeBtn.visible && x >= executeBtn.x - executeBtn.width / 2 && x <= executeBtn.x + executeBtn.width / 2 && y >= executeBtn.y - executeBtn.height / 2 && y <= executeBtn.y + executeBtn.height / 2) { if (canExecuteVillager && canExecuteVillager.isAlive) { canExecuteVillager.execute(); sickLeft--; sickLeftTxt.setText('Sick left: ' + sickLeft); executeBtn.visible = false; canExecuteVillager = null; // Win condition if (sickLeft === 0) { LK.showYouWin(); } } } }; // --- Main game move handler (for dragging player, not used here) --- game.move = function (x, y, obj) { // No drag-to-move, only D-pad }; // --- Main game update loop --- game.update = function () { // --- Player movement --- var dx = 0, dy = 0; if (dpadState.left) dx -= 1; if (dpadState.right) dx += 1; if (dpadState.up) dy -= 1; if (dpadState.down) dy += 1; if (dx !== 0 || dy !== 0) { var len = Math.sqrt(dx * dx + dy * dy); if (len > 0) { dx /= len; dy /= len; } // Store player's world coordinates separately from rendering position playerWorldX += dx * player.speed; playerWorldY += dy * player.speed; } // Clamp player to world coordinates map bounds with consistent padding on all sides playerWorldX = clamp(playerWorldX, 60, VILLAGE_WIDTH - 60); playerWorldY = clamp(playerWorldY, 60, VILLAGE_HEIGHT - 60); // --- Camera scrolling (horizontal and vertical) --- var screenCenterX = 2048 / 2; // Use fixed resolution width var screenCenterY = 2732 / 2; // Use fixed resolution height // Calculate camera position to center player cameraX = playerWorldX - screenCenterX; cameraY = playerWorldY - screenCenterY; // Clamp camera to map bounds cameraX = clamp(cameraX, 0, VILLAGE_WIDTH - 2048); cameraY = clamp(cameraY, 0, VILLAGE_HEIGHT - 2732); // Move all game children (player, villagers, houses, shops, trees) relative to camera position for (var i = 0; i < game.children.length; ++i) { var obj = game.children[i]; obj.visible = true; if (obj === player) { // Position player on screen based on world coordinates obj.x = playerWorldX - cameraX; obj.y = playerWorldY - cameraY; } else if (obj instanceof Villager || obj instanceof House || obj instanceof ShopStand || obj instanceof Tree) { // Position objects on screen based on their world coordinates // Make sure we're using the stored world coordinates consistently obj.x = obj.x0 - cameraX; obj.y = obj.y0 - cameraY; // Hide objects that are completely outside the visible area if (obj.x < -300 || obj.x > 2348 || obj.y < -300 || obj.y > 3032) { obj.visible = false; } } } // --- Villager proximity check --- canExecuteVillager = null; for (var i = 0; i < villagers.length; ++i) { var villager = villagers[i]; if (!villager.isAlive || !villager.isSick) continue; // Use world coordinates for collision var px = playerWorldX; var py = playerWorldY; var vx = villager.x0; // Always use stored world coordinates var vy = villager.y0; // Always use stored world coordinates var dist = Math.sqrt((px - vx) * (px - vx) + (py - vy) * (py - vy)); if (dist < 140) { canExecuteVillager = villager; break; } } // --- Execute button visibility --- if (canExecuteVillager && canExecuteVillager.isAlive) { executeBtn.visible = true; } else { executeBtn.visible = false; } }; // --- Store original world positions for all village objects (for camera) --- function storeVillagerPositions() { // Store villager positions for (var i = 0; i < villagers.length; ++i) { villagers[i].x0 = villagers[i].x; villagers[i].y0 = villagers[i].y; } // Store house positions for (var i = 0; i < houses.length; ++i) { houses[i].x0 = houses[i].x; houses[i].y0 = houses[i].y; } // Store shop positions for (var i = 0; i < shops.length; ++i) { shops[i].x0 = shops[i].x; shops[i].y0 = shops[i].y; } // Store tree positions for (var i = 0; i < trees.length; ++i) { trees[i].x0 = trees[i].x; trees[i].y0 = trees[i].y; } } // Store initial positions storeVillagerPositions(); // --- Initial camera position --- cameraX = mapCenterX - 2048 / 2; // Start camera centered on the player using fixed width cameraY = mapCenterY - 2732 / 2; // Start camera centered on the player using fixed height for (var i = 0; i < game.children.length; ++i) { var obj = game.children[i]; if (obj === player) { obj.x = player.x - cameraX; obj.y = player.y - cameraY; } else if (obj instanceof Villager || obj instanceof House || obj instanceof ShopStand || obj instanceof Tree) { obj.x = obj.x0 - cameraX; obj.y = obj.y0 - cameraY; } }
===================================================================
--- original.js
+++ change.js
@@ -33,8 +33,54 @@
self.addChild(self.label);
self.visible = false;
return self;
});
+// House class
+var House = Container.expand(function () {
+ var self = Container.call(this);
+ // Create house body
+ self.body = new Container();
+ self.addChild(self.body);
+ // House base
+ self.base = self.body.attachAsset('Sickvligers', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 3.6,
+ scaleY: 2.8
+ });
+ self.base.tint = 0x8B4513; // Brown color for house
+ // House roof
+ self.roof = new Container();
+ self.roof.y = -self.base.height * 0.4;
+ self.body.addChild(self.roof);
+ self.roofAsset = self.roof.attachAsset('Sickvligers', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 4.0,
+ scaleY: 1.6
+ });
+ self.roofAsset.tint = 0xA52A2A; // Dark red for roof
+ // Door
+ self.door = self.body.attachAsset('Sickvligers', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.8,
+ scaleY: 1.4,
+ y: self.base.height * 0.15
+ });
+ self.door.tint = 0x4B2F17; // Dark wood door
+ // Window
+ self.window = self.body.attachAsset('Sickvligers', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.8,
+ scaleY: 0.8,
+ x: self.base.width * 0.25,
+ y: -self.base.height * 0.1
+ });
+ self.window.tint = 0xADD8E6; // Light blue window
+ return self;
+});
// Plague Doctor (player) class
var PlagueDoctor = Container.expand(function () {
var self = Container.call(this);
var doctorSprite = self.attachAsset('plagueDoctor', {
@@ -52,8 +98,66 @@
};
};
return self;
});
+// Shop Stand class
+var ShopStand = Container.expand(function () {
+ var self = Container.call(this);
+ // Shop stand base
+ self.base = self.attachAsset('Sickvligers', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 2.6,
+ scaleY: 1.4
+ });
+ self.base.tint = 0x8B4513; // Brown wood
+ // Shop stand canopy
+ self.canopy = self.attachAsset('Sickvligers', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 3.0,
+ scaleY: 0.8,
+ y: -self.base.height * 0.7
+ });
+ self.canopy.tint = 0xE34234; // Red canopy
+ // Shop items (fruits/goods)
+ for (var i = 0; i < 3; i++) {
+ var item = self.attachAsset('Sickvligers', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.5,
+ scaleY: 0.5,
+ x: (i - 1) * 40,
+ y: -20
+ });
+ // Random item colors
+ var colors = [0xFFFF00, 0xFF0000, 0x00FF00]; // Yellow, red, green
+ item.tint = colors[i];
+ }
+ return self;
+});
+// Tree class
+var Tree = Container.expand(function () {
+ var self = Container.call(this);
+ // Tree trunk
+ self.trunk = self.attachAsset('Sickvligers', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.8,
+ scaleY: 2.0
+ });
+ self.trunk.tint = 0x8B4513; // Brown
+ // Tree foliage
+ self.foliage = self.attachAsset('Sickvligers', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 2.4,
+ scaleY: 2.4,
+ y: -80
+ });
+ self.foliage.tint = 0x228B22; // Forest green
+ return self;
+});
// Villager class
var Villager = Container.expand(function () {
var self = Container.call(this);
self.isSick = false;
@@ -111,14 +215,20 @@
// Plague Doctor (player)
// --- Game constants ---
var VILLAGE_WIDTH = 6144; // Expanded map width (3x standard screen width)
var VILLAGE_HEIGHT = 4096; // Expanded map height (2x standard screen height)
-var NUM_VILLAGERS = 30; // More villagers for the larger map
-var NUM_SICK = 10; // More sick villagers
+var NUM_VILLAGERS = 40; // More villagers for the larger map
+var NUM_SICK = 15; // More sick villagers
var VILLAGER_MIN_DIST = 220; // Minimum distance between villagers
+var NUM_HOUSES = 15; // Number of houses to place
+var NUM_SHOPS = 10; // Number of shop stands
+var NUM_TREES = 25; // Number of trees
// --- Game state ---
var player;
var villagers = [];
+var houses = [];
+var shops = [];
+var trees = [];
var sickLeft = NUM_SICK;
var executeBtn;
var dpadBtns = {};
var dpadState = {
@@ -155,8 +265,55 @@
// --- Map and villagers setup ---
// Starting position is the center of the map (no offset needed for scrolling map)
var mapCenterX = VILLAGE_WIDTH / 2;
var mapCenterY = VILLAGE_HEIGHT / 2;
+// Check if a position is clear for placing objects (no collision with existing objects)
+function isPositionClear(x, y, radius, objectArrays) {
+ // Check distance from map center (player start)
+ if (Math.abs(x - mapCenterX) < 300 && Math.abs(y - mapCenterY) < 300) {
+ return false;
+ }
+ // Check distance from existing objects
+ for (var i = 0; i < objectArrays.length; i++) {
+ var objects = objectArrays[i];
+ for (var j = 0; j < objects.length; j++) {
+ var obj = objects[j];
+ var dx = x - obj.x;
+ var dy = y - obj.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < radius) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+// Place objects randomly on the map
+function placeObjects(objectClass, count, minDistance, container) {
+ for (var i = 0; i < count; i++) {
+ var object = new objectClass();
+ // Try to find a valid position
+ var x, y;
+ var attempts = 0;
+ var placed = false;
+ while (!placed && attempts < 50) {
+ // Random position with padding from edges
+ x = 200 + Math.random() * (VILLAGE_WIDTH - 400);
+ y = 200 + Math.random() * (VILLAGE_HEIGHT - 400);
+ if (isPositionClear(x, y, minDistance, [villagers, houses, shops, trees])) {
+ object.x = x;
+ object.y = y;
+ // Store original position for camera calculations
+ object.x0 = x;
+ object.y0 = y;
+ game.addChild(object);
+ container.push(object);
+ placed = true;
+ }
+ attempts++;
+ }
+ }
+}
// Place villagers randomly, but not too close to each other or the player start
function placeVillagers() {
villagers = [];
var placed = 0;
@@ -167,27 +324,19 @@
villager.init(isSick);
// Random position in map bounds with padding from edges
var x = 200 + Math.random() * (VILLAGE_WIDTH - 400);
var y = 200 + Math.random() * (VILLAGE_HEIGHT - 400);
- // Don't place too close to player start (map center)
- if (Math.abs(x - mapCenterX) < 300 && Math.abs(y - mapCenterY) < 300) continue;
- // Don't place too close to other villagers
- var tooClose = false;
- for (var i = 0; i < villagers.length; ++i) {
- var dx = x - villagers[i].x;
- var dy = y - villagers[i].y;
- if (Math.sqrt(dx * dx + dy * dy) < VILLAGER_MIN_DIST) {
- tooClose = true;
- break;
- }
+ if (isPositionClear(x, y, VILLAGER_MIN_DIST, [villagers, houses, shops, trees])) {
+ villager.x = x;
+ villager.y = y;
+ // Store original position for camera calculations
+ villager.x0 = x;
+ villager.y0 = y;
+ game.addChild(villager);
+ villagers.push(villager);
+ if (isSick) sickPlaced++;
+ placed++;
}
- if (tooClose) continue;
- villager.x = x;
- villager.y = y;
- game.addChild(villager);
- villagers.push(villager);
- if (isSick) sickPlaced++;
- placed++;
}
}
// --- Player setup ---
player = new PlagueDoctor();
@@ -195,8 +344,13 @@
playerWorldY = mapCenterY; // Initialize player world coordinates at map center
player.x = mapCenterX; // Start player at map center
player.y = mapCenterY; // Start player at map center
game.addChild(player);
+// --- Place village objects ---
+// Place houses, shops and trees first
+placeObjects(House, NUM_HOUSES, 400, houses);
+placeObjects(ShopStand, NUM_SHOPS, 320, shops);
+placeObjects(Tree, NUM_TREES, 200, trees);
// --- Villagers ---
placeVillagers();
// --- Execute Button ---
// Place execute button in the bottom left corner of the screen
@@ -378,23 +532,23 @@
cameraY = playerWorldY - screenCenterY;
// Clamp camera to map bounds
cameraX = clamp(cameraX, 0, VILLAGE_WIDTH - 2048);
cameraY = clamp(cameraY, 0, VILLAGE_HEIGHT - 2732);
- // Move all game children (player, villagers) relative to camera position
+ // Move all game children (player, villagers, houses, shops, trees) relative to camera position
for (var i = 0; i < game.children.length; ++i) {
var obj = game.children[i];
obj.visible = true;
if (obj === player) {
// Position player on screen based on world coordinates
obj.x = playerWorldX - cameraX;
obj.y = playerWorldY - cameraY;
- } else if (obj instanceof Villager) {
- // Position villagers on screen based on their world coordinates
+ } else if (obj instanceof Villager || obj instanceof House || obj instanceof ShopStand || obj instanceof Tree) {
+ // Position objects on screen based on their world coordinates
// Make sure we're using the stored world coordinates consistently
obj.x = obj.x0 - cameraX;
obj.y = obj.y0 - cameraY;
// Hide objects that are completely outside the visible area
- if (obj.x < -200 || obj.x > 2248 || obj.y < -200 || obj.y > 2932) {
+ if (obj.x < -300 || obj.x > 2348 || obj.y < -300 || obj.y > 3032) {
obj.visible = false;
}
}
}
@@ -420,14 +574,30 @@
} else {
executeBtn.visible = false;
}
};
-// --- Store original world positions for villagers (for camera) ---
+// --- Store original world positions for all village objects (for camera) ---
function storeVillagerPositions() {
+ // Store villager positions
for (var i = 0; i < villagers.length; ++i) {
villagers[i].x0 = villagers[i].x;
villagers[i].y0 = villagers[i].y;
}
+ // Store house positions
+ for (var i = 0; i < houses.length; ++i) {
+ houses[i].x0 = houses[i].x;
+ houses[i].y0 = houses[i].y;
+ }
+ // Store shop positions
+ for (var i = 0; i < shops.length; ++i) {
+ shops[i].x0 = shops[i].x;
+ shops[i].y0 = shops[i].y;
+ }
+ // Store tree positions
+ for (var i = 0; i < trees.length; ++i) {
+ trees[i].x0 = trees[i].x;
+ trees[i].y0 = trees[i].y;
+ }
}
// Store initial positions
storeVillagerPositions();
// --- Initial camera position ---
@@ -437,9 +607,9 @@
var obj = game.children[i];
if (obj === player) {
obj.x = player.x - cameraX;
obj.y = player.y - cameraY;
- } else if (obj instanceof Villager) {
+ } else if (obj instanceof Villager || obj instanceof House || obj instanceof ShopStand || obj instanceof Tree) {
obj.x = obj.x0 - cameraX;
obj.y = obj.y0 - cameraY;
}
}
\ No newline at end of file
Kill button. In-Game asset. 2d. High contrast. No shadows
Palugue doctors full body pixel art. In-Game asset. 2d. High contrast. No shadows
Sick viliger pixel art full body
Not sick viliger pixel art
Pixel art death block.
Viliger house pixel art. In-Game asset. 2d. High contrast. No shadows
Background sand image pixel art. 4k In-Game asset. 2d. High contrast. No shadows