untitled

Pasted Oct 10, 2026, 12:26 PM1 file436 lines

Scan to open on your phone

Point a camera at the QR code - it opens this exact paste, no app needed.

https://codepastes.com/zzgszkxg6vna268x
untitled
<!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