Skip to content

Commit 373fffe

Browse files
Merge pull request #9 from th33k/feature/winning-score-logic
Feature/winning score logic
2 parents 87ee9d7 + 2d50c1e commit 373fffe

10 files changed

Lines changed: 2509 additions & 5 deletions

File tree

client/index.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
<head>
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
6-
<meta name="description" content="Mini Tank Fire - Real-time multiplayer tank battle arena game">
6+
<meta name="description" content="Tank Arena - Real-time multiplayer tank battle arena game">
77
<meta name="theme-color" content="#00ff88">
8-
<title>Mini Tank Fire: Online</title>
8+
<title>Tank Arena: Online</title>
99
<link rel="stylesheet" href="css/style.css">
1010
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
1111
<link rel="preconnect" href="https://cdnjs.cloudflare.com">
@@ -19,7 +19,7 @@
1919
<div class="join-content">
2020
<h1 id="game-title" class="game-title">
2121
<i class="fas fa-chess-rook" aria-hidden="true"></i>
22-
MINI TANK FIRE
22+
TANK ARENA
2323
</h1>
2424
<p class="game-subtitle">Real-time Multiplayer Battle Arena</p>
2525
<form class="join-form" id="join-form">
@@ -78,7 +78,7 @@ <h1 id="game-title" class="game-title">
7878
<div class="lobby-content">
7979
<h1 class="game-title">
8080
<i class="fas fa-chess-rook"></i>
81-
MINI TANK FIRE
81+
TANK ARENA
8282
</h1>
8383
<p class="game-subtitle">Real-time Multiplayer Battle Arena</p>
8484

@@ -203,6 +203,6 @@ <h2>ELIMINATED</h2>
203203
</div>
204204
</div>
205205

206-
<script src="js/game.js"></script>
206+
<script type="module" src="js/game-client.js"></script>
207207
</body>
208208
</html>

client/js/core/config.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Game configuration constants
2+
export const CONFIG = {
3+
CANVAS: {
4+
WIDTH: 1920,
5+
HEIGHT: 1080,
6+
GRID_SIZE: 50
7+
},
8+
9+
MINIMAP: {
10+
WIDTH: 200,
11+
HEIGHT: 150,
12+
GRID_SIZE_X: 40,
13+
GRID_SIZE_Y: 30
14+
},
15+
16+
PLAYER: {
17+
SIZE: 36,
18+
BARREL_LENGTH: 25,
19+
BARREL_OFFSET: 8,
20+
SPEED_NORMAL: 12,
21+
SPEED_BOOSTED: 20,
22+
MIN_X: 15,
23+
MAX_X: 1905,
24+
MIN_Y: 15,
25+
MAX_Y: 1065
26+
},
27+
28+
WEAPON: {
29+
FIRE_RATE: 500,
30+
BASE_DAMAGE: 25,
31+
HEAT_INCREASE: 20,
32+
HEAT_DECAY_RATE: 0.2,
33+
MAX_HEAT: 100,
34+
FIRE_RATES: {
35+
NORMAL: 500,
36+
HEAT_40: 800,
37+
HEAT_60: 1200,
38+
HEAT_80: 2000
39+
}
40+
},
41+
42+
BULLET: {
43+
RADIUS: 4,
44+
TRAIL_LENGTH: 2
45+
},
46+
47+
POWERUP: {
48+
RADIUS: 14,
49+
PULSE_SPEED: 200,
50+
PULSE_AMOUNT: 3,
51+
COLORS: {
52+
SHIELD: '#00ffff',
53+
SPEED_BOOST: '#ffff00',
54+
DOUBLE_FIRE: '#ff6600'
55+
}
56+
},
57+
58+
EFFECTS: {
59+
EXPLOSION_PARTICLES: 30,
60+
PARTICLE_DECAY: 0.02,
61+
SHIELD_PULSE_SPEED: 200,
62+
SHIELD_RADIUS: 30,
63+
ANIMATION_DURATION: 1000,
64+
NOTIFICATION_DURATION: 3000
65+
},
66+
67+
RESPAWN: {
68+
COUNTDOWN: 3,
69+
HEALTH: 100
70+
}
71+
};

