8000 more avanced difficulty level and other ehnacements · sjefvanleeuwen/shooter@4abccde · GitHub
[go: up one dir, main page]

Skip to content

Commit 4abccde

Browse files
more avanced difficulty level and other ehnacements
1 parent 3908c1c commit 4abccde

12 files changed

+444
-115
lines changed

audio/alien-shoot.mp3

242 KB
Binary file not shown.

audio/explosion.mp3

5.52 MB
Binary file not shown.
3.75 MB
Binary file not shown.

audio/player-shoot.flac

23.6 KB
Binary file not shown.

index.html

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,14 @@
1111
}
1212
canvas {
1313
display: block;
14-
border: 5px solid #ffffff; /* Added border */
15-
}
16-
.dg.ac {
17-
z-index: 1000 !important;
18-
}
19-
.dg {
20-
position: fixed !important;
21-
top: 0 !important;
22-
right: 0 !important;
23-
z-index: 9999 !important;
24-
}
25-
.dg.main {
26-
margin-right: 0 !important;
14+
border: 5px solid #ffffff;
2715
}
2816
* { font-family: 'Press Start 2P', cursive; }
2917
</style>
30-
<!-- Load dat.GUI with CORS enabled -->
31-
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.9/dat.gui.min.js" crossorigin="anonymous"></script>
18+
<!-- Remove dat.GUI script -->
3219
</head>
3320
<body>
3421
<canvas id="gameCanvas"></canvas>
35-
<!-- Make sure module script loads after dat.GUI -->
3622
<script type="module" src="js/game.js"></script>
3723
</body>
3824
</html>

js/LaserParticle.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,51 @@ class AlienLaser {
77
this.vy = 600; // Moving downward
88
this.life = 2.0;
99
this.maxLife = this.life;
10+
11+
// Set up audio if it hasn't been initialized yet
12+
if (!AlienLaser.audioContext) {
13+
AlienLaser.setupAudio();
14+
}
15+
}
16+
17+
static async setupAudio() {
18+
AlienLaser.audioContext = new (window.AudioContext || window.webkitAudioContext)();
19+
try {
20+
const response = await fetch('./audio/alien-shoot.mp3');
21+
const arrayBuffer = await response.arrayBuffer();
22+
AlienLaser.shootBuffer = await AlienLaser.audioContext.decodeAudioData(arrayBuffer);
23+
} catch (error) {
24+
console.error('Error loading alien shoot sound:', error);
25+
}
26+
}
27+
28+
static playShootSound(x, virtualWidth) {
29+
if (!AlienLaser.shootBuffer || !AlienLaser.audioContext) return;
30+
31+
const source = AlienLaser.audioContext.createBufferSource();
32+
const gainNode = AlienLaser.audioContext.createGain();
33+
const pannerNode = AlienLaser.audioContext.createStereoPanner();
34+
35+
source.buffer = AlienLaser.shootBuffer;
36+
source.connect(pannerNode);
37+
pannerNode.connect(gainNode);
38+
gainNode.connect(AlienLaser.audioContext.destination);
39+
40+
// Pan based on position
41+
const normalizedX = (x / virtualWidth) * 2 - 1;
42+
pannerNode.pan.value = normalizedX;
43+
44+
// Slightly randomize pitch
45+
const pitchVariation = 1 + (Math.random() * 0.1 - 0.05); // ±5% variation
46+
source.playbackRate.value = pitchVariation;
47+
48+
// Quick fade out
49+
const fadeDuration = 0.2;
50+
gainNode.gain.setValueAtTime(0.3, AlienLaser.audioContext.currentTime);
51+
gainNode.gain.linearRampToValueAtTime(0, AlienLaser.audioContext.currentTime + fadeDuration);
52+
53+
source.start();
54+
source.stop(AlienLaser.audioContext.currentTime + fadeDuration);
1055
}
1156

