This commit is contained in:
Renan LE CARO 2025-04-20 18:40:41 +02:00
parent 419bd8e26b
commit 2b29c0275a
14 changed files with 192 additions and 109 deletions

View file

@ -22,13 +22,11 @@ Other translation are very welcome, contact me if you'd like to submit one.
# Changelog
## To do
## Done
- compound_interest : combo resets as soon as coin passes the paddle line
- added bombs to implosion and kaboom starter levels
- toast an error if storage is blocked
- toast an error if migration fails
- in apk, video download doesn't work
- fixed video download in apk
- ask for permanent storage
- option: reuse past frame's light in new frame lighting computation when there are 150+ coins on screen, to limit the performance impact of rendering lots of lights
@ -384,6 +382,7 @@ Other translation are very welcome, contact me if you'd like to submit one.
- [colin] plusieurs perks qui déclenchent des effets quand une balle est perdue. par ex: +3 combo à chaque balle perdue, 5 blocs transformés en bombe, balle et coins ralentis, blocs régénérés…
- [colin] faster style - augmente le combo en fonction de la vitesse de la balle
- [colin] perk: roulette - gagne instantanément 2 perks aléatoires
- other block types : bumper (speed up ball) [colin], metal (can't break) [nicolas]
## extra levels

113
dist/index.html vendored

File diff suppressed because one or more lines are too long

View file

@ -38,23 +38,58 @@ export async function openCreativeModePerksPicker() {
let creativeModePerks: Partial<{ [id in PerkId]: number }> = getSettingValue(
"creativeModePerks",
{},
),
choice: Upgrade | Level | "reset" | void;
);
const customLevels = (getSettingValue("custom_levels", []) as RawLevel[]).map(
transformRawLevel,
);
while (
(choice = await asyncAlert<Upgrade | Level | "reset">({
while (true ) {
const levelOptions= [
...allLevels.map((l, li) => {
const problem =
reasonLevelIsLocked(li, getHistory(), true)?.text || "";
return {
icon: icons[l.name],
text: l.name,
value: l,
disabled: !!problem,
tooltip: problem || describeLevel(l),
className:''
};
}),
...customLevels.map((l) => ({
icon: levelIconHTML(l.bricks, l.size, l.color),
text: l.name,
value: l,
disabled: !l.bricks.filter((b) => b !== "_").length,
tooltip: describeLevel(l),
className:''
}))
]
const selectedLeveOption= levelOptions.find(l=>l.text===getSettingValue("creativeModeLevel", '')) || levelOptions[0]
selectedLeveOption.className= 'highlight'
const choice=await asyncAlert<Upgrade | Level | "reset" | "play">({
title: t("lab.menu_entry"),
className: "actionsAsGrid",
content: [
t("lab.instructions"),
{
icon: icons['icon:reset'],
value: "reset",
text: t("lab.reset"),
disabled: !sumOfValues(creativeModePerks),
},
{
icon: icons['icon:new_run'],
value: "play",
text: t("lab.play"),
disabled: !sumOfValues(creativeModePerks),
},
t("lab.instructions"),
...upgrades
.filter((u) => !noCreative.includes(u.id))
.map((u) => ({
@ -67,56 +102,35 @@ export async function openCreativeModePerksPicker() {
value: u,
className: creativeModePerks[u.id]
? "sandbox highlight"
: "sandbox ",
: "sandbox not-highlighed",
tooltip: u.help(creativeModePerks[u.id] || 1),
})),
t("lab.select_level"),
...allLevels.map((l, li) => {
const problem =
reasonLevelIsLocked(li, getHistory(), true)?.text || "";
return {
icon: icons[l.name],
text: l.name,
value: l,
disabled: !!problem,
tooltip: problem || describeLevel(l),
className:
getSettingValue("creativeModeLevel", "") === l.name
? "highlight"
: "",
};
}),
...customLevels.map((l) => ({
icon: levelIconHTML(l.bricks, l.size, l.color),
text: l.name,
value: l,
disabled: !l.bricks.filter((b) => b !== "_").length,
tooltip: describeLevel(l),
})),
...levelOptions
],
}))
) {
})
if(!choice)return
if (choice === "reset") {
upgrades.forEach((u) => {
creativeModePerks[u.id] = 0;
});
} else if ("bricks" in choice) {
setSettingValue("creativeModePerks", creativeModePerks);
setSettingValue("creativeModeLevel", choice.name);
setSettingValue("creativeModeLevel", '')
} else if (choice === "play") {
if (await confirmRestart(gameState)) {
restart({
perks: creativeModePerks,
level: choice,
level: selectedLeveOption.value,
isCreativeRun: true,
});
return
}
return;
} else if ("bricks" in choice) {
setSettingValue("creativeModeLevel", choice.name);
} else if (choice) {
creativeModePerks[choice.id] =
((creativeModePerks[choice.id] || 0) + 1) %
(choice.max + 1 + (creativeModePerks.limitless || 0));
} else {
return;
}
}
}

View file

@ -472,7 +472,7 @@
{
"name": "icon:bigger_explosions",
"size": 8,
"bricks": "__r_______ry_rr___ryry__ryyyW_rr_rrWyyy___yryrr__yrry_rr_rr"
"bricks": "__r_______ry_rr___ryry__ryyyWBrr_rrWyyy__Byryrr__yrryBrr_rr_____"
},
{
"name": "icon:extra_levels",
@ -830,7 +830,7 @@
{
"name": "icon:implosions",
"size": 8,
"bricks": "y______W__ryW_W__yr_WW____r_WWWy_WWW_rr___WW_rrryW_Wy___W_____y_",
"bricks": "y______W__ryW_W__yrBWW____rBWWWy_WWWBrr___WWBrrryW_Wy___W_____y_",
"color": ""
},
{
@ -1317,7 +1317,6 @@
"name": "Mario!",
"credit": "Suggested by Nicolas03. A Mario level ! Sprite taken from https://art.pixilart.com/sr2d5c0683c82aws3.png . The sprite belongs to Nintendo"
},
{
"color": "",
"size": 16,
@ -1346,4 +1345,4 @@
"name": "A Very Dangerous High-Five",
"credit": "Suggested by Noodlemire. A unique shape, fun to bounce the ball between fingers. The palm was initially boring on its own, so I gave it a big bomb. It adds a distinct feeling between the top and bottom halves."
}
]
]

View file

@ -585,3 +585,8 @@ h2.histogram-title strong {
opacity: 0.3;
}
}
.not-highlighed{
opacity: 0.8; color: #8a8a8a;
}

