Added a Song duration bar. Contains the song name, song duration and duration bar. Song duration acts as a countdown timer, same as the duration bar. Styling for mobile may need to be adjusted. Name/Duration/Timer updates correctly when the song changes.

This commit is contained in:
Jamon 2024-08-11 13:54:38 +12:00
parent a553fdd46a
commit b240756a64
4 changed files with 150 additions and 11 deletions

View File

@ -180,8 +180,8 @@ class SynthCoin:
self.x = x
self.y = y
self.radius = 5
self.follow_radius = 100
self.follow_speed = 2
self.follow_radius = 200
self.follow_speed = 5
self.created_at = time.time()
def update(self, players):
@ -1482,6 +1482,7 @@ def game_loop():
'action': 'change',
'song': f"/{music_player.get_current_song()}",
'startTime': music_player.start_time,
'serverTime': time.time(),
'songDuration': music_player.get_current_song_duration()
}, room=main_room)
@ -1551,6 +1552,7 @@ def start_music():
'action': 'start',
'song': music_player.get_current_song(),
'startTime': music_player.start_time,
'serverTime': time.time(),
'songDuration': music_player.get_current_song_duration()
}, room=main_room)
@ -1564,6 +1566,7 @@ def change_song():
'action': 'change',
'song': new_song,
'startTime': music_player.start_time,
'serverTime': time.time(),
'songDuration': music_player.get_current_song_duration()
}, room=main_room)
@ -1649,8 +1652,19 @@ class MusicPlayer:
self.current_song_index = (self.current_song_index + 1) % len(self.playlist)
self.start_time = time.time()
self.load_current_song()
send_discord_alert(f"🎵 Now playing: {self.get_current_song()}")
return self.get_current_song()
new_song = self.get_current_song()
send_discord_alert(f"🎵 Now playing: {new_song}")
# Emit updated music sync information
socketio.emit('music_control', {
'action': 'change',
'song': new_song,
'startTime': self.start_time,
'serverTime': time.time(),
'songDuration': self.get_current_song_duration()
}, room=main_room)
return new_song
@ -1864,6 +1878,7 @@ class AdminConsole(cmd.Cmd):
'action': 'change',
'song': new_song,
'startTime': music_player.start_time,
'serverTime': time.time(),
'songDuration': music_player.get_current_song_duration()
}, room=main_room)
@ -1889,6 +1904,7 @@ class AdminConsole(cmd.Cmd):
'action': 'change',
'song': new_song,
'startTime': music_player.start_time,
'serverTime': time.time(),
'songDuration': music_player.get_current_song_duration()
}, room=main_room)

View File

@ -183,5 +183,15 @@
</div>
<button class="close-button">Close</button>
</div>
<div id="songDurationBar" class="song-duration-bar">
<div id="songDurationFill" class="song-duration-fill"></div>
<div class="song-info">
<div id="songName"><div class="scrolling-text"></div></div>
<div id="songTimer"></div>
</div>
</div>
</body>
</html>

View File

