From 37b5511439e6f17f2d870c1c8b81e0981a024c33 Mon Sep 17 00:00:00 2001 From: User Date: Sun, 22 Mar 2026 11:37:11 +0000 Subject: [PATCH] feat: Implement loading screen with retro 80s aesthetic and unit tests --- src/css/main.css | 23 +++++++++ src/css/screens.css | 62 +++++++++++++++++++++++ src/index.html | 29 +++++++++++ src/js/screens/loading.js | 100 +++++++++++++++++++++++++++++++++++++ tests/unit/loading.test.js | 46 +++++++++++++++++ 5 files changed, 260 insertions(+) create mode 100644 src/css/main.css create mode 100644 src/css/screens.css create mode 100644 src/index.html create mode 100644 src/js/screens/loading.js create mode 100644 tests/unit/loading.test.js diff --git a/src/css/main.css b/src/css/main.css new file mode 100644 index 0000000..a9876d3 --- /dev/null +++ b/src/css/main.css @@ -0,0 +1,23 @@ +/* Main styles for retro 80s aesthetic */ +:root { + --primary-color: #00FF00; + --secondary-color: #000080; + --background-color: #000000; + --text-color: #FFFFFF; + --border-color: #00FF00; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Courier New', monospace; + background-color: var(--background-color); + color: var(--text-color); + overflow: hidden; + height: 100vh; +} + diff --git a/src/css/screens.css b/src/css/screens.css new file mode 100644 index 0000000..c5cc933 --- /dev/null +++ b/src/css/screens.css @@ -0,0 +1,62 @@ +/* Loading screen styles */ +.loading-screen { + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + width: 100vw; + background-color: var(--background-color); + position: relative; +} + +.loading-content { + text-align: center; + padding: 20px; + border: 2px solid var(--border-color); + background-color: rgba(0, 0, 0, 0.8); +} + +.logo { + margin-bottom: 20px; +} + +.logo-block { + width: 40px; + height: 40px; + background-color: var(--primary-color); + margin: 0 auto 5px; + display: block; +} + +.logo-text { + font-size: 24px; + font-weight: bold; + color: var(--primary-color); + margin-bottom: 15px; +} + +.copyright { + font-size: 12px; + color: var(--text-color); + margin-bottom: 20px; +} + +.loading-bar { + width: 200px; + height: 20px; + background-color: var(--secondary-color); + margin: 0 auto 10px; + position: relative; +} + +.loading-progress { + width: 0%; + height: 100%; + background-color: var(--primary-color); + transition: width 0.3s ease; +} + +.loading-text { + font-size: 14px; + color: var(--text-color); +} diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..9d59bef --- /dev/null +++ b/src/index.html @@ -0,0 +1,29 @@ + + + + + + 3D Flight Simulator - Loading + + + + +
+
+ + +
+
+
+
Loading assets...
+
+
+ + + + diff --git a/src/js/screens/loading.js b/src/js/screens/loading.js new file mode 100644 index 0000000..8082946 --- /dev/null +++ b/src/js/screens/loading.js @@ -0,0 +1,100 @@ +/** + * Loading screen functionality for WINGS88 3D Flight Simulator + */ + +class LoadingScreen { + constructor() { + this.progress = 0; + this.assets = [ + 'texture1.png', + 'texture2.png', + 'sound1.mp3', + 'sound2.mp3', + 'model1.obj', + 'model2.obj' + ]; + this.audioContext = null; + this.audioBuffer = null; + } + + init() { + this.setupEventListeners(); + this.startLoading(); + this.initAudio(); + } + + setupEventListeners() { + document.addEventListener('DOMContentLoaded', () => { + this.init(); + }); + } + + startLoading() { + const progressBar = document.querySelector('.loading-progress'); + const loadingText = document.querySelector('.loading-text'); + + const interval = setInterval(() => { + this.progress += 5; + if (progressBar) progressBar.style.width = `${this.progress}%`; + + if (this.progress >= 100) { + clearInterval(interval); + if (loadingText) loadingText.textContent = 'Loading complete! Starting game...'; + setTimeout(() => { + this.transitionToIntro(); + }, 1000); + } + }, 200); + } + + initAudio() { + try { + // Check if audio is supported + if (typeof AudioContext !== 'undefined') { + this.audioContext = new AudioContext(); + this.loadBackgroundMusic(); + } + } catch (e) { + console.log('Audio initialization error:', e); + } + } + + loadBackgroundMusic() { + // In a real implementation, this would load actual audio files + // For now, we'll simulate loading + setTimeout(() => { + console.log('Background music loaded'); + }, 500); + } + + playBackgroundMusic() { + if (this.audioContext && this.audioBuffer) { + const source = this.audioContext.createBufferSource(); + source.buffer = this.audioBuffer; + source.connect(this.audioContext.destination); + source.start(0); + } + } + + transitionToIntro() { + // In a real implementation, this would transition to the intro screen + console.log('Transitioning to intro screen'); + // For now, we'll just log the transition + document.querySelector('.loading-text').textContent = 'Welcome to WINGS88!'; + } + + getProgress() { + return this.progress; + } +} + +// Initialize loading screen when DOM is ready +document.addEventListener('DOMContentLoaded', () => { + const loadingScreen = new LoadingScreen(); + loadingScreen.init(); +}); + +// Export for testing +if (typeof module !== 'undefined' && module.exports) { + module.exports = LoadingScreen; +} diff --git a/tests/unit/loading.test.js b/tests/unit/loading.test.js new file mode 100644 index 0000000..cb4bc39 --- /dev/null +++ b/tests/unit/loading.test.js @@ -0,0 +1,46 @@ +/** + * Unit tests for LoadingScreen class + */ + +const LoadingScreen = require('../../src/js/screens/loading'); + +describe('LoadingScreen', () => { + let loadingScreen; + + beforeEach(() => { + loadingScreen = new LoadingScreen(); + }); + + describe('constructor', () => { + it('should initialize with progress 0', () => { + expect(loadingScreen.getProgress()).toBe(0); + }); + + it('should have assets array', () => { + expect(loadingScreen.assets).toBeDefined(); + expect(Array.isArray(loadingScreen.assets)).toBe(true); + expect(loadingScreen.assets.length).toBeGreaterThan(0); + }); + }); + + describe('getProgress', () => { + it('should return current progress', () => { + expect(loadingScreen.getProgress()).toBe(0); + + // Simulate progress update + loadingScreen.progress = 50; + expect(loadingScreen.getProgress()).toBe(50); + }); + }); + + describe('asset loading', () => { + it('should have expected assets', () => { + expect(loadingScreen.assets).toContain('texture1.png'); + expect(loadingScreen.assets).toContain('texture2.png'); + expect(loadingScreen.assets).toContain('sound1.mp3'); + expect(loadingScreen.assets).toContain('sound2.mp3'); + expect(loadingScreen.assets).toContain('model1.obj'); + expect(loadingScreen.assets).toContain('model2.obj'); + }); + }); +});