Skip to content
This repository was archived by the owner on Aug 26, 2025. It is now read-only.

Commit 271d9b7

Browse files
Merge pull request #42 from 42core-team/41-blood-stains
41 blood stains
2 parents a20b9bb + 8bb00e7 commit 271d9b7

File tree

1 file changed

+88
-5
lines changed

1 file changed

+88
-5
lines changed

public/sketch.js

Lines changed: 88 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,86 @@ const BAR_WIDTH = 20; // bar thickness
5454
const BAR_ROUNDING = 10; // px corner radius
5555
const RATIO_EASE = 0.05; // lerp factor
5656

57+
let lastHP = {}; // key: unit.id, value: hp
58+
let bloodStains = [];
59+
5760
const types = {
5861
CORE: 0,
5962
UNIT: 1,
6063
RESOURCE: 2
6164
}
6265

66+
// ─── Blood settings (area-based) ───────────────────────────────────────────
67+
const BLOOD_MAX_AREA = 25000000;
68+
69+
function updateBloodStains() {
70+
// compute the same offsets you use in drawBlood/draw_grid
71+
const xOff = -cols * boxSize / 2;
72+
const yOff = -rows * boxSize / 2;
73+
const f = (cols * boxSize) / config.width;
74+
75+
for (let unit of game.units || []) {
76+
if (!(unit.id in lastHP)) lastHP[unit.id] = unit.hp;
77+
const prev = lastHP[unit.id];
78+
const lost = prev - unit.hp;
79+
80+
if (lost > 0) {
81+
// instead of top-left, we now add +boxSize/2 to center it
82+
const x = unit.pos.x * f + xOff + boxSize / 2;
83+
const y = unit.pos.y * f + yOff + boxSize / 2;
84+
85+
let merged = false;
86+
for (let stain of bloodStains) {
87+
const r = Math.sqrt(stain.area / Math.PI);
88+
if (dist(x, y, stain.x, stain.y) < r) {
89+
stain.area += lost;
90+
if (stain.area > BLOOD_MAX_AREA) {
91+
stain.area = BLOOD_MAX_AREA;
92+
}
93+
merged = true;
94+
break;
95+
}
96+
}
97+
if (!merged) {
98+
bloodStains.push({
99+
x: x,
100+
y: y,
101+
area: Math.min(lost, BLOOD_MAX_AREA)
102+
});
103+
}
104+
}
105+
lastHP[unit.id] = unit.hp;
106+
}
107+
}
108+
109+
function drawBlood() {
110+
noStroke();
111+
fill(150, 0, 0, 200);
112+
113+
for (let i = 0; i < bloodStains.length; i++) {
114+
const a = bloodStains[i];
115+
// compute radius from stored area
116+
const rA = Math.sqrt(a.area / Math.PI);
117+
ellipse(a.x, a.y, rA*2, rA*2);
118+
119+
// connect overlaps with a nice bridge
120+
for (let j = i + 1; j < bloodStains.length; j++) {
121+
const b = bloodStains[j];
122+
const rB = Math.sqrt(b.area / Math.PI);
123+
if (dist(a.x, a.y, b.x, b.y) < (rA + rB) * 0.5) {
124+
const midX = (a.x + b.x) / 2;
125+
const midY = (a.y + b.y) / 2;
126+
const h = min(rA, rB) * 0.3;
127+
beginShape();
128+
vertex(a.x, a.y);
129+
quadraticVertex(midX, midY - h, b.x, b.y);
130+
quadraticVertex(midX, midY + h, a.x, a.y);
131+
endShape(CLOSE);
132+
}
133+
}
134+
}
135+
}
136+
63137
function updateWinRatio() {
64138
if (!game.units || game.units.length === 0) return;
65139
if (!game.teams || game.teams.length < 2) return;
@@ -329,6 +403,7 @@ function preload() {
329403
}
330404

331405
function setupWebSocket() {
406+
bloodStains = [];
332407
socket = new WebSocket('ws://{{.socket}}/ws');
333408

334409
// WebSocket event listeners
@@ -421,6 +496,7 @@ function isUnitMoving(unit)
421496
}
422497

423498
function setup() {
499+
bloodStains = [];
424500
setupWebSocket();
425501

426502
cols = config.width / 1000;
@@ -449,6 +525,7 @@ function setup() {
449525
}
450526

451527
function reconnect() {
528+
bloodStains = [];
452529
configPresent = false;
453530
isGameOver = false;
454531
setTimeout(setupWebSocket, 1000);
@@ -881,12 +958,16 @@ function draw_game_over() {
881958
stroke(0);
882959
strokeWeight(2);
883960
text
884-
if (game.cores[0].team_id == 1) {
885-
fill('lightgray');
886-
text("Skeleton Team " + config.teams[0].name + " wins!", 0, 0);
961+
if (game.cores.length > 1) {
962+
text("Someone exited, Pauls gotta look at the log uwu", 0, 0);
887963
} else {
888-
fill('greenyellow');
889-
text("Goblin Team " + config.teams[1].name + " wins!", 0, 0);
964+
if (game.cores[0].team_id == 1) {
965+
fill('lightgray');
966+
text("Skeleton Team " + config.teams[0].name + " wins!", 0, 0);
967+
} else {
968+
fill('greenyellow');
969+
text("Goblin Team " + config.teams[1].name + " wins!", 0, 0);
970+
}
890971
}
891972
pop();
892973
isGameOver = true;
@@ -901,6 +982,8 @@ function draw() {
901982

902983
// draw playing field and its elements
903984
draw_grid();
985+
updateBloodStains();
986+
drawBlood();
904987
draw_target_lines();
905988
draw_cores();
906989
draw_resources();

0 commit comments

Comments
 (0)