-
Notifications
You must be signed in to change notification settings - Fork 0
Collapse file tree
Files
Search this repository
/
Copy pathbloood and bond.html
More file actions
More file actions
Latest commit
714 lines (631 loc) · 36.6 KB
/
bloood and bond.html
File metadata and controls
714 lines (631 loc) · 36.6 KB
You must be signed in to make or propose changes
More edit options
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
>gt;
/* ===== base ===== */
*{box-sizing:border-box;margin:0;padding:0}
html,body,#gameContainer{width:100%;height:100%}
body{
background:#0a0a0a;color:#fff;font-family: 'Courier New',monospace;overflow:hidden;
-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
}
#gameContainer{
position:relative; width:100vw; height:100vh;
background:linear-gradient(135deg,#1a1a2e 0%,#0f0f1e 100%);
overflow:hidden;
}
/* canvas fills screen */
canvas{ display:block; width:100%; height:100%; background:#0f0f14; }
/* UI */
#ui{ position:absolute; left:20px; top:20px; background:rgba(0,0,0,0.78); border:2px solid #333;
padding:12px; border-radius:8px; min-width:320px; backdrop-filter: blur(6px); transition:opacity .18s }
.character-stats{ margin-bottom:12px; padding:8px; background:rgba(255,255,255,0.03); border-radius:6px}
.character-stats.active{ border:2px solid #4CAF50; background:rgba(76,175,80,0.06) }
.character-stats.collapsed{ opacity:.45; border:2px solid #f44336 }
.stat-bar{ display:flex; align-items:center; margin:6px 0 }
.stat-label{ width:92px; font-size:12px }
.stat-value{ flex:1; height:18px; background:#111; border:1px solid #333; overflow:hidden; border-radius:4px }
.stat-fill{ height:100%; transition:width .12s linear }
.health-fill{ background:linear-gradient(90deg,#f44336,#ff6b6b) }
.oxygen-fill{ background:linear-gradient(90deg,#2196F3,#64B5F6) }
.food-fill{ background:linear-gradient(90deg,#FF9800,#FFB74D) }
/* top right HUD */
#waveIndicator,#scoreDisplay{ position:absolute; right:20px; border-radius:8px; background:rgba(0,0,0,0.78);
border:2px solid #333;padding:10px 14px; backdrop-filter: blur(6px) }
#waveIndicator{ top:20px; color:#4CAF50; font-weight:700; font-size:18px; transition:transform .18s,opacity .18s }
#waveIndicator.flash{ transform:translateY(-6px) scale(1.03); }
#scoreDisplay{ top:80px; color:#FFD700; font-weight:600; font-size:14px }
/* popups */
#sacrificePopup,#finalChoice,#gameOver,#introScreen,#transferNotice{ position:absolute; left:50%; transform:translateX(-50%); z-index:1200; }
#sacrificePopup{ top:50%; padding:24px; border-radius:10px; border:3px solid #f44336; background:rgba(0,0,0,0.95); display:none }
#finalChoice{ top:50%; padding:28px; border-radius:10px; border:3px solid #9C27B0; background:rgba(0,0,0,0.95); display:none }
#gameOver{ top:50%; padding:28px; border-radius:10px; border:3px solid #f44336; background:rgba(0,0,0,0.95); display:none; min-width:260px }
#transferNotice{ top:12%; padding:12px 18px; border-radius:8px; display:none; min-width:240px; background:rgba(0,0,0,0.88); border:2px solid #fff }
/* intro overlay covers screen and centers text */
#introScreen{ position:absolute; left:0; top:0; width:100%; height:100%; z-index:2000;
display:flex; flex-direction:column; align-items:center; justify-content:center; background:linear-gradient(180deg, rgba(0,0,0,0.9), rgba(0,0,0,0.6)); transition:opacity .32s}
#introCard{ width:min(920px,94%); max-width:1100px; padding:28px; border-radius:12px; background:linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01)); border:2px solid rgba(255,255,255,0.04) }
#introCard h1{ font-size:52px; margin-bottom:8px; background:linear-gradient(90deg,#f44336,#ff6b6b); -webkit-background-clip:text; color:transparent; text-shadow:0 0 22px rgba(244,67,54,0.18) }
.intro-text{ color:#ddd; font-size:15px; line-height:1.55; margin-bottom:16px }
.intro-actions{ display:flex; gap:12px; justify-content:center }
/* emotion icons floating */
.emotion{ position:absolute; font-size:32px; pointer-events:none; z-index:2100; text-shadow:0 0 10px rgba(0,0,0,0.6) }
/* boss warning */
.boss-warning{ position:absolute; left:50%; top:46%; transform:translate(-50%,-50%); font-size:84px; color:#FF0000; text-shadow:0 0 40px rgba(255,0,0,0.9); z-index:1900; display:none }
/* small helpers */
.hidden{ display:none }
.start-btn{ padding:12px 28px; border-radius:8px; border:0; font-weight:700; cursor:pointer }
.btn-green{ background:linear-gradient(135deg,#4CAF50,#388E3C); color:#fff }
.btn-blue{ background:linear-gradient(135deg,#2196F3,#1976D2); color:#fff }
.small{ padding:8px 12px;font-size:13px }
style>gt;
head>gt;
-->
ul>gt;
div>gt;
div>gt;
div>gt;
div>gt;
-->
div>gt;
div>gt;
div>gt;
// draw blood
for(const b of bloodSplatters){
ctx.globalAlpha = Math.max(0, Math.min(1, b.life/200));
ctx.fillStyle = '#5b0000'; ctx.beginPath(); ctx.ellipse(b.x,b.y,b.size*0.8,b.size*0.5,Math.random()*Math.PI,0,Math.PI*2); ctx.fill();
ctx.globalAlpha = 1;
}
// draw buffs
for(const f of buffs){
ctx.globalAlpha = Math.max(0, Math.min(1, f.life/420));
ctx.fillStyle = f.type === 'damage' ? '#ffcc00' : (f.type === 'invisibility' ? '#66ccff' : '#66ff88');
ctx.beginPath(); ctx.arc(f.x + f.width/2, f.y + f.height/2, f.width/2, 0, Math.PI*2); ctx.fill();
ctx.fillStyle = '#111'; ctx.font = '12px monospace'; ctx.textAlign='center'; ctx.textBaseline='middle';
ctx.fillText(f.type[0].toUpperCase(), f.x + f.width/2, f.y + f.height/2);
ctx.globalAlpha = 1;
}
// particles
for(const p of particles){ ctx.globalAlpha = Math.max(0, Math.min(1, p.life/80)); ctx.fillStyle = p.color; ctx.fillRect(p.x, p.y, p.size, p.size); } ctx.globalAlpha = 1;
// bullets
for(const b of bullets){ ctx.fillStyle = '#FFD700'; ctx.beginPath(); ctx.arc(b.x,b.y,b.size,0,Math.PI*2); ctx.fill(); }
// zombies
for(const z of zombies){
if(z.projectile){ ctx.fillStyle = z.color || '#ff6b00'; ctx.beginPath(); ctx.arc(z.x, z.y, z.width/2, 0, Math.PI*2); ctx.fill(); continue; }
ctx.fillStyle = z.color || '#48BB78';
ctx.fillRect(z.x, z.y, z.width, z.height);
// health bar
const hw = z.width, hh = 4;
ctx.fillStyle = 'rgba(0,0,0,0.6)'; ctx.fillRect(z.x, z.y-8, hw, hh);
ctx.fillStyle = '#ff6666'; ctx.fillRect(z.x, z.y-8, hw * (z.health / (z.maxHealth||1)), hh);
}
// boss
if(boss.alive){ ctx.fillStyle = boss.color; ctx.fillRect(boss.x,boss.y,boss.width,boss.height); ctx.fillStyle = '#222'; ctx.fillRect(boss.x,boss.y-12,boss.width,8); ctx.fillStyle = '#ff66cc'; ctx.fillRect(boss.x,boss.y-12,boss.width * Math.max(0,boss.health)/boss.maxHealth,8); }
// players
if(father.alive){ ctx.fillStyle = father.armed ? '#7B8A8C' : father.color; ctx.fillRect(father.x, father.y, father.width, father.height); } else { ctx.fillStyle='#222'; ctx.fillRect(father.x,father.y,father.width,father.height); }
if(child.alive){ ctx.fillStyle = child.armed ? '#FFD87D' : child.color; ctx.fillRect(child.x, child.y, child.width, child.height); } else { ctx.fillStyle='#222'; ctx.fillRect(child.x, child.y, child.width, child.height); }
// draw floating emotions
for(const e of emotionPool){ ctx.globalAlpha = e.alpha; ctx.font = `${e.size}px monospace`; ctx.textAlign='center'; ctx.fillText(e.emoji, e.x, e.y); } ctx.globalAlpha = 1;
// HUD bottom overlay
ctx.fillStyle = 'rgba(255,255,255,0.02)'; ctx.fillRect(10, canvas.height - 80, 380, 64);
requestAnimationFrame(render);
}
/* loops */
function mainLoop(){ update(); setTimeout(mainLoop, 1000/60); }
render(); mainLoop();
/* spawn initial wave only after Start pressed */
/* utility functions for UI/popups */
function showTransferNotice(text, timeMs=1200){
const el = document.getElementById('transferNotice'); el.textContent = text; el.style.display='block';
sound.transfer(); setTimeout(()=>gt;{ el.style.display='none'; }, timeMs);
}
/* automatic buff spawner when none exists */
setInterval(()=>gt;{ if(gameRunning &∓& Math.random() 0.18) spawnBuff(); }, 6000);
/* expose some functions globally */
window.startGame = startGame; window.restartGame = restartGame; window.finalSacrifice = finalSacrifice; window.chooseSacrifice = performSacrifice;
/* small convenience: hide intro on load if skipped */
document.addEventListener('DOMContentLoaded', ()=>gt; { /* nothing until Start */ });
script>gt;
body>gt;
html>gt;