can leave lobby

This commit is contained in:
evanpelle
2024-08-25 09:33:58 -07:00
parent 2d7d4875f7
commit 6f1848dbc7
7 changed files with 61 additions and 80 deletions
+1
View File
@@ -54,3 +54,4 @@
* BUG: fix hotreload (priority queue breaks it)
* PERF: use hierarchical a* search for boats
* Add terrain elevation to map
* boats can go around the world
+32 -44
View File
@@ -24,6 +24,7 @@ class Client {
private lobbiesContainer: HTMLElement | null;
private lobbiesInterval: NodeJS.Timeout | null = null;
private isLobbyHighlighted: boolean = false;
private random = new PseudoRandom(1234)
@@ -52,34 +53,31 @@ class Client {
}
private updateLobbiesDisplay(lobbies: Lobby[]): void {
if (!this.lobbiesContainer) return;
if (lobbies.length === 0) {
document.getElementById('lobby-button').style.display = 'none';
return;
}
this.lobbiesContainer.innerHTML = ''; // Clear existing lobbies
const lobby = lobbies[0];
const lobbyButton = document.getElementById('lobby-button');
const nameElement = document.getElementById('lobby-name');
const timerElement = document.getElementById('lobby-timer');
const playerCountElement = document.getElementById('player-count');
lobbies.forEach(lobby => {
const button = document.createElement('button');
button.className = 'lobby-button';
if (lobbyButton) {
lobbyButton.style.display = 'flex';
lobbyButton.onclick = () => this.joinLobby(lobby);
const nameElement = document.createElement('div');
nameElement.className = 'lobby-name';
nameElement.textContent = `Lobby ${lobby.id}`;
// Preserve the highlighted state
lobbyButton.classList.toggle('highlighted', this.isLobbyHighlighted);
}
const timerElement = document.createElement('div');
timerElement.className = 'lobby-timer';
if (nameElement) nameElement.textContent = `Lobby ${lobby.id}`;
if (timerElement) {
const timeRemaining = Math.max(0, Math.floor((lobby.startTime - Date.now()) / 1000));
timerElement.textContent = `Starts in: ${timeRemaining}s`;
const playerCountElement = document.createElement('div');
playerCountElement.className = 'player-count';
playerCountElement.textContent = `Players: ${lobby.numClients}`
button.appendChild(nameElement);
button.appendChild(timerElement);
button.appendChild(playerCountElement);
button.onclick = () => this.joinLobby(lobby);
this.lobbiesContainer.appendChild(button);
});
}
if (playerCountElement) playerCountElement.textContent = `Players: ${lobby.numClients}`;
}
async fetchLobbies(): Promise<Lobby[]> {
@@ -97,25 +95,16 @@ class Client {
}
}
private async joinLobby(lobby: Lobby) {
clearInterval(this.lobbiesInterval);
if (this.lobbiesContainer) {
// Clear existing content
this.lobbiesContainer.innerHTML = '';
// Ensure the container takes up the full height of the viewport
this.lobbiesContainer.style.display = 'flex';
this.lobbiesContainer.style.justifyContent = 'center';
this.lobbiesContainer.style.alignItems = 'center';
this.lobbiesContainer.style.minHeight = '100vh';
// Create and add the joining message
const joiningMessage = document.createElement('div');
joiningMessage.textContent = `Joining: ${lobby.id}`;
joiningMessage.className = 'joining-message';
this.lobbiesContainer.appendChild(joiningMessage);
private joinLobby(lobby: Lobby) {
const lobbyButton = document.getElementById('lobby-button');
if (lobbyButton) {
this.isLobbyHighlighted = !this.isLobbyHighlighted;
lobbyButton.classList.toggle('highlighted', this.isLobbyHighlighted);
}
if (!this.isLobbyHighlighted) {
this.game.stop()
this.game = null
return
}
if (this.game != null) {
@@ -123,11 +112,10 @@ class Client {
}
this.game = createClientGame(getUsername(), new PseudoRandom(Date.now()).nextID(), lobby.id, getConfig(), this.terrainMap);
this.game.join();
const g = this.game
const g = this.game;
window.addEventListener('beforeunload', function (event) {
// Your function logic here
console.log('Browser is closing');
g.stop()
g.stop();
});
}
}
+4
View File
@@ -97,6 +97,9 @@ export class ClientGame {
};
this.socket.onclose = (event: CloseEvent) => {
console.log(`WebSocket closed. Code: ${event.code}, Reason: ${event.reason}`);
if (!this.isActive) {
return
}
if (event.code != 1000) {
this.join()
}
@@ -126,6 +129,7 @@ export class ClientGame {
clearInterval(this.intervalID)
this.isActive = false
if (this.socket.readyState === WebSocket.OPEN) {
console.log('on stop: leaving game')
const msg = ClientLeaveMessageSchema.parse({
type: "leave",
clientID: this.id,
+17 -30
View File
@@ -5,7 +5,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OpenFront (ALPHA)</title>
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" type="text/css" href="styles.css">
<style>
body {
font-family: Arial, sans-serif;
@@ -13,7 +13,6 @@
padding: 0;
min-height: 100vh;
background-color: #15151500;
/* Dark grey background */
background-image: url('/resources/images/watercolor_worldmap.jpg');
background-size: cover;
background-position: center;
@@ -23,17 +22,16 @@
.content {
max-width: 1020px;
/* Allows for two 500px buttons side by side with some margin */
margin: 0 auto;
padding: 20px;
position: relative;
}
h1 {
font-family: Arial, serif;
text-align: center;
color: #ffffff;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
font-size: 2.5em;
color: #2e2e2e;
font-size: 8em;
margin-bottom: 30px;
}
@@ -50,25 +48,12 @@
background-color: rgba(255, 255, 255, 0.8);
}
.lobby-button:hover {
background-color: rgba(0, 123, 255, 0.4);
transform: translateY(-5px);
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.4);
}
.player-count {
font-size: 24px;
margin-top: 20px;
color: #aaddff;
}
#lobbies-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 20px;
}
.lobby-button {
width: 500px;
height: 500px;
@@ -96,6 +81,13 @@
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.4);
}
.lobby-button.highlighted {
background-color: rgba(0, 123, 255, 0.6);
transform: translateY(-5px);
box-shadow: 0 6px 20px rgba(0, 123, 255, 0.6);
border-color: #ffffff;
}
.lobby-name {
font-size: 36px;
margin-bottom: 20px;
@@ -117,15 +109,6 @@
text-align: center;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
h1 {
font-family: Overpass, serif;
text-align: center;
color: #3d3c3c;
/* text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5); */
font-size: 8em;
margin-bottom: 30px;
}
</style>
</head>
@@ -136,7 +119,11 @@
<input type="text" id="username" placeholder="Enter your username">
</div>
<div id="lobbies-container">
<!-- Lobby buttons will be inserted here by your existing JavaScript -->
<button id="lobby-button" class="lobby-button">
<div id="lobby-name" class="lobby-name"></div>
<div id="lobby-timer" class="lobby-timer"></div>
<div id="player-count" class="player-count"></div>
</button>
</div>
</div>
+2 -2
View File
@@ -71,11 +71,11 @@ export class DefaultPlayerConfig implements PlayerConfig {
}
troopAdditionRate(player: Player): number {
const max = Math.sqrt(player.numTilesOwned()) * 1000 + 1000
const max = Math.sqrt(player.numTilesOwned()) * 1000 + 10000
let toAdd = 10 + (player.troops() + Math.sqrt(player.troops() * player.numTilesOwned())) / 250
return Math.min(player.troops() + toAdd, max)
return Math.min(Math.min(player.troops() + toAdd, max), 1_000_0000)
}
}
+4 -4
View File
@@ -4,10 +4,10 @@ import {DefaultConfig, DefaultPlayerConfig, defaultPlayerConfig} from "./Default
export const devConfig = new class extends DefaultConfig {
gameCreationRate(): number {
return 2 * 1000
return 21 * 1000
}
lobbyLifetime(): number {
return 5 * 1000
return 20 * 1000
}
turnIntervalMs(): number {
return 100
@@ -16,7 +16,7 @@ export const devConfig = new class extends DefaultConfig {
return devPlayerConfig
}
numBots(): number {
return 500
return 250
}
}
@@ -25,6 +25,6 @@ export const devPlayerConfig = new class extends DefaultPlayerConfig {
if (playerInfo.isBot) {
return 5000
}
return 5000
return 10000
}
}
+1
View File
@@ -43,6 +43,7 @@ export class GameServer {
}
}
if (clientMsg.type == "leave") {
// TODO: get rid of leave message, just use on close?
const toRemove = this.clients.filter(c => c.id)
if (toRemove.length == 0) {
return