Skip to content

Commit 0bb6dd7

Browse files
committed
ants are kinda there but not properly synced and have a dupe issue
1 parent 4cf4900 commit 0bb6dd7

File tree

8 files changed

+431
-2
lines changed

8 files changed

+431
-2
lines changed

game/classes/brain.js

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
class Brain {
2+
constructor(vision){
3+
this.state = "Wander";
4+
this.target = null; //pos to chase
5+
this.targetEntity = null;
6+
this.stateTimer = 0;
7+
this.obj = null; //obj to move and stuff
8+
this.id = random(10000);
9+
this.vision = vision;
10+
this.deleteTag = false;
11+
}
12+
13+
update(){
14+
if(this.obj != null){
15+
this.stateTimer ++;
16+
if(this.state == "Wander"){
17+
this.wander();
18+
if (this.findTarget()){
19+
this.stateTimer = 0;
20+
this.state = "Chasing";
21+
22+
let chunkPos = testMap.globalToChunk(this.obj.pos.x, this.obj.pos.y);
23+
socket.emit("update_obj", {
24+
cx: chunkPos.x, cy: chunkPos.y,
25+
objName: this.obj.objName,
26+
pos: {x: this.obj.pos.x, y: this.obj.pos.y},
27+
z: this.obj.z,
28+
id: this.obj.id,
29+
brainID: this.id,
30+
update_name: "hp",
31+
update_value: this.obj.hp
32+
});
33+
}
34+
}
35+
if(this.state == "Chasing"){
36+
this.chase();
37+
if (!this.canSee(this.targetEntity.pos.x, this.targetEntity.pos.y)){
38+
this.stateTimer = 0;
39+
this.state = "Wander";
40+
this.target = null;
41+
this.targetEntity = null;
42+
43+
let chunkPos = testMap.globalToChunk(this.obj.pos.x, this.obj.pos.y);
44+
socket.emit("update_obj", {
45+
cx: chunkPos.x, cy: chunkPos.y,
46+
objName: this.obj.objName,
47+
pos: {x: this.obj.pos.x, y: this.obj.pos.y},
48+
z: this.obj.z,
49+
id: this.obj.id,
50+
brainID: this.id,
51+
update_name: "hp",
52+
update_value: this.obj.hp
53+
});
54+
}
55+
}
56+
if(this.state == "Space"){
57+
this.space();
58+
}
59+
}
60+
}
61+
62+
wander(){
63+
//Move randomly
64+
if(this.target == null || this.obj.pos.dist(this.target) < 6){
65+
socket.emit("wander_request", {id: this.id, pos: {x: this.obj.pos.x, y: this.obj.pos.y}});
66+
return;
67+
}
68+
this.moveObjTowards(this.target.x,this.target.y,2);
69+
}
70+
71+
chase(){
72+
//Move towards target
73+
if(this.obj.pos.dist(this.target) > projDic[this.obj.projName].sr){
74+
this.moveObjTowards(this.target.x,this.target.y,6);
75+
}
76+
else{ //if close enough spawn melee projectile and switch to space
77+
let chunkPos = testMap.globalToChunk(this.obj.pos.x, this.obj.pos.y);
78+
let toTarget = createVector(this.target.x,this.target.y).sub(this.obj.pos).setMag(50);
79+
let proj = createProjectile(this.obj.projName, this.obj.objName, this.obj.color, this.obj.pos.x, this.obj.pos.y, toTarget.heading());
80+
if(testMap.chunks[chunkPos.x+','+chunkPos.y] != undefined){
81+
testMap.chunks[chunkPos.x+','+chunkPos.y].projectiles.push(
82+
proj
83+
);
84+
//tell the server you made a projectile
85+
socket.emit("new_proj", proj);
86+
87+
let temp = new SoundObj("swing.wav", this.obj.pos.x, this.obj.pos.y);
88+
testMap.chunks[chunkPos.x+','+chunkPos.y].soundObjs.push(temp);
89+
socket.emit("new_sound", {sound: "swing.wav", cPos: chunkPos, pos: {x: this.obj.pos.x, y: this.obj.pos.y}, id: temp.id});
90+
}
91+
92+
this.stateTimer = 0;
93+
this.state = "Space";
94+
95+
socket.emit("update_obj", {
96+
cx: chunkPos.x, cy: chunkPos.y,
97+
objName: this.obj.objName,
98+
pos: {x: this.obj.pos.x, y: this.obj.pos.y},
99+
z: this.obj.z,
100+
id: this.obj.id,
101+
brainID: this.id,
102+
update_name: "hp",
103+
update_value: this.obj.hp
104+
});
105+
}
106+
}
107+
108+
space(){
109+
// back up away from target until stateTimer == 120
110+
if(this.stateTimer < 120){
111+
this.target = this.obj.pos.copy().sub(this.targetEntity.pos).setMag(100).add(this.targetEntity.pos);
112+
if(this.obj.pos.dist(this.target) > 4){
113+
this.moveObjTowards(this.target.x, this.target.y, 4);
114+
}
115+
//If player gets too close, prolong retreat
116+
if(this.obj.pos.dist(this.targetEntity.pos) < 60){
117+
this.stateTimer = 0;
118+
}
119+
//If player gets too far, reduce retreat
120+
if(this.obj.pos.dist(this.targetEntity.pos) > 100){
121+
this.stateTimer += 5;
122+
}
123+
}
124+
else{
125+
this.target = this.targetEntity.pos;
126+
this.stateTimer = 0;
127+
this.state = "Chasing";
128+
129+
let chunkPos = testMap.globalToChunk(this.obj.pos.x, this.obj.pos.y);
130+
socket.emit("update_obj", {
131+
cx: chunkPos.x, cy: chunkPos.y,
132+
objName: this.obj.objName,
133+
pos: {x: this.obj.pos.x, y: this.obj.pos.y},
134+
z: this.obj.z,
135+
id: this.obj.id,
136+
brainID: this.id,
137+
update_name: "hp",
138+
update_value: this.obj.hp
139+
});
140+
}
141+
}
142+
143+
findTarget(){
144+
this.targetEntity = null;
145+
146+
//sort players from closest to furthest
147+
let playerArray = Object.values(players);
148+
playerArray.push(curPlayer);
149+
150+
playerArray.sort((a, b) => {
151+
let distA = this.obj.pos.dist(a.pos);
152+
let distB = this.obj.pos.dist(b.pos);
153+
return distA - distB;
154+
});
155+
156+
playerArray.filter(player => {
157+
return this.obj.pos.dist(player.pos) < this.vision;
158+
});
159+
160+
for(let i=0; i<playerArray.length; i++){
161+
if(this.canSee(playerArray[i].pos.x, playerArray[i].pos.y)){
162+
if(this.targetEntity == null){
163+
this.targetEntity = playerArray[i];
164+
this.target = playerArray[i].pos;
165+
i = playerArray.length;
166+
}
167+
}
168+
}
169+
170+
return this.targetEntity != null;
171+
}
172+
173+
canSee(x,y){
174+
//check if there are any objects imbetween this.obj and x,y
175+
return createVector(x,y).dist(this.obj.pos) < this.vision;
176+
}
177+
178+
moveObjTowards(x,y,speed){
179+
//TODO: collishion
180+
let oldChunkPos = testMap.globalToChunk(this.obj.pos.x, this.obj.pos.y);
181+
this.obj.pos.add(createVector(x,y).sub(this.obj.pos).setMag(speed));
182+
183+
socket.emit("update_obj", {
184+
cx: oldChunkPos.x, cy: oldChunkPos.y,
185+
objName: this.obj.objName,
186+
pos: {x: this.obj.pos.x, y: this.obj.pos.y},
187+
z: this.obj.z,
188+
id: this.obj.id,
189+
brainID: this.id,
190+
update_name: "hp",
191+
update_value: this.obj.hp
192+
});
193+
194+
let newChunkPos = testMap.globalToChunk(this.obj.pos.x, this.obj.pos.y);
195+
if(oldChunkPos.x != newChunkPos.x || oldChunkPos.y != newChunkPos.y){
196+
this.obj.deleteTag = true;
197+
socket.emit("delete_obj", {
198+
cx: oldChunkPos.x,
199+
cy: oldChunkPos.y,
200+
objName: this.obj.objName,
201+
pos: {x: this.obj.pos.x, y: this.obj.pos.y},
202+
z: this.obj.z,
203+
cost: objDic[this.obj.objName].cost
204+
});
205+
206+
let temp = createObject("Ant", this.obj.pos.x, this.obj.pos.y, 0, this.obj.color, this.obj.id, this.obj.ownerName);
207+
temp.brainID = this.id;
208+
testMap.chunks[newChunkPos.x+","+newChunkPos.y].objects.push(temp);
209+
socket.emit("new_object", {
210+
cx: newChunkPos.x,
211+
cy: newChunkPos.y,
212+
obj: temp
213+
})
214+
this.obj = temp;
215+
}
216+
}
217+
218+
giveBody(obj){
219+
this.obj = obj;
220+
this.obj.brainID = this.id;
221+
}
222+
223+
debugRender(){
224+
if(this.target == null) return;
225+
push();
226+
fill(255,0,0,100);
227+
noStroke();
228+
circle(this.target.x-camera.pos.x + width / 2, this.target.y-camera.pos.y + height / 2, 6);
229+
pop();
230+
}
231+
}
232+
233+
function scareBrain(brainID, proj){
234+
if(brainID == undefined) return;
235+
let scarer;
236+
237+
for(let i=0; i<testMap.brains.length; i++){
238+
if(brainID == testMap.brains[i].id){
239+
if(proj.flightPath != undefined){
240+
//check if turret is at proj.flightPath.origin
241+
let chunkPos = testMap.globalToChunk(proj.flightPath.origin.x, proj.flightPath.origin.y);
242+
let chunk = testMap.chunks[chunkPos.x+","+chunkPos.y];
243+
if(chunk != undefined){
244+
for(let j=0; j<chunk.objects.length; j++){
245+
if(chunk.objects[j].objName == "Turret"){
246+
247+
if(chunk.objects[j].pos.dist(proj.flightPath.origin) < 70){
248+
scarer = chunk.objects[j];
249+
j = chunk.objects.length;
250+
}
251+
}
252+
}
253+
}
254+
255+
//check if proj.ownerName is curPlayer.name
256+
if(proj.ownerName == curPlayer.name){
257+
scarer = curPlayer;
258+
}
259+
//check if proj.ownerName belongs to another player
260+
let keys = Object.keys(players);
261+
for(let j=0; j<keys.length; j++){
262+
if(proj.ownerName == players[keys[j]].name){
263+
scarer = players[keys[j]];
264+
j = keys.length;
265+
}
266+
}
267+
268+
}
269+
270+
if(scarer != undefined){
271+
testMap.brains[i].targetEntity = scarer;
272+
testMap.brains[i].state = "Space";
273+
testMap.brains[i].stateTimer = 0;
274+
i = testMap.brains.length;
275+
}
276+
}
277+
}
278+
}

