← back to Model Arena

data/artifacts/035b7009e366/qwen3-14b.html

378 lines

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Designer Wallcoverings</title>
  <style>
    :root {
      --bg: #faf8f4;
      --surface: #ffffff;
      --ink: #1c1a17;
      --muted: #9b948a;
      --accent: #b0472e;
      --line: #e0e0e0;
      --shadow: 0 8px 24px rgba(0,0,0,0.12);
      --ease: cubic-bezier(0.22, 1, 0.36, 1);
      --glow: 0 0 24px var(--accent, #b0472e)35%;
      --spacing-4: 4px;
      --spacing-8: 8px;
      --spacing-12: 12px;
      --spacing-16: 16px;
      --spacing-24: 24px;
      --spacing-32: 32px;
      --spacing-48: 48px;
      --spacing-64: 64px;
      --card-radius: 14px;
      --text-h1: 50px;
      --text-h2: 38px;
      --text-h3: 28px;
      --text-lead: 21px;
      --text-body: 16px;
      --text-caption: 12px;
      --font-display: 'Playfair Display', Georgia, serif;
      --font-body: -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
    }

    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
      font-family: var(--font-body);
    }

    body {
      background-color: var(--bg);
      color: var(--ink);
      font-size: var(--text-body);
      line-height: 1.6;
      min-height: 100vh;
      display: flex;
      flex-direction: column;
    }

    header {
      display: flex;
      align-items: center;
      padding: var(--spacing-16) var(--spacing-24);
      background-color: var(--surface);
      box-shadow: var(--shadow);
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      z-index: 1000;
    }

    header h1 {
      font-family: var(--font-display);
      font-size: var(--text-h2);
      letter-spacing: 0.18em;
      color: var(--ink);
      margin-right: auto;
      max-width: 280px;
      white-space: nowrap;
    }

    .game-container {
      position: relative;
      flex: 1;
      overflow: hidden;
      display: flex;
      align-items: flex-end;
      justify-content: center;
      padding-bottom: var(--spacing-48);
      padding-top: var(--spacing-64);
    }

    canvas {
      display: block;
      width: 100%;
      height: 100%;
    }

    .overlay {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: rgba(0, 0, 0, 0.7);
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 1000;
      flex-direction: column;
      gap: var(--spacing-24);
      color: var(--ink);
      font-family: var(--font-display);
      font-size: var(--text-h3);
      letter-spacing: 0.18em;
      text-align: center;
    }

    .overlay h2 {
      font-size: var(--text-h2);
    }

    .overlay button {
      font-family: var(--font-body);
      font-size: var(--text-caption);
      text-transform: uppercase;
      letter-spacing: 0.15em;
      background-color: var(--accent);
      color: var(--surface);
      border: none;
      padding: var(--spacing-12) var(--spacing-24);
      border-radius: var(--card-radius);
      cursor: pointer;
      transition: 0.2s ease;
    }

    .overlay button:hover {
      box-shadow: var(--glow);
    }

    .scoreboard {
      position: fixed;
      top: var(--spacing-24);
      left: var(--spacing-24);
      background-color: var(--surface);
      padding: var(--spacing-12) var(--spacing-16);
      border: 1px solid var(--line);
      border-radius: var(--card-radius);
      box-shadow: var(--shadow);
      font-family: var(--font-body);
      font-size: var(--text-caption);
      text-transform: uppercase;
      letter-spacing: 0.15em;
    }

    .scoreboard span {
      font-weight: bold;
    }
  </style>
