| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- class LyricsSystem {
- constructor() {
- this.lyrics = [];
- this.currentLyricIndex = -1;
- this.showLyrics = true; // Mostrar letras por defecto
- this.font = null;
- this.songDuration = 189; // 3:09 en segundos
- this.isGameOver = false;
- this.gameOverScreen = false;
- this.fadeOpacity = 1.0;
- this.fadeDirection = 1; // 1 para aparecer, -1 para desaparecer
-
- // Offset de tiempo para ajustar sincronización (en segundos)
- // Valor positivo = letras aparecen ANTES
- // Valor negativo = letras aparecen DESPUÉS
- this.timeOffset = 0.25;
-
- // Configuración de texto
- this.maxLineWidth = 280; // Ancho máximo de línea en píxeles
- this.lineHeight = 18; // Altura entre líneas
-
- // Cargar la fuente personalizada
- this.loadCustomFont();
-
- // Parsear las letras desde el archivo
- this.parseLyrics();
- }
-
- loadCustomFont() {
- this.font = new FontFace('CustomFont', 'url(assets/font.ttf)');
- this.font.load().then(() => {
- document.fonts.add(this.font);
- }).catch(err => {
- console.warn('No se pudo cargar la fuente personalizada:', err);
- });
- }
-
- parseLyrics() {
- // Letras en romaji usando los tiempos exactos del archivo
- const lyricsData = [
- { time: 2.8, text: "mogumogu" },
- { time: 6.4, text: "shinra banshou no akusenkutou mo mayoneizu kaketara daitai oishiku naru?" },
- { time: 13.3, text: "kimi ga naite mo onaka wa suku yo shouka dekinakatta \"gomen gomen\"" },
- { time: 19.8, text: "sui mo amai mo katte ni tabete gomeiwaku okakeshite imasu" },
- { time: 26.7, text: "pakuchii na okite hen na aji no juusu kokoro wo mu ni shite nomikomimasu" },
- { time: 33.3, text: "aa konton jouhou kata no resutoran de usoppachi no menyuu ni ocha koboshite" },
- { time: 39.8, text: "kimi to mogumogu (mogumogu) mogumogu (mogumogu)" },
- { time: 43, text: "juugeki-sen no mannaka de mogumogu (ugya~)" },
- { time: 46, text: "chimi mouryou harapeko no mure manpuku ni naru mirai wo negatteiru yo" },
- { time: 53, text: "mogumogu (mogumogu) mogumogu (mogumogu) sekai ga owaru mae ni" },
- { time: 59, text: "mogumogu yamii maji kami yamuyamu ari no manma" },
- { time: 66, text: "mogumogu yamii Magic Coming konoyo wo ajiwaun da umauma" },
- { time: 67, text: "sorry i got lazy lmfao" },
- // { time: 43.2, text: "riron busou no mirufiiyu sando (sando)" },
- // { time: 44.9, text: "tokumei kibou no ourora sousu (sousu)" },
- // { time: 48.3, text: "oozappa na ajitsuke oome ni mite yo oishiku nattara \"ok ok.\"" },
- // { time: 51.1, text: "ii mon warui mon ippai tabete yogoreta kuchimoto nuguimasu" },
- // { time: 55.2, text: "onigiri piza keiki gouka na furu kousu wana wo utagai ki wo tsukemasu" },
- // { time: 58.6, text: "aa mousou ryuugen higo no baikingu de dokuiri to zeppin ryouri yoriwakete" },
- // { time: 61.2, text: "kimi to mogumogu (mogumogu) mogumogu (mogumogu)" },
- // { time: 64.5, text: "desugeimu no kyoushitsu de mogumogu (ugya~)" },
- // { time: 67.9, text: "chimi mouryou harapeko no mure naka no ii kimi to ikinokoretara ii na" },
- // { time: 162, text: "mogumogu (mogumogu) mogumogu (mogumogu) suu nen-go mo kono basho de" },
- // { time: 74.6, text: "mogumogu yamii maji kami kon'ya no bangohan wa" },
- // { time: 78, text: "mogumogu yamii Magic Coming tsugi wa omae no ban da" },
- // { time: 81.4, text: "mogumogu yamii maji kami yamuyamu ari no manma" },
- // { time: 84.8, text: "mogumogu yamii Magic Coming konoyo wo ajiwaun da umauma" },
- { time: 162, text: "mogumogu mogumogu mogumogu mogumogu mogumogu mogumogu mogumogu yamii" },
- { time: 168, text: "mogumogu mogumogu mogumogu mogumogu mogumogu mogumogu mogumogu yamii" },
- { time: 175, text: "mogumogu mogumogu mogumogu mogumogu mogumogu mogumogu mogumogu yamii" },
- { time: 181, text: "mogumogu mogumogu mogumogu mogumogu"},
- { time: 187, text: "yamii yamii" }
- ];
-
- this.lyrics = lyricsData;
- }
-
- update(currentTime) {
- // Aplicar offset de tiempo
- const adjustedTime = currentTime + this.timeOffset;
-
- // Verificar si la canción ha terminado
- if (adjustedTime >= this.songDuration && !this.isGameOver) {
- this.isGameOver = true;
- this.gameOverScreen = true;
- return;
- }
-
- // Actualizar letra actual basada en el tiempo ajustado
- this.updateCurrentLyric(adjustedTime);
- }
-
- updateCurrentLyric(currentTime) {
- let newIndex = -1;
-
- for (let i = 0; i < this.lyrics.length; i++) {
- if (currentTime >= this.lyrics[i].time) {
- newIndex = i;
- } else {
- break;
- }
- }
-
- if (newIndex !== this.currentLyricIndex) {
- this.currentLyricIndex = newIndex;
- }
- }
-
- draw(ctx, canvas) {
- if (!this.showLyrics && this.fadeOpacity <= 0) return;
-
- // Actualizar opacidad para transición suave
- if (this.showLyrics && this.fadeOpacity < 1.0) {
- this.fadeOpacity += 0.05;
- } else if (!this.showLyrics && this.fadeOpacity > 0) {
- this.fadeOpacity -= 0.05;
- }
-
- // Dibujar letra actual
- if (this.currentLyricIndex >= 0 && this.currentLyricIndex < this.lyrics.length) {
- const currentLyric = this.lyrics[this.currentLyricIndex];
-
- // Configurar fuente
- ctx.font = '14px CustomFont, Arial, sans-serif';
- ctx.fillStyle = `rgba(255, 255, 255, ${this.fadeOpacity})`;
- ctx.strokeStyle = `rgba(0, 0, 0, ${this.fadeOpacity})`;
- ctx.lineWidth = 3;
- ctx.textAlign = 'center';
-
- // Dividir texto en líneas
- const lines = this.wrapText(currentLyric.text, ctx, this.maxLineWidth);
-
- // Calcular posición Y inicial
- const totalHeight = lines.length * this.lineHeight;
- const startY = canvas.height - 180 - (totalHeight - this.lineHeight);
-
- // Agregar sombra
- ctx.shadowColor = `rgba(0, 0, 0, ${this.fadeOpacity * 0.8})`;
- ctx.shadowBlur = 4;
- ctx.shadowOffsetX = 2;
- ctx.shadowOffsetY = 2;
-
- // Dibujar cada línea
- lines.forEach((line, index) => {
- const x = canvas.width / 2;
- const y = startY + (index * this.lineHeight);
-
- ctx.strokeText(line, x, y);
- ctx.fillText(line, x, y);
- });
-
- // Resetear sombra
- ctx.shadowColor = 'transparent';
- ctx.shadowBlur = 0;
- ctx.shadowOffsetX = 0;
- ctx.shadowOffsetY = 0;
- }
-
- }
-
- toggleLyrics() {
- this.showLyrics = !this.showLyrics;
- this.fadeDirection = this.showLyrics ? 1 : -1;
- }
-
- // Método para ajustar offset de tiempo
- // seconds > 0: letras aparecen ANTES (más temprano)
- // seconds < 0: letras aparecen DESPUÉS (más tarde)
- adjustTimeOffset(seconds) {
- this.timeOffset += seconds;
- console.log(`Offset de tiempo ajustado a: ${this.timeOffset} segundos`);
- console.log(`Positivo = letras ANTES, Negativo = letras DESPUÉS`);
- }
-
- // Método para establecer offset de tiempo específico
- setTimeOffset(seconds) {
- this.timeOffset = seconds;
- console.log(`Offset de tiempo establecido a: ${this.timeOffset} segundos`);
- }
-
- // Método para dividir texto en líneas
- wrapText(text, ctx, maxWidth) {
- const words = text.split(' ');
- const lines = [];
- let currentLine = words[0];
-
- for (let i = 1; i < words.length; i++) {
- const word = words[i];
- const width = ctx.measureText(currentLine + ' ' + word).width;
-
- if (width < maxWidth) {
- currentLine += ' ' + word;
- } else {
- lines.push(currentLine);
- currentLine = word;
- }
- }
-
- lines.push(currentLine);
- return lines;
- }
-
- // Método para desarrollo: simular fin de canción
- simulateGameOver() {
- this.isGameOver = true;
- this.gameOverScreen = true;
- }
-
- // Método para reiniciar el juego
- reset() {
- this.currentLyricIndex = -1;
- this.isGameOver = false;
- this.gameOverScreen = false;
- this.showLyrics = true;
- this.fadeOpacity = 1.0;
- this.timeOffset = 0; // Resetear offset
- }
- }
|