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

@ -21,6 +21,7 @@ Break colourful bricks, catch bouncing coins and select powerful upgrades !
## next release. ## next release.
- icons in settings menu
- choose starting perks - choose starting perks
- fixed issue with reloading with [R] key - fixed issue with reloading with [R] key
- gameover screen restarts in the same game mode - gameover screen restarts in the same game mode

View file

@ -11,8 +11,8 @@ android {
applicationId = "me.lecaro.breakout" applicationId = "me.lecaro.breakout"
minSdk = 21 minSdk = 21
targetSdk = 34 targetSdk = 34
versionCode = 29058981 versionCode = 29059721
versionName = "29058981" versionName = "29059721"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables { vectorDrawables {
useSupportLibrary = true useSupportLibrary = true

File diff suppressed because one or more lines are too long

36
dist/index.html vendored
View file

@ -1079,12 +1079,12 @@ async function openSettingsMenu() {
{ {
text: "English", text: "English",
value: "en", value: "en",
icon: (0, _loadGameData.icons)['UK'] icon: (0, _loadGameData.icons)["UK"]
}, },
{ {
text: "Fran\xe7ais", text: "Fran\xe7ais",
value: "fr", value: "fr",
icon: (0, _loadGameData.icons)['France'] icon: (0, _loadGameData.icons)["France"]
} }
]; ];
actions.push({ actions.push({
@ -1118,7 +1118,7 @@ async function openSettingsMenu() {
} }
}); });
actions.push({ actions.push({
icon: (0, _loadGameData.icons)['icon:download'], icon: (0, _loadGameData.icons)["icon:download"],
text: (0, _i18N.t)("main_menu.download_save_file"), text: (0, _i18N.t)("main_menu.download_save_file"),
help: (0, _i18N.t)("main_menu.download_save_file_help"), help: (0, _i18N.t)("main_menu.download_save_file_help"),
async value () { async value () {
@ -1144,7 +1144,7 @@ async function openSettingsMenu() {
} }
}); });
actions.push({ actions.push({
icon: (0, _loadGameData.icons)['icon:upload'], icon: (0, _loadGameData.icons)["icon:upload"],
text: (0, _i18N.t)("main_menu.load_save_file"), text: (0, _i18N.t)("main_menu.load_save_file"),
help: (0, _i18N.t)("main_menu.load_save_file_help"), help: (0, _i18N.t)("main_menu.load_save_file_help"),
async value () { async value () {
@ -1207,7 +1207,7 @@ async function openSettingsMenu() {
} }
}); });
actions.push({ actions.push({
icon: (0, _loadGameData.icons)['icon:coins'], icon: (0, _loadGameData.icons)["icon:coins"],
text: (0, _i18N.t)("main_menu.max_coins", { text: (0, _i18N.t)("main_menu.max_coins", {
max: (0, _settings.getCurrentMaxCoins)() max: (0, _settings.getCurrentMaxCoins)()
}), }),
@ -1218,7 +1218,7 @@ async function openSettingsMenu() {
} }
}); });
actions.push({ actions.push({
icon: (0, _loadGameData.icons)['icon:particles'], icon: (0, _loadGameData.icons)["icon:particles"],
text: (0, _i18N.t)("main_menu.max_particles", { text: (0, _i18N.t)("main_menu.max_particles", {
max: (0, _settings.getCurrentMaxParticles)() max: (0, _settings.getCurrentMaxParticles)()
}), }),
@ -1229,7 +1229,7 @@ async function openSettingsMenu() {
} }
}); });
actions.push({ actions.push({
icon: (0, _loadGameData.icons)['icon:reset'], icon: (0, _loadGameData.icons)["icon:reset"],
text: (0, _i18N.t)("main_menu.reset"), text: (0, _i18N.t)("main_menu.reset"),
help: (0, _i18N.t)("main_menu.reset_help"), help: (0, _i18N.t)("main_menu.reset_help"),
async value () { async value () {
@ -1474,7 +1474,7 @@ const upgrades = (0, _upgrades.rawUpgrades).map((u)=>({
})); }));
},{"./data/palette.json":"ktRBU","./data/levels.json":"8JSUc","./data/version.json":"iyP6E","./upgrades":"1u3Dx","./getLevelBackground":"7OIPf","./levelIcon":"6rQoT","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"iyP6E":[function(require,module,exports,__globalThis) { },{"./data/palette.json":"ktRBU","./data/levels.json":"8JSUc","./data/version.json":"iyP6E","./upgrades":"1u3Dx","./getLevelBackground":"7OIPf","./levelIcon":"6rQoT","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"iyP6E":[function(require,module,exports,__globalThis) {
module.exports = JSON.parse("\"29058981\""); module.exports = JSON.parse("\"29059721\"");
},{}],"1u3Dx":[function(require,module,exports,__globalThis) { },{}],"1u3Dx":[function(require,module,exports,__globalThis) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
@ -4982,7 +4982,7 @@ function setupTooltips() {
while(parent && !parent.hasAttribute("data-tooltip"))parent = parent.parentElement; while(parent && !parent.hasAttribute("data-tooltip"))parent = parent.parentElement;
if (parent?.hasAttribute("data-tooltip")) { if (parent?.hasAttribute("data-tooltip")) {
hovering = parent; hovering = parent;
tooltip.innerHTML = hovering.getAttribute("data-tooltip") || ''; tooltip.innerHTML = hovering.getAttribute("data-tooltip") || "";
tooltip.style.display = ""; tooltip.style.display = "";
updateTooltipPosition(e); updateTooltipPosition(e);
} else closeToolTip(); } else closeToolTip();
@ -5011,21 +5011,21 @@ var _loadGameData = require("./loadGameData");
var _settings = require("./settings"); var _settings = require("./settings");
function startingPerkMenuButton() { function startingPerkMenuButton() {
return { return {
icon: (0, _loadGameData.icons)['icon:starting_perks'], icon: (0, _loadGameData.icons)["icon:starting_perks"],
text: (0, _i18N.t)('main_menu.starting_perks'), text: (0, _i18N.t)("main_menu.starting_perks"),
help: (0, _i18N.t)('main_menu.starting_perks_help'), help: (0, _i18N.t)("main_menu.starting_perks_help"),
async value () { async value () {
await openStartingPerksEditor(); await openStartingPerksEditor();
} }
}; };
} }
function isChecked(u) { function isChecked(u) {
return (0, _settings.getSettingValue)('start_with_' + u.id, u.giftable); return (0, _settings.getSettingValue)("start_with_" + u.id, u.giftable);
} }
async function openStartingPerksEditor() { async function openStartingPerksEditor() {
const ts = (0, _settings.getTotalScore)(); const ts = (0, _settings.getTotalScore)();
const avaliable = (0, _loadGameData.upgrades).filter((u)=>!u.requires && ![ const avaliable = (0, _loadGameData.upgrades).filter((u)=>!u.requires && ![
'instant_upgrade' "instant_upgrade"
].includes(u.id) && u.threshold <= ts); ].includes(u.id) && u.threshold <= ts);
const starting = avaliable.filter((u)=>isChecked(u)); const starting = avaliable.filter((u)=>isChecked(u));
const buttons = avaliable.map((u)=>{ const buttons = avaliable.map((u)=>{
@ -5040,17 +5040,17 @@ async function openStartingPerksEditor() {
}; };
}); });
const perk = await (0, _asyncAlert.asyncAlert)({ const perk = await (0, _asyncAlert.asyncAlert)({
title: (0, _i18N.t)('main_menu.starting_perks'), title: (0, _i18N.t)("main_menu.starting_perks"),
actionsAsGrid: true, actionsAsGrid: true,
content: [ content: [
(0, _i18N.t)('main_menu.starting_perks_checked'), (0, _i18N.t)("main_menu.starting_perks_checked"),
...buttons.filter((b)=>b.checked), ...buttons.filter((b)=>b.checked),
(0, _i18N.t)('main_menu.starting_perks_unchecked'), (0, _i18N.t)("main_menu.starting_perks_unchecked"),
...buttons.filter((b)=>!b.checked) ...buttons.filter((b)=>!b.checked)
] ]
}); });
if (perk) { if (perk) {
(0, _settings.setSettingValue)('start_with_' + perk.id, !isChecked(perk)); (0, _settings.setSettingValue)("start_with_" + perk.id, !isChecked(perk));
openStartingPerksEditor(); openStartingPerksEditor();
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -136,7 +136,7 @@ export function gameOver(title: string, intro: string) {
}).then(() => }).then(() =>
restart({ restart({
levelToAvoid: currentLevelInfo(gameState).name, 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.globalCompositeOperation = "source-over";
ctx.globalAlpha = gameState.perks.unbounded ? 0.1 : 1; ctx.globalAlpha = gameState.perks.unbounded ? 0.1 : 1;
let redLeftSide = hasCombo &&!gameState.perks.unbounded&& (gameState.perks.left_is_lava || gameState.perks.trampoline) let redLeftSide =
let redRightSide = hasCombo &&!gameState.perks.unbounded&& (gameState.perks.right_is_lava || gameState.perks.trampoline) hasCombo &&
let redTop = hasCombo && gameState.perks.unbounded<=2 && (gameState.perks.top_is_lava || gameState.perks.trampoline) !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) { if (gameState.offsetXRoundedDown) {
// draw outside of gaming area to avoid capturing borders in recordings // draw outside of gaming area to avoid capturing borders in recordings
drawStraightLine( drawStraightLine(
ctx, ctx,
gameState, gameState,
(redLeftSide && "red") || (redLeftSide && "red") || "white",
"white",
gameState.offsetX - 1, gameState.offsetX - 1,
0, 0,
gameState.offsetX - 1, gameState.offsetX - 1,
@ -418,8 +426,7 @@ export function render(gameState: GameState) {
drawStraightLine( drawStraightLine(
ctx, ctx,
gameState, gameState,
(redRightSide && "red") || (redRightSide && "red") || "white",
"white",
width - gameState.offsetX + 1, width - gameState.offsetX + 1,
0, 0,
width - gameState.offsetX + 1, width - gameState.offsetX + 1,
@ -427,12 +434,10 @@ export function render(gameState: GameState) {
gameState.perks.unbounded ? 0.1 : 1, gameState.perks.unbounded ? 0.1 : 1,
); );
} else { } else {
drawStraightLine( drawStraightLine(
ctx, ctx,
gameState, gameState,
(redLeftSide && "red") || (redLeftSide && "red") || "",
"",
0, 0,
0, 0,
0, 0,
@ -443,8 +448,7 @@ export function render(gameState: GameState) {
drawStraightLine( drawStraightLine(
ctx, ctx,
gameState, gameState,
(redRightSide && "red") || (redRightSide && "red") || "",
"",
width - 1, width - 1,
0, 0,
width - 1, width - 1,

View file

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

View file

@ -7,7 +7,6 @@ export function setupTooltips() {
return; return;
} }
function updateTooltipPosition(e: MouseEvent) { function updateTooltipPosition(e: MouseEvent) {
tooltip.style.transform = tooltip.style.transform =
`translate(${e.clientX}px,${e.clientY + 20}px) ` + `translate(${e.clientX}px,${e.clientY + 20}px) ` +
@ -16,9 +15,9 @@ export function setupTooltips() {
function closeToolTip() { function closeToolTip() {
tooltip.style.display = "none"; tooltip.style.display = "none";
hovering=null hovering = null;
} }
let hovering:HTMLElement|null=null let hovering: HTMLElement | null = null;
document.body.addEventListener( document.body.addEventListener(
"mouseenter", "mouseenter",
(e: MouseEvent) => { (e: MouseEvent) => {
@ -27,12 +26,12 @@ export function setupTooltips() {
parent = parent.parentElement; parent = parent.parentElement;
} }
if (parent?.hasAttribute("data-tooltip")) { if (parent?.hasAttribute("data-tooltip")) {
hovering=parent as HTMLElement hovering = parent as HTMLElement;
tooltip.innerHTML = hovering.getAttribute("data-tooltip") || ''; tooltip.innerHTML = hovering.getAttribute("data-tooltip") || "";
tooltip.style.display = ""; tooltip.style.display = "";
updateTooltipPosition(e); updateTooltipPosition(e);
} else { } else {
closeToolTip() closeToolTip();
} }
}, },
true, true,
@ -41,10 +40,10 @@ export function setupTooltips() {
setInterval(() => { setInterval(() => {
if (hovering) { if (hovering) {
if (!document.body.contains(hovering)) { if (!document.body.contains(hovering)) {
closeToolTip() closeToolTip();
} }
} }
},200) }, 200);
document.body.addEventListener( document.body.addEventListener(
"mousemove", "mousemove",
(e) => { (e) => {
@ -54,10 +53,7 @@ export function setupTooltips() {
}, },
true, true,
); );
document.body.addEventListener( document.body.addEventListener("mouseleave", (e) => {
"mouseleave", closeToolTip();
(e) => { });
closeToolTip()
}
);
} }