</head>
<body>
  <header>
    <h1>DESIGNER WALLCOVERINGS</h1>
  </header>
  <div class="scoreboard">
    <span>Score:</span> <span id="score">0</span> | <span>High Score:</span> <span id="highScore">0</span>
  </div>
  <div class="game-container">
    <canvas id="gameCanvas"></canvas>
  </div>
  <div class="overlay" id="gameOverOverlay" style="display: none;">
    <h2>GAME OVER</h2>
    <button onclick="restartGame()">RESTART</button>
  </div>

  <script>
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');
    const scoreDisplay = document.getElementById('score');
    const highScoreDisplay = document.getElementById('highScore');
    const gameOverOverlay = document.getElementById('gameOverOverlay');

    let score = 0;
    let highScore = parseInt(localStorage.getItem('highScore') || '0');
    let gravity = 0.8;
    let velocity = 0;
    let position = 0;
    let isJumping = false;
    let lastTime = 0;
    let gameLoop;
    let obstacles = [];
    let wallpaperRolls = [];
    let obstacleTimer = 0;
    let wallpaperTimer = 0;
    let isGameOver = false;

    function initCanvas() {
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
    }

    function resizeHandler() {
      initCanvas();
    }

    window.addEventListener('resize', resizeHandler);
    resizeHandler();

    function updateScore() {
      scoreDisplay.textContent = score;
      if (score > highScore) {
        highScore = score;
        localStorage.setItem('highScore', highScore);
        highScoreDisplay.textContent = highScore;
      }
    }

    function resetGame() {
      score = 0;
      updateScore();
      position = 0;
      velocity = 0;
      isJumping = false;
      obstacles = [];
      wallpaperRolls = [];
      obstacleTimer = 0;
      wallpaperTimer = 0;
      isGameOver = false;
      gameOverOverlay.style.display = 'none';
    }

    function restartGame() {
      resetGame();
      gameLoop = requestAnimationFrame(gameLoop);
    }

    function drawPlayer() {
      ctx.fillStyle = '#c9a961';
      ctx.beginPath();
      ctx.arc(canvas.width / 2, canvas.height - position, 20, 0, Math.PI * 2);
      ctx.fill();
    }

    function drawObstacle(x, y) {
      ctx.fillStyle = '#7d6a45';
      ctx.fillRect(x, y, 40, 60);
    }

    function drawWallpaper(x, y, color) {
      ctx.fillStyle = color;
      ctx.fillRect(x, y, 30, 40);
      ctx.beginPath();
      ctx.arc(x + 15, y + 20, 10, 0, Math.PI * 2);
      ctx.fill();
    }

    function updateObstacles(timeDelta) {
      obstacleTimer += timeDelta;
      if (obstacleTimer > 1500) {
        obstacles.push({
          x: canvas.width + 40,
          y: canvas.height - 120
        });
        obstacleTimer = 0;
      }

      for (let i = 0; i < obstacles.length; i++) {
        obstacles[i].x -= 5;
        if (obstacles[i].x + 40 < 0) {
          obstacles.splice(i, 1);
          i--;
        }
      }
    }

    function updateWallpapers(timeDelta) {
      wallpaperTimer += timeDelta;
      if (wallpaperTimer > 2000) {
        const colors = ['#c9a961', '#7d6a45', '#b0472e', '#e0a458'];
        wallpaperRolls.push({
          x: canvas.width + 30,
          y: canvas.height - 100,
          color: colors[Math.floor(Math.random() * colors.length)]
        });
        wallpaperTimer = 0;
      }

      for (let i = 0; i < wallpaperRolls.length; i++) {
        wallpaperRolls[i].x -= 3;
        if (wallpaperRolls[i].x + 30 < 0) {
          wallpaperRolls.splice(i, 1);
          i--;
        }
      }
    }

    function checkCollisions() {
      for (let i = 0; i < obstacles.length; i++) {
        const obs = obstacles[i];
        const dx = canvas.width / 2 - (obs.x + 20);
        const dy = (canvas.height - position) - (obs.y + 60);
        if (Math.sqrt(dx * dx + dy * dy) < 30) {
          endGame();
          return;
        }
      }

      for (let i = 0; i < wallpaperRolls.length; i++) {
        const roll = wallpaperRolls[i];
        const dx = canvas.width / 2 - (roll.x + 15);
        const dy = (canvas.height - position) - (roll.y + 40);
        if (Math.sqrt(dx * dx + dy * dy) < 30) {
          score += 10;
          updateScore();
          wallpaperRolls.splice(i, 1);
          i--;
        }
      }
    }

    function endGame() {
      isGameOver = true;
      cancelAnimationFrame(gameLoop);
      gameOverOverlay.style.display = 'flex';
    }

    function gameLoop(time) {
      if (isGameOver) return;

      const timeDelta = time - lastTime;
      lastTime = time;

      ctx.clearRect(0, 0, canvas.width, canvas.height);

      velocity += gravity;
      position += velocity;

      if (position > 0) {
        position = 0;
        velocity = 0;
      }

      drawPlayer();

      updateObstacles(timeDelta);
      updateWallpapers(timeDelta);

      for (let i = 0; i < obstacles.length; i++) {
        drawObstacle(obstacles[i].x, obstacles[i].y);
      }

      for (let i = 0; i < wallpaperRolls.length; i++) {
        drawWallpaper(wallpaperRolls[i].x, wallpaperRolls[i].y, wallpaperRolls[i].color);
      }

      checkCollisions();

      gameLoop = requestAnimationFrame(gameLoop);
    }

    window.addEventListener('keydown', (e) => {
      if (e.code === 'Space' || e.code === 'ArrowUp') {
        if (!isJumping) {
          velocity = -12;
          isJumping = true;
        }
      }
    });

    window.addEventListener('touchstart', (e) => {
      if (e.touches.length > 0) {
        if (!isJumping) {
          velocity = -12;
          isJumping = true;
        }
      }
    });

    resetGame();
    gameLoop = requestAnimationFrame(gameLoop);
  </script>
</body>
</html>