game/classes/flightPath.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ defineFlightPath("FollowMouse", "(mouseX-lpX+camera.pos.x-(width/2))*p", "(mouse
99

1010
class FlightPath{
1111
constructor(sx,sy,a,eqX, eqY, calcRes, repeate = true){
12+
this.origin = createVector(sx,sy); //where the origonal path started
1213
this.s = createVector(sx,sy); //start of the path
1314
this.eqX = eqX; //equation for x movement
1415
this.eqY = eqY; //equation for y movement

game/classes/map.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ class Map{
55
constructor(){
66
this.chunks = {}; //referance with a string "x,y" {ex. chunks["0,0"]}
77
this.chunkBools = {}; //same referance, just used so you dont ask for the same chunk tons of times undefined if never asked for, false if asked, true if loaded
8+
this.brains = []; //a list of npc brains (might move this to chunk later)
89
}
910

1011
getChunk(x,y){
@@ -30,6 +31,12 @@ class Map{
3031
if(chunk != undefined) chunk.update();
3132
}
3233
}
34+
for(let i=this.brains.length-1; i>=0; i--){
35+
this.brains[i].update();
36+
if(this.brains[i].deleteTag){
37+
this.brains.splice(i, 1);
38+
}
39+
}
3340
}
3441

3542
render(){
@@ -84,6 +91,11 @@ class Map{
8491
}
8592
}
8693

94+
if(Debuging){
95+
for(let i=this.brains.length-1; i>=0; i--){
96+
this.brains[i].debugRender();
97+
}
98+
}
8799
}
88100
}
89101

game/classes/musicSystem.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ setVolume() {
6262
const ctx = getAudioContext();
6363
if (ctx.state !== 'running') {
6464
await ctx.resume(); // resume if suspended
65-
console.log("AudioContext resumed");
65+
//console.log("AudioContext resumed");
6666
}
6767

6868
// 2) now do your usual once-per-state logic

0 commit comments

Comments
 (0)