Build 29126551

This commit is contained in:
Renan LE CARO 2025-05-18 20:31:58 +02:00
parent 4c135968e0
commit 810df5962a
20 changed files with 295 additions and 69 deletions

View file

@ -14,9 +14,15 @@ Break colourful bricks, catch bouncing coins and select powerful upgrades !
# Changelog
## To do
- picky eater : +1 combo per color on screen per brick
-
## Done
- picky eater : +1 combo per color on screen per brick
- New perk : wrap up - balls touching the top of the screen teleport just above your paddle, aiming upward
- credits for icons levels
- transparency makes steering level 2 line transparent too
## 29123607
- updated icons for pierce_color,slow_down,extra_life,yoyo, one_more_choice,zen, ghost coin
- added levels Lotus flower,Zen monk, Piñata
- fixed level A Very Dangerous High Five

View file

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

File diff suppressed because one or more lines are too long

55
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.
const VERSION = "29123607";
const VERSION = "29126551";
// The name of the cache
const CACHE_NAME = `breakout-71-${VERSION}`;

View file

@ -149,6 +149,12 @@
"bricks": "__________t__W_tt_WWW_t__W_ttt______",
"credit": ""
},
{
"name": "icon:extra_life",
"size": 5,
"bricks": "_W_W_WGWGWWGGGW_WGW___W__",
"credit": "By Noodlemire"
},
{
"name": "icon:forgiving",
"size": 8,
@ -263,6 +269,12 @@
"bricks": "gggggggggggggggggggggg______ggggg____ggg_g_gggg_g___gg__gg____g____g____g____g_____g__g_______gg____",
"credit": ""
},
{
"name": "icon:one_more_choice",
"size": 6,
"bricks": "WW____WGG___WGWW___GWGG___WGG____GG_",
"credit": "By Noodlemire"
},
{
"name": "icon:ottawa_treaty",
"size": 8,
@ -402,10 +414,10 @@
"credit": ""
},
{
"name": "Big turtle",
"size": 10,
"bricks": "_____________kk_______kkkk_____kkkkkkGG__kkkkkkGBG_kkkkkkGGGGkkkkkkGG__GGGGGG____GG__GG_____________",
"credit": ""
"name": "icon:slow_down",
"size": 6,
"bricks": "________k_G__kkkBG_kkkGGGGGG___G_G__",
"credit": "By Noodlemire"
},
{
"name": "icon:smaller_puck",
@ -539,6 +551,30 @@
"bricks": "___W_____b_____b_____y_____y_____b_____b____WWW__",
"credit": ""
},
{
"name": "icon:wrap_up",
"size": 8,
"bricks": "___y__b___b__b____b__b___b__b____b__b___b__b____b__y____WWW_____",
"credit": ""
},
{
"name": "icon:yoyo",
"size": 5,
"bricks": "_GGG_GGGGG_WWW_GWGGG_GWG_",
"credit": "By Noodlemire"
},
{
"name": "icon:zen",
"size": 7,
"bricks": "___t___t_btb_tbtbtbtbtbtbtbtttbrbtt_trBrt____r___",
"credit": "By Noodlemire"
},
{
"name": "Big turtle",
"size": 10,
"bricks": "_____________kk_______kkkk_____kkkkkkGG__kkkkkkGBG_kkkkkkGGGGkkkkkkGG__GGGGGG____GG__GG_____________",
"credit": ""
},
{
"name": "Big yoyo",
"size": 8,
@ -1536,59 +1572,21 @@
"credit": "https://www.gog.com/en/game/teleglitch_die_more_edition"
},
{
"color": "#000000",
"name": "Piñata",
"size": 11,
"bricks": "____OOO______OSOBOSO___SOO___OOS__OSS_b_SSO___O_y_b_O____b___y__y____y____y___y_b__y_b___b___b____yy__y___y_b___b___b____",
"name": "Piñata",
"credit": "By Obigre"
},
{
"color": "#000000",
"name": "Zen monk",
"size": 7,
"bricks": "_ee__B__ee_B_BOOOO_e_SOOOOO_SSeO___OOSSS__SSSSO__",
"name": "Zen monk",
"credit": "By Obigre"
},
{
"color": "#000000",
"size": 7,
"bricks": "___t___t_btb_tbtbtbtbtbtbtbtttbrbtt_trBrt____r___",
"name": "icon:zen",
"credit": "By Noodlemire"
},
{
"color": "#000000",
"name": "Lotus flower",
"size": 9,
"bricks": "____t_____tBbtbBt__tbtttbt_bbbtttbbbBbbtttbbBtttbtbttt___RBR_______R________R____",
"name": "Lotus flower",
"credit": "A little bit bigger than the Zen icon, by Obigre"
},
{
"color": "#000000",
"size": 6,
"bricks": "________k_G__kkkBG_kkkGGGGGG___G_G__",
"name": "icon:slow_down",
"credit": "By Noodlemire"
},
{
"color": "#000000",
"size": 5,
"bricks": "_W_W_WGWGWWGGGW_WGW___W__",
"name": "icon:extra_life",
"credit": "By Noodlemire"
},
{
"color": "#000000",
"size": 5,
"bricks": "_GGG_GGGGG_WWW_GWGGG_GWG_",
"name": "icon:yoyo",
"credit": "By Noodlemire"
},
{
"color": "#000000",
"size": 6,
"bricks": "WW____WGG___WGWW___GWGG___WGG____GG_",
"name": "icon:one_more_choice",
"credit": "By Noodlemire"
}
]

