mirror of
https://gitlab.com/lecarore/breakout71.git
synced 2025-04-22 04:56:15 -04:00
Made the "combo lost" text last 500ms instead of the pointless 150ms
This commit is contained in:
parent
da89cdb647
commit
23798c4e58
9 changed files with 262 additions and 265 deletions
166
src/game.ts
166
src/game.ts
|
@ -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,
|
||||
}) ||
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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)+'%')
|
||||
}
|
|
@ -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/>
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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}}.",
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue