Build 29061490

This commit is contained in:
Renan LE CARO 2025-04-03 16:10:51 +02:00
parent ba7e368938
commit 00094d5efa
13 changed files with 168 additions and 90 deletions

View file

@ -18,10 +18,9 @@ Break colourful bricks, catch bouncing coins and select powerful upgrades !
## Todo ## Todo
## Next release ## Next release
- Abandoned : WebGl rendering of the lights in the background is too complex, first results unconvincing - Graphics : option to make coins more readable (on by default)
- Graphics : option to make coins pretty vs readable - Graphics : option to add more light (on by default)
- Graphics : much more light thanks to faster computations
- Graphics : background effects are not computed on a much smaller resolution, and then stretched out to the full res - Graphics : background effects are not computed on a much smaller resolution, and then stretched out to the full res
- Graphics : all levels background have been checked (4 buggy ones removed) and will be asigned randomly - Graphics : all levels background have been checked (4 buggy ones removed) and will be asigned randomly
- Fixed : display gained combo was showing +0 sometimes - Fixed : display gained combo was showing +0 sometimes

View file

@ -29,8 +29,8 @@ android {
applicationId = "me.lecaro.breakout" applicationId = "me.lecaro.breakout"
minSdk = 21 minSdk = 21
targetSdk = 34 targetSdk = 34
versionCode = 29061433 versionCode = 29061490
versionName = "29061433" versionName = "29061490"
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

58
dist/index.html vendored

File diff suppressed because one or more lines are too long

View file

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

View file

@ -1108,7 +1108,7 @@
"size": 21, "size": 21,
"bricks": "_____bbbWbbbWbbb_________PWbWPWbWPWbWP_______bWbbbWbbbWbbbWb_____WbbbWbbbWbbbWbbbW___WPWbWPWbWPWbWPWbWPW__bWbbbWbbbWbbbWbbbWb__bbbPbbbPbbbPbbbPbbb__bbPPPbPPPbPPPbPPPbb___PPWPPPWPPPWPPPWPP____PWbWPWbWPWbWPWbWP_____PWPPPWPPPWPPPWP_______PPWPPPWPPPWPP_________WbWPWbWPWbW___________bbbbbbbbb_____________b_____b______________b_____b______________b_____b______________WWWWWWW_______________PPPPP________________PPPPP________________PPPPP________", "bricks": "_____bbbWbbbWbbb_________PWbWPWbWPWbWP_______bWbbbWbbbWbbbWb_____WbbbWbbbWbbbWbbbW___WPWbWPWbWPWbWPWbWPW__bWbbbWbbbWbbbWbbbWb__bbbPbbbPbbbPbbbPbbb__bbPPPbPPPbPPPbPPPbb___PPWPPPWPPPWPPPWPP____PWbWPWbWPWbWPWbWP_____PWPPPWPPPWPPPWP_______PPWPPPWPPPWPP_________WbWPWbWPWbW___________bbbbbbbbb_____________b_____b______________b_____b______________b_____b______________WWWWWWW_______________PPPPP________________PPPPP________________PPPPP________",
"svg": null, "svg": null,
"color": "", "color": "#240a8b",
"credit": "https://prohama.com/balloon-1/" "credit": "https://prohama.com/balloon-1/"
}, },
{ {
@ -1116,7 +1116,7 @@
"size": 14, "size": 14,
"bricks": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbyyyyyyyyyyyybbyB___BB___Bybby__________ybbyyy______yyybbbbyyB__Byybbbbbbbyy__yybbbbbbbbby__ybbbbbyyyyby__ybyyyy___yby__yby______yby__yby______yBy__yBy______yyy__yyy___", "bricks": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbyyyyyyyyyyyybbyB___BB___Bybby__________ybbyyy______yyybbbbyyB__Byybbbbbbbyy__yybbbbbbbbby__ybbbbbyyyyby__ybyyyy___yby__yby______yby__yby______yBy__yBy______yyy__yyy___",
"svg": null, "svg": null,
"color": "" "color": "#000000"
}, },
{ {
"name": "Stripes", "name": "Stripes",
@ -1167,4 +1167,4 @@
"svg": null, "svg": null,
"color": "" "color": ""
} }
] ]

View file

@ -1 +1 @@
"29061433" "29061490"

View file

@ -1042,6 +1042,36 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>extra_bright</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>extra_bright_help</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> <concept_node>
<name>footer_html</name> <name>footer_html</name>
<description/> <description/>
@ -1612,6 +1642,36 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>saturate_more</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>saturate_more_help</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> <concept_node>
<name>save_file_error</name> <name>save_file_error</name>
<description/> <description/>