View file

@ -1230,6 +1230,9 @@ export function gameStateTick(
coin.x,
(clamp(speed, 20, 100) / 100) * 0.2,
);
if (gameState.perks.compound_interest) {
resetCombo(gameState, coin.x, gameState.gameZoneHeight - 20);
}
if (!isOptionOn("basic")) {
makeParticle(
gameState,
@ -1257,9 +1260,7 @@ export function gameStateTick(
} else if (coin.y > gameState.canvasHeight + coinRadius * 10) {
gameState.levelLostCoins += coin.points;
destroy(gameState.coins, coinIndex);
if (gameState.perks.compound_interest) {
resetCombo(gameState, coin.x, gameState.gameZoneHeight - 20);
}
if (
gameState.combo < gameState.perks.fountain_toss * 30 &&
Math.random() < (1 / gameState.combo) * gameState.perks.fountain_toss

View file

@ -58,9 +58,10 @@
"history.locked": "العب عشر مباريات على الأقل لفتح القفل",
"history.title": "سجل التشغيل",
"lab.help": "جرب أي بناء تريده",
"lab.instructions": "قم بتحديد الترقيات أدناه، ثم اختر المستوى للعب.",
"lab.instructions": "",
"lab.menu_entry": "الوضع الإبداعي",
"lab.reset": "إعادة تعيين الكل إلى 0",
"lab.play": "",
"lab.reset": "",
"lab.select_level": "حدد المستوى للعب عليه",
"lab.unlocks_at": "يتم فتحه عند إجمالي النتيجة {{score}}",
"level_up.after_buttons": "لقد انتهيت للتو من المستوى {{level}}/{{max}}.",

View file

@ -2160,7 +2160,7 @@
</translation>
<translation>
<language>fr-FR</language>
<approved>true</approved>
<approved>false</approved>
</translation>
<translation>
<language>ru-RU</language>
@ -2207,6 +2207,41 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>play</name>
<description/>
<comment/>
<translations>
<translation>
<language>ar-LB</language>
<approved>false</approved>
</translation>
<translation>
<language>de-DE</language>
<approved>false</approved>
</translation>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-CL</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>false</approved>
</translation>
<translation>
<language>ru-RU</language>
<approved>false</approved>
</translation>
<translation>
<language>tr-TR</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>reset</name>
<description/>
@ -2230,7 +2265,7 @@
</translation>
<translation>
<language>fr-FR</language>
<approved>true</approved>
<approved>false</approved>
</translation>
<translation>
<language>ru-RU</language>

View file

@ -58,9 +58,10 @@
"history.locked": "Mindestens zehn Spiele spielen, um freizuschalten",
"history.title": "Läuft Geschichte",
"lab.help": "Versuchen Sie jede beliebige Konstruktion",
"lab.instructions": "Wählen Sie unten die Upgrades aus und wählen Sie dann ein Level, das Sie spielen möchten.",
"lab.instructions": "",
"lab.menu_entry": "Kreativ-Modus",
"lab.reset": "Alle auf 0 zurücksetzen",
"lab.play": "",
"lab.reset": "",
"lab.select_level": "Wählen Sie einen Level zum Spielen",
"lab.unlocks_at": "Wird freigeschaltet bei Gesamtpunktzahl {{score}}",
"level_up.after_buttons": "Du hast gerade Level {{level}}/{{max}}beendet.",

View file

@ -58,9 +58,10 @@
"history.locked": "Play at least ten games to unlock",
"history.title": "Runs history",
"lab.help": "Try any build you want",
"lab.instructions": "Select upgrades below, then pick a level to play. ",
"lab.instructions": "Select upgrades and a level, then click the play button above",
"lab.menu_entry": "Creative mode",
"lab.reset": "Reset all to 0",
"lab.play": "Play",
"lab.reset": "Reset",
"lab.select_level": "Select a level to play on",
"lab.unlocks_at": "Unlocks at total score {{score}}",
"level_up.after_buttons": "You just finished level {{level}}/{{max}}.",

View file

@ -58,9 +58,10 @@
"history.locked": "Juega primero al menos diez partidos",
"history.title": "Historia",
"lab.help": "Prueba cualquier combinación de mejoras y niveles.",
"lab.instructions": "Selecciona las mejoras que aparecen a continuación y elige el nivel al que quieres jugar. .",
"lab.instructions": "",
"lab.menu_entry": "Modo creativo",
"lab.reset": "Eliminar todas las mejoras",
"lab.play": "",
"lab.reset": "",
"lab.select_level": "Selecciona un nivel para jugar",
"lab.unlocks_at": "Desbloqueado a partir de una puntuación total de {{score}}.",
"level_up.after_buttons": "Acabas de completar el nivel {{level}}/{{max}}.",

View file

@ -58,9 +58,10 @@
"history.locked": "Jouez d'abord au moins dix parties",
"history.title": "Historique",
"lab.help": "Essayez n'importe quel combinaison d'améliorations et de niveaux.",
"lab.instructions": "Sélectionnez les améliorations ci-dessous, puis choisissez le niveau à jouer. .",
"lab.instructions": "Sélectionnez les améliorations et un niveau, puis cliquez sur le bouton \"jouer\" ci-dessus",
"lab.menu_entry": "Mode créatif",
"lab.reset": "Retirer toutes les améliorations",
"lab.play": "Jouer",
"lab.reset": "Réinitialiser",
"lab.select_level": "Sélectionnez un niveau sur lequel jouer",
"lab.unlocks_at": "Déverrouillé à partir d'un score total de {{score}}",
"level_up.after_buttons": "Vous venez de terminer le niveau {{level}}/{{max}}.",

View file

@ -58,9 +58,10 @@
"history.locked": "Сыграйте не менее десяти игр, чтобы разблокировать",
"history.title": "История побегов",
"lab.help": "Попробуйте любую сборку.",
"lab.instructions": "Выберите апгрейды ниже, а затем выберите уровень для игры.",
"lab.instructions": "",
"lab.menu_entry": "Творческий режим",
"lab.reset": "Сбросить все в 0",
"lab.play": "",
"lab.reset": "",
"lab.select_level": "Выберите уровень для игры",
"lab.unlocks_at": "Открывается при общем количестве очков {{score}}",
"level_up.after_buttons": "Вы только что закончили уровень {{level}}/{{max}}.",

View file

@ -58,9 +58,10 @@
"history.locked": "Kilidi açmak için en az on oyun oynayın",
"history.title": "Koşu geçmişi",
"lab.help": "İstediğiniz herhangi bir yapıyı deneyin",
"lab.instructions": "Aşağıdan yükseltmeleri seçin, ardından oynayacağınız seviyeyi seçin.",
"lab.instructions": "",
"lab.menu_entry": "Yaratıcı mod",
"lab.reset": "Hepsini 0'a sıfırla",
"lab.play": "",
"lab.reset": "",
"lab.select_level": "Oynamak için bir seviye seçin",
"lab.unlocks_at": "Toplam puan {{score}}olduğunda açılır",
"level_up.after_buttons": " {{level}}/{{max}}seviyesini yeni bitirdiniz.",