Escape Room

by Dutton

HTML

<div id="vpEscape">

  <!-- Eerste kamer -->
  <div id="firstGame">
    <img class="vp-bg" src="https://i.imgur.com/cmcuXII.png" alt="Escape room">

    <div id="scanlines"></div>
    <div id="screenEffect"></div>
    <div id="blackout"></div>
    <div id="screenText"></div>

    <button class="hotspot deur" data-item="deur" aria-label="Deur"></button>
    <button class="hotspot boeken" data-item="boeken" aria-label="Boeken"></button>
    <button class="hotspot klok" data-item="klok" aria-label="Klok"></button>
    <button class="hotspot sleutels" data-item="sleutels" aria-label="Sleutels"></button>
    <button class="hotspot vaas" data-item="vaas" aria-label="Vaas"></button>
    <button class="hotspot plant" data-item="plant" aria-label="Plant"></button>
    <button class="hotspot schilderij" data-item="schilderij" aria-label="Schilderij"></button>

    <button id="claimHotspot" aria-label="Uitgang"></button>
  </div>

  <!-- Detectivekamer -->
  <div id="detectiveGame">
    <img class="detectiveBg" src="https://i.imgur.com/XdABjpV.png" alt="Detectivekamer">

    <button id="hackerButton" aria-label="Onderzoek bestanden"></button>

    <button class="suspect suspect1" data-suspect="1" aria-label="Verdachte 1"></button>
    <button class="suspect suspect2" data-suspect="2" aria-label="Verdachte 2"></button>
    <button class="suspect suspect3" data-suspect="3" aria-label="Verdachte 3"></button>
    <button class="suspect suspect4" data-suspect="4" aria-label="Verdachte 4"></button>

    <div id="detectiveScreen">
      <div id="terminalTitle">ONDERZOEK</div>
      <div id="terminalContent"></div>
    </div>
  </div>

  <!-- Navigatie tussen de pagina's -->
  <div id="gameNavigation">
    <button id="navBack" class="navArrow" aria-label="Vorige pagina">&#10094;</button>
    <span id="navPage">KAMER 1</span>
    <button id="navNext" class="navArrow" aria-label="Volgende pagina">&#10095;</button>
  </div>

  <!-- Start...

CSS

html, body {
  margin: 0;
  padding: 0;
  width: 100%;
  min-height: 100%;
  background: #061006;
  overflow: hidden;
}

#vpEscape {
  position: relative;
  width: 688px;
  height: 550px;
  overflow: hidden;
  font-family: "Courier New", monospace;
  color: #baff75;
  background: #061006;
}

#vpEscape * {
  box-sizing: border-box;
}

#firstGame,
#detectiveGame {
  position: absolute;
  inset: 0;
  width: 688px;
  height: 550px;
  overflow: hidden;
}

#detectiveGame {
  display: none;
}

.vp-bg,
.detectiveBg {
  position: absolute;
  left: 0;
  top: 0;
  width: 688px;
  height: 550px;
  pointer-events: none;
  user-select: none;
}

/* Tekstscherm eerste kamer */

#screenText {
  position: absolute;
  left: 385px;
  top: 158px;
  width: 205px;
  height: 232px;
  padding: 12px 16px 12px 12px;
  overflow-y: auto;
  overflow-x: hidden;
  color: #baff75;
  font-size: 11px;
  line-height: 1.65;
  text-shadow: 0 0 6px #91ff00;
  opacity: 0;
  transition: opacity .3s;
  z-index: 5;
  scrollbar-width: thin;
  scrollbar-color: #91ff00 transparent;
}

#screenText.show {
  opacity: 1;
}

.itemImageWrap {
  width: 100%;
  text-align: center;
  margin-bottom: 8px;
}

.itemImage {
  max-width: 72px;
  max-height: 52px;
  object-fit: contain;
}

.itemTitle {
  font-size: 15px;
  font-weight: bold;
  color: white;
  margin-bottom: 8px;
}

.itemBody {
  font-size: 11px;
  line-height: 1.65;
  overflow-wrap: break-word;
}

.fileName {
  color: #e1ffae;
}

.fileError {
  color: #ff7777;
  font-weight: bold;
}

/* Klok */

.puzzleClock {
  position: relative;
  width: 70px;
  height: 70px;
  margin: 0 auto 10px;
  border: 4px solid #a88b58;
  border-radius: 50%;
  background: #eee1bd;
  box-shadow: inset 0 0 9px #8e7853;
}

.clockNumber {
  position: absolute;
  color: #342b20;
  font-family: Georgia, serif;
  font-size: 12px;
  font-weight: bold;
 ...

JavaScript

const firstCode = "7642";
const firstReward = "!!!W0eh0eherf$tt!!!";
const secondReward = "@lm0stw!ntery@y!";

let gameStarted = false;
let firstCompleted = false;
let secondCompleted = false;
let currentPage = 0;
let typingTimer = null;
let disconnectTimer = null;
let attempts = 0;
let securityLocked = false;

// Begintekst
const introText = `
  <div class="itemBody">
    <span class="fileError">SYSTEEMFOUT 404</span><br><br>
    Het VP-systeem is vergrendeld.<br><br>
    Vier cijfers zijn nodig om de verbinding te herstellen.<br><br>
    Onderzoek de voorwerpen en ontdek de juiste volgorde.<br><br>
    Heb je de vier cijfers gevonden? Ga dan naar de uitgang om de toegangscode in te voeren.
  </div>
`;

// Klok met lange wijzer op de 4
const clockImage = `
  <div class="puzzleClock">
    <span class="clockNumber n12">12</span>
    <span class="clockNumber n3">3</span>
    <span class="clockNumber n6">6</span>
    <span class="clockNumber n9">9</span>
    <div class="clockHand hourHand"></div>
    <div class="clockHand minuteHand"></div>
    <div class="clockCenter"></div>
  </div>
`;

// Voorwerpen eerste kamer
const items = {
  deur: {
    title: "DEUR",
    img: "https://i.imgur.com/GD0rCeX.png",
    text: `
      <span class="fileName">DOOR_LOCK.sys</span><br><br>
      Op de deur staan vier woorden gekrast.<br><br>
      SLEUTEL - VAAS - KLOK - PLANT<br><br>
      Alle vier verbergen ze een cijfer. Heb jij ze al gevonden?
    `
  },

  boeken: {
    title: "BOEKEN",
    img: "https://i.imgur.com/6t9QdaA.png",
    text: `
      <span class="fileName">ARCHIEF_01.txt</span><br><br>
      Tussen de boeken ligt een oude notitie.<br><br>
      Vier cijfers openen de deur. Maar de volgorde vind je niet hier.<br><br>
      Zoek naar wat opent, wat gebroken is, wat stilstaat en wat groeit.
    `
  },

  klok: {
    title: "KLOK",
    customImage: clockImage,
    text: `
      <span...