@ -30,7 +30,8 @@ let gameStarted = false;
let joystick = { active: false, startX: 0, startY: 0, endX: 0, endY: 0 };
let isDebugging = document.getElementById('debugCheckbox').checked;
let socket;
let currentSongDuration = 180; // Default to 3 minutes
let currentSongDuration = 0;
let songStartTime = 0;
let backgroundCanvas, backgroundCtx;
let uiButton, uiWidget, menuButton;
let isWidgetVisible = false;
@ -72,6 +73,7 @@ let shootingJoystick = {
};
let lastUpdateTime = Date.now();
let impactEffects = [];
let currentSongName = '';
@ -2188,6 +2190,15 @@ function startGame() {
});
});
socket.on('server_restart', (data) => {
notificationSystem.showNotification(data.message);
// Optionally, you could implement a reconnection attempt after a short delay
setTimeout(() => {
location.reload();
}, 5000); // Wait for 5 seconds before reloading the page
});
socket.on('achievement_unlocked', handleAchievementUnlock);
@ -2232,8 +2243,13 @@ function startGame() {
if (gameStarted) {
const serverClientTimeDiff = Date.now() / 1000 - data.serverTime;
currentSongDuration = data.songDuration || 180; // Use the provided duration or default to 3 minutes
songStartTime = data.startTime + serverClientTimeDiff;
const songPosition = (Date.now() / 1000 - data.startTime - serverClientTimeDiff) % currentSongDuration;
setupAudio(data.song, songPosition);
currentSongName = data.song.split('/').pop();
updateSongDurationBar();
}
});
@ -2527,10 +2543,14 @@ socket.on('bullet_impact', (data) => {
switch(data.action) {
case 'start':
case 'change':
const currentTime = Date.now() / 1000;
const elapsedTime = currentTime - data.startTime;
const serverClientTimeDiff = Date.now() / 1000 - data.serverTime;
currentSongDuration = data.songDuration || 180; // Use the provided duration or default to 3 minutes
setupAudio(data.song, elapsedTime % currentSongDuration);
songStartTime = data.startTime + serverClientTimeDiff;
const songPosition = 0; // Start from the beginning for 'change' action
setupAudio(data.song, songPosition);
currentSongName = data.song.split('/').pop();
updateSongDurationBar();
break;
case 'stop':
if (audioElement) {
@ -2550,7 +2570,7 @@ socket.on('bullet_impact', (data) => {
otherPlayers[player_id].setSkin(skin_data);
}
});
showSongDurationBar();
}
function hideShopButton() {
@ -3179,6 +3199,9 @@ function update() {
if (gameStarted) {
alertSystem.draw(ctx);
}
if (gameStarted) {
updateSongDurationBar();
}
requestAnimationFrame(update);
debugLog('Player position:', player.x, player.y);
debugLog('Number of enemies:', serverEnemies.length);
@ -3798,6 +3821,34 @@ class ImpactEffect {
}
}
function updateSongDurationBar() {
const now = Date.now() / 1000;
const elapsed = now - songStartTime;
const remaining = Math.max(0, currentSongDuration - elapsed);
const progress = Math.min(1, elapsed / currentSongDuration);
const fillElement = document.getElementById('songDurationFill');
const timerElement = document.getElementById('songTimer');
const songNameElement = document.querySelector('#songName .scrolling-text');
fillElement.style.width = `${(1 - progress) * 100}%`;
timerElement.textContent = formatTime(remaining);
songNameElement.textContent = `Now playing: ${currentSongName}`;
}
function formatTime(seconds) {
const minutes = Math.floor(seconds / 60);
const remainingSeconds = Math.floor(seconds % 60);
return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
}
function showSongDurationBar() {
document.getElementById('songDurationBar').style.display = 'block';
}
function hideSongDurationBar() {
document.getElementById('songDurationBar').style.display = 'none';
}
init();

View File

@ -548,6 +548,68 @@ body {
}
}
.song-duration-bar {
position: fixed;
top: 10px;
left: 50%;
transform: translateX(-50%);
width: 300px;
height: 30px;
background-color: rgba(0, 0, 0, 0.5);
border: 2px solid #00ffff;
border-radius: 15px;
overflow: hidden;
display: none;
align-items: center;
}
.song-duration-fill {
height: 100%;
background-color: rgba(0, 255, 255, 0.3);
transition: width 1s linear;
}
.song-info {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
box-sizing: border-box;
font-family: 'Orbitron', sans-serif;
font-size: 14px;
color: #00ffff;
}
#songName {
flex-grow: 1;
overflow: hidden;
white-space: nowrap;
}
#songName .scrolling-text {
display: inline-block;
padding-left: 100%;
animation: scroll 15s linear infinite;
}
@keyframes scroll {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(-100%, 0);
}
}
#songTimer {
flex-shrink: 0;
}
.skin-option.glow-effect {
box-shadow: 0 0 10px 3px currentColor;
animation: glow 1.5s ease-in-out infinite alternate;