diff --git a/App/Levels/desert.js b/App/Levels/desert.js index f2219165..f9daa1db 100644 --- a/App/Levels/desert.js +++ b/App/Levels/desert.js @@ -74,30 +74,45 @@ const DESERT = { { speaker: 'Ada', color: '#FFF', - content: 'Well, how was it?', + content: tn({ + en: 'Well, how was it?', + es: '¿Qué tal estuvo?', + }), direction: 'up-up-left', }, { speaker: 'Jack', color: '#FFF', - content: 'What?', + content: tn({ + en: 'What?', + es: 'Qué?', + }), direction: 'up-up-right', }, { speaker: 'Ada', color: '#FFF', - content: 'Your canyon.', + content: tn({ + en: 'Your canyon.', + es: 'Tu cañón', + }), direction: 'up-up-left', }, { speaker: 'Jack', color: '#FFF', - content: 'Scary. Hard.', + content: tn({ + en: 'Scary. Hard.', + es: 'Atterador. Duro', + }), direction: 'up-up-right', speech: [ { color: '#FFF', - content: 'Oh.', + content: tn({ + en: 'Oh.', + es: 'Vaya.', + }), direction: 'up', distance: 0.8, }, @@ -106,19 +121,28 @@ const DESERT = { { speaker: 'Ada', color: '#FFF', - content: "Well, that's why it's not on the route.", + content: tn({ + en: "Well, that's why it's not on the route.", + es: "Pues, por eso no está en la ruta." + }), direction: 'up-up-left', }, { speaker: 'Jack', color: '#FFF', - content: 'I did a backflip!', + content: tn({ + en: 'I did a backflip!', + es: 'Hice una voltereta hacia atrás!', + }), direction: 'up-up-right', speech: [ { speaker: 'Jack', color: '#FFF', - content: 'I still had fun.', + content: tn({ + en:'I still had fun.', + es: 'Todavía me divertí.', + }), direction: 'up', }, ], @@ -126,13 +150,19 @@ const DESERT = { { speaker: 'Ada', color: '#FFF', - content: "No, you didn't.", + content: tn({ + en: 'No, you didn’t.', + es: 'No, no lo hiciste.' + }), direction: 'up-up-left', }, { speaker: 'Jack', color: '#FFF', - content: 'Yes I did!', + content: tn({ + en: 'Yes I did!', + es: 'Sí lo hice!', + }), direction: 'up-up-left', gap: 1, length: 2, @@ -140,14 +170,20 @@ const DESERT = { { speaker: 'Ada', color: '#FFF', - content: 'Spinning in place is not a backflip.', + content: tn({ + en: 'Spinning in place is not a backflip.', + es: ' Girando en lugar no es una voltereta hacia atrás.', + }), direction: 'up-left', length: 4, speech: [ { speaker: 'Ada', color: '#FFF', - content: 'Jack… we are ghosts. We can float.', + content: tn({ + en: 'Jack… we are ghosts. We can float.', + es: 'Jack... somos fantasmas. Podemos flotar.', + }), direction: 'up-up-left', }, ], @@ -155,19 +191,28 @@ const DESERT = { { speaker: 'Jack', color: '#FFF', - content: "You're being negative again.", + content: tn({ + en: 'You’re being negative again.', + es: 'Estás siendo negativo otra vez.', + }), direction: 'up-up-left', }, { speaker: 'Ada', color: '#FFF', - content: "It's just the truth!!", + content: tn({ + en: "It's just the truth!!", + es: "Es sólo la verdad!!", + }), direction: 'up-left', speech: [ { speaker: 'Ada', color: '#FFF', - content: "The truth isn't negative!", + content: tn({ + en: "The truth isn't negative!", + es: "La verdad no es negativa!", + }), direction: 'up', }, ], @@ -175,26 +220,38 @@ const DESERT = { { speaker: 'Jack', color: '#FFF', - content: 'Are you mad at me?', + content: tn({ + en: 'Are you mad at me?', + es: 'Estás enojada conmigo?', + }), direction: 'up-up-left', }, { speaker: 'Ada', color: '#FFF', - content: 'Obviously, yes!', + content: tn({ + en:'Obviously, yes!', + es: 'Obviamente, sí!', + }), direction: 'up-up-left', gap: 1, }, { speaker: 'Ada', color: '#FFF', - content: 'And probably the race.', + content:tn({ + en: 'And probably the race.', + es: 'Y probablemente la carrera.', + }), direction: 'up-up-left', speech: [ { speaker: 'Ada', color: '#FFF', - content: 'Your detour cost us time.', + content: tn({ + en: 'Your detour cost us time.', + es: 'Tu desvío nos costó tiempo.', + }), direction: 'up', }, ], @@ -202,32 +259,47 @@ const DESERT = { { speaker: 'Jack', color: '#FFF', - content: "You're right, I'm sorry.", + content: tn({ + en: "You're right, I'm sorry.", + es: "Tienes razón, lo siento.", + }), direction: 'up-up-right', }, { speaker: 'Jack', color: '#FFF', speakerx: -4, - content: 'Let me make it up to you. Watch this', + content: tn({ + en: 'Let me make it up to you. Watch this', + es: 'Déjame compensarte. Mira esto', + }), direction: 'up-up-left', }, { speaker: 'Ada', color: '#FFF', - content: '...how is this helping', + content: tn({ + en: '...how is this helping', + es: '...como está ayudando esto', + }), direction: 'up-up-left', }, { speaker: 'Jack', color: '#FFF', - content: 'Because it made you smile.', + content: tn({ + en: 'Because it made you smile.', + es: 'Porque te hizo sonreír.', + }), direction: 'up-up-left', }, { speaker: 'Ada', color: '#FFF', - content: 'You do have a talent for that.', + content: tn({ + en: 'You do have a talent for that.', + es: 'Tu si tienes un talento para eso.', + }), direction: 'up-up-left', }, ], diff --git a/App/main.js b/App/main.js index 9bc6cca1..61b55484 100644 --- a/App/main.js +++ b/App/main.js @@ -136,6 +136,10 @@ const ui = { graphicsSettingsCloseButton: $('#graphics-settings-close-button'), setResolutionButton: $('#set-resolution-button'), setSampleDensityButton: $('#set-sample-density-button'), + setMiscGraphicsButton: $('#set-misc-graphics-button'), + + languageDropdown: $('#language-dropdown'), + setTerrainLayersButton: $('#set-terrain-layers-button'), // closeGraphicsButton: $('#close-graphics-button'), @@ -533,6 +537,8 @@ makeButtonCloseDialog(ui.graphicsSettingsCloseButton, ui.graphicsSettingsDialog) makeButtonOpenDialog(ui.settingsButton, ui.graphicsSettingsDialog) // makeButtonCloseDialog(ui.closeGraphicsButton, ui.graphicsSettingsDialog) + + makeButtonOpenDialog( ui.editorLevelConfigurationButton, ui.editorLevelConfigurationDialog, @@ -681,6 +687,10 @@ function onClickCanvas() { canvas.addEventListener('click', onClickCanvas) ui.veil.addEventListener('click', onClickCanvas) +// Don't start the game when picking language +ui.languageDropdown.addEventListener('click', (e) => { + e.stopPropagation() +}) function onMouseMoveCanvas(event) { world.clickableContext.processEvent(event, 'mouseMove') @@ -833,3 +843,30 @@ for (const [name, input] of Object.entries(ui.editorInspector.inputs)) { ui.editorInspector.deleteSelectionButton.addEventListener('click', () => { world.sendEvent('deleteSelection') }) + +/* Multiple languages setting button */ +const languages = { + en: 'English', + es: 'Español', + fr: 'Français', + de: 'Deutsch', +}; + +const languageDropdown = document.getElementById('language-dropdown') + +languageDropdown.addEventListener( + 'change', + (e) => { + localStorage.setItem('language', e.target.value ?? "en") + window.location.reload(); + } +); + +for (const language in languages) { + const option = document.createElement('option') + option.value = language + option.innerText = languages[language] + languageDropdown.appendChild(option) +} + +languageDropdown.value = localStorage.getItem('language') ?? "en" \ No newline at end of file diff --git a/App/style.css b/App/style.css index 40fb868d..5adaf558 100644 --- a/App/style.css +++ b/App/style.css @@ -342,6 +342,13 @@ input[valid='false'] { top: 0; } +#language-dropdown { + position: absolute; + right: 1rem; + top: 1rem; + font-size: 1.2rem; +} + #math-field-static { background: #ddd; } diff --git a/App/translation.js b/App/translation.js new file mode 100644 index 00000000..61ccc561 --- /dev/null +++ b/App/translation.js @@ -0,0 +1,40 @@ +const LANGUAGE = localStorage.getItem('language') ?? 'en'; + +function tn(spec) { + if (spec[LANGUAGE] == undefined) { + return spec.en + } + return spec[LANGUAGE] +} + +const translations = { + 'veil-feedback': { + es: '¿Ideas? ¿Comentario? ¿Asuntos? Envíalos a ' + }, + 'puzzles-text': { + es: 'Nuevos rompecabezas publicados diariamente en' + }, + 'github-link': { + es: 'Construido y mantenido por adolescentes. Versión 1.0' + } +} + +function getTextNode(elem) { + for (const node of elem.childNodes) { + if (node.nodeType === Node.TEXT_NODE && node.nodeValue.trim() !== ''){ + return node + } + } +} + +function tnHTML(id) { + getTextNode(document.getElementById(id)).nodeValue = tn(translations[id]) +} + +if (LANGUAGE !== "en") { + const elems = document.body.querySelectorAll("*[data-tn]"); + + for (const elem of elems) { + tnHTML(elem.id) + } +} diff --git a/Assets/Images/Untitled_Artwork.webp b/Assets/Images/Untitled_Artwork.webp deleted file mode 100644 index 548d7b87..00000000 Binary files a/Assets/Images/Untitled_Artwork.webp and /dev/null differ diff --git a/Assets/Images/lsys joshua tree (1).png b/Assets/Images/lsys joshua tree (1).png deleted file mode 100644 index b31eface..00000000 Binary files a/Assets/Images/lsys joshua tree (1).png and /dev/null differ diff --git a/Types/Entities/World.js b/Types/Entities/World.js index 36598dd1..44a24540 100644 --- a/Types/Entities/World.js +++ b/Types/Entities/World.js @@ -471,7 +471,11 @@ function World(spec) { // Show loading veil again for click ui.loadingVeil.setAttribute('hide', false) - ui.loadingVeilString.innerHTML = 'click to begin' + ui.loadingVeilString.innerHTML = tn({ + en: 'click to begin.', + es: 'haga clic para comenzar.', + }) + ui.loadingVeil.addEventListener('click', loadingVeilClicked) const c = playerStorage.getCompletedLevels().length diff --git a/index.html b/index.html index ca2ebc44..020a8859 100644 --- a/index.html +++ b/index.html @@ -254,9 +254,7 @@
Y=
-
-
@@ -396,6 +394,29 @@
MESSAGE
+ + //needs id name (below) + + +
Graphics Settings
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
MESSAGE
+
+
@@ -488,6 +509,9 @@

Reddit Command Copied!

+ +
@@ -500,14 +524,14 @@

Reddit Command Copied!

-
+

Ideas? Feedback? Issues? Send them to sinerider@hackclub.com
-

New puzzles published daily on

+

New puzzles published daily on