Skip to content

Commit 108bf47

Browse files
author
Brigit Murtaugh
committed
Initial game
1 parent 6b9ef43 commit 108bf47

4 files changed

Lines changed: 209 additions & 0 deletions

File tree

Gemfile.lock

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@ GEM
210210
jekyll-feed (~> 0.9)
211211
jekyll-seo-tag (~> 2.1)
212212
minitest (5.18.0)
213+
nokogiri (1.14.3-aarch64-linux)
214+
racc (~> 1.4)
213215
nokogiri (1.14.3-x86_64-linux)
214216
racc (~> 1.4)
215217
octokit (4.25.1)
@@ -250,6 +252,7 @@ GEM
250252
webrick (1.8.1)
251253

252254
PLATFORMS
255+
aarch64-linux
253256
x86_64-linux
254257

255258
DEPENDENCIES

_includes/topnav.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ <h1>Development Containers</h1>
3838
<li {% if page.sectionid=='collections' %} class="nav-item active" {% else %} class="nav-item" {% endif %}>
3939
<a class="nav-link" href='{{ "/collections" | prepend: site.baseurl }}'>Collections</a>
4040
</li>
41+
<li {% if page.sectionid=='frogger-game' %} class="nav-item active" {% else %} class="nav-item" {% endif %}>
42+
<a class="nav-link" href='{{ "/frogger-game" | prepend: site.baseurl }}'>Frogger Game</a>
43+
</li>
4144
</ul>
4245
</div>
4346

