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.
- icons in settings menu
- choose starting perks
- fixed issue with reloading with [R] key
- gameover screen restarts in the same game mode

View file

@ -11,8 +11,8 @@ android {
applicationId = "me.lecaro.breakout"
minSdk = 21
targetSdk = 34
versionCode = 29058981
versionName = "29058981"
versionCode = 29059721
versionName = "29059721"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
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",
value: "en",
icon: (0, _loadGameData.icons)['UK']
icon: (0, _loadGameData.icons)["UK"]
},
{
text: "Fran\xe7ais",
value: "fr",
icon: (0, _loadGameData.icons)['France']
icon: (0, _loadGameData.icons)["France"]
}
];
actions.push({
@ -1118,7 +1118,7 @@ async function openSettingsMenu() {
}
});
actions.push({
icon: (0, _loadGameData.icons)['icon:download'],
icon: (0, _loadGameData.icons)["icon:download"],
text: (0, _i18N.t)("main_menu.download_save_file"),
help: (0, _i18N.t)("main_menu.download_save_file_help"),
async value () {
@ -1144,7 +1144,7 @@ async function openSettingsMenu() {
}
});
actions.push({
icon: (0, _loadGameData.icons)['icon:upload'],
icon: (0, _loadGameData.icons)["icon:upload"],
text: (0, _i18N.t)("main_menu.load_save_file"),
help: (0, _i18N.t)("main_menu.load_save_file_help"),
async value () {
@ -1207,7 +1207,7 @@ async function openSettingsMenu() {
}
});
actions.push({
icon: (0, _loadGameData.icons)['icon:coins'],
icon: (0, _loadGameData.icons)["icon:coins"],
text: (0, _i18N.t)("main_menu.max_coins", {
max: (0, _settings.getCurrentMaxCoins)()
}),
@ -1218,7 +1218,7 @@ async function openSettingsMenu() {
}
});
actions.push({
icon: (0, _loadGameData.icons)['icon:particles'],
icon: (0, _loadGameData.icons)["icon:particles"],
text: (0, _i18N.t)("main_menu.max_particles", {
max: (0, _settings.getCurrentMaxParticles)()
}),
@ -1229,7 +1229,7 @@ async function openSettingsMenu() {
}
});
actions.push({
icon: (0, _loadGameData.icons)['icon:reset'],
icon: (0, _loadGameData.icons)["icon:reset"],
text: (0, _i18N.t)("main_menu.reset"),
help: (0, _i18N.t)("main_menu.reset_help"),
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) {
module.exports = JSON.parse("\"29058981\"");
module.exports = JSON.parse("\"29059721\"");
},{}],"1u3Dx":[function(require,module,exports,__globalThis) {
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;
if (parent?.hasAttribute("data-tooltip")) {
hovering = parent;
tooltip.innerHTML = hovering.getAttribute("data-tooltip") || '';
tooltip.innerHTML = hovering.getAttribute("data-tooltip") || "";
tooltip.style.display = "";
updateTooltipPosition(e);
} else closeToolTip();
@ -5011,21 +5011,21 @@ var _loadGameData = require("./loadGameData");
var _settings = require("./settings");
function startingPerkMenuButton() {
return {
icon: (0, _loadGameData.icons)['icon:starting_perks'],
text: (0, _i18N.t)('main_menu.starting_perks'),
help: (0, _i18N.t)('main_menu.starting_perks_help'),
icon: (0, _loadGameData.icons)["icon:starting_perks"],
text: (0, _i18N.t)("main_menu.starting_perks"),
help: (0, _i18N.t)("main_menu.starting_perks_help"),
async value () {
await openStartingPerksEditor();
}
};
}
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() {
const ts = (0, _settings.getTotalScore)();
const avaliable = (0, _loadGameData.upgrades).filter((u)=>!u.requires && ![
'instant_upgrade'
"instant_upgrade"
].includes(u.id) && u.threshold <= ts);
const starting = avaliable.filter((u)=>isChecked(u));
const buttons = avaliable.map((u)=>{
@ -5040,17 +5040,17 @@ async function openStartingPerksEditor() {
};
});
const perk = await (0, _asyncAlert.asyncAlert)({
title: (0, _i18N.t)('main_menu.starting_perks'),
title: (0, _i18N.t)("main_menu.starting_perks"),
actionsAsGrid: true,
content: [
(0, _i18N.t)('main_menu.starting_perks_checked'),
(0, _i18N.t)("main_menu.starting_perks_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)
]
});
if (perk) {
(0, _settings.setSettingValue)('start_with_' + perk.id, !isChecked(perk));
(0, _settings.setSettingValue)("start_with_" + perk.id, !isChecked(perk));
openStartingPerksEditor();
}
}

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

@ -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()
}
}
}
function isChecked(u:Upgrade):boolean{
return getSettingValue('start_with_'+u.id, u.giftable)
}
icon: u.icon,
text: u.name,
tooltip: u.help(1),
value: u,
disabled: checked && starting.length < 2,
checked,
};
});
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()
}
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();
});
}