Made the "combo lost" text last 500ms instead of the pointless 150ms

This commit is contained in:
Renan LE CARO 2025-03-29 17:40:07 +01:00
parent da89cdb647
commit 23798c4e58
9 changed files with 262 additions and 265 deletions

View file

@ -43,6 +43,7 @@ import {hashCode} from "./getLevelBackground";
import {premiumMenuEntry} from "./premium";
export function play() {
if (applyFullScreenChoice()) return;
if (gameState.running) return;
gameState.running = true;
gameState.ballStickToPuck = false;
@ -50,7 +51,6 @@ export function play() {
startRecordingGame(gameState);
getAudioContext()?.resume();
resumeRecording();
// document.body.classList[gameState.running ? 'add' : 'remove']('running')
}
@ -571,36 +571,12 @@ async function openSettingsMenu() {
help: options[key].help,
value: () => {
toggleOption(key);
if (key === "mobile-mode") fitSize();
fitSize();
applyFullScreenChoice()
openSettingsMenu();
},
});
}
if (document.fullscreenEnabled || document.webkitFullscreenEnabled) {
if (document.fullscreenElement !== null) {
actions.push({
text: t("main_menu.fullscreen_exit"),
help: t("main_menu.fullscreen_exit_help"),
icon: icons["icon:exit_fullscreen"],
value() {
toggleFullScreen();
openSettingsMenu();
},
});
} else {
actions.push({
text: t("main_menu.fullscreen"),
help: t("main_menu.fullscreen_help"),
icon: icons["icon:fullscreen"],
value() {
toggleFullScreen();
openSettingsMenu();
},
});
}
}
actions.push({
text: t("main_menu.reset"),
help: t("main_menu.reset_help"),
@ -818,51 +794,84 @@ async function openSettingsMenu() {
}
}
function applyFullScreenChoice(): boolean {
try {
if (!(document.fullscreenEnabled || document.webkitFullscreenEnabled)) {
return false
}
if (document.fullscreenElement !== null && !isOptionOn("fullscreen")) {
if (document.exitFullscreen) {
document.exitFullscreen();
return true
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
return true
}
} else if (isOptionOn("fullscreen") && !document.fullscreenElement) {
const docel = document.documentElement;
if (docel.requestFullscreen) {
docel.requestFullscreen();
return true
} else if (docel.webkitRequestFullscreen) {
docel.webkitRequestFullscreen();
return true
}
}
} catch (e) {
console.warn(e);
}
return false
}
async function openUnlocksList() {
const ts = getTotalScore();
const actions = [
...upgrades
.sort((a, b) => a.threshold - b.threshold)
.map(({name, id, threshold, icon, help}) => ({
text: name,
// help:
// ts >= threshold ? help(1) : t("unlocks.unlocks_at", { threshold }),
disabled: ts < threshold,
value: {perks: {[id]: 1}} as RunParams,
icon,
})),
...allLevels
.sort((a, b) => a.threshold - b.threshold)
.map((l) => {
const available = ts >= l.threshold;
return {
text: l.name,
// help: available
// ? t("unlocks.level_description", {
// size: l.size,
// bricks: l.bricks.filter((i) => i).length,
// })
// : t("unlocks.unlocks_at", { threshold: l.threshold }),
disabled: !available,
value: {level: l.name} as RunParams,
icon: icons[l.name],
};
}),
];
const upgradeActions = upgrades
.sort((a, b) => a.threshold - b.threshold)
.map(({name, id, threshold, icon, help}) => ({
text: name,
// help:
// ts >= threshold ? help(1) : t("unlocks.unlocks_at", { threshold }),
disabled: ts < threshold,
value: {perks: {[id]: 1}} as RunParams,
icon,
}))
const levelActions = allLevels
.sort((a, b) => a.threshold - b.threshold)
.map((l) => {
const available = ts >= l.threshold;
return {
text: l.name,
// help: available
// ? t("unlocks.level_description", {
// size: l.size,
// bricks: l.bricks.filter((i) => i).length,
// })
// : t("unlocks.unlocks_at", { threshold: l.threshold }),
disabled: !available,
value: {level: l.name} as RunParams,
icon: icons[l.name],
};
})
const percentUnlock = Math.round(
(actions.filter((a) => !a.disabled).length / actions.length) * 100,
([...upgradeActions, ...levelActions].filter((a) => !a.disabled).length / (upgradeActions.length +
levelActions.length)) * 100,
);
const tryOn = await asyncAlert<RunParams>({
title: t("unlocks.title", {percentUnlock}),
content: [
`<p>${t("unlocks.intro", {ts})}
`<p>${t("unlocks.intro", {ts, highScore: gameState.highScore})}
${percentUnlock < 100 ? t("unlocks.greyed_out_help") : ""}</p> `,
...actions,
`<p>
Your high score is ${gameState.highScore}.
Click an item above to start a run with it.
</p>`,
...upgradeActions,
t("unlocks.level"),
...levelActions,
],
allowClose: true,
actionsAsGrid: true,
@ -893,26 +902,6 @@ export async function confirmRestart(gameState) {
});
}
export function toggleFullScreen() {
try {
if (document.fullscreenElement !== null) {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
}
} else {
const docel = document.documentElement;
if (docel.requestFullscreen) {
docel.requestFullscreen();
} else if (docel.webkitRequestFullscreen) {
docel.webkitRequestFullscreen();
}
}
} catch (e) {
console.warn(e);
}
}
const pressed: { [k: string]: number } = {
ArrowLeft: 0,
@ -931,7 +920,8 @@ export function setKeyPressed(key: string, on: 0 | 1) {
document.addEventListener("keydown", (e) => {
if (e.key.toLowerCase() === "f" && !e.ctrlKey && !e.metaKey) {
toggleFullScreen();
toggleOption('fullscreen');
applyFullScreenChoice()
} else if (e.key in pressed) {
setKeyPressed(e.key, 1);
}
@ -988,13 +978,15 @@ export function restart(params: RunParams) {
setLevel(gameState, 0);
}
restart(
(window.location.search.includes("stressTest") && {
level: "Bird",
perks: {
pierce:1,
sapper:1,
implosions: 3
pierce: 1,
sapper: 1,
implosions: 3,
streak_shots:1
},
levelsPerLoop: 2,
}) ||

View file

@ -178,7 +178,8 @@ export function resetCombo(
);
}
if (typeof x !== "undefined" && typeof y !== "undefined") {
makeText(gameState, x, y, "red", "-" + lost, 20, 150);
makeText(gameState, x, y, "red", "-" + lost, 20, 500+clamp(lost, 0,500));
}
}
return lost;
@ -197,7 +198,7 @@ export function decreaseCombo(
if (lost) {
schedulGameSound(gameState, "comboDecrease", x, 1);
if (typeof x !== "undefined" && typeof y !== "undefined") {
makeText(gameState, x, y, "red", "-" + lost, 20, 300);
makeText(gameState, x, y, "red", "-" + lost, 20, 400+lost);
}
}
}
@ -1709,7 +1710,7 @@ function makeText(
color: colorString,
text: string,
size = 20,
duration = 150,
duration = 500,
) {
append(gameState.texts, (p: Partial<TextFlash>) => {
p.time = gameState.levelTime;
@ -1717,7 +1718,7 @@ function makeText(
p.y = y;
p.color = color;
p.size = size;
p.duration = duration;
p.duration = clamp(duration,400,2000);
p.text = text;
});
}

View file

@ -191,6 +191,8 @@ export function countBricksBelow(gameState: GameState, index: number) {
}
export function comboKeepingRate(level:number){
if(level<=0) return 0
return 1-1/(1+level)*1.5
return clamp(1-1/(1+level)*1.5,0,1)
}
for(let i = 0;i<5;i++){
console.log(Math.round(comboKeepingRate(i)*100)+'%')
}

View file

@ -837,36 +837,6 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>fullscreen_exit</name>
<description/>
<comment/>
<translations>
<translation>
<language>en-US</language>
<approved>true</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>true</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>fullscreen_exit_help</name>
<description/>
<comment/>
<translations>
<translation>
<language>en-US</language>
<approved>true</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>true</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>fullscreen_help</name>
<description/>
@ -2032,6 +2002,21 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>level</name>
<description/>
<comment/>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>level_description</name>
<description/>

View file

@ -51,9 +51,7 @@
"main_menu.download_save_file_help": "Get a save file",
"main_menu.footer_html": "<p> \n<span>Made in France by <a href=\"https://lecaro.me\">Renan LE CARO</a>.</span> \n<a href=\"https://paypal.me/renanlecaro\" target=\"_blank\">Donate</a>\n<a href=\"https://discord.gg/DZSPqyJkwP\" target=\"_blank\">Discord</a>\n<a href=\"https://f-droid.org/en/packages/me.lecaro.breakout/\" target=\"_blank\">F-Droid</a>\n<a href=\"https://play.google.com/store/apps/details?id=me.lecaro.breakout\" target=\"_blank\">Google Play</a>\n<a href=\"https://renanlecaro.itch.io/breakout71\" target=\"_blank\">itch.io</a> \n<a href=\"https://gitlab.com/lecarore/breakout71\" target=\"_blank\">Gitlab</a>\n<a href=\"https://breakout.lecaro.me/\" target=\"_blank\">Web version</a>\n<a href=\"https://news.ycombinator.com/item?id=43183131\" target=\"_blank\">HackerNews</a>\n<a href=\"https://breakout.lecaro.me/privacy.html\" target=\"_blank\">Privacy Policy</a>\n<span>v.{{appVersion}}</span>\n</p>\n",
"main_menu.fullscreen": "Fullscreen",
"main_menu.fullscreen_exit": "Exit Fullscreen",
"main_menu.fullscreen_exit_help": "Might not work on some machines",
"main_menu.fullscreen_help": "Might not work on some machines",
"main_menu.fullscreen_help": "Game will try to go full screen before starting",
"main_menu.kid": "Kids mode",
"main_menu.kid_help": "Start future runs with \"slower ball\".",
"main_menu.language": "Language",
@ -128,9 +126,10 @@
"score_panel.upcoming_levels": "Upcoming levels :",
"score_panel.upgrades_picked": "Upgrades picked so far : ",
"unlocks.greyed_out_help": "The greyed out ones can be unlocked by increasing your total score. The total score increases every time you score in game.",
"unlocks.intro": "Your total score is {{ts}}. Below are all the upgrades and levels the games has to offer.",
"unlocks.intro": "Your total score is {{ts}}. Below are all the upgrades and levels the games has to offer. Click an upgrade or level below to start a run with it .Your high score is {{highScore}}.",
"unlocks.level": "Here are all the game levels, click one to start a run with that starting level. ",
"unlocks.level_description": "A {{size}}x{{size}} level with {{bricks}} bricks",
"unlocks.title": "You unlocked {{percentUnlock}}% of the game.",
"unlocks.title": "You unlocked {{percentUnlock}}% of the game. ",
"unlocks.unlocks_at": "Unlocks at total score {{threshold}}.",
"upgrades.asceticism.fullHelp": "You'll need to store the coins somewhere while your combo climbs. ",
"upgrades.asceticism.help": "+{{combo}} combo / brick, combo resets on coin catch",

View file

@ -51,9 +51,7 @@
"main_menu.download_save_file_help": "Obtenir un fichier de sauvegarde",
"main_menu.footer_html": " <p> \n<span>Programmé en France par <a href=\"https://lecaro.me\">Renan LE CARO</a>.</span>\n<a href=\"https://paypal.me/renanlecaro\" target=\"_blank\">Donner</a>\n<a href=\"https://discord.gg/DZSPqyJkwP\" target=\"_blank\">Discord</a>\n<a href=\"https://f-droid.org/en/packages/me.lecaro.breakout/\" target=\"_blank\">F-Droid</a>\n<a href=\"https://play.google.com/store/apps/details?id=me.lecaro.breakout\" target=\"_blank\">Google Play</a>\n<a href=\"https://renanlecaro.itch.io/breakout71\" target=\"_blank\">itch.io</a>\n<a href=\"https://gitlab.com/lecarore/breakout71\" target=\"_blank\">Gitlab</a>\n<a href=\"https://breakout.lecaro.me/\" target=\"_blank\">Version web</a>\n<a href=\"https://news.ycombinator.com/item?id=43183131\" target=\"_blank\">HackerNews</a>\n<a href=\"https://breakout.lecaro.me/privacy.html\" target=\"_blank\">Politique de confidentialité</a> \n<span>v.{{appVersion}}</span>\n</p>",
"main_menu.fullscreen": "Plein écran",
"main_menu.fullscreen_exit": "Quitter le plein écran",
"main_menu.fullscreen_exit_help": "Ne fonctionne pas toujours",
"main_menu.fullscreen_help": "Ne fonctionne pas toujours",
"main_menu.fullscreen_help": "Le jeu essaiera de passer en plein écran quand vous le démarrez",
"main_menu.kid": "Mode enfants",
"main_menu.kid_help": "Balle plus lente",
"main_menu.language": "Langue",
@ -128,7 +126,8 @@
"score_panel.upcoming_levels": "Niveaux de la parties : ",
"score_panel.upgrades_picked": "Améliorations choisies jusqu'à présent :",
"unlocks.greyed_out_help": "Les éléments grisées peuvent être débloquées en augmentant votre score total. Le score total augmente à chaque fois que vous marquez des points dans le jeu.",
"unlocks.intro": "Votre score total est de {{ts}}. Vous trouverez ci-dessous toutes les améliorations et tous les niveaux que le jeu peut offrir.",
"unlocks.intro": "Votre score total est de {{ts}}. Vous trouverez ci-dessous toutes les améliorations et tous les niveaux que le jeu peut offrir. Cliquez sur l'un d'entre eux pour commencer une nouvelle partie. ",
"unlocks.level": "Voci tous les niveaux du jeu. Cliquez sur un niveau pour commencer une nouvelle partie avec ce niveau de départ. ",
"unlocks.level_description": "Un niveau {{size}}x{{size}} avec {{bricks}} briques",
"unlocks.title": "Vous avez débloqué {{percentUnlock}}% du jeu.",
"unlocks.unlocks_at": "Déverrouillé au score total {{threshold}}.",

View file

@ -50,6 +50,11 @@ export const options = {
name: t("main_menu.record"),
help: t("main_menu.record_help"),
},
fullscreen: {
default: false,
name: t("main_menu.fullscreen"),
help: t("main_menu.fullscreen_help"),
},
} as const satisfies { [k: string]: OptionDef };
export function isOptionOn(key: OptionId) {