View file

@ -64,6 +64,8 @@
"main_menu.donation_reminder_help": "See time played and donation link in main menu", "main_menu.donation_reminder_help": "See time played and donation link in main menu",
"main_menu.download_save_file": "Download score and stats", "main_menu.download_save_file": "Download score and stats",
"main_menu.download_save_file_help": "Get a save file", "main_menu.download_save_file_help": "Get a save file",
"main_menu.extra_bright": "Extra bright",
"main_menu.extra_bright_help": "Increases the size of the halo around coins and bricks.",
"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/bbcQw4x5zA\" 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.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/bbcQw4x5zA\" 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": "Fullscreen",
"main_menu.fullscreen_help": "Game will try to go full screen before starting", "main_menu.fullscreen_help": "Game will try to go full screen before starting",
@ -102,6 +104,8 @@
"main_menu.reset_confirm": "Yes", "main_menu.reset_confirm": "Yes",
"main_menu.reset_help": "Erase high score, play time and statistics", "main_menu.reset_help": "Erase high score, play time and statistics",
"main_menu.reset_instruction": "You will loose all progress you made in the game, are you sure ?", "main_menu.reset_instruction": "You will loose all progress you made in the game, are you sure ?",
"main_menu.saturate_more": "Higher saturation",
"main_menu.saturate_more_help": "Increases the colorfulness of the light emitted by coins and bricks.",
"main_menu.save_file_error": "Error loading save file", "main_menu.save_file_error": "Error loading save file",
"main_menu.save_file_loaded": "Save file loaded", "main_menu.save_file_loaded": "Save file loaded",
"main_menu.save_file_loaded_help": "The app will now reload to apply your save", "main_menu.save_file_loaded_help": "The app will now reload to apply your save",

View file

@ -64,6 +64,8 @@
"main_menu.donation_reminder_help": "Afficher le temps de jeu et un lien pour donner dans le menu principal", "main_menu.donation_reminder_help": "Afficher le temps de jeu et un lien pour donner dans le menu principal",
"main_menu.download_save_file": "Sauvegarder mes progrès", "main_menu.download_save_file": "Sauvegarder mes progrès",
"main_menu.download_save_file_help": "Obtenir un fichier de sauvegarde", "main_menu.download_save_file_help": "Obtenir un fichier de sauvegarde",
"main_menu.extra_bright": "Plus de lumière",
"main_menu.extra_bright_help": "Plus grand halo lumineux autours des briques et pièces.",
"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/bbcQw4x5zA\" 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.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/bbcQw4x5zA\" 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": "Plein écran",
"main_menu.fullscreen_help": "Le jeu essaiera de passer en plein écran quand vous le démarrez", "main_menu.fullscreen_help": "Le jeu essaiera de passer en plein écran quand vous le démarrez",
@ -88,8 +90,8 @@
"main_menu.mobile_help": "Laisse un espace sous le palet.", "main_menu.mobile_help": "Laisse un espace sous le palet.",
"main_menu.normal": "Nouvelle partie rapide", "main_menu.normal": "Nouvelle partie rapide",
"main_menu.normal_help": "Avec un avantage de départ aléatoire", "main_menu.normal_help": "Avec un avantage de départ aléatoire",
"main_menu.opaque_coins": "", "main_menu.opaque_coins": "Pièces opaques avec bordure blanche",
"main_menu.opaque_coins_help": "", "main_menu.opaque_coins_help": "Moins joli mais plus lisible",
"main_menu.pointer_lock": "Verrouillage du pointeur", "main_menu.pointer_lock": "Verrouillage du pointeur",
"main_menu.pointer_lock_help": "Cache aussi le curseur de la souris.", "main_menu.pointer_lock_help": "Cache aussi le curseur de la souris.",
"main_menu.record": "Enregistrer des vidéos de jeu", "main_menu.record": "Enregistrer des vidéos de jeu",
@ -102,6 +104,8 @@
"main_menu.reset_confirm": "Oui", "main_menu.reset_confirm": "Oui",
"main_menu.reset_help": "Effacer les scores, statistiques et temps de jeu", "main_menu.reset_help": "Effacer les scores, statistiques et temps de jeu",
"main_menu.reset_instruction": "Vous perdrez tous les progrès que vous avez faits dans le jeu, êtes-vous sûr ?", "main_menu.reset_instruction": "Vous perdrez tous les progrès que vous avez faits dans le jeu, êtes-vous sûr ?",
"main_menu.saturate_more": "Saturation boostée",
"main_menu.saturate_more_help": "Augmente la couleur de la lumière émise par les pièces et les briques.",
"main_menu.save_file_error": "Erreur lors du chargement du fichier de sauvegarde", "main_menu.save_file_error": "Erreur lors du chargement du fichier de sauvegarde",
"main_menu.save_file_loaded": "Sauvegarde chargée", "main_menu.save_file_loaded": "Sauvegarde chargée",
"main_menu.save_file_loaded_help": "L'appli va redémarrer", "main_menu.save_file_loaded_help": "L'appli va redémarrer",

