Build 29059721

This commit is contained in:
Renan LE CARO 2025-04-02 10:42:01 +02:00
parent 1cf82d6641
commit a3ff7d81ad
13 changed files with 148 additions and 157 deletions

View file

@ -1,5 +1,5 @@
// The version of the cache.
const VERSION = "29058981";
const VERSION = "29059721";
// The name of the cache
const CACHE_NAME = `breakout-71-${VERSION}`;

View file

@ -1164,4 +1164,4 @@
"svg": null,
"color": ""
}
]
]

View file

@ -1 +1 @@
"29058981"
"29059721"

View file

@ -1,9 +1,10 @@
* {
font-family: Courier New,
Courier,
Lucida Sans Typewriter,
Lucida Typewriter,
monospace;
font-family:
Courier New,
Courier,
Lucida Sans Typewriter,
Lucida Typewriter,
monospace;
box-sizing: border-box;
}
@ -178,7 +179,6 @@ body:not(.has-alert-open) #popup {
opacity: 0.2;
}
}
}
}
}

View file

@ -68,10 +68,9 @@ import { hoursSpentPlaying } from "./pure_functions";
import { helpMenuEntry } from "./help";
import { creativeMode } from "./creative";
import { setupTooltips } from "./tooltip";
import {startingPerkMenuButton} from "./startingPerks";
import { startingPerkMenuButton } from "./startingPerks";
export async function play() {
if (await applyFullScreenChoice()) return;
if (gameState.running) return;
gameState.running = true;
@ -558,33 +557,28 @@ function donationNag(gameState) {
async function openSettingsMenu() {
pause(true);
const actions: AsyncAlertAction<() => void>[] = [
startingPerkMenuButton()
];
const actions: AsyncAlertAction<() => void>[] = [startingPerkMenuButton()];
const languages= [
{
text: "English",
value: "en",
icon: icons['UK']
},
{
text: "Français",
value: "fr",
icon: icons['France']
}
]
const languages = [
{
text: "English",
value: "en",
icon: icons["UK"],
},
{
text: "Français",
value: "fr",
icon: icons["France"],
},
];
actions.push({
icon:languages.find(l=>l.value===getCurrentLang())?.icon,
icon: languages.find((l) => l.value === getCurrentLang())?.icon,
text: t("main_menu.language"),
help: t("main_menu.language_help"),
async value() {
const pick = await asyncAlert({
title: t("main_menu.language"),
content: [
t("main_menu.language_help"),
...languages
],
content: [t("main_menu.language_help"), ...languages],
allowClose: true,
});
if (
@ -614,7 +608,7 @@ async function openSettingsMenu() {
});
}
actions.push({
icon:icons['icon:download'],
icon: icons["icon:download"],
text: t("main_menu.download_save_file"),
help: t("main_menu.download_save_file_help"),
async value() {
@ -663,7 +657,7 @@ async function openSettingsMenu() {
});
actions.push({
icon:icons['icon:upload'],
icon: icons["icon:upload"],
text: t("main_menu.load_save_file"),
help: t("main_menu.load_save_file_help"),
async value() {
@ -747,9 +741,8 @@ async function openSettingsMenu() {
},
});
actions.push({
icon:icons['icon:coins'],
icon: icons["icon:coins"],
text: t("main_menu.max_coins", { max: getCurrentMaxCoins() }),
help: t("main_menu.max_coins_help"),
async value() {
@ -758,7 +751,7 @@ async function openSettingsMenu() {
},
});
actions.push({
icon:icons['icon:particles'],
icon: icons["icon:particles"],
text: t("main_menu.max_particles", { max: getCurrentMaxParticles() }),
help: t("main_menu.max_particles_help"),
async value() {
@ -768,7 +761,7 @@ async function openSettingsMenu() {
});
actions.push({
icon:icons['icon:reset'],
icon: icons["icon:reset"],
text: t("main_menu.reset"),
help: t("main_menu.reset_help"),
async value() {
@ -817,13 +810,13 @@ async function applyFullScreenChoice() {
await document.exitFullscreen();
return true;
} else if (document.webkitCancelFullScreen) {
await document.webkitCancelFullScreen();
await document.webkitCancelFullScreen();
return true;
}
} else if (isOptionOn("fullscreen") && !document.fullscreenElement) {
const docel = document.documentElement;
if (docel.requestFullscreen) {
await docel.requestFullscreen()
await docel.requestFullscreen();
return true;
} else if (docel.webkitRequestFullscreen) {
await docel.webkitRequestFullscreen();
@ -941,9 +934,6 @@ document.addEventListener("keydown", async (e) => {
let pageLoad = new Date();
document.addEventListener("keyup", async (e) => {
const focused = document.querySelector("button:focus");
if (e.key in pressed) {
setKeyPressed(e.key, 0);

View file

@ -136,7 +136,7 @@ export function gameOver(title: string, intro: string) {
}).then(() =>
restart({
levelToAvoid: currentLevelInfo(gameState).name,
mode:gameState.mode
mode: gameState.mode,
}),
);
}

View file

@ -397,17 +397,25 @@ export function render(gameState: GameState) {
ctx.globalCompositeOperation = "source-over";
ctx.globalAlpha = gameState.perks.unbounded ? 0.1 : 1;
let redLeftSide = hasCombo &&!gameState.perks.unbounded&& (gameState.perks.left_is_lava || gameState.perks.trampoline)
let redRightSide = hasCombo &&!gameState.perks.unbounded&& (gameState.perks.right_is_lava || gameState.perks.trampoline)
let redTop = hasCombo && gameState.perks.unbounded<=2 && (gameState.perks.top_is_lava || gameState.perks.trampoline)
let redLeftSide =
hasCombo &&
!gameState.perks.unbounded &&
(gameState.perks.left_is_lava || gameState.perks.trampoline);
let redRightSide =
hasCombo &&
!gameState.perks.unbounded &&
(gameState.perks.right_is_lava || gameState.perks.trampoline);
let redTop =
hasCombo &&
gameState.perks.unbounded <= 2 &&
(gameState.perks.top_is_lava || gameState.perks.trampoline);
if (gameState.offsetXRoundedDown) {
// draw outside of gaming area to avoid capturing borders in recordings
drawStraightLine(
ctx,
gameState,
(redLeftSide && "red") ||
"white",
(redLeftSide && "red") || "white",
gameState.offsetX - 1,
0,
gameState.offsetX - 1,
@ -418,8 +426,7 @@ export function render(gameState: GameState) {
drawStraightLine(
ctx,
gameState,
(redRightSide && "red") ||
"white",
(redRightSide && "red") || "white",
width - gameState.offsetX + 1,
0,
width - gameState.offsetX + 1,
@ -427,12 +434,10 @@ export function render(gameState: GameState) {
gameState.perks.unbounded ? 0.1 : 1,
);
} else {
drawStraightLine(
ctx,
gameState,
(redLeftSide && "red") ||
"",
(redLeftSide && "red") || "",
0,
0,
0,
@ -443,8 +448,7 @@ export function render(gameState: GameState) {
drawStraightLine(
ctx,
gameState,
(redRightSide && "red") ||
"",
(redRightSide && "red") || "",
width - 1,
0,
width - 1,
@ -452,17 +456,17 @@ export function render(gameState: GameState) {
1,
);
}
if(redTop)
drawStraightLine(
ctx,
gameState,
"red",
gameState.perks.unbounded ? 0 : gameState.offsetXRoundedDown,
1,
gameState.perks.unbounded ? width : width - gameState.offsetXRoundedDown,
1,
1,
);
if (redTop)
drawStraightLine(
ctx,
gameState,
"red",
gameState.perks.unbounded ? 0 : gameState.offsetXRoundedDown,
1,
gameState.perks.unbounded ? width : width - gameState.offsetXRoundedDown,
1,
1,
);
ctx.globalAlpha = 1;
drawStraightLine(

View file

@ -1,54 +1,54 @@
import {asyncAlert} from "./asyncAlert";
import {PerkId, Upgrade} from "./types";
import {t} from "./i18n/i18n";
import {icons, upgrades} from "./loadGameData";
import {getSettingValue, getTotalScore, setSettingValue} from "./settings";
import { asyncAlert } from "./asyncAlert";
import { PerkId, Upgrade } from "./types";
import { t } from "./i18n/i18n";
import { icons, upgrades } from "./loadGameData";
import { getSettingValue, getTotalScore, setSettingValue } from "./settings";
export function startingPerkMenuButton() {
return {
icon: icons["icon:starting_perks"],
text: t("main_menu.starting_perks"),
help: t("main_menu.starting_perks_help"),
async value() {
await openStartingPerksEditor();
},
};
}
function isChecked(u: Upgrade): boolean {
return getSettingValue("start_with_" + u.id, u.giftable);
}
export function startingPerkMenuButton(){
export async function openStartingPerksEditor() {
const ts = getTotalScore();
const avaliable = upgrades.filter(
(u) =>
!u.requires && !["instant_upgrade"].includes(u.id) && u.threshold <= ts,
);
const starting = avaliable.filter((u) => isChecked(u));
const buttons = avaliable.map((u) => {
const checked = isChecked(u);
return {
icon:icons['icon:starting_perks'],
text:t('main_menu.starting_perks'),
help:t('main_menu.starting_perks_help'),
async value(){
await openStartingPerksEditor()
}
}
icon: u.icon,
text: u.name,
tooltip: u.help(1),
value: u,
disabled: checked && starting.length < 2,
checked,
};
});
const perk: Upgrade | null | void = await asyncAlert({
title: t("main_menu.starting_perks"),
actionsAsGrid: true,
content: [
t("main_menu.starting_perks_checked"),
...buttons.filter((b) => b.checked),
t("main_menu.starting_perks_unchecked"),
...buttons.filter((b) => !b.checked),
],
});
if (perk) {
setSettingValue("start_with_" + perk.id, !isChecked(perk));
openStartingPerksEditor();
}
}
function isChecked(u:Upgrade):boolean{
return getSettingValue('start_with_'+u.id, u.giftable)
}
export async function openStartingPerksEditor(){
const ts=getTotalScore()
const avaliable=upgrades.filter(u=>!u.requires && !['instant_upgrade'].includes(u.id) && u.threshold<=ts)
const starting = avaliable.filter(u=>isChecked(u))
const buttons=avaliable
.map(u=> {
const checked = isChecked(u);
return {
icon: u.icon,
text: u.name,
tooltip: u.help(1),
value:u,
disabled:checked && starting.length<2,
checked
}
})
const perk :Upgrade|null|void= await asyncAlert({
title:t('main_menu.starting_perks'),
actionsAsGrid:true,
content:[
t('main_menu.starting_perks_checked'),
...buttons.filter(b=>b.checked),
t('main_menu.starting_perks_unchecked'),
...buttons.filter(b=>!b.checked),
]
})
if(perk){
setSettingValue('start_with_'+perk.id,!isChecked(perk))
openStartingPerksEditor()
}
}

View file

@ -7,18 +7,17 @@ export function setupTooltips() {
return;
}
function updateTooltipPosition(e: MouseEvent) {
tooltip.style.transform =
`translate(${e.clientX}px,${e.clientY + 20}px) ` +
(e.clientX > window.innerWidth / 2 ? " translate(-100%,0)" : "");
}
function closeToolTip(){
tooltip.style.display = "none";
hovering=null
function closeToolTip() {
tooltip.style.display = "none";
hovering = null;
}
let hovering:HTMLElement|null=null
let hovering: HTMLElement | null = null;
document.body.addEventListener(
"mouseenter",
(e: MouseEvent) => {
@ -27,24 +26,24 @@ export function setupTooltips() {
parent = parent.parentElement;
}
if (parent?.hasAttribute("data-tooltip")) {
hovering=parent as HTMLElement
tooltip.innerHTML = hovering.getAttribute("data-tooltip") || '';
hovering = parent as HTMLElement;
tooltip.innerHTML = hovering.getAttribute("data-tooltip") || "";
tooltip.style.display = "";
updateTooltipPosition(e);
} else {
closeToolTip()
closeToolTip();
}
},
true,
);
setInterval(()=>{
if(hovering){
if(!document.body.contains(hovering)){
closeToolTip()
}
setInterval(() => {
if (hovering) {
if (!document.body.contains(hovering)) {
closeToolTip();
}
},200)
}
}, 200);
document.body.addEventListener(
"mousemove",
(e) => {
@ -54,10 +53,7 @@ export function setupTooltips() {
},
true,
);
document.body.addEventListener(
"mouseleave",
(e) => {
closeToolTip()
}
);
document.body.addEventListener("mouseleave", (e) => {
closeToolTip();
});
}