File size: 4,586 Bytes
3327c96
 
 
 
 
 
 
855e0be
 
 
3327c96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
855e0be
 
 
 
3327c96
 
 
 
 
 
855e0be
3327c96
855e0be
 
 
 
 
 
 
3327c96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
855e0be
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3327c96
 
 
 
 
 
855e0be
 
3327c96
855e0be
3327c96
 
 
 
855e0be
3327c96
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
class TowerGame extends HTMLElement {
  connectedCallback() {
    this.attachShadow({ mode: 'open' });
    this.shadowRoot.innerHTML = `
      <style>
        .game-container {
          width: 100%;
          height: 60vh;
          min-height: 400px;
background: #f0f0f0;
          position: relative;
          overflow: hidden;
          border-radius: 8px;
          border: 2px solid #333;
        }
        .block {
          position: absolute;
          background: linear-gradient(135deg, #667eea, #764ba2);
          border-radius: 4px;
          box-shadow: 0 4px 8px rgba(0,0,0,0.2);
          transition: transform 0.2s;
        }
        .active-block {
          background: linear-gradient(135deg, #f56565, #ed8936);
        }
        .score-display {
          position: absolute;
          top: 10px;
          right: 10px;
          font-size: 1.5rem;
          font-weight: bold;
          color: #333;
          z-index: 10;
        }
      </style>
      <div class="game-container">
        <div class="score-display">Height: 0</div>
      </div>
    `;
    this.initGame();
  }

  initGame() {
    const container = this.shadowRoot.querySelector('.game-container');
    this.gameWidth = container.clientWidth;
    this.gameHeight = container.clientHeight;
    this.blockWidth = Math.min(60, this.gameWidth * 0.2);
    this.blockHeight = 20;
    this.speed = 2;
    this.direction = 1;
    this.tower = [];
    this.score = 0;
    this.gameOver = false;
    this.activeBlock = null;

    // Create base block centered
    const baseX = (this.gameWidth - this.blockWidth) / 2;
    this.createBlock(baseX, this.gameHeight - this.blockHeight, true);

    // Create first moving block
    this.createBlock(0, this.gameHeight - this.blockHeight * 2);
// Start game loop
    this.gameLoop();
    
    // Set up controls
    this.shadowRoot.querySelector('.game-container').addEventListener('click', () => this.placeBlock());
  }

  createBlock(x, y, isBase = false) {
    const block = document.createElement('div');
    block.className = isBase ? 'block' : 'block active-block';
    block.style.width = `${this.blockWidth}px`;
    block.style.height = `${this.blockHeight}px`;
    block.style.left = `${x}px`;
    block.style.top = `${y}px`;
    this.shadowRoot.querySelector('.game-container').appendChild(block);

    if (!isBase) {
      this.activeBlock = { element: block, x, y, movingRight: true };
    } else {
      this.tower.push({ element: block, x, y });
    }
  }

  gameLoop() {
    if (this.gameOver) return;

    if (this.activeBlock) {
      // Move active block
      this.activeBlock.x += this.direction * this.speed;
      this.activeBlock.element.style.left = `${this.activeBlock.x}px`;

      // Change direction at edges
      if (this.activeBlock.x <= 0) this.direction = 1;
      if (this.activeBlock.x + this.blockWidth >= this.gameWidth) this.direction = -1;
    }

    requestAnimationFrame(() => this.gameLoop());
  }
  placeBlock() {
    if (!this.activeBlock || this.gameOver) return;

    // Calculate overlap with previous block
    const prevBlock = this.tower[this.tower.length - 1];
    const overlapLeft = Math.max(0, prevBlock.x - this.activeBlock.x);
    const overlapRight = Math.max(0, (this.activeBlock.x + this.blockWidth) - (prevBlock.x + this.blockWidth));
    const overlapTotal = overlapLeft + overlapRight;

    // Check if block is completely off
    if (overlapTotal >= this.blockWidth) {
      this.gameOver = true;
      this.shadowRoot.querySelector('.score-display').textContent += ` - Game Over!`;
      return;
    }

    // Trim the block to fit
    if (overlapTotal > 0) {
      this.blockWidth -= overlapTotal;
      this.activeBlock.element.style.width = `${this.blockWidth}px`;
      if (overlapLeft > 0) {
        this.activeBlock.x += overlapLeft;
        this.activeBlock.element.style.left = `${this.activeBlock.x}px`;
      }
    }

    // Add active block to tower
    this.activeBlock.element.classList.remove('active-block');
    this.tower.push(this.activeBlock);
    this.score++;
    this.updateScore();

    // Create new active block (slightly narrower)
    const newWidth = Math.max(20, this.blockWidth * 0.98);
    const newY = this.tower[this.tower.length-1].y - this.blockHeight;
    this.blockWidth = newWidth;
    this.createBlock(0, newY);

    // Increase speed slightly
    this.speed = Math.min(5, this.speed + 0.1);
}

  updateScore() {
    this.shadowRoot.querySelector('.score-display').textContent = `Height: ${this.score}`;
  }
}

customElements.define('tower-game', TowerGame);