diff --git a/src/app/game/game.component.ts b/src/app/game/game.component.ts index 3c86e38..8c8a126 100644 --- a/src/app/game/game.component.ts +++ b/src/app/game/game.component.ts @@ -17,9 +17,11 @@ export class GameComponent implements AfterViewInit { this.game = new Game(this.rendererContainer.nativeElement); this.game.start(); - // Listen to pointer lock changes document.addEventListener('pointerlockchange', () => { - this.pointerLockChange.emit(document.pointerLockElement === document.body); + const isLocked = document.pointerLockElement === document.body; + this.pointerLockChange.emit(isLocked); + + //document.body.requestPointerLock(); }); } } diff --git a/src/app/pages/index.page.ts b/src/app/pages/index.page.ts index 44c8c45..ee2f6c0 100644 --- a/src/app/pages/index.page.ts +++ b/src/app/pages/index.page.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, HostListener } from '@angular/core'; import { GameComponent } from '../game/game.component.ts'; import { MenuComponent } from '../ui/menu.component.ts'; @@ -15,7 +15,27 @@ import { MenuComponent } from '../ui/menu.component.ts'; export default class HomeComponent { showMenu = false; + // Add to class + @HostListener('document:keydown', ['$event']) + handleKeyboardEvent(event: KeyboardEvent) { + // Escape key shows menu + if (event.key === 'Escape') { + this.showMenu = true; + document.exitPointerLock(); + } + + // WASD locks pointer if menu is visible + if (['w', 'a', 's', 'd'].includes(event.key.toLowerCase()) && this.showMenu) { + this.showMenu = false; + document.body.requestPointerLock(); + } + } + + // Update pointer lock handler onPointerLockChange(isLocked: boolean) { this.showMenu = !isLocked; + if (!isLocked) { + document.exitPointerLock(); + } } } diff --git a/src/app/ui/browse.component.ts b/src/app/ui/browse.component.ts index d891d36..9a9c121 100644 --- a/src/app/ui/browse.component.ts +++ b/src/app/ui/browse.component.ts @@ -6,21 +6,28 @@ import { CommonModule } from '@angular/common'; standalone: true, imports: [CommonModule], template: ` - <div> - <h2 class="text-xl text-gray-100 mb-4">Browse Servers</h2> - <div class="space-y-4"> - <div class="server-item"> - Server 1 - </div> - <button class="btn-menu" (click)="back.emit()">Back</button> - </div> - </div> - `, + <div class="h-full"> + <h2 class="text-xl text-gray-100 mb-4">internet (for possum)</h2> + <div class="space-y-4 h-full"> + <div class="server-item whitespace-nowrap overflow-hidden text-ellipsis"> + possum world + </div> + <div class="server-item whitespace-nowrap overflow-hidden text-ellipsis"> + possum world 2 + </div> + <button class="btn-menu" (click)="back.emit()">back</button> + </div> + </div> + `, styles: [` - .server-item { - @apply p-2 bg-gray-700/50 rounded-md text-gray-200 mb-2; - } - `], + .server-item { + @apply p-2 bg-gray-700/50 text-gray-200 mb-2; + } + .btn-menu { + @apply w-full text-left px-4 py-2 text-gray-100 hover:bg-gray-700/50 transition-colors mb-2; + border-radius: 0; + } + `], }) export class BrowseComponent { @Output() diff --git a/src/app/ui/menu.component.ts b/src/app/ui/menu.component.ts index 25ab658..1702b7a 100644 --- a/src/app/ui/menu.component.ts +++ b/src/app/ui/menu.component.ts @@ -8,27 +8,38 @@ import { BrowseComponent } from './browse.component.ts'; standalone: true, imports: [CommonModule, SettingsComponent, BrowseComponent], template: ` - <div *ngIf="visible" class="fixed inset-0 bg-gray-900/80 backdrop-blur-sm z-50" - (click)="onBackdropClick($event)"> - <div class="absolute top-4 left-4 bg-gray-800/90 p-4 rounded-lg shadow-xl w-64" - style="z-index: 60;" - (click)="$event.stopPropagation()"> - <div *ngIf="activePage === 'main'"> - <button class="btn-menu" (click)="navigate('play')">Play</button> - <button class="btn-menu" (click)="navigate('settings')">Settings</button> - <button class="btn-menu" (click)="navigate('browse')">Browse</button> - </div> + <div *ngIf="visible" class="fixed inset-0 bg-gray-900/80 backdrop-blur-sm z-50" + (click)="onBackdropClick($event)"> + <div class="absolute top-4 left-4 bg-gray-800/90 p-4 w-64 max-h-[calc(100vh-2rem)] overflow-y-auto" + style="z-index: 60;" + (click)="$event.stopPropagation()"> + <div *ngIf="activePage === 'main'"> + <button class="btn-menu" (click)="navigate('play')">play</button> + <button class="btn-menu" (click)="navigate('settings')">settings</button> + <button class="btn-menu" (click)="navigate('browse')">possum net</button> + </div> - <app-settings *ngIf="activePage === 'settings'" (back)="activePage = 'main'"></app-settings> - <app-browse *ngIf="activePage === 'browse'" (back)="activePage = 'main'"></app-browse> - </div> - </div> - `, + <app-settings *ngIf="activePage === 'settings'" + class="h-full overflow-y-auto" + (back)="activePage = 'main'"></app-settings> + <app-browse *ngIf="activePage === 'browse'" + class="h-full overflow-y-auto" + (back)="activePage = 'main'"></app-browse> + </div> + </div> + `, styles: [` - .btn-menu { - @apply w-full text-left px-4 py-2 text-gray-100 hover:bg-gray-700/50 rounded-md transition-colors mb-2; - } - `], + :host { + @apply contents; + } + .fixed { + @apply overflow-hidden; + } + .btn-menu { + @apply w-full text-left px-4 py-2 text-gray-100 hover:bg-gray-700/50 transition-colors mb-2; + border-radius: 0; + } + `], }) export class MenuComponent { @Input() @@ -47,6 +58,7 @@ export class MenuComponent { navigate(page: 'settings' | 'browse' | 'play') { if (page === 'play') { this.close.emit(); + document.body.requestPointerLock(); return; } this.activePage = page; diff --git a/src/app/ui/settings.component.ts b/src/app/ui/settings.component.ts index b46542e..3afa126 100644 --- a/src/app/ui/settings.component.ts +++ b/src/app/ui/settings.component.ts @@ -8,23 +8,32 @@ import { SettingsManager } from '../../client/core/SettingsManager.ts'; standalone: true, imports: [CommonModule, FormsModule], template: ` - <div> - <h2 class="text-xl text-gray-100 mb-4">Settings</h2> - <div class="space-y-4"> - <div class="setting-item"> - <label>Sensitivity</label> - <input type="range" min="0.1" max="2" step="0.1" - [(ngModel)]="settings.sense" (change)="saveSettings()"> - </div> - <button class="btn-menu" (click)="back.emit()">Back</button> - </div> - </div> - `, + <div class="h-full"> + <h2 class="text-xl text-gray-100 mb-4">Settings</h2> + <div class="space-y-4 h-full"> + <div class="setting-item flex-nowrap"> + <label class="truncate">Sensitivity</label> + <div class="flex items-center gap-4 min-w-[160px]"> + <input type="range" min="0.1" max="2" step="0.1" + [(ngModel)]="settings.sense" (change)="saveSettings()"> + <span class="text-gray-200 min-w-[40px] text-right"> + {{ settings.sense | number:'1.1-1' }} + </span> + </div> + </div> + <button class="btn-menu" (click)="back.emit()">Back</button> + </div> + </div> + `, styles: [` - .setting-item { - @apply flex justify-between items-center mb-4 text-gray-200; - } - `], + .setting-item { + @apply flex justify-between items-center mb-4 text-gray-200; + } + .btn-menu { + @apply w-full text-left px-4 py-2 text-gray-100 hover:bg-gray-700/50 transition-colors mb-2; + border-radius: 0; + } + `], }) export class SettingsComponent { @Output()