<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The RGT Shmup</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body { font-family: 'Inter', sans-serif; }
canvas { cursor: crosshair; }
</style>
</head>
<body class="bg-gray-900 text-gray-100 flex items-center justify-center h-screen">
<div class="flex flex-col items-center justify-center p-6 rounded-xl shadow-lg bg-gray-800 border border-gray-700">
<h1 class="text-3xl font-bold mb-4 text-white">The RGT Shmup</h1>
<span id="s" class="text-xl font-mono text-blue-400 mb-4 self-start">Score: 0</span>
<canvas id="gc" width="400" height="600" class="border-2 border-gray-700 bg-black"></canvas>
<div id="go" class="absolute inset-0 flex-col items-center justify-center bg-gray-900 bg-opacity-90 z-10 hidden">
<p class="text-5xl font-extrabold text-red-500 mb-4 tracking-wider">GAME OVER DUUHH...</p>
<p class="text-xl font-mono text-gray-300">Final Score: <span id="fs">0</span></p>
<button id="rb" class="mt-8 px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-bold rounded-lg shadow-lg transition-colors duration-200">Restart</button>
<p class="text-lg font-mono text-gray-500 mt-4">You made qw90700 disappointed in you and he is glad he is not your father.</p>
</div>
</div>
<script>
const [C, CX, SD, GOS, FSD, RB] = ['gc', '2d', 's', 'go', 'fs', 'rb'].map(id => id === '2d' ? document.getElementById('gc').getContext(id) : document.getElementById(id));
const { width: CW, height: CH } = C;
const CFG = { PS: 12, ES: 12, BS: 4, PSpd: 2.5, BSpd: 5, ESpd: 1.5, ESC: 0.015, EFC: 0.005, MPB: 3, PMaxCD: 10 };
let GID, S = 0, GO = false;
let P = { x: CW / 2 - CFG.PS / 2, y: CH - CFG.PS - 20, w: CFG.PS, h: CFG.PS, spd: CFG.PSpd, cd: 0, mcd: CFG.PMaxCD };
let PB = [], E = [], EB = [];
let K = {}, TS = null;
const coll = (o1, o2) => o1.x < o2.x + o2.w && o1.x + o1.w > o2.x && o1.y < o2.y + o2.h && o1.y + o1.h > o2.y;
const draw = (ent, col) => (CX.fillStyle = col, CX.fillRect(ent.x, ent.y, ent.w, ent.h));
const uS = () => SD.textContent = `Score: ${S}`;
const uB = (bA, dir) => bA.filter(b => (b.y += b.spd * dir, dir === -1 ? b.y > 0 : b.y < CH));
const hPI = () => {
if (K['a'] || K['arrowleft']) P.x -= P.spd;
if (K['d'] || K['arrowright']) P.x += P.spd;
if (K['w'] || K['arrowup']) P.y -= P.spd;
if (K['s'] || K['arrowdown']) P.y += P.spd;
P.x = Math.max(0, Math.min(P.x, CW - P.w));
P.y = Math.max(0, Math.min(P.y, CH - P.h));
if (P.cd <= 0 && K[' '] && PB.length < CFG.MPB) {
PB.push({ x: P.x + P.w / 2 - CFG.BS / 2, y: P.y, w: CFG.BS, h: CFG.BS, spd: CFG.BSpd });
P.cd = P.mcd;
} else P.cd--;
};
const uE = () => {
E.forEach(e => {
e.y += e.spd;
if (Math.random() < CFG.EFC) EB.push({ x: e.x + e.w / 2 - CFG.BS / 2, y: e.y + e.h, w: CFG.BS, h: CFG.BS, spd: CFG.BSpd });
});
E = E.filter(e => e.y < CH);
};
const hC = () => {
E = E.filter(e => !(coll(P, e) && (eG(), true)));
PB = PB.filter(pb => {
let hit = false;
E = E.filter(e => !(coll(pb, e) && (hit = true, S++, uS(), true)));
return !hit;
});
EB = EB.filter(eb => !(coll(eb, P) && (eG(), true)));
};
const sE = () => {
if (Math.random() < CFG.ESC) E.push({ x: Math.random() * (CW - CFG.ES), y: -CFG.ES, w: CFG.ES, h: CFG.ES, spd: CFG.ESpd });
};
const eG = () => {
GO = true;
cancelAnimationFrame(GID);
FSD.textContent = S;
GOS.classList.remove('hidden');
GOS.classList.add('flex');
};
const rG = () => {
S = 0; P.x = CW / 2 - CFG.PS / 2; P.y = CH - CFG.PS - 20;
PB = []; E = []; EB = []; GO = false;
GOS.classList.add('hidden');
GOS.classList.remove('flex');
uS(); sGL();
};
const sGL = () => {
const gL = () => {
if (!GO) {
CX.clearRect(0, 0, CW, CH);
const bS = 80, tFS = '35px';
CX.save();
CX.font = `bold ${tFS} sans-serif`; CX.textAlign = 'center'; CX.textBaseline = 'middle'; CX.globalAlpha = 0.1;
for (let y = 0; y < CH; y += bS) {
for (let x = 0; x < CW; x += bS) {
const iEB = ((x / bS) + (y / bS)) % 2 === 0;
CX.fillStyle = iEB ? '#4a5568' : '#cbd5e0'; CX.fillRect(x, y, bS, bS);
CX.fillStyle = iEB ? '#cbd5e0' : '#4a5568'; CX.fillText('RGT', x + bS / 2, y + bS / 2);
}
}
CX.restore();
hPI(); PB = uB(PB, -1); uE(); EB = uB(EB, 1); hC(); sE();
draw(P, '#63b3ed');
E.forEach(e => draw(e, '#e53e3e'));
PB.forEach(b => draw(b, '#63b3ed'));
EB.forEach(b => draw(b, '#e53e3e'));
GID = requestAnimationFrame(gL);
}
};
gL();
};
window.addEventListener('keydown', e => K[e.key.toLowerCase()] = true);
window.addEventListener('keyup', e => K[e.key.toLowerCase()] = false);
C.addEventListener('touchstart', e => (e.preventDefault(), TS = e.touches[0].clientX));
C.addEventListener('touchmove', e => {
e.preventDefault();
if (TS !== null) {
const TM = e.touches[0].clientX;
P.x += (TM - TS) * 0.5;
TS = TM;
P.x = Math.max(0, Math.min(P.x, CW - P.w));
}
});
C.addEventListener('touchend', () => TS = null);
RB.addEventListener('click', rG);
window.onload = sGL;
</script>
</body>
</html>