1257
update(delta) {

js/PatternFormation.js

Lines changed: 47 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,34 @@ class PatternFormation {
1111
this.virtualWidth = options.virtualWidth || 1080;
1212
this.virtualHeight = options.virtualHeight || 1080;
1313

14-
// Initialize config first
14+
// Initialize config with new starting values
1515
this.config = {
1616
speed: 0.3,
1717
radius: 80,
1818
patternType: 'infinity',
1919
loopDuration: 10,
20-
alienCount: 5,
21-
showPath: false, // Changed from true to false
20+
alienCount: 10, // Increased from 5 to 10
21+
showPath: false,
2222
pathPoints: 100, // number of points to draw on path
2323
formationRadius: 150, // New separate radius for formation
2424
pulseIntensity: 0, // Add pulse intensity control
2525
pulseSpeed: 1, // Add pulse speed control
2626
shootingEnabled: true // Add shooting enabled control
2727
};
2828

29+
// Add difficulty progression parameters
30+
this.difficulty = options.difficulty || 1;
31+
this.maxDifficulty = 10; // After this, reset and speed up
32+
this.baseFormationRadius = 150;
33+
this.radiusIncrease = 20; // Amount to increase per level
34+
this.basePulseIntensity = 0;
35+
this.pulseIntensityIncrease = 0.5;
36+
this.basePulseSpeed = 1;
37+
this.pulseSpeedIncrease = 0.2;
38+
39+
// Apply difficulty modifiers
40+
this.applyDifficultyModifiers();
41+
2942
this.aliens = [];
3043
this.pattern = patterns[options.pattern || 'circle'];
3144
this.time = 0;
@@ -64,9 +77,6 @@ class PatternFormation {
6477
this.shootTimer = 0;
6578
this.shootInterval = 1.0; // Time between shots
6679

67-
// Delay GUI setup to ensure dat.GUI is loaded
68-
setTimeout(() => this.setupGUI(), 100);
69-
7080
this.difficulty = options.difficulty || 1;
7181
this.shootInterval = Math.max(0.3, 1.0 - (this.difficulty * 0.1)); // Shoot faster with higher difficulty
7282
this.config.speed = Math.min(2.0, 0.3 + (this.difficulty * 0.1)); // Move faster with higher difficulty
@@ -76,77 +86,31 @@ class PatternFormation {
7686
this.explosionEffect = new ExplosionEffect(ctx);
7787
}
7888

79-
setupGUI() {
80-
if (!window.dat || !window.dat.GUI) {
81-
console.error('dat.GUI not loaded, retrying...');
82-
setTimeout(() => this.setupGUI(), 100);
83-
return;
84-
}
89+
applyDifficultyModifiers() {
90+
// Calculate actual difficulty level (cycles through 1-10)
91+
const cycleDifficulty = ((this.difficulty - 1) % this.maxDifficulty) + 1;
92+
93+
// Increase formation radius with difficulty
94+
this.config.formationRadius = this.baseFormationRadius +
95+
(cycleDifficulty - 1) * this.radiusIncrease;
96+
97+
// Increase pulse intensity and speed
98+
this.config.pulseIntensity = this.basePulseIntensity +
99+
(cycleDifficulty - 1) * this.pulseIntensityIncrease;
100+
this.config.pulseSpeed = this.basePulseSpeed +
101+
(cycleDifficulty - 1) * this.pulseSpeedIncrease;
102+
103+
// Adjust base shooting speed based on cycle count
104+
const cycleCount = Math.floor((this.difficulty - 1) / this.maxDifficulty);
105+
this.shootInterval = Math.max(0.3, 1.0 - (cycleCount * 0.1) - (cycleDifficulty * 0.05));
106+
107+
// Adjust movement speed
108+
this.config.speed = Math.min(2.0, 0.3 + (cycleCount * 0.1) + (cycleDifficulty * 0.05));
85109

86-
try {
87-
this.gui = new dat.GUI({
88-
width: 300,
89-
autoPlace: true,
90-
closed: false
91-
});
92-
93-
// Add controls to the GUI
94-
const folder = this.gui.addFolder('Formation Controls');
95-
96-
// Update speed control to affect loopDuration
97-
folder.add(this.config, 'speed', 0.1, 2.0)
98-
.name('Speed')
99-
.onChange(value => {
100-
this.loopDuration = 10 / value; // Adjust base duration by speed
101-
});
102-
103-
// Formation radius control
104-
folder.add(this.config, 'formationRadius', 50, 300)
105-
.name('Formation Radius')
106-
.onChange(value => {
107-
this.calculateFormationParameters();
108-
});
109-
110-
folder.add(this.config, 'alienCount', 3, 10)
111-
.step(1)
112-
.name('Alien Count')
113-
.onChange(value => {
114-
// Recreate formation with new count
115-
this.createFormation();
116-
});
117-
folder.add(this.config, 'loopDuration', 5, 20).name('Loop Duration');
118-
folder.add(this.config, 'showPath').name('Show Path').onChange((value) => {
119-
this.config.showPath = value;
120-
});
121-
122-
folder.add(this.path, 'smoothingFactor', 0.8, 0.99)
123-
.name('Path Smoothing')
124-
.onChange(value => {
125-
this.path.smoothingFactor = value;
126-
});
127-
128-
// Add pulse controls
129-
folder.add(this.config, 'pulseIntensity', 0, 10)
130-
.name('Pulse Intensity')
131-
.onChange(() => this.calculateFormationParameters());
132-
133-
folder.add(this.config, 'pulseSpeed', 0.1, 2)
134-
.name('Pulse Speed');
135-
136-
folder.add(this.config, 'shootingEnabled')
137-
.name('Alien Shooting');
138-
139-
// Force the folder to be open
140-
folder.open();
141-
142-
// Ensure GUI is visible
143-
this.gui.domElement.style.zIndex = '10000';
144-
document.body.appendChild(this.gui.domElement);
145-
146-
console.log('GUI setup complete');
147-
} catch (error) {
148-
console.error('Error setting up GUI:', error);
149-
}
110+
console.log(`Level ${this.difficulty} (Cycle ${cycleCount + 1}, Difficulty ${cycleDifficulty})`);
111+
console.log(`Formation Radius: ${this.config.formationRadius}`);
112+
console.log(`Pulse Intensity: ${this.config.pulseIntensity}`);
113+
console.log(`Pulse Speed: ${this.config.pulseSpeed}`);
150114
}
151115

152116
calculateFormationParameters() {
@@ -158,7 +122,11 @@ class PatternFormation {
158122
this.formationSpacing = Math.max(minSpacing, this.config.formationRadius * 0.8);
159123
}
160124

125+
// Modify createFormation to apply current difficulty settings
161126
createFormation() {
127+
// Apply new difficulty modifiers before creating formation
128+
this.applyDifficultyModifiers();
129+
162130
this.aliens = [];
163131
this.alienSlots = []; // Reset slots
164132
const count = Math.floor(this.config.alienCount);
@@ -303,6 +271,9 @@ class PatternFormation {
303271
shooter.y + shooter.height
304272
);
305273
this.lasers.push(laser);
274+
275+
// Play shoot sound with position
276+
AlienLaser.playShootSound(shooter.x + shooter.width/2, this.virtualWidth);
306277
}
307278

308279
getPatternPosition(angle, centerX, centerY, radiusX, radiusY) {

js/audio/MusicPlayer.js

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
class MusicPlayer {
2+
constructor() {
3+
this.tracks = [
4+
'./audio/music/XENOWAR - Dark Matter Protocol.mp3'
5+
];
6+
this.currentTrack = 0;
7+
this.audioElement = new Audio();
8+
this.audioElement.volume = 0.4; // Start at 40% volume
9+
this.isPlaying = false;
10+
11+
// Setup track ending handler
12+
this.audioElement.addEventListener('ended', () => {
13+
this.playNext();
14+
});
15+
}
16+
17+
async start() {
18+
try {
19+
await this.playTrack(this.currentTrack);
20+
} catch (error) {
21+
console.error('Error starting music:', error);
22+
}
23+
}
24+
25+
async playTrack(index) {
26+
if (index >= 0 && index < this.tracks.length) {
27+
this.currentTrack = index;
28+
this.audioElement.src = this.tracks[index];
29+
try {
30+
await this.audioElement.play();
31+
this.isPlaying = true;
32+
} catch (error) {
33+
console.error('Error playing track:', error);
34+
}
35+
}
36+
}
37+
38+
playNext() {
39+
this.currentTrack = (this.currentTrack + 1) % this.tracks.length;
40+
this.playTrack(this.currentTrack);
41+
}
42+
43+
pause() {
44+
this.audioElement.pause();
45+
this.isPlaying = false;
46+
}
47+
48+
resume() {
49+
this.audioElement.play();
50+
this.isPlaying = true;
51+
}
52+
53+
stop() {
54+
this.audioElement.pause();
55+
this.audioElement.currentTime = 0;
56+
this.isPlaying = false;
57+
}
58+
59+
setVolume(value) {
60+
// Clamp volume between 0 and 1
61+
this.audioElement.volume = Math.max(0, Math.min(1, value));
62+
}
63+
64+
fadeOut(duration = 2) {
65+
const steps = 60;
66+
const initialVolume = this.audioElement.volume;
67+
const volumeStep = initialVolume / steps;
68+
let currentStep = 0;
69+
70+
const fadeInterval = setInterval(() => {
71+
currentStep++;
72+
if (currentStep >= steps) {
73+
clearInterval(fadeInterval);
74+
this.pause();
75+
this.audioElement.volume = initialVolume;
76+
} else {
77+
this.audioElement.volume = initialVolume - (volumeStep * currentStep);
78+
}
79+
}, (duration * 1000) / steps);
80+
}
81+
82+
fadeIn(duration = 2) {
83+
const steps = 60;
84+
const targetVolume = 0.4; // Default volume
85+
const volumeStep = targetVolume / steps;
86+
let currentStep = 0;
87+
88+
this.audioElement.volume = 0;
89+
this.resume();
90+
91+
const fadeInterval = setInterval(() => {
92+
currentStep++;
93+
if (currentStep >= steps) {
94+
clearInterval(fadeInterval);
95+
}
96+
this.audioElement.volume = volumeStep * currentStep;
97+
}, (duration * 1000) / steps);
98+
}
99+
}
100+
101+
export default MusicPlayer;

0 commit comments

Comments
 (0)
0