Skip to content

Commit 5938e39

Browse files
committed
Content update
1 parent f4dce59 commit 5938e39

1 file changed

Lines changed: 258 additions & 0 deletions

File tree

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Territory Breakout PvP</title>
7+
<style>
8+
* {
9+
box-sizing: border-box;
10+
margin: 0;
11+
padding: 0;
12+
}
13+
body {
14+
background-color: #1a1a1a;
15+
color: #ffffff;
16+
font-family: 'Courier New', Courier, monospace;
17+
display: flex;
18+
flex-direction: column;
19+
align-items: center;
20+
justify-content: center;
21+
min-height: 100vh;
22+
}
23+
#game-container {
24+
display: flex;
25+
flex-direction: column;
26+
align-items: center;
27+
gap: 15px;
28+
}
29+
#ui {
30+
display: flex;
31+
justify-content: space-between;
32+
width: 600px;
33+
font-size: 1.2rem;
34+
font-weight: bold;
35+
}
36+
canvas {
37+
border: 4px solid #333;
38+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
39+
background-color: #000;
40+
}
41+
#controls {
42+
text-align: center;
43+
font-size: 0.9rem;
44+
color: #aaa;
45+
}
46+
</style>
47+
</head>
48+
<body>
49+
50+
<div id="game-container">
51+
<div id="ui">
52+
<span style="color: #e0e0e0;">DAY (P1): <span id="day-score">50</span>%</span>
53+
<span style="color: #1e3d59;">NIGHT (P2): <span id="night-score">50</span>%</span>
54+
</div>
55+
56+
<canvas id="gameCanvas" width="600" height="600"></canvas>
57+
58+
<div id="controls">
59+
<strong>P1 (Light):</strong> A / D to Move | <strong>P2 (Dark):</strong> Left / Right Arrows to Move
60+
</div>
61+
</div>
62+
63+
<script>
64+
const canvas = document.getElementById('gameCanvas');
65+
const ctx = canvas.getContext('2d');
66+
67+
const DAY_COLOR = '#e0e0e0';
68+
const NIGHT_COLOR = '#1e3d59';
69+
70+
// Grid Setup
71+
const COLS = 30;
72+
const ROWS = 30;
73+
const TILE_SIZE = canvas.width / COLS;
74+
75+
// 0 = Day (Light), 1 = Night (Dark)
76+
let grid = Array.from({ length: ROWS }, (_, r) =>
77+
Array.from({ length: COLS }, () => (r < ROWS / 2 ? 0 : 1))
78+
);
79+
80+
// Paddles
81+
const paddleWidth = 80;
82+
const paddleHeight = 12;
83+
84+
const p1 = {
85+
x: canvas.width / 2 - paddleWidth / 2,
86+
y: 10,
87+
width: paddleWidth,
88+
height: paddleHeight,
89+
dx: 0,
90+
speed: 7,
91+
color: '#ffffff'
92+
};
93+
94+
const p2 = {
95+
x: canvas.width / 2 - paddleWidth / 2,
96+
y: canvas.height - 10 - paddleHeight,
97+
width: paddleWidth,
98+
height: paddleHeight,
99+
dx: 0,
100+
speed: 7,
101+
color: '#0f2027'
102+
};
103+
104+
// Balls
105+
// Ball 1 (Belongs to Day/Light): Destroys Night (1 -> 0)
106+
const ball1 = {
107+
x: canvas.width / 2,
108+
y: canvas.height / 2 - 20,
109+
radius: 7,
110+
dx: 3,
111+
dy: -4,
112+
color: '#ffffff',
113+
targetTile: 1, // Target to convert
114+
fillWith: 0 // Value to write
115+
};
116+
117+
// Ball 2 (Belongs to Night/Dark): Destroys Day (0 -> 1)
118+
const ball2 = {
119+
x: canvas.width / 2,
120+
y: canvas.height / 2 + 20,
121+
radius: 7,
122+
dx: -3,
123+
dy: 4,
124+
color: '#0f2027',
125+
targetTile: 0,
126+
fillWith: 1
127+
};
128+
129+
// Key Listeners
130+
const keys = {};
131+
window.addEventListener('keydown', (e) => keys[e.key] = true);
132+
window.addEventListener('keyup', (e) => keys[e.key] = false);
133+
134+
function handleInput() {
135+
// P1 Controls (A / D)
136+
if (keys['a'] || keys['A']) p1.dx = -p1.speed;
137+
else if (keys['d'] || keys['D']) p1.dx = p1.speed;
138+
else p1.dx = 0;
139+
140+
// P2 Controls (Arrow Left / Arrow Right)
141+
if (keys['ArrowLeft']) p2.dx = -p2.speed;
142+
else if (keys['ArrowRight']) p2.dx = p2.speed;
143+
else p2.dx = 0;
144+
145+
// Move Paddles with Constraints
146+
p1.x = Math.max(0, Math.min(canvas.width - p1.width, p1.x + p1.dx));
147+
p2.x = Math.max(0, Math.min(canvas.width - p2.width, p2.x + p2.dx));
148+
}
149+
150+
function updateBall(b) {
151+
b.x += b.dx;
152+
b.y += b.dy;
153+
154+
// Wall Collisions (Left / Right)
155+
if (b.x - b.radius < 0 || b.x + b.radius > canvas.width) {
156+
b.dx *= -1;
157+
b.x = Math.max(b.radius, Math.min(canvas.width - b.radius, b.x));
158+
}
159+
160+
// Paddle Collisions
161+
// Top Paddle (P1)
162+
if (
163+
b.y - b.radius <= p1.y + p1.height &&
164+
b.x >= p1.x && b.x <= p1.x + p1.width &&
165+
b.dy < 0
166+
) {
167+
b.dy *= -1;
168+
let hitPoint = (b.x - (p1.x + p1.width / 2)) / (p1.width / 2);
169+
b.dx = hitPoint * 5;
170+
}
171+
172+
// Bottom Paddle (P2)
173+
if (
174+
b.y + b.radius >= p2.y &&
175+
b.x >= p2.x && b.x <= p2.x + p2.width &&
176+
b.dy > 0
177+
) {
178+
b.dy *= -1;
179+
let hitPoint = (b.x - (p2.x + p2.width / 2)) / (p2.width / 2);
180+
b.dx = hitPoint * 5;
181+
}
182+
183+
// Top / Bottom Out of Bounds Reset
184+
if (b.y - b.radius < 0) {
185+
b.y = canvas.height / 2;
186+
b.dy = Math.abs(b.dy);
187+
}
188+
if (b.y + b.radius > canvas.height) {
189+
b.y = canvas.height / 2;
190+
b.dy = -Math.abs(b.dy);
191+
}
192+
193+
// Tile Collisions & Territory Flipping
194+
let gridX = Math.floor(b.x / TILE_SIZE);
195+
let gridY = Math.floor(b.y / TILE_SIZE);
196+
197+
if (gridY >= 0 && gridY < ROWS && gridX >= 0 && gridX < COLS) {
198+
if (grid[gridY][gridX] === b.targetTile) {
199+
grid[gridY][gridX] = b.fillWith;
200+
b.dy *= -1; // Bounce back on impact
201+
}
202+
}
203+
}
204+
205+
function drawGridAndScores() {
206+
let dayCount = 0;
207+
let totalTiles = COLS * ROWS;
208+
209+
for (let r = 0; r < ROWS; r++) {
210+
for (let c = 0; c < COLS; c++) {
211+
ctx.fillStyle = grid[r][c] === 0 ? DAY_COLOR : NIGHT_COLOR;
212+
ctx.fillRect(c * TILE_SIZE, r * TILE_SIZE, TILE_SIZE, TILE_SIZE);
213+
if (grid[r][c] === 0) dayCount++;
214+
}
215+
}
216+
217+
// UI Updates
218+
let dayPercentage = Math.round((dayCount / totalTiles) * 100);
219+
document.getElementById('day-score').textContent = dayPercentage;
220+
document.getElementById('night-score').textContent = 100 - dayPercentage;
221+
}
222+
223+
function drawPaddle(p) {
224+
ctx.fillStyle = p.color;
225+
ctx.fillRect(p.x, p.y, p.width, p.height);
226+
ctx.strokeStyle = '#888';
227+
ctx.strokeRect(p.x, p.y, p.width, p.height);
228+
}
229+
230+
function drawBall(b) {
231+
ctx.beginPath();
232+
ctx.arc(b.x, b.y, b.radius, 0, Math.PI * 2);
233+
ctx.fillStyle = b.color;
234+
ctx.fill();
235+
ctx.strokeStyle = '#888';
236+
ctx.stroke();
237+
ctx.closePath();
238+
}
239+
240+
function loop() {
241+
handleInput();
242+
updateBall(ball1);
243+
updateBall(ball2);
244+
245+
ctx.clearRect(0, 0, canvas.width, canvas.height);
246+
drawGridAndScores();
247+
drawPaddle(p1);
248+
drawPaddle(p2);
249+
drawBall(ball1);
250+
drawBall(ball2);
251+
252+
requestAnimationFrame(loop);
253+
}
254+
255+
loop();
256+
</script>
257+
</body>
258+
</html>

0 commit comments

Comments
 (0)