View file

@ -1 +1 @@
"29123607"
"29126551"

View file

@ -14,6 +14,7 @@ import {
brickCenterX,
brickCenterY,
canvasCenterX,
countBrickColors,
currentLevelInfo,
distance2,
distanceBetween,
@ -27,6 +28,7 @@ import {
max_levels,
reachRedRowIndex,
shouldPierceByColor,
sumOfValues,
telekinesisEffectRate,
yoyoEffectRate,
zoneLeftBorderX,
@ -509,7 +511,6 @@ export function explodeBrick(
gameState.perks.left_is_lava +
gameState.perks.right_is_lava +
gameState.perks.top_is_lava +
gameState.perks.picky_eater +
gameState.perks.asceticism * 3 +
gameState.perks.passive_income +
gameState.perks.addiction;
@ -531,6 +532,10 @@ export function explodeBrick(
}
}
if (gameState.perks.picky_eater) {
comboGain += gameState.perks.picky_eater * countBrickColors(gameState);
}
if (redRowReach !== -1) {
if (Math.floor(index / gameState.level.size) === redRowReach) {
resetComboNeeeded = true;
@ -1261,6 +1266,10 @@ export function gameStateTick(
);
}
if (gameState.perks.wrap_up > 1 && hitBorder >= 2) {
applyWrapUp(gameState, coin, gameState.coinSize / 2);
}
if (
coin.previousY < gameState.gameZoneHeight &&
coin.y > gameState.gameZoneHeight &&
@ -1835,6 +1844,10 @@ export function ballTick(gameState: GameState, ball: Ball, frames: number) {
);
}
if (gameState.perks.wrap_up && borderHitCode >= 2) {
applyWrapUp(gameState, ball, gameState.ballSize / 2);
}
if (
gameState.perks.left_is_lava &&
borderHitCode % 2 &&
@ -1856,6 +1869,7 @@ export function ballTick(gameState: GameState, ball: Ball, frames: number) {
if (gameState.perks.top_is_lava && borderHitCode >= 2) {
resetCombo(gameState, ball.x, ball.y);
}
if (gameState.perks.trampoline) {
offsetCombo(gameState, -gameState.perks.trampoline, ball.x, ball.y);
}
@ -2394,3 +2408,26 @@ export function zenTick(gameState: GameState) {
);
}
}
function applyWrapUp(gameState: GameState, ball: Ball | Coin, radius) {
schedulGameSound(gameState, "plouf", ball.x, 1);
ball.y = gameState.gameZoneHeight - gameState.puckHeight - radius;
ball.x = clamp(
gameState.puckPosition,
gameState.offsetXRoundedDown + radius,
gameState.canvasWidth - gameState.offsetXRoundedDown - radius,
);
if (ball.vy > 0) {
ball.vy *= -1;
}
spawnParticlesExplosion(gameState, 7, ball.x, ball.y, "#6262EA");
spawnParticlesImplosion(
gameState,
7,
ball.previousX,
ball.previousY,
"#6262EA",
);
}

View file

@ -355,3 +355,14 @@ export function zoneLeftBorderX(gameState: GameState) {
export function zoneRightBorderX(gameState: GameState) {
return gameState.canvasWidth - gameState.offsetXRoundedDown + 1;
}
let countsCounterSet: Record<string, number> = {};
export function countBrickColors(gameState: GameState) {
for (let key in countsCounterSet) {
countsCounterSet[key] = 0;
}
gameState.bricks.forEach((brick) => {
if (brick && brick !== "black") countsCounterSet[brick] = 1;
});
return sumOfValues(countsCounterSet);
}

View file

@ -1,4 +1,4 @@
import { allLevels, icons, upgrades } from "./loadGameData";
import { allLevels, allLevelsAndIcons, icons, upgrades } from "./loadGameData";
import { t } from "./i18n/i18n";
import { asyncAlert } from "./asyncAlert";
import { miniMarkDown } from "./pure_functions";
@ -37,7 +37,7 @@ export function helpMenuEntry() {
`,
),
"<h2>" + t("help.levels") + "</h2>",
...allLevels
...allLevelsAndIcons
.filter((l) => l.credit?.trim())
.map(
(l) => `

View file

@ -474,6 +474,9 @@
"upgrades.wrap_right.name": "لف إلى اليمين",
"upgrades.wrap_right.tooltip": "ضرب الجانب الأيمن ينقل الكرة إلى الجانب الأيسر",
"upgrades.wrap_right.verbose_description": "يمكن نقل العملات المعدنية إلى المستويات الأعلى أيضًا.",
"upgrades.wrap_up.name": "اختتام",
"upgrades.wrap_up.tooltip": "سوف يؤدي لمس الجزء العلوي من الشاشة إلى نقل الكرة إلى ما فوق المضرب مباشرة.",
"upgrades.wrap_up.verbose_description": "لن يُحتسب هذا كضربة قرص. في المستوى الثاني، تنتقل العملات المعدنية أيضًا.",
"upgrades.yoyo.name": "يو يو",
"upgrades.yoyo.tooltip": "الكرة تسقط نحو المضرب",
"upgrades.yoyo.verbose_description": "إنه عكس التحريك الذهني، أي التحكم بالكرة أثناء سقوطها مرة أخرى إلى الأسفل.",

View file

@ -17127,6 +17127,116 @@
</concept_node>
</children>
</folder_node>
<folder_node>
<name>wrap_up</name>
<children>
<concept_node>
<name>name</name>
<description/>
<comment/>
<translations>
<translation>
<language>ar-LB</language>
<approved>false</approved>
</translation>
<translation>
<language>de-DE</language>
<approved>false</approved>
</translation>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-CL</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>false</approved>
</translation>
<translation>
<language>ru-RU</language>
<approved>false</approved>
</translation>
<translation>
<language>tr-TR</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>tooltip</name>
<description/>
<comment/>
<translations>
<translation>
<language>ar-LB</language>
<approved>false</approved>
</translation>
<translation>
<language>de-DE</language>
<approved>false</approved>
</translation>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-CL</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>false</approved>
</translation>
<translation>
<language>ru-RU</language>
<approved>false</approved>
</translation>
<translation>
<language>tr-TR</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>verbose_description</name>
<description/>
<comment/>
<translations>
<translation>
<language>ar-LB</language>
<approved>false</approved>
</translation>
<translation>
<language>de-DE</language>
<approved>false</approved>
</translation>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-CL</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>false</approved>
</translation>
<translation>
<language>ru-RU</language>
<approved>false</approved>
</translation>
<translation>
<language>tr-TR</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
</children>
</folder_node>
<folder_node>
<name>yoyo</name>
<children>

View file

@ -474,6 +474,9 @@
"upgrades.wrap_right.name": "Rechts umbrechen",
"upgrades.wrap_right.tooltip": "Wenn Sie die rechte Seite treffen, wird der Ball auf die linke Seite teleportiert",
"upgrades.wrap_right.verbose_description": "Höhere Level teleportieren auch Münzen.",
"upgrades.wrap_up.name": "Einpacken",
"upgrades.wrap_up.tooltip": "Durch Berühren der Oberseite des Bildschirms wird der Ball direkt über den Schläger teleportiert.",
"upgrades.wrap_up.verbose_description": "Dies zählt nicht als Pucktreffer. Auf Stufe 2 werden auch Münzen teleportiert.",
"upgrades.yoyo.name": "Yo-Yo",
"upgrades.yoyo.tooltip": "Ball fällt in Richtung Paddel",
"upgrades.yoyo.verbose_description": "Es ist das Gegenteil von Telekinese, den Ball zu kontrollieren, während er wieder nach unten fällt.",

View file

@ -374,7 +374,7 @@
"upgrades.passive_income.verbose_description": "+{{lvl}} combo / brick broken, paddle is immaterial {{time}}s after moving. Some perks can help the balls do what you want without needing to do anything.",
"upgrades.picky_eater.name": "Picky eater",
"upgrades.picky_eater.tooltip": "More coins if you break bricks color by color",
"upgrades.picky_eater.verbose_description": "Whenever you break a brick the same color as your ball, your combo increases by one. \nIf it's a different color, the ball takes that new color, but the combo resets, unless there were no bricks left of the ball's color. \nOnce you get a combo higher than your minimum, the bricks of the wrong color will get a red border. \nIf you have more than one ball, they all switch color whenever one of them hits a brick.",
"upgrades.picky_eater.verbose_description": "Whenever you break a brick the same color as your ball, your combo increases by the number of colors on screen. \nIf it's a different color, the ball takes that new color, but the combo resets, unless there were no bricks left of the ball's color. \nOnce you get a combo higher than your minimum, the bricks of the wrong color will get a red border. \nIf you have more than one ball, they all switch color whenever one of them hits a brick.",
"upgrades.pierce.name": "Piercing",
"upgrades.pierce.tooltip": "Ball pierces {{count}} bricks after a paddle bounce",
"upgrades.pierce.verbose_description": "The ball normally bounces as soon as it touches something. With this perk, it will continue its trajectory for up to 3 bricks broken. \n\nAfter that, it will bounce on the 4th brick, and you'll need to touch the paddle to reset the counter.",
@ -474,6 +474,9 @@
"upgrades.wrap_right.name": "Wrap right",
"upgrades.wrap_right.tooltip": "Hitting the right side teleports the ball to the left side",
"upgrades.wrap_right.verbose_description": "Higher levels teleport coins too.",
"upgrades.wrap_up.name": "Wrap up",
"upgrades.wrap_up.tooltip": "Touching the top of the screen will teleport the ball just above the paddle.",
"upgrades.wrap_up.verbose_description": "This won't count as a puck hit. At level 2, coins teleport too. ",
"upgrades.yoyo.name": "Yo-yo",
"upgrades.yoyo.tooltip": "The ball falls toward the paddle",
"upgrades.yoyo.verbose_description": "It's the opposite of telekinesis, control the ball while it's falling back down.",

View file

@ -474,6 +474,9 @@
"upgrades.wrap_right.name": "Envolver a la derecha",
"upgrades.wrap_right.tooltip": "Golpear el lado derecho teletransporta la pelota al lado izquierdo.",
"upgrades.wrap_right.verbose_description": "Los niveles superiores también teletransportan monedas.",
"upgrades.wrap_up.name": "Envolver",
"upgrades.wrap_up.tooltip": "Al tocar la parte superior de la pantalla, la pelota se teletransportará justo por encima de la paleta.",
"upgrades.wrap_up.verbose_description": "Esto no cuenta como golpe de disco. En el nivel 2, las monedas también se teletransportan.",
"upgrades.yoyo.name": "Yo-Yo",
"upgrades.yoyo.tooltip": "La pelota desciende hacia la raqueta.",
"upgrades.yoyo.verbose_description": "Es lo contrario de la Telequinesis: controlar la pelota mientras cae hacia la raqueta.",

View file

@ -474,6 +474,9 @@
"upgrades.wrap_right.name": "Envelopper à droite",
"upgrades.wrap_right.tooltip": "Frapper le côté droit téléporte la balle vers le côté gauche",
"upgrades.wrap_right.verbose_description": "Les niveaux supérieurs téléportent également des pièces.",
"upgrades.wrap_up.name": "Conclure",
"upgrades.wrap_up.tooltip": "Toucher le haut de l'écran téléportera la balle juste au-dessus de la raquette.",
"upgrades.wrap_up.verbose_description": "Cela ne compte pas comme un coup de rondelle. Au niveau 2, les pièces se téléportent également.",
"upgrades.yoyo.name": "Yo-yo",
"upgrades.yoyo.tooltip": "La balle se dirige vers la raquette en descendant.",
"upgrades.yoyo.verbose_description": "C'est l'inverse de Télékinésie, contrôlez la balle alors qu'elle redescend vers la raquette.",

View file

@ -474,6 +474,9 @@
"upgrades.wrap_right.name": "Обернуть вправо",
"upgrades.wrap_right.tooltip": "Удар по правой стороне телепортирует мяч на левую сторону.",
"upgrades.wrap_right.verbose_description": "Более высокие уровни также телепортируют монеты.",
"upgrades.wrap_up.name": "Заворачивать",
"upgrades.wrap_up.tooltip": "Прикосновение к верхней части экрана телепортирует мяч чуть выше ракетки.",
"upgrades.wrap_up.verbose_description": "Это не будет считаться попаданием шайбы. На уровне 2 монеты тоже телепортируются.",
"upgrades.yoyo.name": "Йо-йо",
"upgrades.yoyo.tooltip": "Мяч падает на лопатку",
"upgrades.yoyo.verbose_description": "Это противоположность телекинезу: управляйте мячом, пока он падает обратно.",

View file

@ -474,6 +474,9 @@
"upgrades.wrap_right.name": "Sağa doğru sarın",
"upgrades.wrap_right.tooltip": "Sağ tarafa vurmak topu sol tarafa ışınlar",
"upgrades.wrap_right.verbose_description": "Daha yüksek seviyelerde ışınlanma paraları da var.",
"upgrades.wrap_up.name": "Özetlemek gerekirse",
"upgrades.wrap_up.tooltip": "Ekranın üst kısmına dokunduğunuzda top, küreğin hemen üstüne ışınlanacaktır.",
"upgrades.wrap_up.verbose_description": "Bu bir disk vuruşu olarak sayılmaz. 2. seviyede, paralar da ışınlanır.",
"upgrades.yoyo.name": "Yo-yo",
"upgrades.yoyo.tooltip": "Top küreğe doğru düşer",
"upgrades.yoyo.verbose_description": "Telekinezinin tam tersi, topun aşağı düşerken kontrol edilmesi.",

View file

@ -425,7 +425,8 @@ export function render(gameState: GameState) {
ctx.lineWidth = 2;
ctx.setLineDash(emptyArray);
}
ctx.globalAlpha = 1;
ctx.globalAlpha = ballAlpha;
if (
(gameState.perks.clairvoyant && gameState.ballStickToPuck) ||
(gameState.perks.steering > 1 && !gameState.ballStickToPuck)

View file

@ -969,4 +969,15 @@ export const rawUpgrades = [
help: (lvl: number) => t("upgrades.steering.tooltip"),
fullHelp: (lvl: number) => t("upgrades.steering.verbose_description"),
},
{
category: categories.advanced,
requires: "",
threshold: 255000,
gift: false,
id: "wrap_up",
max: 1,
name: t("upgrades.wrap_up.name"),
help: (lvl: number) => t("upgrades.wrap_up.tooltip"),
fullHelp: (lvl: number) => t("upgrades.wrap_up.verbose_description"),
},
] as const;