Scan to open on your phone
Point a camera at the QR code - it opens this exact paste, no app needed.
https://codepastes.com/zzgszkxg6vna268xuntitledPlain Text
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sex Royale</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #0d0d12; color: #eee; font-family: system-ui, sans-serif; overflow: hidden; }
canvas { display: block; background: #15151f; }
#ui {
position: absolute; top: 12px; left: 12px;
background: rgba(0,0,0,0.7); padding: 10px 16px;
border-radius: 8px; font-size: 14px; line-height: 1.5;
pointer-events: none;
}
#killfeed {
position: absolute; top: 12px; right: 12px;
width: 280px; text-align: right; font-size: 13px;
pointer-events: none;
}
.kill { background: rgba(255,40,80,0.25); margin-bottom: 4px; padding: 4px 8px; border-radius: 4px; }
#center {
position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
pointer-events: none; font-size: 48px; font-weight: 800; text-shadow: 0 0 20px #ff2d55;
opacity: 0; transition: opacity 0.3s;
}
#center.show { opacity: 1; }
</style>
</head>
<body>
<canvas id="c"></canvas>
<div id="ui">
<div>Players alive: <span id="alive">0</span></div>
<div>Kills: <span id="kills">0</span></div>
<div>Zone closes in: <span id="timer">60</span>s</div>
<div style="margin-top:6px;font-size:12px;opacity:0.7">WASD move ยท Space = Fuck attack</div>
</div>
<div id="killfeed"></div>
<div id="center"></div>
<script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
let W, H;
function resize() {
W = canvas.width = window.innerWidth;
H = canvas.height = window.innerHeight;
}
window.addEventListener('resize', resize);
resize();
// ========== CONFIG ==========
const ACTS = [
{ name: "Handjob", range: 55, cooldown: 0.6, dmg: 35, color: "#ff9f43", emoji: "โ" },
{ name: "Blowjob", range: 45, cooldown: 0.9, dmg: 55, color: "#ff6b9d", emoji: "๐
" },
{ name: "Missionary",range: 40, cooldown: 1.2, dmg: 80, color: "#ff2d55", emoji: "๐" },
{ name: "Doggy", range: 50, cooldown: 1.0, dmg: 70, color: "#a55eea", emoji: "๐ถ" },
{ name: "Anal", range: 35, cooldown: 1.4, dmg: 100, color: "#2ed573", emoji: "๐" }
];
// ========== ENTITIES ==========
class Player {
constructor(x, y, isBot = false, name = "You") {
this.x = x; this.y = y;
this.vx = 0; this.vy = 0;
this.r = 18;
this.hp = 100;
this.maxHp = 100;
this.isBot = isBot;
this.name = name;
this.alive = true;
this.actIdx = 2; // default Missionary
this.cd = 0;
this.angle = 0;
this.killCount = 0;
this.color = isBot ? `hsl(${Math.random()*360},70%,60%)` : "#00f0ff";
this.target = null;
this.sexAnim = 0; // >0 while fucking
}
get act() { return ACTS[this.actIdx]; }
}
const names = ["Luna","Rico","Jade","Knox","Mila","Zane","Sasha","Kai","Nina","Rex","Ava","Jax","Chloe","Leo","Ivy","Cole"];
let players = [];
let me;
let zoneR, zoneX, zoneY, nextZoneR, zoneTimer, zonePhase;
let kills = 0;
let gameOver = false;
let particles = [];
let floatTexts = [];
function init() {
players = [];
me = new Player(W/2, H/2, false, "You");
players.push(me);
for (let i = 0; i < 15; i++) {
const a = Math.random() * Math.PI * 2;
const d = 200 + Math.random() * 400;
players.push(new Player(
W/2 + Math.cos(a)*d,
H/2 + Math.sin(a)*d,
true,
names[i % names.length]
));
}
zoneX = W/2; zoneY = H/2;
zoneR = Math.max(W, H) * 0.55;
nextZoneR = zoneR * 0.7;
zoneTimer = 45;
zonePhase = 0;
kills = 0;
gameOver = false;
particles = [];
floatTexts = [];
document.getElementById('kills').textContent = 0;
}
// ========== INPUT ==========
const keys = {};
window.addEventListener('keydown', e => { keys[e.code] = true; if (e.code === 'Space') e.preventDefault(); });
window.addEventListener('keyup', e => keys[e.code] = false);
// cycle acts with 1-5
window.addEventListener('keydown', e => {
if (e.key >= '1' && e.key <= '5') me.actIdx = parseInt(e.key) - 1;
});
// ========== COMBAT ==========
function tryFuck(p) {
if (p.cd > 0 || !p.alive) return;
const act = p.act;
let best = null, bestD = act.range;
for (const o of players) {
if (o === p || !o.alive) continue;
const d = Math.hypot(o.x - p.x, o.y - p.y);
if (d < bestD) { bestD = d; best = o; }
}
if (!best) return;
p.cd = act.cooldown;
p.sexAnim = 0.45;
p.angle = Math.atan2(best.y - p.y, best.x - p.x);
// damage
best.hp -= act.dmg;
spawnHeart(best.x, best.y, act.color);
floatText(best.x, best.y - 30, `-${act.dmg} ${act.emoji}`, act.color);
if (best.hp <= 0) {
best.alive = false;
best.hp = 0;
p.killCount++;
if (p === me) {
kills++;
document.getElementById('kills').textContent = kills;
}
addKillFeed(`${p.name} ${act.name.toLowerCase()}ed ${best.name}`);
spawnBurst(best.x, best.y, act.color);
}
}
function addKillFeed(txt) {
const el = document.createElement('div');
el.className = 'kill';
el.textContent = txt;
document.getElementById('killfeed').prepend(el);
setTimeout(() => el.remove(), 4000);
}
function floatText(x, y, txt, col) {
floatTexts.push({ x, y, txt, col, life: 1 });
}
function spawnHeart(x, y, col) {
for (let i = 0; i < 6; i++) {
particles.push({
x, y,
vx: (Math.random()-0.5)*4,
vy: (Math.random()-0.5)*4 - 2,
life: 0.8 + Math.random()*0.4,
col, size: 4 + Math.random()*4, type: 'heart'
});
}
}
function spawnBurst(x, y, col) {
for (let i = 0; i < 18; i++) {
const a = Math.random()*Math.PI*2;
const sp = 2 + Math.random()*5;
particles.push({
x, y, vx: Math.cos(a)*sp, vy: Math.sin(a)*sp,
life: 0.6 + Math.random()*0.5, col, size: 3 + Math.random()*5, type: 'circle'
});
}
}
// ========== BOT AI ==========
function updateBot(p, dt) {
if (!p.alive) return;
// find nearest alive
let nearest = null, nd = 9999;
for (const o of players) {
if (o === p || !o.alive) continue;
const d = Math.hypot(o.x-p.x, o.y-p.y);
if (d < nd) { nd = d; nearest = o; }
}
p.target = nearest;
if (nearest) {
const dx = nearest.x - p.x, dy = nearest.y - p.y;
const dist = Math.hypot(dx, dy);
const act = p.act;
if (dist > act.range * 0.85) {
p.vx = (dx / dist) * 110;
p.vy = (dy / dist) * 110;
} else {
p.vx *= 0.85; p.vy *= 0.85;
if (p.cd <= 0) tryFuck(p);
}
// random act switch
if (Math.random() < 0.002) p.actIdx = Math.floor(Math.random()*ACTS.length);
}
// stay in zone
const zd = Math.hypot(p.x - zoneX, p.y - zoneY);
if (zd > zoneR - 40) {
const a = Math.atan2(zoneY - p.y, zoneX - p.x);
p.vx += Math.cos(a) * 80;
p.vy += Math.sin(a) * 80;
}
}
// ========== ZONE ==========
function updateZone(dt) {
zoneTimer -= dt;
if (zoneTimer <= 0) {
zonePhase++;
zoneR = nextZoneR;
nextZoneR *= 0.65;
zoneTimer = Math.max(20, 40 - zonePhase * 5);
// move center a bit
zoneX += (Math.random()-0.5) * 80;
zoneY += (Math.random()-0.5) * 80;
}
// damage outside
for (const p of players) {
if (!p.alive) continue;
if (Math.hypot(p.x - zoneX, p.y - zoneY) > zoneR) {
p.hp -= 12 * dt;
if (p.hp <= 0) {
p.alive = false;
addKillFeed(`${p.name} got zone-fucked`);
}
}
}
}
// ========== UPDATE ==========
let last = performance.now();
function loop(now) {
const dt = Math.min(0.05, (now - last) / 1000);
last = now;
if (!gameOver) {
// player movement
let mx = 0, my = 0;
if (keys['KeyW'] || keys['ArrowUp']) my -= 1;
if (keys['KeyS'] || keys['ArrowDown']) my += 1;
if (keys['KeyA'] || keys['ArrowLeft']) mx -= 1;
if (keys['KeyD'] || keys['ArrowRight']) mx += 1;
if (mx || my) {
const l = Math.hypot(mx, my);
me.vx = (mx / l) * 160;
me.vy = (my / l) * 160;
me.angle = Math.atan2(my, mx);
} else {
me.vx *= 0.82; me.vy *= 0.82;
}
if (keys['Space']) tryFuck(me);
// bots + physics
for (const p of players) {
if (!p.alive) continue;
if (p.isBot) updateBot(p, dt);
p.x += p.vx * dt;
p.y += p.vy * dt;
p.cd = Math.max(0, p.cd - dt);
p.sexAnim = Math.max(0, p.sexAnim - dt);
// soft bounds
p.x = Math.max(20, Math.min(W-20, p.x));
p.y = Math.max(20, Math.min(H-20, p.y));
}
updateZone(dt);
// particles
particles = particles.filter(pt => {
pt.x += pt.vx; pt.y += pt.vy; pt.life -= dt;
return pt.life > 0;
});
floatTexts = floatTexts.filter(f => {
f.y -= 30 * dt; f.life -= dt;
return f.life > 0;
});
// win check
const alive = players.filter(p => p.alive);
document.getElementById('alive').textContent = alive.length;
document.getElementById('timer').textContent = Math.ceil(zoneTimer);
if (alive.length <= 1) {
gameOver = true;
const msg = (alive[0] === me) ? "YOU WIN โ LAST ONE FUCKING" : `${alive[0]?.name || "Nobody"} wins`;
const el = document.getElementById('center');
el.textContent = msg;
el.classList.add('show');
setTimeout(() => { el.classList.remove('show'); init(); }, 4000);
}
}
draw();
requestAnimationFrame(loop);
}
// ========== DRAW ==========
function draw() {
ctx.clearRect(0, 0, W, H);
// zone
ctx.beginPath();
ctx.arc(zoneX, zoneY, zoneR, 0, Math.PI*2);
ctx.strokeStyle = "rgba(255,45,85,0.6)";
ctx.lineWidth = 4;
ctx.stroke();
ctx.fillStyle = "rgba(255,45,85,0.04)";
ctx.fill();
// next zone ghost
ctx.beginPath();
ctx.arc(zoneX, zoneY, nextZoneR, 0, Math.PI*2);
ctx.strokeStyle = "rgba(0,240,255,0.25)";
ctx.lineWidth = 2;
ctx.setLineDash([8, 8]);
ctx.stroke();
ctx.setLineDash([]);
// players
for (const p of players) {
if (!p.alive) {
// corpse
ctx.globalAlpha = 0.35;
ctx.fillStyle = "#555";
ctx.beginPath();
ctx.arc(p.x, p.y, p.r * 0.7, 0, Math.PI*2);
ctx.fill();
ctx.globalAlpha = 1;
continue;
}
// body
const scale = p.sexAnim > 0 ? 1 + Math.sin(p.sexAnim * 20) * 0.12 : 1;
ctx.save();
ctx.translate(p.x, p.y);
ctx.rotate(p.angle);
ctx.scale(scale, scale);
ctx.fillStyle = p.color;
ctx.beginPath();
ctx.arc(0, 0, p.r, 0, Math.PI*2);
ctx.fill();
// direction indicator
ctx.fillStyle = "#fff";
ctx.fillRect(p.r * 0.3, -3, 12, 6);
ctx.restore();
// hp bar
const bw = 36, bh = 5;
ctx.fillStyle = "#333";
ctx.fillRect(p.x - bw/2, p.y - p.r - 14, bw, bh);
ctx.fillStyle = p.hp > 40 ? "#2ed573" : "#ff2d55";
ctx.fillRect(p.x - bw/2, p.y - p.r - 14, bw * (p.hp / p.maxHp), bh);
// name
ctx.fillStyle = "#ccc";
ctx.font = "11px system-ui";
ctx.textAlign = "center";
ctx.fillText(p.name, p.x, p.y - p.r - 20);
// act icon when attacking
if (p.sexAnim > 0) {
ctx.font = "20px serif";
ctx.fillText(p.act.emoji, p.x, p.y - p.r - 36);
}
}
// particles
for (const pt of particles) {
ctx.globalAlpha = pt.life;
ctx.fillStyle = pt.col;
if (pt.type === 'heart') {
ctx.font = pt.size * 2 + "px serif";
ctx.fillText("โฅ", pt.x, pt.y);
} else {
ctx.beginPath();
ctx.arc(pt.x, pt.y, pt.size, 0, Math.PI*2);
ctx.fill();
}
ctx.globalAlpha = 1;
}
// float damage
for (const f of floatTexts) {
ctx.globalAlpha = f.life;
ctx.fillStyle = f.col;
ctx.font = "bold 16px system-ui";
ctx.textAlign = "center";
ctx.fillText(f.txt, f.x, f.y);
ctx.globalAlpha = 1;
}
// current act HUD under player
if (me.alive) {
ctx.fillStyle = "rgba(0,0,0,0.6)";
ctx.fillRect(me.x - 50, me.y + 28, 100, 22);
ctx.fillStyle = me.act.color;
ctx.font = "12px system-ui";
ctx.textAlign = "center";
ctx.fillText(`${me.act.emoji} ${me.act.name} [1-5]`, me.x, me.y + 43);
}
}
init();
requestAnimationFrame(loop);
</script>
</body>
</html>11,974 chars ยท codepastes.com