View file

@ -28,6 +28,7 @@ export const allLevels = rawLevelsList
bricks, bricks,
bricksCount, bricksCount,
icon, icon,
color: level.color || "#000000",
svg: getLevelBackground(level), svg: getLevelBackground(level),
}; };
}) })

View file

@ -26,10 +26,15 @@ export const options = {
help: t("main_menu.colorful_coins_help"), help: t("main_menu.colorful_coins_help"),
}, },
opaque_coins: { opaque_coins: {
default: false, default: true,
name: t("main_menu.opaque_coins"), name: t("main_menu.opaque_coins"),
help: t("main_menu.opaque_coins_help"), help: t("main_menu.opaque_coins_help"),
}, },
extra_bright: {
default: true,
name: t("main_menu.extra_bright"),
help: t("main_menu.extra_bright_help"),
},
show_fps: { show_fps: {
default: false, default: false,
name: t("main_menu.show_fps"), name: t("main_menu.show_fps"),

View file

@ -100,16 +100,10 @@ export function render(gameState: GameState) {
gameState.lastScoreIncrease > gameState.levelTime - 500 ? "active" : ""; gameState.lastScoreIncrease > gameState.levelTime - 500 ? "active" : "";
// Clear // Clear
if (!isOptionOn("basic") && !level.color && level.svg) { if (!isOptionOn("basic") && level.svg && level.color === "#000000") {
// Without this the light trails everything
// ctx.globalCompositeOperation = "source-over";
// ctx.globalAlpha = 1;
// ctx.fillStyle = "#000";
// ctx.fillRect(0, 0, width, height);
haloCanvasCtx.globalCompositeOperation = "source-over"; haloCanvasCtx.globalCompositeOperation = "source-over";
haloCanvasCtx.globalAlpha = 1; haloCanvasCtx.globalAlpha = 0.8;
haloCanvasCtx.fillStyle = "#000"; haloCanvasCtx.fillStyle = level.color;
haloCanvasCtx.fillRect(0, 0, width / haloScale, height / haloScale); haloCanvasCtx.fillRect(0, 0, width / haloScale, height / haloScale);
haloCanvasCtx.globalCompositeOperation = "screen"; haloCanvasCtx.globalCompositeOperation = "screen";
@ -125,30 +119,33 @@ export function render(gameState: GameState) {
coin.y / haloScale, coin.y / haloScale,
); );
haloCanvasCtx.globalAlpha = 0.4; if (isOptionOn("extra_bright")) {
drawFuzzyBall( haloCanvasCtx.globalAlpha = 0.4;
haloCanvasCtx, drawFuzzyBall(
coin.color, haloCanvasCtx,
(gameState.coinSize * 6) / haloScale, coin.color,
coin.x / haloScale, (gameState.coinSize * 6) / haloScale,
coin.y / haloScale, coin.x / haloScale,
); coin.y / haloScale,
);
}
}); });
gameState.balls.forEach((ball) => { gameState.balls.forEach((ball) => {
drawFuzzyBall( drawFuzzyBall(
haloCanvasCtx, haloCanvasCtx,
gameState.ballsColor, gameState.ballsColor,
(gameState.ballSize * 2) / haloScale, gameState.ballSize / haloScale,
ball.x / haloScale,
ball.y / haloScale,
);
drawFuzzyBall(
haloCanvasCtx,
gameState.ballsColor,
(gameState.ballSize * 4) / haloScale,
ball.x / haloScale, ball.x / haloScale,
ball.y / haloScale, ball.y / haloScale,
); );
if (isOptionOn("extra_bright"))
drawFuzzyBall(
haloCanvasCtx,
gameState.ballsColor,
(gameState.ballSize * 4) / haloScale,
ball.x / haloScale,
ball.y / haloScale,
);
}); });
haloCanvasCtx.globalAlpha = 0.6; haloCanvasCtx.globalAlpha = 0.6;
gameState.bricks.forEach((color, index) => { gameState.bricks.forEach((color, index) => {
@ -158,7 +155,8 @@ export function render(gameState: GameState) {
drawFuzzyBall( drawFuzzyBall(
haloCanvasCtx, haloCanvasCtx,
color == "black" ? "#666" : color, color == "black" ? "#666" : color,
(gameState.brickWidth * 2) / haloScale, (gameState.brickWidth * (isOptionOn("extra_bright") ? 2 : 1)) /
haloScale,
x / haloScale, x / haloScale,
y / haloScale, y / haloScale,
); );
@ -175,24 +173,20 @@ export function render(gameState: GameState) {
x / haloScale, x / haloScale,
y / haloScale, y / haloScale,
); );
drawFuzzyBall( if (isOptionOn("extra_bright"))
haloCanvasCtx, drawFuzzyBall(
color, haloCanvasCtx,
(size * 4) / haloScale, color,
x / haloScale, (size * 4) / haloScale,
y / haloScale, x / haloScale,
); y / haloScale,
);
}); });
ctx.globalAlpha = 1; ctx.globalAlpha = 1;
ctx.globalCompositeOperation = "source-over"; ctx.globalCompositeOperation = "source-over";
ctx.drawImage(haloCanvas, 0, 0, width, height); ctx.drawImage(haloCanvas, 0, 0, width, height);
// Decides how brights the bg black parts can get
// ctx.globalAlpha = 0.2;
// ctx.globalCompositeOperation = "multiply";
// ctx.fillStyle = "black";
// ctx.fillRect(0, 0, width, height);
// Decides how dark the background black parts are when lit (1=black)
ctx.globalAlpha = 0.9; ctx.globalAlpha = 0.9;
ctx.globalCompositeOperation = "multiply"; ctx.globalCompositeOperation = "multiply";
if (level.svg && background.width && background.complete) { if (level.svg && background.width && background.complete) {
@ -203,6 +197,8 @@ export function render(gameState: GameState) {
const bgctx = backgroundCanvas.getContext( const bgctx = backgroundCanvas.getContext(
"2d", "2d",
) as CanvasRenderingContext2D; ) as CanvasRenderingContext2D;
bgctx.globalCompositeOperation = "source-over";
bgctx.fillStyle = level.color || "#000"; bgctx.fillStyle = level.color || "#000";
bgctx.fillRect(0, 0, gameState.canvasWidth, gameState.canvasHeight); bgctx.fillRect(0, 0, gameState.canvasWidth, gameState.canvasHeight);
if (gameState.perks.clairvoyant >= 3) { if (gameState.perks.clairvoyant >= 3) {
@ -227,12 +223,14 @@ export function render(gameState: GameState) {
} else { } else {
const pattern = ctx.createPattern(background, "repeat"); const pattern = ctx.createPattern(background, "repeat");
if (pattern) { if (pattern) {
bgctx.globalCompositeOperation = "screen";
bgctx.fillStyle = pattern; bgctx.fillStyle = pattern;
bgctx.fillRect(0, 0, width, height); bgctx.fillRect(0, 0, width, height);
} }
} }
} }
ctx.globalCompositeOperation = "darken";
ctx.drawImage(backgroundCanvas, 0, 0); ctx.drawImage(backgroundCanvas, 0, 0);
} else { } else {
// Background not loaded yes // Background not loaded yes
@ -264,19 +262,22 @@ export function render(gameState: GameState) {
Math.sin(Date.now() + 36) * amplitude, Math.sin(Date.now() + 36) * amplitude,
); );
} }
if (gameState.perks.bigger_explosions && !isOptionOn("basic") && shaked) { // if (gameState.perks.bigger_explosions && !isOptionOn("basic") && shaked) {
gameCanvas.style.filter = // gameCanvas.style.filter =
"brightness(" + (1 + 100 / (1 + lastExplosionDelay)) + ")"; // "brightness(" + (1 + 100 / (1 + lastExplosionDelay)) + ")";
} else { // } else {
gameCanvas.style.filter = ""; // gameCanvas.style.filter = "";
} // }
// Coins // Coins
ctx.globalAlpha = 1; ctx.globalAlpha = 1;
forEachLiveOne(gameState.coins, (coin) => { forEachLiveOne(gameState.coins, (coin) => {
// ctx.globalCompositeOperation = "source-over"; // ctx.globalCompositeOperation = "source-over";
ctx.globalCompositeOperation = isOptionOn("opaque_coins") ctx.globalCompositeOperation =
? "source-over" coin.color === "gold" ||
: "screen"; level.color !== "#000000" ||
isOptionOn("opaque_coins")
? "source-over"
: "screen";
// ctx.globalCompositeOperation = // ctx.globalCompositeOperation =
// coin.color === "gold" || level.color ? "source-over" : "screen"; // coin.color === "gold" || level.color ? "source-over" : "screen";
drawCoin( drawCoin(