frogger-game.html

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
---
2+
layout: default
3+
title: Frogger Game
4+
sectionid: frogger-game
5+
---
6+
7+
<div class="container mt-5 mb-5">
8+
<h2 class="mb-4"><a href="#frogger-game" id="frogger-game">Frogger Game</a></h2>
9+
<div class="text-center mb-3">
10+
<button id="restartBtn" class="btn btn-primary" style="min-width:120px;">Restart</button>
11+
</div>
12+
<canvas id="froggerCanvas" width="400" height="500" style="border:1px solid #0078D4; background:#1e1e2f; display:block; margin:auto; box-shadow:0 0 24px #0078D4,0 0 0 8px #222 inset;"></canvas>
13+
<p class="text-center mt-3">Use the arrow keys to move the frog. Get to the top without hitting cars!</p>
14+
<p class="text-center">Press <strong>R</strong> to restart the game at any time.</p>
15+
</div>
16+
<script>
17+
18+
const canvas = document.getElementById('froggerCanvas');
19+
const ctx = canvas.getContext('2d');
20+
const grid = 50;
21+
const rows = 10;
22+
const cols = 8;
23+
let frog, cars, gameOver, win;
24+
25+
function resetGame() {
26+
frog = { x: 3, y: 9 };
27+
cars = [
28+
{ y: 7, speed: 2, dir: 1, positions: [0, 4] },
29+
{ y: 6, speed: 3, dir: -1, positions: [2, 6] },
30+
{ y: 5, speed: 2, dir: 1, positions: [1, 5] },
31+
{ y: 3, speed: 3, dir: -1, positions: [3, 7] }
32+
];
33+
gameOver = false;
34+
win = false;
35+
}
36+
37+
resetGame();
38+
// Restart button handler
39+
document.getElementById('restartBtn').addEventListener('click', function() {
40+
resetGame();
41+
});
42+
43+
function drawFrog() {
44+
// Draw a dev container: blue box with devcontainers logo (or icon-like)
45+
const x = frog.x * grid + 10;
46+
const y = frog.y * grid + 10;
47+
const size = grid - 20;
48+
// Draw blue box
49+
ctx.fillStyle = '#0078D4'; // VS Code/devcontainers blue
50+
ctx.fillRect(x, y, size, size);
51+
// Draw white border
52+
ctx.strokeStyle = '#fff';
53+
ctx.lineWidth = 3;
54+
ctx.strokeRect(x, y, size, size);
55+
// Draw a simple devcontainer icon (white brackets)
56+
ctx.strokeStyle = '#fff';
57+
ctx.lineWidth = 2;
58+
ctx.beginPath();
59+
ctx.moveTo(x + 6, y + size/2 - 8); ctx.lineTo(x + 6, y + size/2 + 8); // left bracket |
60+
ctx.moveTo(x + 6, y + size/2 - 8); ctx.lineTo(x + 14, y + size/2 - 8); // top _
61+
ctx.moveTo(x + 6, y + size/2 + 8); ctx.lineTo(x + 14, y + size/2 + 8); // bottom _
62+
ctx.moveTo(x + size - 6, y + size/2 - 8); ctx.lineTo(x + size - 6, y + size/2 + 8); // right bracket |
63+
ctx.moveTo(x + size - 14, y + size/2 - 8); ctx.lineTo(x + size - 6, y + size/2 - 8); // top _
64+
ctx.moveTo(x + size - 14, y + size/2 + 8); ctx.lineTo(x + size - 6, y + size/2 + 8); // bottom _
65+
ctx.stroke();
66+
}
67+
68+
// Draw cars as dev tool icons (VS Code, Docker, Git, Terminal)
69+
function drawCars() {
70+
const toolColors = ['#0078D4', '#2496ED', '#F05032', '#222']; // VS Code, Docker, Git, Terminal
71+
const toolLabels = ['</>', '🐳', 'GIT', 'TER'];
72+
cars.forEach((carRow, i) => {
73+
carRow.positions.forEach((pos, j) => {
74+
const x = pos * grid + 5;
75+
const y = carRow.y * grid + 15;
76+
const w = grid - 10;
77+
const h = grid - 30;
78+
// Pick a tool type based on row and car index
79+
const toolIdx = (i + j) % toolColors.length;
80+
ctx.fillStyle = toolColors[toolIdx];
81+
ctx.strokeStyle = '#fff';
82+
ctx.lineWidth = 2;
83+
ctx.fillRect(x, y, w, h);
84+
ctx.strokeRect(x, y, w, h);
85+
// Draw tool label/icon
86+
ctx.fillStyle = '#fff';
87+
ctx.font = 'bold 18px sans-serif';
88+
ctx.textAlign = 'center';
89+
ctx.textBaseline = 'middle';
90+
ctx.fillText(toolLabels[toolIdx], x + w/2, y + h/2);
91+
});
92+
});
93+
}
94+
95+
function moveCars() {
96+
// Reduce the movement multiplier to slow down the cars
97+
const speedMultiplier = 0.025; // was 0.05
98+
cars.forEach(carRow => {
99+
for (let i = 0; i < carRow.positions.length; i++) {
100+
carRow.positions[i] += carRow.speed * carRow.dir * speedMultiplier;
101+
if (carRow.dir === 1 && carRow.positions[i] > cols) carRow.positions[i] = -1;
102+
if (carRow.dir === -1 && carRow.positions[i] < -1) carRow.positions[i] = cols;
103+
}
104+
});
105+
}
106+
107+
function checkCollision() {
108+
for (const carRow of cars) {
109+
if (frog.y === carRow.y) {
110+
for (const pos of carRow.positions) {
111+
if (Math.abs(frog.x - Math.round(pos)) < 0.7) {
112+
gameOver = true;
113+
return;
114+
}
115+
}
116+
}
117+
}
118+
}
119+
120+
function checkWin() {
121+
if (frog.y === 0) {
122+
win = true;
123+
gameOver = true;
124+
}
125+
}
126+
127+
function draw() {
128+
ctx.clearRect(0, 0, canvas.width, canvas.height);
129+
// Draw code editor background (lines)
130+
ctx.save();
131+
for (let y = 0; y < canvas.height; y += 24) {
132+
ctx.strokeStyle = 'rgba(255,255,255,0.04)';
133+
ctx.beginPath();
134+
ctx.moveTo(0, y);
135+
ctx.lineTo(canvas.width, y);
136+
ctx.stroke();
137+
}
138+
// Draw left gutter (like a code editor)
139+
ctx.fillStyle = '#232336';
140+
ctx.fillRect(0, 0, 36, canvas.height);
141+
// Draw line numbers
142+
ctx.fillStyle = '#6a9fb5';
143+
ctx.font = '12px monospace';
144+
ctx.textAlign = 'right';
145+
ctx.textBaseline = 'top';
146+
for (let i = 1; i <= rows; i++) {
147+
ctx.fillText(i, 32, (i-1)*grid + 8);
148+
}
149+
ctx.restore();
150+
// Draw safe zones (as terminal/code header/footer)
151+
ctx.fillStyle = '#222c37';
152+
ctx.fillRect(0, 0, canvas.width, grid);
153+
ctx.fillRect(0, canvas.height - grid, canvas.width, grid);
154+
// Draw road (pipeline)
155+
ctx.fillStyle = '#252540';
156+
ctx.fillRect(36, grid, canvas.width - 36, canvas.height - 2 * grid);
157+
// Draw a pipeline line
158+
ctx.strokeStyle = '#0078D4';
159+
ctx.lineWidth = 4;
160+
ctx.beginPath();
161+
ctx.moveTo(36, canvas.height/2);
162+
ctx.lineTo(canvas.width, canvas.height/2);
163+
ctx.stroke();
164+
drawFrog();
165+
drawCars();
166+
if (gameOver) {
167+
ctx.fillStyle = win ? 'lime' : 'red';
168+
ctx.font = 'bold 32px sans-serif';
169+
ctx.textAlign = 'center';
170+
ctx.fillText(win ? 'You Win!' : 'Game Over', canvas.width / 2, canvas.height / 2);
171+
}
172+
}
173+
174+
document.addEventListener('keydown', e => {
175+
// Only handle arrow keys if the canvas is focused or mouse is over it
176+
const arrowKeys = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];
177+
if (arrowKeys.includes(e.key)) {
178+
// Prevent page from scrolling
179+
e.preventDefault();
180+
if (gameOver) return;
181+
if (e.key === 'ArrowUp' && frog.y > 0) frog.y--;
182+
if (e.key === 'ArrowDown' && frog.y < rows - 1) frog.y++;
183+
if (e.key === 'ArrowLeft' && frog.x > 0) frog.x--;
184+
if (e.key === 'ArrowRight' && frog.x < cols - 1) frog.x++;
185+
}
186+
// Keyboard shortcut: R or r to restart
187+
if (e.key === 'r' || e.key === 'R') {
188+
e.preventDefault();
189+
resetGame();
190+
}
191+
});
192+
193+
function gameLoop() {
194+
if (!gameOver) {
195+
moveCars();
196+
checkCollision();
197+
checkWin();
198+
}
199+
draw();
200+
requestAnimationFrame(gameLoop);
201+
}
202+
gameLoop();
203+
</script>

frogger.html

Whitespace-only changes.

0 commit comments

Comments
 (0)