<h3>Instructions for Users</h3> <p>Middle Mouse Click to open the build Menu Gather: Wood, Stone People, And Food Build more storages for Wood and Stone Fight off the hordes of Zombies that come at night if the game crashes, you have lost, it is not a bug, defintetly</p>
xxxxxxxxxx
function draw() {
circle(mouseX, mouseY, 20);
}let semiBoolGridZombie = [];
let semiBoolGridPlayer = [];
let gridLineX = [];
let gridLineY = [];
let zombies = [];
let zombieSpawners = [];
let buildings = [];
let projectiles = []
let listTree = [];
let listMountain = [];
let mouseXGrid = 0;
let mouseYGrid = 0;
let offTitle = false;
let lengthOfSunGone = 0;
let lengthOfSunGoneDif = 30000;
let isDay = true;
let nightsSurvived = 0;
let credits = 0;
let r = 115;
let g = 240;
let b = 120;
let buildMenuX = 0
let buildMenuY = 0
let homeBaseDown = false
let peoplesLeft = 5
let peoplesTotal = 5
let storageStone = 500
let storageWood = 500
let wood = 200
let stone = 100
let food = 10
function setup() {
textSize(10)
createCanvas(1800, 1800);
// the table was made with help from chatGPT
for (let i = 0; i < width / 10; i++) {
let innerArray = [];
gridLineX.push(i * 10);
gridLineY.push(i * 10);
for (let j = 0; j < height / 10; j++) {
innerArray.push("empty");
}
semiBoolGridZombie.push(innerArray.concat());
semiBoolGridPlayer.push(innerArray.concat());
}
for (let i = 300; i < width - 300; i++) {
if (random(0, 301) > 297) {
let randomTreeY = floor(random(100, height - 100));
createForest(
i,
randomTreeY,
random(20, 100),
random(30, 70),
random(30, 200)
);
}
}
for (let i = 300; i < width - 300; i++) {
if (random(0, 500) > 497) {
let randomMountainY = floor(random(300, height - 300));
createMountain(
i,
randomMountainY,
random(50, 200),
random(0, 360),
random(50, 180)
);
}
}
} //end setup
function draw() {
textAlign(CENTER, CENTER)
background(r, g, b);
if (!offTitle) {
} else {
if (millis() > lengthOfSunGone && isDay) {
isDay = false;
r = 5;
g = 30;
b = 30;
lengthOfSunGone += lengthOfSunGoneDif;
nightsSurvived += 1
credits = floor(
Math.pow(nightsSurvived + 5, 2) + 20 * (nightsSurvived / 2)
);
setSpawners(nightsSurvived);
}
if (millis() > lengthOfSunGone - lengthOfSunGoneDif / 3 && isDay) {
r = 225;
g = 220;
b = 65;
}
if (millis() > lengthOfSunGone && !isDay) {
isDay = true;
r = 115;
g = 240;
b = 120;
lengthOfSunGone += lengthOfSunGoneDif;
for (let i = 0; (zombieSpawners.length = 0);) {
zombieSpawners.splice(i, 1);
i--;
}
let numOfFarms = 0
for (let i = 0; i < buildings.length; i++) {
if (buildings[i] instanceof Farm) {
numOfFarms++
}
if (buildings[i] instanceof Mine) {
stone += buildings[i].resourscesProduced
} if (buildings[i] instanceof Lumber) {
wood += buildings[i].resourscesProduced
buildings[i].checkWoodTotalToProduce()
}
}
food += numOfFarms * 5
food -= peoplesTotal
if (storageStone > stone) {
stone = storageStone
} if (storageWood > wood)
wood = storageWood
}
mouseXGrid = mouseX - (mouseX % 10);
mouseYGrid = mouseY - (mouseY % 10);
strokeWeight(1);
stroke(0);
for (let i = 0; i < gridLineX.length; i++) {
line(gridLineX[i], 0, gridLineX[i], height);
}
for (let i = 0; i < gridLineY.length; i++) {
line(0, gridLineY[i], width, gridLineY[i]);
}
fill(200);
noStroke();
square(mouseXGrid, mouseYGrid, 10);
fill(50, 205, 50);
for (let i = 0; i < listTree.length; i++) {
listTree[i].display();
}
fill(100);
for (let i = 0; i < listMountain.length; i++) {
listMountain[i].display();
}
strokeWeight(1);
stroke(255);
for (let i = 0; i < buildings.length; i++) {
buildings[i].display()
if (buildings[i].health <= 0) {
for (let j = 0; j < buildings[i].id.length; j++) {
let removeX = buildings[i].id[j] % 180
let removeY = floor(buildings[i].id[j] / 180)
let removePotential = listTree.findIndex(listTree => listTree.id == removeX + removeY * 180)
if (removePotential != -1) {
listTree.splice(removePotential, 1)
}
semiBoolGridPlayer[removeX][removeY] = 'empty'
semiBoolGridZombie[removeX][removeY] = 'empty'
buildings[i].id.splice(j, 1)
j--
}
if (buildings[i] instanceof House) {
peoplesLeft -= 5
peoplesTotal -= 5
} else {
peoplesTotal -= buildings[i].peoplesUsed
}
buildings.splice(i, 1)
i--
}
if (buildings[i].doesAttack) {
if (buildings[i].cooldown < millis()) {
buildings[i].attack()
buildings[i].cooldown += buildings[i].attackColldowjn
} if (buildings[i].cooldown > millis() && buildings[i].target[2] != -1) {
line(buildings[i].x * 10 + 10, buildings[i].y * 10 + 10, buildings[i].target[0] * 10 + 5, buildings[i].target[1] * 10 + 5)
}
}
}
for (let i = 0; i < zombies.length; i++) {
if (zombies[i].health <= 0) {
semiBoolGridZombie[zombies[i].x][zombies[i].y] = 'empty'
zombies.splice(i, 1)
i--
break
}
zombies[i].display();
if (zombies[i].timer < millis()) {
if (!(zombies[i].x == 0 || zombies[i].x == 179 || zombies[i].y == 0 || zombies[i].y == 179)) {
if ((semiBoolGridZombie[(zombies[i].x)][(zombies[i].y) + 1] == 'building' ||
semiBoolGridZombie[(zombies[i].x)][(zombies[i].y) - 1] == 'building' ||
semiBoolGridZombie[(zombies[i].x) - 1][(zombies[i].y)] == 'building' ||
semiBoolGridZombie[(zombies[i].x) + 1][(zombies[i].y)] == 'building')) {
zombies[i].attack()
} else {
zombies[i].timesStuck += 1;
zombies[i].move();
}
} else {
zombies[i].timesStuck += 1;
zombies[i].move();
}
zombies[i].timer += zombies[i].moveCooldown;
}
}
fill(255, 0, 0);
for (let i = 0; i < zombieSpawners.length; i++) {
zombieSpawners[i].display();
zombieSpawners[i].spawn();
}
for (let i = 0; i < projectiles.length; i++) {
projectiles[i].show();
if (projectiles[i].time <= millis()) {
projectiles[i].attack();
projectiles.splice(i, 1)
i--
}
}
}
if (mouseButton == CENTER) {
buildMenu(buildMenuX, buildMenuY)
}
} //end draw
function keyPressed() {
if (
semiBoolGridZombie[mouseXGrid / 10][mouseYGrid / 10] != 'zombie' &&
(key == "q" || key == "Q")
) {
zombies.push(new Zombie(mouseXGrid, mouseYGrid));
} else if (
semiBoolGridZombie[mouseXGrid / 10][mouseYGrid / 10] != 'zombie' &&
(key == "s" || key == "S")
) {
zombies.push(new SpeedZombie(mouseXGrid, mouseYGrid));
} else if (
semiBoolGridZombie[mouseXGrid / 10][mouseYGrid / 10] != 'zombie' &&
(key == "C" || key == "c")
) {
zombies.push(new ChunkyZombie(mouseXGrid, mouseYGrid));
}
}
function createForest(x, y, r, angleStart, angleEnd) {
let rLimit = r;
let x1, y1;
let aE = angleStart + angleEnd;
for (let r = 0; r < rLimit; r += 10) {
for (i = angleStart; i < aE; i += 1) {
x1 = floor(r * cos((i * Math.PI) / 180));
y1 = floor(r * sin((i * Math.PI) / 180));
if (
semiBoolGridPlayer[floor((x1 + x) / 10)][floor((y1 + y) / 10)] != "tree"
) {
listTree.push(new Tree(floor((x1 + x) / 10), floor((y1 + y) / 10)));
}
}
}
}
function createMountain(x, y, r, angleStart, angleEnd) {
let x1, y1;
let aE = angleStart + angleEnd;
for (i = angleStart; i < aE; i += 1) {
x1 = floor(r * cos((i * Math.PI) / 180));
y1 = floor(r * sin((i * Math.PI) / 180));
if (
semiBoolGridPlayer[floor((x1 + x) / 10)][floor((y1 + y) / 10)] !=
"mountain"
) {
listMountain.push(
new Mountain(floor((x1 + x) / 10), floor((y1 + y) / 10))
);
}
if (
semiBoolGridPlayer[floor((x1 + x) / 10) + 1][floor((y1 + y) / 10)] !=
"mountain"
) {
listMountain.push(
new Mountain(floor((x1 + x) / 10) + 1, floor((y1 + y) / 10))
);
}
}
}
function setSpawners() {
for (let i = 0; i < width / 10; i++) {
zombieSpawners.push(new ZombieSpawner(i, 0));
zombieSpawners.push(new ZombieSpawner(i, 179));
}
for (let i = 1; i < (height / 10) - 1; i++) {
zombieSpawners.push(new ZombieSpawner(0, i));
zombieSpawners.push(new ZombieSpawner(179, i));
}
let creditsToGive = ceil(credits / zombieSpawners.length);
let creditsPerSpawner = credits / zombieSpawners.length
for (let i = 0; i < zombieSpawners.length; i++) {
if (random(0, 1) > creditsPerSpawner / creditsToGive) {
creditsToGive--
}
zombieSpawners[i].creditsAllocated = creditsToGive
zombieSpawners[i].setSpawnOrder()
credits -= creditsToGive
creditsToGive = ceil(credits / zombieSpawners.length)
creditsPerSpawner = credits / zombieSpawners.length
}
}
function mousePressed() {
if (!offTitle) {
lengthOfSunGone = millis() + lengthOfSunGoneDif;
offTitle = true;
} else if (mouseButton == CENTER) {
buildMenuX = mouseXGrid
buildMenuY = mouseYGrid
}
if (!homeBaseDown) {
if (mouseX > buildMenuX + 75 && mouseX < buildMenuX + 125 && mouseY > buildMenuY + 125 && mouseY < buildMenuY + 175) {
semiBoolGridPlayer[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 2][buildMenuY / 10] = 'building'
semiBoolGridPlayer[buildMenuX / 10][(buildMenuY / 10) + 1] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 2][(buildMenuY / 10) + 1] = 'building'
semiBoolGridPlayer[buildMenuX / 10][(buildMenuY / 10) + 2] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][(buildMenuY / 10) + 2] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 2][(buildMenuY / 10) + 2] = 'building'
semiBoolGridZombie[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 2][buildMenuY / 10] = 'building'
semiBoolGridZombie[buildMenuX / 10][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 2][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[buildMenuX / 10][(buildMenuY / 10) + 2] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][(buildMenuY / 10) + 2] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 2][(buildMenuY / 10) + 2] = 'building'
homeBaseDown = true
buildings.push(new HomeBase(buildMenuX / 10, buildMenuY / 10))
}
} else if (semiBoolGridPlayer[buildMenuX / 10][buildMenuY / 10] != 'building' &&
semiBoolGridPlayer[(buildMenuX / 10) + 1][buildMenuY / 10] != 'building' &&
semiBoolGridPlayer[(buildMenuX / 10)][(buildMenuY / 10) + 1] != 'building' &&
semiBoolGridPlayer[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] != 'building' &&
semiBoolGridPlayer[buildMenuX / 10][buildMenuY / 10] != 'mountain' &&
semiBoolGridPlayer[(buildMenuX / 10) + 1][buildMenuY / 10] != 'mountain' &&
semiBoolGridPlayer[(buildMenuX / 10)][(buildMenuY / 10) + 1] != 'mountain' &&
semiBoolGridPlayer[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] != 'mountain' &&
semiBoolGridZombie[buildMenuX / 10][buildMenuY / 10] != 'zombie' &&
semiBoolGridZombie[(buildMenuX / 10) + 1][buildMenuY / 10] != 'zombie' &&
semiBoolGridZombie[(buildMenuX / 10)][(buildMenuY / 10) + 1] != 'zombie' &&
semiBoolGridZombie[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] != 'zombie') {
if ((mouseX > buildMenuX + 25 && mouseX < buildMenuX + 75 && mouseY > buildMenuY + 25 && mouseY < buildMenuY + 75) && wood >= 10 && stone >= 20 && peoplesLeft >= 1) {
stone -= 10
wood -= 20
peoplesLeft -= 1
semiBoolGridPlayer[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10)][(buildMenuY / 10) + 1] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10)][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
buildings.push(new Tower(buildMenuX / 10, buildMenuY / 10))
} else if ((mouseX > buildMenuX + 125 && mouseX < buildMenuX + 175 && mouseY > buildMenuY + 25 && mouseY < buildMenuY + 75) && wood >= 40 && stone >= 40 && peoplesLeft >= 2) {
stone -= 40
wood -= 40
peoplesLeft -= 2
semiBoolGridPlayer[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10)][(buildMenuY / 10) + 1] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10)][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
buildings.push(new Mortar(buildMenuX / 10, buildMenuY / 10))
} else if ((mouseX > buildMenuX + 25 && mouseX < buildMenuX + 75 && mouseY > buildMenuY + 125 && mouseY < buildMenuY + 175) && wood >= 10 && stone >= 5) {
stone -= 5
wood -= 10
semiBoolGridPlayer[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10)][(buildMenuY / 10) + 1] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10)][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
buildings.push(new House(buildMenuX / 10, buildMenuY / 10))
} else if ((mouseX > buildMenuX + 125 && mouseX < buildMenuX + 175 && mouseY > buildMenuY + 125 && mouseY < buildMenuY + 175) && wood >= 15 && peoplesLeft >= 1) {
wood -= 15
peoplesLeft--
semiBoolGridPlayer[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10)][(buildMenuY / 10) + 1] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10)][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
buildings.push(new Farm(buildMenuX / 10, buildMenuY / 10))
} else if ((mouseX > buildMenuX + 25 && mouseX < buildMenuX + 75 && mouseY > buildMenuY + 225 && mouseY < buildMenuY + 275) && wood >= 30 && peoplesLeft >= 1) {
wood -= 30
peoplesLeft--
semiBoolGridPlayer[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10)][(buildMenuY / 10) + 1] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10)][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
buildings.push(new Mine(buildMenuX / 10, buildMenuY / 10))
} else if ((mouseX > buildMenuX + 125 && mouseX < buildMenuX + 175 && mouseY > buildMenuY + 225 && mouseY < buildMenuY + 275) && stone >= 20 && peoplesLeft >= 1) {
stone -= 20
peoplesLeft--
semiBoolGridPlayer[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10)][(buildMenuY / 10) + 1] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10)][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
buildings.push(new Lumber(buildMenuX / 10, buildMenuY / 10))
buildings[buildings.length - 1].checkWoodTotalToProduce()
} else if ((mouseX > buildMenuX + 25 && mouseX < buildMenuX + 75 && mouseY > buildMenuY + 325 && mouseY < buildMenuY + 375) && wood >= 20 && stone >= 20) {
wood -= 20
stone -= 20
semiBoolGridPlayer[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10)][(buildMenuY / 10) + 1] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10)][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
buildings.push(new StorageStoneBuilding(buildMenuX / 10, buildMenuY / 10))
} else if ((mouseX > buildMenuX + 125 && mouseX < buildMenuX + 175 && mouseY > buildMenuY + 325 && mouseY < buildMenuY + 375) && stone >= 20 && stone >= 20) {
stone -= 20
wood -= 20
semiBoolGridPlayer[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridPlayer[(buildMenuX / 10)][(buildMenuY / 10) + 1] = 'building'
semiBoolGridPlayer[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[buildMenuX / 10][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][buildMenuY / 10] = 'building'
semiBoolGridZombie[(buildMenuX / 10)][(buildMenuY / 10) + 1] = 'building'
semiBoolGridZombie[(buildMenuX / 10) + 1][(buildMenuY / 10) + 1] = 'building'
buildings.push(new StorageWoodBuilding(buildMenuX / 10, buildMenuY / 10))
}
} else {
if (buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))] instanceof Tower && (mouseX > buildMenuX + 75 && mouseX < buildMenuX + 125 && mouseY > buildMenuY + 125 && mouseY < buildMenuY + 175)) {
let buildingI = buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))
peoplesLeft += 1
semiBoolGridPlayer[buildings[buildingI].x][buildings[buildingI].y] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x + 1][buildings[buildingI].y] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x][buildings[buildingI].y + 1] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x + 1][buildings[buildingI].y + 1] = 'empty'
buildings.splice(buildingI, 1)
} else if (buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))] instanceof Mortar && (mouseX > buildMenuX + 75 && mouseX < buildMenuX + 125 && mouseY > buildMenuY + 125 && mouseY < buildMenuY + 175)) {
let buildingI = buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))
peoplesLeft += 2
semiBoolGridPlayer[buildings[buildingI].x][buildings[buildingI].y] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x + 1][buildings[buildingI].y] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x][buildings[buildingI].y + 1] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x + 1][buildings[buildingI].y + 1] = 'empty'
buildings.splice(buildingI, 1)
} else if (buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))] instanceof Farm && (mouseX > buildMenuX + 75 && mouseX < buildMenuX + 125 && mouseY > buildMenuY + 125 && mouseY < buildMenuY + 175)) {
let buildingI = buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))
peoplesLeft += 1
semiBoolGridPlayer[buildings[buildingI].x][buildings[buildingI].y] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x + 1][buildings[buildingI].y] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x][buildings[buildingI].y + 1] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x + 1][buildings[buildingI].y + 1] = 'empty'
buildings.splice(buildingI, 1)
} else if (buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))] instanceof Lumber && (mouseX > buildMenuX + 75 && mouseX < buildMenuX + 125 && mouseY > buildMenuY + 125 && mouseY < buildMenuY + 175)) {
let buildingI = buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))
peoplesLeft += 1
semiBoolGridPlayer[buildings[buildingI].x][buildings[buildingI].y] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x + 1][buildings[buildingI].y] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x][buildings[buildingI].y + 1] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x + 1][buildings[buildingI].y + 1] = 'empty'
buildings.splice(buildingI, 1)
} else if (buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))] instanceof Mine && (mouseX > buildMenuX + 75 && mouseX < buildMenuX + 125 && mouseY > buildMenuY + 125 && mouseY < buildMenuY + 175)) {
let buildingI = buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))
peoplesLeft += 1
semiBoolGridPlayer[buildings[buildingI].x][buildings[buildingI].y] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x + 1][buildings[buildingI].y] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x][buildings[buildingI].y + 1] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x + 1][buildings[buildingI].y + 1] = 'empty'
buildings.splice(buildingI, 1)
} else if (buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))] instanceof House && (mouseX > buildMenuX + 75 && mouseX < buildMenuX + 125 && mouseY > buildMenuY + 125 && mouseY < buildMenuY + 175) && peoplesLeft - 5 >= 0) {
let buildingI = buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))
peoplesLeft -= 5
peoplesTotal -= 5
semiBoolGridPlayer[buildings[buildingI].x][buildings[buildingI].y] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x + 1][buildings[buildingI].y] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x][buildings[buildingI].y + 1] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x + 1][buildings[buildingI].y + 1] = 'empty'
buildings.splice(buildingI, 1)
} else if (buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))] instanceof StorageStoneBuilding && (mouseX > buildMenuX + 75 && mouseX < buildMenuX + 125 && mouseY > buildMenuY + 125 && mouseY < buildMenuY + 175)) {
let buildingI = buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))
storageStone -= 300
semiBoolGridPlayer[buildings[buildingI].x][buildings[buildingI].y] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x + 1][buildings[buildingI].y] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x][buildings[buildingI].y + 1] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x + 1][buildings[buildingI].y + 1] = 'empty'
buildings.splice(buildingI, 1)
} else if (buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))] instanceof StorageWoodBuilding && (mouseX > buildMenuX + 75 && mouseX < buildMenuX + 125 && mouseY > buildMenuY + 125 && mouseY < buildMenuY + 175)) {
let buildingI = buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))
storageWood -= 300
semiBoolGridPlayer[buildings[buildingI].x][buildings[buildingI].y] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x + 1][buildings[buildingI].y] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x][buildings[buildingI].y + 1] = 'empty'
semiBoolGridPlayer[buildings[buildingI].x + 1][buildings[buildingI].y + 1] = 'empty'
buildings.splice(buildingI, 1)
}
}
}
function buildMenu(x, y) {
x += 10
y += 10
if (x + 200 > width) {
x = width - 200
}
if (y + 400 > height) {
y = height - 400
}
fill(100)
strokeWeight(1)
stroke(0)
rect(x, y, 200, 400)
rectMode(CENTER)
fill(255)
if (!homeBaseDown) {
rect(x + 100, y + 150, 50, 50)
text("Home Base", x + 100, y + 150)
} else if (semiBoolGridPlayer[buildMenuX / 10][buildMenuY / 10] == 'building') {
if (buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))] instanceof HomeBase) {
//chatgpt saved me, I needed to find a specific value in an array in an object in an array of objectsaa
text("There are no options \navailabe for this building.", x + 100, y + 200)
} else if (buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))] instanceof Tower) {
rect(x + 100, y + 150, 50, 50)
text("Destroy.", x + 100, y + 200)
} else if (buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))] instanceof Mortar) {
rect(x + 100, y + 150, 50, 50)
text("Destroy.", x + 100, y + 200)
} else if (buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))] instanceof Farm) {
rect(x + 100, y + 150, 50, 50)
text("Destroy.", x + 100, y + 200)
} else if (buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))] instanceof House) {
rect(x + 100, y + 150, 50, 50)
text("Destroy.", x + 100, y + 200)
} else if (buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))] instanceof Mine) {
rect(x + 100, y + 150, 50, 50)
text("Destroy.", x + 100, y + 200)
} else if (buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))] instanceof Lumber) {
rect(x + 100, y + 150, 50, 50)
text("Destroy.", x + 100, y + 200)
} else if (buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))] instanceof StorageStoneBuilding) {
rect(x + 100, y + 150, 50, 50)
text("Destroy.", x + 100, y + 200)
} else if (buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor((buildMenuX / 10) + (buildMenuY * 18))))] instanceof StorageWoodBuilding) {
rect(x + 100, y + 150, 50, 50)
text("Destroy.", x + 100, y + 200)
}
} else {
rect(x + 50, y + 50, 50, 50)
rect(x + 150, y + 50, 50, 50)
rect(x + 50, y + 150, 50, 50)
rect(x + 150, y + 150, 50, 50)
rect(x + 50, y + 250, 50, 50)
rect(x + 150, y + 250, 50, 50)
rect(x + 50, y + 350, 50, 50)
rect(x + 150, y + 350, 50, 50)
fill(0)
text('Tower', x + 50, y + 50)
text('Mortar', x + 150, y + 50)
text('House', x + 50, y + 150)
text('Farm', x + 150, y + 150)
text('Mine', x + 50, y + 250)
text('Lumber Hut', x + 150, y + 250)
text('Stone Storage', x + 50, y + 350)
text('Wood Storage', x + 150, y + 350)
text('Wood: 10', x + 50, y + 60)
text('Stone: 20', x + 50, y + 70)
text('Person: 1', x + 50, y + 80)
text('Wood: 40', x + 150, y + 60)
text('Stone: 40', x + 150, y + 70)
text('Person: 2', x + 150, y + 80)
text('Wood: 10', x + 50, y + 160)
text('Stone: 5', x + 50, y + 170)
text('Wood: 15', x + 150, y + 160)
text('Stone: 0', x + 150, y + 170)
text('Person: 1', x + 150, y + 180)
text('Wood: 30', x + 50, y + 260)
text('Stone: 0', x + 50, y + 270)
text('Person: 1', x + 50, y + 280)
text('Wood: 0', x + 150, y + 260)
text('Stone: 20', x + 150, y + 270)
text('Person: 1', x + 150, y + 280)
text('Wood: 20', x + 50, y + 360)
text('Stone: 20', x + 50, y + 370)
text('Wood: 20 ', x + 150, y + 360)
text('Stone: 20', x + 150, y + 370)
}
rectMode(CORNER)
}
//--------------------------------------------------------------------------------
class ZombieSpawner {
constructor(x, y) {
this.x = x;
this.y = y;
this.creditsAllocated = 0;
this.spawnOrder = []
this.shouldISpawn = false
this.spawnOrderLengthInital = 0
this.timeSpawned = millis()
}
display() {
if (this.creditsAllocated != 0) {
square(this.x * 10, this.y * 10, 10);
}
}
setSpawnOrder() {
this.creditsToUse = this.creditsAllocated
this.randomVar = 0
while (this.creditsToUse > 0) {
if (this.creditsToUse > 3) {
this.randomVar = random(0, 3)
if (this.randomVar > 2) {
this.spawnOrder.push('chunkyZombie')
this.creditsToUse -= 3
} else if (this.randomVar > 1) {
this.spawnOrder.push('fastZombie')
this.creditsToUse -= 2
} else {
this.spawnOrder.push('zombie')
this.creditsToUse -= 1
}
} else if (this.creditsToUse > 2) {
this.randomVar = random(0, 2)
if (this.randomVar > 1) {
this.spawnOrder.push('fastZombie')
this.creditsToUse -= 2
} else {
this.spawnOrder.push('zombie')
this.creditsToUse -= 1
}
} else {
this.spawnOrder.push('zombie')
this.creditsToUse -= 1
}
}
this.timerRandom = random(0, lengthOfSunGoneDif / this.spawnOrder.length)
}
spawn() {
if (this.timerRandom < 3500) {
this.timerRandom == 3500
}
if (millis() > this.timeSpawned + this.timerRandom && semiBoolGridZombie[this.x][this.y] != 'zombie') {
if (this.spawnOrder[0] == 'zombie') {
zombies.push(new Zombie(this.x * 10, this.y * 10))
this.spawnOrder.shift()
} if (this.spawnOrder[0] == 'fastZombie') {
zombies.push(new SpeedZombie(this.x * 10, this.y * 10))
this.spawnOrder.shift()
} if (this.spawnOrder[0] == 'chunkyZombie') {
zombies.push(new ChunkyZombie(this.x * 10, this.y * 10))
this.spawnOrder.shift()
}
this.timerRandom = random(0, lengthOfSunGoneDif / this.spawnOrder.length)
}
}
}
// ---------------------------------------------------
class Tree {
constructor(x, y) {
this.id = x + y * 180
this.x = x;
this.y = y;
semiBoolGridPlayer[x][y] = "tree";
this.isMined = false
}
display() {
square(this.x * 10, this.y * 10, 10);
}
}
// ---------------------------------------------------
class Mountain {
constructor(x, y) {
semiBoolGridPlayer[x][y] = "mountain";
semiBoolGridZombie[x][y] = 'mountain';
this.x = x;
this.y = y;
}
display() {
square(this.x * 10, this.y * 10, 10);
}
}// ---------------------------------------------------
class HomeBase {
constructor(x, y) {
this.id = [x + y * 180, x + 1 + y * 180, x + 2 + y * 180, x + (y + 1) * 180, x + 1 + (y + 1) * 180, x + 2 + (y + 1) * 180, x + (y + 2) * 180, x + 1 + (y + 2) * 180, x + 2 + (y + 2) * 180]
this.x = x;
this.y = y;
this.doesAttack = false
this.health = 1000
this.peoplesUsed=0
}
display() {
fill(220, 35, 190)
square(this.x * 10, this.y * 10, 30);
fill(0)
textAlign(CENTER)
noStroke()
text('Wood: ' + wood, this.x * 10 + 15, this.y * 10 + 5)
text('Stone: ' + stone, this.x * 10 + 15, this.y * 10 + 15)
text('Person: ' + peoplesLeft + '(' + peoplesTotal + ')', this.x * 10 + 15, this.y * 10 + 25)
stroke(255)
strokeWeight(1)
}
}// ---------------------------------------------------
class House {
constructor(x, y) {
this.id = [x + y * 180, x + 1 + y * 180, x + 2 + y * 180, x + (y + 1) * 180, x + 1 + (y + 1) * 180, x + 2 + (y + 1) * 180, x + (y + 2) * 180, x + 1 + (y + 2) * 180, x + 2 + (y + 2) * 180]
this.x = x;
this.y = y;
this.doesAttack = false
this.health = 100
peoplesTotal += 5
peoplesLeft += 5
this.peoplesUsed=5
}
display() {
fill(220, 35, 190)
square(this.x * 10, this.y * 10, 20);
}
}// ---------------------------------------------------
class StorageStoneBuilding {
constructor(x, y) {
this.id = [x + y * 180, x + 1 + y * 180, x + 2 + y * 180, x + (y + 1) * 180, x + 1 + (y + 1) * 180, x + 2 + (y + 1) * 180, x + (y + 2) * 180, x + 1 + (y + 2) * 180, x + 2 + (y + 2) * 180]
this.x = x;
this.y = y;
this.doesAttack = false
this.health = 100
storageStone += 300
this.peoplesUsed=0
}
display() {
fill(250, 75, 70)
square(this.x * 10, this.y * 10, 20);
}
}// ---------------------------------------------------
class StorageWoodBuilding {
constructor(x, y) {
this.id = [x + y * 180, x + 1 + y * 180, x + 2 + y * 180, x + (y + 1) * 180, x + 1 + (y + 1) * 180, x + 2 + (y + 1) * 180, x + (y + 2) * 180, x + 1 + (y + 2) * 180, x + 2 + (y + 2) * 180]
this.x = x;
this.y = y;
this.doesAttack = false
this.health = 100
storageWood += 300
this.peoplesUsed=0
}
display() {
fill(220, 35, 190)
square(this.x * 10, this.y * 10, 20);
}
}
// ---------------------------------------------------
class Farm {
constructor(x, y) {
this.id = [x + y * 180, x + 1 + y * 180, x + 2 + y * 180, x + (y + 1) * 180, x + 1 + (y + 1) * 180, x + 2 + (y + 1) * 180, x + (y + 2) * 180, x + 1 + (y + 2) * 180, x + 2 + (y + 2) * 180]
this.x = x;
this.y = y;
this.doesAttack = false
this.health = 100
this.peoplesUsed=1
}
display() {
fill(250, 140, 70)
square(this.x * 10, this.y * 10, 20);
}
}
class Mine {
constructor(x, y) {
this.id = [x + y * 180, x + 1 + y * 180, x + 2 + y * 180, x + (y + 1) * 180, x + 1 + (y + 1) * 180, x + 2 + (y + 1) * 180, x + (y + 2) * 180, x + 1 + (y + 2) * 180, x + 2 + (y + 2) * 180]
this.x = x;
this.y = y;
this.doesAttack = false
this.health = 100
this.resourscesProduced = muinNum(x, y)
this.peoplesUsed=1
}
display() {
fill(50)
square(this.x * 10, this.y * 10, 20);
}
}
class Lumber {
constructor(x, y) {
this.id = [x + y * 180, x + 1 + y * 180, x + 2 + y * 180, x + (y + 1) * 180, x + 1 + (y + 1) * 180, x + 2 + (y + 1) * 180, x + (y + 2) * 180, x + 1 + (y + 2) * 180, x + 2 + (y + 2) * 180]
this.x = x;
this.y = y;
this.doesAttack = false
this.health = 100
this.resourscesProduced = 0
this.radius = 7
this.peoplesUsed=1
}
checkWoodTotalToProduce() {
this.resourscesProduced = 0
let x1 = 0
let y1 = 0
for (let r = 1; r < this.radius; r += 1) {
for (i = 0; i < 360; i += 1) {
x1 = floor(r * cos((i * Math.PI) / 180));
y1 = floor(r * sin((i * Math.PI) / 180));
if ((x1 + this.x >= 0 && x1 + this.x <= 179) && (y1 + this.y >= 0 && y1 + this.y <= 179)) {
if (semiBoolGridPlayer[x1 + this.x][y1 + this.y] == 'tree' && !listTree[listTree.findIndex(listTree => listTree.id == (x1 + this.x) + (this.y + y1) * 180)].isMined) {
this.resourscesProduced += 10
listTree[listTree.findIndex(listTree => listTree.id == (x1 + this.x) + (this.y + y1) * 180)].isMined = true
}
}
}
}
}
display() {
fill(220, 250, 15)
square(this.x * 10, this.y * 10, 20);
}
}
function muinNum(x, y) {
let num = 0
if (semiBoolGridPlayer[x][y - 1] == 'mountain') {
num += 10
} if (semiBoolGridPlayer[x + 1][y - 1] == 'mountain') {
num += 10
} if (semiBoolGridPlayer[x + 2][y] == 'mountain') {
num += 10
} if (semiBoolGridPlayer[x + 2][y + 1] == 'mountain') {
num += 10
} if (semiBoolGridPlayer[x + 1][y + 2] == 'mountain') {
num += 10
} if (semiBoolGridPlayer[x][y + 2] == 'mountain') {
num += 10
} if (semiBoolGridPlayer[x - 1][y + 1] == 'mountain') {
num += 10
} if (semiBoolGridPlayer[x - 1][y] == 'mountain') {
num += 10
}
return num
}
//----------------------------------------------------------------------------------------
class Mortar {
constructor(x, y) {
this.id = [x + y * 180, x + 1 + y * 180, x + (y + 1) * 180, x + 1 + (y + 1) * 180]
this.x = x;
this.y = y;
this.isMortar = true
this.doesAttack = true
this.health = 400
this.cooldown = 4000 + millis()
this.radius = 10
this.damage = 20
this.explostionRadius = 5
this.attackColldowjn = 4000
this.target = findTarget(this.x, this.y, this.radius)
this.peoplesUsed=2
}
display() {
fill(15, 120, 250)
square(this.x * 10, this.y * 10, 20);
}
attack() {
this.target = findTarget(this.x, this.y, this.radius)
mortarAttack(this.x, this.y, this.target, this.damage, this.explostionRadius)
}//----------------------------------------------------------------------------------------
}
class Projectile {
constructor(x, y, endX, endY, damage, r) {
this.x = x + 1
this.y = y + 1
this.i = endX + endY * 180
this.endX = endX
this.endY = endY
this.damage = damage
this.radisu = r
this.time = 2000 + millis()
this.xSpeed = ((endX - x - 0.5) / dist(x, y, endX, endY)) / 50
this.ySpeed = ((endY - y - 0.5) / dist(x, y, endX, endY)) / 50
}
show() {
circle(this.x * 10, this.y * 10, 10)
this.x += this.xSpeed
this.y += this.ySpeed
}
attack() {
let x1 = 0
let y1 = 0
let zombiesAttackArray = []
for (let r = 1; r < this.radisu; r += 1) {
for (i = 0; i < 360; i += 1) {
x1 = floor(r * cos((i * Math.PI) / 180));
y1 = floor(r * sin((i * Math.PI) / 180));
if (!(zombiesAttackArray.includes((x1 + this.endX) + (y1 + this.endY) * 180))) {
if ((x1 + this.endX >= 0 && x1 + this.endX <= 179) && (y1 + this.endY >= 0 && y1 + this.endY <= 179)) {
let id = zombies.findIndex(zombies => zombies.id === (x1 + this.endX) + (y1 + this.endY) * 180)
if (semiBoolGridZombie[x1 + this.endX][y1 + this.endY] == 'zombie' && id != 0) {
zombies[id].health -= this.damage
zombiesAttackArray.push((x1 + this.endX) + (y1 + this.endY) * 180)
}
}
}
}
}
}
}
function mortarAttack(x, y, target, damage, explostionRadius) {
if (target[2] != -1) {
projectiles.push(new Projectile(x, y, target[0], target[1], damage, explostionRadius))
}
}
//-----------------------------------------------------
class Tower {
constructor(x, y) {
this.id = [x + y * 180, x + 1 + y * 180, x + (y + 1) * 180, x + 1 + (y + 1) * 180]
this.x = x;
this.y = y;
this.isMortar
this.doesAttack = true
this.health = 200
this.cooldown = 1000 + millis()
this.radius = 7
this.damage = 25
this.attackColldowjn = 1000
this.target = findTarget(this.x, this.y, this.radius)
this.peoplesUsed=1
}
display() {
fill(250, 15, 100)
square(this.x * 10, this.y * 10, 20);
}
attack() {
this.target = findTarget(this.x, this.y, this.radius)
towerAttack(this.target, this.damage)
}
}
// --------------------------------------------------------------------------
class Zombie {
constructor(x, y) {
this.id = x + y * 180
this.x = floor(x / 10);
this.y = floor(y / 10);
this.timer = millis() + 25;
this.health = 100;
this.moveCooldown = 1000;
this.col = color(25, 25, 25);
this.damage = 10;
this.attractor = [buildings[0].x, buildings[0].y, true];
this.timesStuck = 0;
semiBoolGridZombie[this.x][this.y] = 'zombie';
this.followingFakeAttractor = false
this.moveX = false
}
display() {
fill(this.col);
square(this.x * 10 + 2, this.y * 10 + 2, 6);
}
move() {
if (this.attractor[2]) {
this.attractor = attractingFindind(this.x, this.y, this.attractor)
}
zombieMove(this.x, this.y, zombies.findIndex(zombies => zombies.id === this.id), this.attractor, this.followingFakeAttractor, this.moveX)
this.id = this.x + this.y * 180
}
attack() {
zombieAttack(this.x, this.y, this.damage)
}
}
// ------------------------------------------------------------------------------------------------
class SpeedZombie {
constructor(x, y) {
this.x = floor(x / 10);
this.y = floor(y / 10);
this.id = x + y * 180
this.timer = millis() + 25;
this.health = 90;
this.moveCooldown = 500;
this.col = color(100, 100, 100);
this.damage = 10;
semiBoolGridZombie[this.x][this.y] = 'zombie';
this.attractor = [buildings[0].x, buildings[0].y, true];
this.timesStuck = 0;
this.followingFakeAttractor = false
this.moveX = false
}
display() {
fill(this.col);
square(this.x * 10 + 2, this.y * 10 + 2, 6);
}
move() {
if (this.attractor[2]) {
this.attractor = attractingFindind(this.x, this.y, this.attractor)
}
zombieMove(this.x, this.y, zombies.findIndex(zombies => zombies.id === this.id), this.attractor, this.followingFakeAttractor, this.moveX)
this.id = this.x + this.y * 180
}
attack() {
zombieAttack(this.x, this.y, this.damage)
}
}
// --------------------------------------------------------------------------
class ChunkyZombie {
constructor(x, y) {
this.x = floor(x / 10);
this.y = floor(y / 10);
this.id = x + y * 180
this.timer = millis() + 25;
this.health = 250;
this.moveCooldown = 1500;
this.col = color(25, 25, 25);
this.damage = 15;
semiBoolGridZombie[this.x][this.y] = 'zombie';
this.attractor = [buildings[0].x, buildings[0].y, true];
this.timesStuck = 0;
this.followingFakeAttractor = false
this.moveX = false
}
display() {
fill(this.col);
square(this.x * 10, this.y * 10, 10);
}
move() {
if (this.attractor[2]) {
this.attractor = attractingFindind(this.x, this.y, this.attractor)
}
zombieMove(this.x, this.y, zombies.findIndex(zombies => zombies.id === this.id), this.attractor, this.followingFakeAttractor, this.moveX)
this.id = this.x + this.y * 180
}
attack() {
zombieAttack(this.x, this.y, zombies.findIndex(zombies => zombies.id === this.id), this.damage)
}
}
function zombieMove(x, y, i, attractor, followingFakeAttractor, moveX) {
let zombieLeft = false
let zombieRight = false
let zombieAbove = false
let zombieBelow = false
if (x == 0 || semiBoolGridZombie[x - 1][y] == 'zombie' || semiBoolGridZombie[x - 1][y] == 'mountain') {
zombieLeft = true;
}
if (
x == (width - 10) / 10 ||
semiBoolGridZombie[x + 1][y] == 'zombie' ||
semiBoolGridZombie[x + 1][y] == 'mountain'
) {
zombieRight = true;
}
if (
y == (height / 10) - 1 ||
semiBoolGridZombie[x][y + 1] == 'zombie' ||
semiBoolGridZombie[x][y + 1] == 'mountain'
) {
zombieBelow = true;
}
if (y == 0 || semiBoolGridZombie[x][y - 1] == 'zombie' ||
semiBoolGridZombie[x][y - 1] == 'mountain') {
zombieAbove = true;
}
if (moveX && attractor[0] - x != 0) {
if (attractor[0] - x > 0) {
if (!zombieRight) {
semiBoolGridZombie[x][y] = "empty";
x += 1;
semiBoolGridZombie[x][y] = 'zombie';
zombies[i].timesStuck = 0;
zombies[i].x = x;
}
} else {
if (!zombieLeft) {
semiBoolGridZombie[x][y] = "empty";
x -= 1;
semiBoolGridZombie[x][y] = 'zombie';
zombies[i].timesStuck = 0;
zombies[i].x = x;
}
}
} else if (attractor[1] - y != 0) {
if (attractor[1] - y > 0) {
if (!zombieBelow) {
semiBoolGridZombie[x][y] = "empty";
y += 1;
semiBoolGridZombie[x][y] = 'zombie';
zombies[i].timesStuck = 0;
zombies[i].y = y;
}
} else {
if (!zombieAbove) {
semiBoolGridZombie[x][y] = "empty";
y -= 1;
semiBoolGridZombie[x][y] = 'zombie';
zombies[i].timesStuck = 0;
zombies[i].y = y;
}
}
}
if (
zombies[i].timesStuck > 7 &&
!(
zombieLeft &&
zombieAbove &&
zombieBelow &&
zombieRight
)
) {
followingFakeAttractor = true;
let randomX = floor(random(5, 11));
let randomY = floor(random(5, 11));
let squishedHori = false;
let squishedVert = false;
if (zombieLeft == zombieRight) {
squishedHori = true;
}
if (zombieAbove == zombieBelow) {
squishedVert = true;
}
if (
zombieRight &&
!squishedHori &&
x - randomX >= 0
) {
attractor[0] = x - randomX;
} else if (zombieLeft && x + randomX < width / 10) {
attractor[0] = x + randomX;
}
if (zombieAbove && !this.squishedVert) {
attractor[1] = y - randomY;
} else if (this.zombieBelow && !squishedVert) {
attractor[1] = y + randomY;
}
if (squishedHori) {
if (random(0, 2) > 1) {
attractor[1] = y - randomY;
} else {
attractor[1] = y + randomY;
}
}
if (squishedVert) {
if (random(0, 2) > 1) {
attractor[0] = x - randomX;
} else {
attractor[0] = x + randomX;
}
}
if (attractor[0] < 0) {
attractor[0] = 0;
} else if (attractor[0] > width / 10) {
attractor[0] = width / 10;
}
if (attractor[1] < 0) {
attractor[1] = 0;
} else if (attractor[1] > height / 10) {
attractor[1] = height / 10;
}
}
if (
attractor[0] == x &&
attractor[1] == y &&
followingFakeAttractor
) {
attractor = [buildings[0].x, buildings[0].y, true];
followingFakeAttractor = false;
}
moveX = !moveX
zombies[i].x = x
zombies[i].y = y
zombies[i].moveX = moveX
zombies[i].followingFakeAttractor = followingFakeAttractor
zombies[i].attractor = attractor
}
function zombieAttack(x, y, damage) {
for (let i = 0; i < buildings.length; i++) {
for (let j = 0; j < buildings[i].id.length; j++) {
if (buildings[i].id[j] == (x - 1) + y * 180 ||
buildings[i].id[j] == (x + 1) + y * 180 ||
buildings[i].id[j] == (x) + (y - 1) * 180 ||
buildings[i].id[j] == (x) + (y + 1) * 180) {
buildings[i].health -= damage
}
}
}
}
function attractingFindind(x, y, baseAttr) {
for (let i = 0; i < 180; i++) {
if (semiBoolGridPlayer[i][y] == 'building' && buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor(i + y * 180)))].constructor != HomeBase) {
return [i, y, false]
}
if (semiBoolGridPlayer[x][i] == 'building' && buildings[buildings.findIndex(buildings => buildings.id.some(val => val === floor(x + i * 180)))].constructor != HomeBase) {
return [x, i, false]
}
}
return baseAttr
}
function findTarget(x, y, radius) {
x += 1
y += 1
for (let r = 1; r < radius; r += 1) {
for (i = 0; i < 360; i += 1) {
x1 = floor(r * cos((i * Math.PI) / 180));
y1 = floor(r * sin((i * Math.PI) / 180));
if ((x1 + x >= 0 && x1 + x <= 179) && (y1 + y >= 0 && y1 + y <= 179)) {
if (semiBoolGridZombie[x1 + x][y1 + y] == 'zombie') {
return [x1 + x, y1 + y, zombies.findIndex(zombies => zombies.id === (x1 + x) + (y1 + y) * 180)]
}
}
}
}
return [0, 0, -1]
}
function towerAttack(target, damage) {
if (target[2] != -1) {
zombies[target[2]].health -= damage
}
}