client/js/core/input-manager.js

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import { CONFIG } from '../core/config.js';
2+
3+
// Input Manager - Handles keyboard and mouse input
4+
export class InputManager {
5+
constructor(gameClient) {
6+
this.game = gameClient;
7+
this.keys = {};
8+
this.mouseX = 0;
9+
this.mouseY = 0;
10+
}
11+
12+
setupEventListeners(canvas) {
13+
this.setupKeyboardEvents();
14+
this.setupMouseEvents(canvas);
15+
this.setupUIButtonEvents();
16+
}
17+
18+
setupKeyboardEvents() {
19+
document.addEventListener('keydown', (e) => {
20+
this.keys[e.code] = true;
21+
22+
if (e.code === 'Enter') {
23+
this.handleEnterKey(e);
24+
}
25+
26+
if (e.code === 'Escape') {
27+
this.handleEscapeKey();
28+
}
29+
});
30+
31+
document.addEventListener('keyup', (e) => {
32+
this.keys[e.code] = false;
33+
});
34+
}
35+
36+
handleEnterKey(e) {
37+
const joinScreen = document.getElementById('join-screen');
38+
const playerNameInput = document.getElementById('player-name');
39+
const serverAddressInput = document.getElementById('server-address');
40+
41+
if (joinScreen && joinScreen.style.display !== 'none') {
42+
if (document.activeElement === playerNameInput ||
43+
document.activeElement === serverAddressInput) {
44+
return;
45+
}
46+
}
47+
48+
const chatInput = document.getElementById('chat-input');
49+
if (document.activeElement === chatInput) {
50+
this.game.sendChat();
51+
chatInput.blur();
52+
} else if (chatInput) {
53+
chatInput.focus();
54+
}
55+
56+
e.preventDefault();
57+
}
58+
59+
handleEscapeKey() {
60+
const chatInput = document.getElementById('chat-input');
61+
if (chatInput) {
62+
chatInput.blur();
63+
}
64+
}
65+
66+
setupMouseEvents(canvas) {
67+
canvas.addEventListener('mousemove', (e) => {
68+
const rect = canvas.getBoundingClientRect();
69+
const scaleX = canvas.width / rect.width;
70+
const scaleY = canvas.height / rect.height;
71+
72+
this.mouseX = (e.clientX - rect.left) * scaleX;
73+
this.mouseY = (e.clientY - rect.top) * scaleY;
74+
});
75+
76+
canvas.addEventListener('click', () => {
77+
this.game.tryFire();
78+
});
79+
}
80+
81+
setupUIButtonEvents() {
82+
const voiceBtn = document.getElementById('voice-toggle');
83+
if (voiceBtn) {
84+
voiceBtn.addEventListener('click', () => {
85+
this.game.voiceChatManager.toggle((msg, type) => {
86+
this.game.uiManager.showNotification(msg, type);
87+
});
88+
});
89+
}
90+
91+
const sendBtn = document.getElementById('send-btn');
92+
if (sendBtn) {
93+
sendBtn.addEventListener('click', () => {
94+
this.game.sendChat();
95+
});
96+
}
97+
98+
const chatToggleBtn = document.getElementById('chat-toggle');
99+
if (chatToggleBtn) {
100+
chatToggleBtn.addEventListener('click', () => {
101+
this.game.uiManager.chatOpen = !this.game.uiManager.chatOpen;
102+
const chatPanel = document.getElementById('chat-panel');
103+
chatPanel.style.height = this.game.uiManager.chatOpen ? 'auto' : '45px';
104+
document.getElementById('chat-messages').style.display = this.game.uiManager.chatOpen ? 'block' : 'none';
105+
document.querySelector('.chat-input-wrapper').style.display = this.game.uiManager.chatOpen ? 'flex' : 'none';
106+
});
107+
}
108+
109+
const settingsBtn = document.getElementById('settings-btn');
110+
if (settingsBtn) {
111+
settingsBtn.addEventListener('click', () => {
112+
this.game.uiManager.toggleSettings(
113+
this.game.aimLineEnabled,
114+
(enabled) => { this.game.aimLineEnabled = enabled; }
115+
);
116+
});
117+
}
118+
}
119+
120+
getAngle() {
121+
if (this.game.myPlayer) {
122+
return Math.atan2(
123+
this.mouseY - this.game.myPlayer.y,
124+
this.mouseX - this.game.myPlayer.x
125+
) * 180 / Math.PI;
126+
}
127+
return 0;
128+
}
129+
130+
getMovement() {
131+
if (!this.game.myPlayer || !this.game.isAlive) return null;
132+
133+
let x = this.game.myPlayer.x;
134+
let y = this.game.myPlayer.y;
135+
const speed = this.game.myPlayer.speedBoost ? CONFIG.PLAYER.SPEED_BOOSTED : CONFIG.PLAYER.SPEED_NORMAL;
136+
137+
if (this.keys['KeyW'] || this.keys['ArrowUp']) y -= speed;
138+
if (this.keys['KeyS'] || this.keys['ArrowDown']) y += speed;
139+
if (this.keys['KeyA'] || this.keys['ArrowLeft']) x -= speed;
140+
if (this.keys['KeyD'] || this.keys['ArrowRight']) x += speed;
141+
142+
x = Math.max(CONFIG.PLAYER.MIN_X, Math.min(CONFIG.PLAYER.MAX_X, x));
143+
y = Math.max(CONFIG.PLAYER.MIN_Y, Math.min(CONFIG.PLAYER.MAX_Y, y));
144+
145+
return { x, y };
146+
}
147+
148+
isSpacePressed() {
149+
return this.keys['Space'];
150+
}
151+
}

0 commit comments

Comments
 (0)