This commit is contained in:
Renan LE CARO 2025-04-29 16:10:24 +02:00
parent 08a61d6967
commit d17eba50e5
24 changed files with 711 additions and 1028 deletions

View file

@ -25,7 +25,8 @@ Break colourful bricks, catch bouncing coins and select powerful upgrades !
- you can pick an upgrade multiple time to level it up - you can pick an upgrade multiple time to level it up
- missed challenges show as greyed out choices (with unlock condition). - missed challenges show as greyed out choices (with unlock condition).
- bigger "level X or Y cleared", continue to level X/Y as button - bigger "level X or Y cleared", continue to level X/Y as button
- lives = upgrade points
- instead of bouncing the ball,loosing a life pauses the game (with coins still in the air)
## Done ## Done

524
dist/index.html vendored

File diff suppressed because one or more lines are too long

View file

@ -102,6 +102,9 @@ export async function asyncAlert<t>({
popup.appendChild(addto); popup.appendChild(addto);
} }
const buttonWrap = document.createElement("div")
addto.appendChild(buttonWrap)
const { const {
text, text,
value, value,
@ -134,16 +137,16 @@ ${icon}
} }
button.className = button.className =
className + (lastClickedItemIndex === index ? " needs-focus" : ""); className + (lastClickedItemIndex === index ? " needs-focus" : "")+' choice-button';
addto.appendChild(button); buttonWrap.appendChild(button);
if (tooltip) { if (tooltip) {
if (isOptionOn("mobile-mode")) { if (isOptionOn("mobile-mode")) {
const helpBtn = document.createElement("button"); const helpBtn = document.createElement("button");
helpBtn.innerText = "?"; helpBtn.innerText = "?";
helpBtn.setAttribute("data-help-content", tooltip); helpBtn.setAttribute("data-help-content", tooltip);
button.appendChild(helpBtn); buttonWrap.appendChild(helpBtn);
} else { } else {
button.setAttribute("data-tooltip", tooltip); button.setAttribute("data-tooltip", tooltip);
} }

View file

@ -149,12 +149,6 @@
"bricks": "__________t__W_tt_WWW_t__W_ttt______", "bricks": "__________t__W_tt_WWW_t__W_ttt______",
"credit": "" "credit": ""
}, },
{
"name": "icon:extra_life",
"size": 9,
"bricks": "___________GG_WG___GGWWGGW_GGWWGGWWGGWWGGWWGG_WGGWWGG___GWWGG_____WGG_______G____",
"credit": ""
},
{ {
"name": "icon:forgiving", "name": "icon:forgiving",
"size": 8, "size": 8,

View file

@ -55,12 +55,25 @@ canvas:not(#game) {
&:hover, &:hover,
&:focus { &:focus {
background: white; background: rgba(255, 255, 255, 0.2);
color: black; color: white;
cursor: pointer; cursor: pointer;
} }
text-shadow: 0 0 4px var(--level-background); text-shadow: 0 0 4px var(--level-background);
&.button-look {
// Look more like buttons for begginer to understand they are clickable
text-shadow: none;
background: #000000d6;
border: 1px solid #fff;
border-radius: 5px;
margin: 5px;
padding: 0 6px;
line-height: 20px;
box-shadow: 0 2px #fff;
}
} }
#score { #score {
@ -142,7 +155,11 @@ body:not(.has-alert-open) #popup {
flex-direction: column; flex-direction: column;
align-items: stretch; align-items: stretch;
> button { > div {
display: flex;
& > button.choice-button {
flex-grow: 1;
font: inherit; font: inherit;
background: rgba(0, 0, 0, 0.8); background: rgba(0, 0, 0, 0.8);
color: white; color: white;
@ -161,13 +178,16 @@ body:not(.has-alert-open) #popup {
z-index: 1; z-index: 1;
} }
&[disabled] { &[disabled]:not(.no-border) {
opacity: 0.5; opacity: 0.5;
filter: saturate(0); filter: saturate(0);
//pointer-events: none;
cursor: not-allowed; cursor: not-allowed;
} }
&.no-border{
border-color: transparent;
}
& > div { & > div {
flex-grow: 1; flex-grow: 1;
} }
@ -191,10 +211,12 @@ body:not(.has-alert-open) #popup {
} }
} }
button[data-help-content] { }
> button[data-help-content] {
border-radius: 4px; border-radius: 4px;
outline: none; outline: none;
align-self: flex-start; align-self: center;
width: 30px; width: 30px;
height: 30px; height: 30px;
background: #5da3ea; background: #5da3ea;
@ -205,6 +227,7 @@ body:not(.has-alert-open) #popup {
flex-shrink: 0; flex-shrink: 0;
font-weight: bold; font-weight: bold;
font-size: 22px; font-size: 22px;
margin: 5px;
} }
} }
} }
@ -412,6 +435,7 @@ h2.histogram-title strong {
top: -3px; top: -3px;
font-weight: bold; font-weight: bold;
border: 1px solid #FFF; border: 1px solid #FFF;
margin-left: 5px;
> span { > span {
display: inline-block; display: inline-block;
@ -442,9 +466,21 @@ h2.histogram-title strong {
transform: skewX(-10deg) transform: skewX(-10deg)
} }
} }
}
&.capped {
> span:first-child {
color: #FFF;
background: #000;
} }
> span:last-child::before {
width: 1px;
background: white;
}
}
} }
&.used { &.used {

View file

@ -1,22 +1,5 @@
import { import {allLevels, allLevelsAndIcons, appVersion, icons, upgrades,} from "./loadGameData";
allLevels, import {Ball, Coin, GameState, LightFlash, OptionId, ParticleFlash, PerksMap, RunParams, TextFlash,} from "./types";
allLevelsAndIcons,
appVersion,
icons,
upgrades,
} from "./loadGameData";
import {
Ball,
Coin,
GameState,
LightFlash,
OptionId,
ParticleFlash,
PerkId,
PerksMap,
RunParams,
TextFlash,
} from "./types";
import {getAudioContext, playPendingSounds} from "./sounds"; import {getAudioContext, playPendingSounds} from "./sounds";
import { import {
currentLevelInfo, currentLevelInfo,
@ -24,9 +7,6 @@ import {
getRowColIndex, getRowColIndex,
highScoreText, highScoreText,
hoursSpentPlaying, hoursSpentPlaying,
levelsListHTMl,
max_levels,
pickedUpgradesHTMl,
sample, sample,
sumOfValues, sumOfValues,
} from "./game_utils"; } from "./game_utils";
@ -47,45 +27,15 @@ import {
gameStateTick, gameStateTick,
liveCount, liveCount,
normalizeGameState, normalizeGameState,
pickRandomUpgrades,
setLevel, setLevel,
setMousePos, setMousePos,
} from "./gameStateMutators"; } from "./gameStateMutators";
import { import {backgroundCanvas, gameCanvas, getHaloScale, haloCanvas, render, scoreDisplay,} from "./render";
backgroundCanvas, import {pauseRecording, recordOneFrame, resumeRecording, startRecordingGame,} from "./recording";
gameCanvas,
getHaloScale,
haloCanvas,
render,
scoreDisplay,
} from "./render";
import {
pauseRecording,
recordOneFrame,
resumeRecording,
startRecordingGame,
} from "./recording";
import {newGameState} from "./newGameState"; import {newGameState} from "./newGameState";
import { import {alertsOpen, asyncAlert, AsyncAlertAction, closeModal,} from "./asyncAlert";
alertsOpen,
asyncAlert,
AsyncAlertAction,
closeModal,
requiredAsyncAlert,
} from "./asyncAlert";
import {isOptionOn, options, toggleOption} from "./options"; import {isOptionOn, options, toggleOption} from "./options";
import { import {clamp, miniMarkDown,} from "./pure_functions";
catchRateBest,
catchRateGood,
clamp,
levelTimeBest,
levelTimeGood,
miniMarkDown,
missesBest,
missesGood,
wallBouncedBest,
wallBouncedGood,
} from "./pure_functions";
import {helpMenuEntry} from "./help"; import {helpMenuEntry} from "./help";
import {creativeMode} from "./creative"; import {creativeMode} from "./creative";
import {hideAnyTooltip, setupTooltips} from "./tooltip"; import {hideAnyTooltip, setupTooltips} from "./tooltip";
@ -94,7 +44,7 @@ import "./migrations";
import {getHistory} from "./gameOver"; import {getHistory} from "./gameOver";
import {generateSaveFileContent} from "./generateSaveFileContent"; import {generateSaveFileContent} from "./generateSaveFileContent";
import {runHistoryViewerMenuEntry} from "./runHistoryViewer"; import {runHistoryViewerMenuEntry} from "./runHistoryViewer";
import { getNearestUnlockHTML, openScorePanel } from "./openScorePanel"; import {openScorePanel} from "./openScorePanel";
import {monitorLevelsUnlocks} from "./monitorLevelsUnlocks"; import {monitorLevelsUnlocks} from "./monitorLevelsUnlocks";
import {levelEditorMenuEntry} from "./levelEditor"; import {levelEditorMenuEntry} from "./levelEditor";
import {categories} from "./upgrades"; import {categories} from "./upgrades";
@ -131,8 +81,6 @@ export function pause(playerAskedForPause: boolean) {
pauseRecording(); pauseRecording();
gameState.pauseTimeout = null; gameState.pauseTimeout = null;
// document.body.className = gameState.running ? " running " : " paused ";
scoreDisplay.className = "";
gameState.needsRender = true; gameState.needsRender = true;
}; };
@ -249,122 +197,6 @@ setInterval(() => {
fitSize(gameState); fitSize(gameState);
}, 1000); }, 1000);
export async function openUpgradesPicker(gameState: GameState) {
const catchRate =
gameState.levelCoughtCoins / (gameState.levelSpawnedCoins || 1);
let repeats = 1;
let timeGain = "",
catchGain = "",
wallHitsGain = "",
missesGain = "";
if (gameState.levelWallBounces < wallBouncedBest) {
repeats++;
gameState.rerolls++;
wallHitsGain = t("level_up.plus_one_upgrade_and_reroll");
} else if (gameState.levelWallBounces < wallBouncedGood) {
repeats++;
wallHitsGain = t("level_up.plus_one_upgrade");
}
if (gameState.levelTime < levelTimeBest * 1000) {
repeats++;
gameState.rerolls++;
timeGain = t("level_up.plus_one_upgrade_and_reroll");
} else if (gameState.levelTime < levelTimeGood * 1000) {
repeats++;
timeGain = t("level_up.plus_one_upgrade");
}
if (catchRate > catchRateBest / 100) {
repeats++;
gameState.rerolls++;
catchGain = t("level_up.plus_one_upgrade_and_reroll");
} else if (catchRate > catchRateGood / 100) {
repeats++;
catchGain = t("level_up.plus_one_upgrade");
}
if (gameState.levelMisses < missesBest) {
repeats++;
gameState.rerolls++;
missesGain = t("level_up.plus_one_upgrade_and_reroll");
} else if (gameState.levelMisses < missesGood) {
repeats++;
missesGain = t("level_up.plus_one_upgrade");
}
while (repeats--) {
const actions: Array<{
text: string;
icon: string;
value: PerkId | "reroll";
help: string;
className: string;
tooltip: string;
}> = pickRandomUpgrades(gameState, 3 + gameState.perks.one_more_choice);
if (!actions.length) break;
if (gameState.rerolls)
actions.push({
text: t("level_up.reroll", { count: gameState.rerolls }),
help: t("level_up.reroll_help"),
value: "reroll" as const,
icon: icons["icon:reroll"],
});
const compliment =
(timeGain &&
catchGain &&
missesGain &&
wallHitsGain &&
t("level_up.compliment_perfect")) ||
((timeGain || catchGain || missesGain || wallHitsGain) &&
t("level_up.compliment_good")) ||
t("level_up.compliment_advice");
const upgradeId = await requiredAsyncAlert<PerkId | "reroll">({
title:
t("level_up.pick_upgrade_title") +
(repeats ? " (" + (repeats + 1) + ")" : ""),
content: [
`<p>${t("level_up.before_buttons", {
score: gameState.levelCoughtCoins,
catchGain,
levelSpawnedCoins: gameState.levelSpawnedCoins,
time: Math.round(gameState.levelTime / 1000),
timeGain,
levelMisses: gameState.levelMisses,
missesGain,
levelWallBounces: gameState.levelWallBounces,
wallHitsGain,
compliment,
})}
</p>
<p>${t("level_up.after_buttons", {
level: gameState.currentLevel + 1,
max: max_levels(gameState),
})} </p>
<p>${levelsListHTMl(gameState, gameState.currentLevel + 1)}</p>
`,
...actions,
pickedUpgradesHTMl(gameState),
getNearestUnlockHTML(gameState),
`<div id="level-recording-container"></div>`,
],
});
if (upgradeId === "reroll") {
repeats++;
gameState.rerolls--;
} else {
gameState.perks[upgradeId]++;
gameState.runStatistics.upgrades_picked++;
}
}
}
gameCanvas.addEventListener("mouseup", (e) => { gameCanvas.addEventListener("mouseup", (e) => {
if (e.button !== 0) return; if (e.button !== 0) return;
if (gameState.running) { if (gameState.running) {
@ -543,21 +375,33 @@ document.addEventListener("visibilitychange", () => {
pause(true); pause(true);
} }
}); });
if(getSettingValue('score-opened',0 )<3){
scoreDisplay.classList.add('button-look')
}
const menuDisplay = document.getElementById("menu") as HTMLButtonElement;
if(getSettingValue('menu-opened',0 )<3){
menuDisplay.classList.add('button-look')
}
function scoreOpen(e){ function scoreOpen(e){
e.preventDefault(); e.preventDefault();
if (!alertsOpen) { if (!alertsOpen) {
setSettingValue('score-opened',getSettingValue('score-opened',0 )+1 )
openScorePanel(gameState); openScorePanel(gameState);
} }
} }
scoreDisplay.addEventListener("click",scoreOpen); scoreDisplay.addEventListener("click",scoreOpen);
scoreDisplay.addEventListener("mousedown", scoreOpen); scoreDisplay.addEventListener("mousedown", scoreOpen);
(document.getElementById("menu") as HTMLButtonElement).addEventListener( menuDisplay.addEventListener(
"click", "click",
(e) => { (e) => {
e.preventDefault(); e.preventDefault();
if (!alertsOpen) { if (!alertsOpen) {
setSettingValue('menu-opened',getSettingValue('menu-opened',0 )+1 )
openMainMenu(); openMainMenu();
} }
}, },

View file

@ -6,7 +6,6 @@ import {
GameState, GameState,
LightFlash, LightFlash,
ParticleFlash, ParticleFlash,
PerkId,
ReusableArray, ReusableArray,
TextFlash, TextFlash,
} from "./types"; } from "./types";
@ -21,7 +20,6 @@ import {
getCoinRenderColor, getCoinRenderColor,
getCornerOffset, getCornerOffset,
getMajorityValue, getMajorityValue,
getPossibleUpgrades,
getRowColIndex, getRowColIndex,
isMovingWhilePassiveIncome, isMovingWhilePassiveIncome,
isPickyEatingPossible, isPickyEatingPossible,
@ -32,31 +30,17 @@ import {
yoyoEffectRate, yoyoEffectRate,
} from "./game_utils"; } from "./game_utils";
import {t} from "./i18n/i18n"; import {t} from "./i18n/i18n";
import { icons } from "./loadGameData";
import {getCurrentMaxCoins, getCurrentMaxParticles} from "./settings"; import {getCurrentMaxCoins, getCurrentMaxParticles} from "./settings";
import {background} from "./render"; import {background} from "./render";
import {gameOver} from "./gameOver"; import {gameOver} from "./gameOver";
import { import {brickIndex, fitSize, gameState, hasBrick, hitsSomething, pause, startComputerControlledGame,} from "./game";
brickIndex,
fitSize,
gameState,
hasBrick,
hitsSomething,
openUpgradesPicker,
pause,
startComputerControlledGame,
} from "./game";
import {stopRecording} from "./recording"; import {stopRecording} from "./recording";
import {isOptionOn} from "./options"; import {isOptionOn} from "./options";
import { import {ballTransparency, clamp, coinsBoostedCombo, comboKeepingRate,} from "./pure_functions";
ballTransparency,
clamp,
coinsBoostedCombo,
comboKeepingRate,
} from "./pure_functions";
import {addToTotalScore} from "./addToTotalScore"; import {addToTotalScore} from "./addToTotalScore";
import {hashCode} from "./getLevelBackground"; import {hashCode} from "./getLevelBackground";
import {openUpgradesPicker} from "./openUpgradesPicker";
export function setMousePos(gameState: GameState, x: number) { export function setMousePos(gameState: GameState, x: number) {
if (gameState.startParams.computer_controlled) return; if (gameState.startParams.computer_controlled) return;
@ -556,41 +540,6 @@ export function explodeBrick(
} }
} }
export function dontOfferTooSoon(gameState: GameState, id: PerkId) {
gameState.lastOffered[id] = Math.round(Date.now() / 1000);
}
export function pickRandomUpgrades(gameState: GameState, count: number) {
let list = getPossibleUpgrades(gameState)
.map((u) => ({
...u,
score: Math.random() + (gameState.lastOffered[u.id] || 0),
}))
.sort((a, b) => a.score - b.score)
.filter((u) => gameState.perks[u.id] < u.max + gameState.perks.limitless)
.slice(0, count)
.sort((a, b) => (a.id > b.id ? 1 : -1));
list.forEach((u) => {
dontOfferTooSoon(gameState, u.id);
});
return list.map((u) => ({
text:
u.name +
(gameState.perks[u.id]
? t("level_up.upgrade_perk_to_level", {
level: gameState.perks[u.id] + 1,
})
: ""),
icon: icons["icon:" + u.id],
value: u.id as PerkId,
help: u.help(gameState.perks[u.id] + 1),
className: "upgrade ",
tooltip: u.fullHelp(gameState.perks[u.id] + 1),
}));
}
export function schedulGameSound( export function schedulGameSound(
gameState: GameState, gameState: GameState,
sound: keyof GameState["aboutToPlaySound"], sound: keyof GameState["aboutToPlaySound"],
@ -654,12 +603,13 @@ export async function setLevel(gameState: GameState, l: number) {
gameState.upgradesOfferedFor = l; gameState.upgradesOfferedFor = l;
stopRecording(); stopRecording();
gameState.currentLevel = l;
gameState.level = gameState.runLevels[l % gameState.runLevels.length];
if (l > 0) { if (l > 0) {
await openUpgradesPicker(gameState); await openUpgradesPicker(gameState);
} }
gameState.currentLevel = l;
gameState.level = gameState.runLevels[l % gameState.runLevels.length];
gameState.levelTime = 0; gameState.levelTime = 0;
gameState.winAt = 0; gameState.winAt = 0;
@ -667,6 +617,7 @@ export async function setLevel(gameState: GameState, l: number) {
gameState.lastPuckMove = 0; gameState.lastPuckMove = 0;
gameState.lastZenComboIncrease = 0; gameState.lastZenComboIncrease = 0;
gameState.autoCleanUses = 0; gameState.autoCleanUses = 0;
gameState.lastTickDown = gameState.levelTime; gameState.lastTickDown = gameState.levelTime;
gameState.levelStartScore = gameState.score; gameState.levelStartScore = gameState.score;
gameState.levelSpawnedCoins = 0; gameState.levelSpawnedCoins = 0;
@ -1005,8 +956,8 @@ export function gameStateTick(
} }
} }
if ( if (( window.location.search.includes("skipplaying") ||
remainingBricks <= gameState.perks.skip_last && remainingBricks <= gameState.perks.skip_last) &&
!gameState.autoCleanUses !gameState.autoCleanUses
) { ) {
gameState.bricks.forEach((type, index) => { gameState.bricks.forEach((type, index) => {
@ -1819,7 +1770,7 @@ export function ballTick(gameState: GameState, ball: Ball, frames: number) {
ball.vy > 0 && ball.vy > 0 &&
(ballIsUnderPuck || (ballIsUnderPuck ||
(gameState.balls.length < 2 && (gameState.balls.length < 2 &&
gameState.perks.extra_life && gameState.extra_lives &&
ball.y > ylimit + gameState.puckHeight / 2)) ball.y > ylimit + gameState.puckHeight / 2))
) { ) {
if (ballIsUnderPuck) { if (ballIsUnderPuck) {
@ -2038,9 +1989,9 @@ export function ballTick(gameState: GameState, ball: Ball, frames: number) {
} }
function justLostALife(gameState: GameState, ball: Ball, x: number, y: number) { function justLostALife(gameState: GameState, ball: Ball, x: number, y: number) {
gameState.perks.extra_life -= 1; gameState.extra_lives -= 1;
if (gameState.perks.extra_life < 0) { if (gameState.extra_lives < 0) {
gameState.perks.extra_life = 0; gameState.extra_lives = 0;
} else if (gameState.perks.sacrifice) { } else if (gameState.perks.sacrifice) {
gameState.combo *= gameState.perks.sacrifice; gameState.combo *= gameState.perks.sacrifice;
gameState.bricks.forEach( gameState.bricks.forEach(

View file

@ -1,4 +1,4 @@
import { Ball, Coin, GameState, Level, PerkId, PerksMap } from "./types"; import {Ball, Coin, GameState, Level, PerkId, PerksMap, Upgrade} from "./types";
import {icons, upgrades} from "./loadGameData"; import {icons, upgrades} from "./loadGameData";
import {t} from "./i18n/i18n"; import {t} from "./i18n/i18n";
import {clamp} from "./pure_functions"; import {clamp} from "./pure_functions";
@ -99,6 +99,12 @@ export function max_levels(gameState: GameState) {
return 7 + gameState.perks.extra_levels; return 7 + gameState.perks.extra_levels;
} }
export function upgradeLevelAndMaxDisplay(upgrade: Upgrade, gameState: GameState) {
const lvl = gameState.perks[upgrade.id];
const max = upgrade.max + gameState.perks.limitless
return `<span class="level ${lvl < max ? 'can-upgrade' : 'capped'}"><span>${lvl}</span><span>${max}</span></span>`
}
export function pickedUpgradesHTMl(gameState: GameState) { export function pickedUpgradesHTMl(gameState: GameState) {
const upgradesList = getPossibleUpgrades(gameState) const upgradesList = getPossibleUpgrades(gameState)
.filter((u) => gameState.perks[u.id]) .filter((u) => gameState.perks[u.id])
@ -114,7 +120,7 @@ export function pickedUpgradesHTMl(gameState: GameState) {
${icons["icon:" + u.id]} ${icons["icon:" + u.id]}
<p> <p>
<strong>${u.name}</strong> <strong>${u.name}</strong>
<span class="level"><span>${gameState.perks[u.id]}</span><span>${newMax}</span></span> ${upgradeLevelAndMaxDisplay(u, gameState)}
${u.help(Math.max(1, gameState.perks[u.id]))} ${u.help(Math.max(1, gameState.perks[u.id]))}
</p> </p>
</div> </div>

View file

@ -16,7 +16,6 @@ function isExcluded(id: PerkId) {
if (!excluded) { if (!excluded) {
excluded = new Set([ excluded = new Set([
"extra_levels", "extra_levels",
"extra_life",
"one_more_choice", "one_more_choice",
"shunt", "shunt",
"slow_down", "slow_down",

View file

@ -68,17 +68,13 @@
"lab.reset": "إعادة ضبط", "lab.reset": "إعادة ضبط",
"lab.select_level": "حدد المستوى للعب عليه", "lab.select_level": "حدد المستوى للعب عليه",
"lab.unlocks_at": "يتم فتحه عند إجمالي النتيجة {{score}}", "lab.unlocks_at": "يتم فتحه عند إجمالي النتيجة {{score}}",
"level_up.after_buttons": "لقد انتهيت للتو من المستوى {{level}}/{{max}}.", "level_up.go": "",
"level_up.before_buttons": "لقد اصطدت {{score}} عملة {{catchGain}} من أصل {{levelSpawnedCoins}} في {{time}} ثانية {{timeGain}}.\n\nأخطأت {{levelMisses}} مرات {{missesGain}} واصطدمت بالجدران أو السقف {{levelWallBounces}} مرات{{wallHitsGain}}.\n{{compliment}}", "level_up.instructions": "",
"level_up.compliment_advice": "حاول التقاط جميع العملات المعدنية، ولا تفوت الطوب أبدًا، ولا تصطدم أبدًا بالجدران/السقف أو قم بتجاوز المستوى في أقل من 30 ثانية للحصول على ترقيات إضافية.", "level_up.maxed_upgrade": "",
"level_up.compliment_good": "أحسنت !", "level_up.no_points": "",
"level_up.compliment_perfect": "رائع، استمر في ذلك!", "level_up.pick_upgrade": "",
"level_up.pick_upgrade_title": "اختر ترقية", "level_up.title": "لقد انتهيت للتو من المستوى {{level}}/{{max}}.",
"level_up.plus_one_upgrade": "(+1 ترقية)", "level_up.upgrade_perk_to_level": "",
"level_up.plus_one_upgrade_and_reroll": "(+1 ترقية و+1 إعادة رمي)",
"level_up.reroll": "إعادة الرمي ({{count}})",
"level_up.reroll_help": "تقديم خيارات جديدة",
"level_up.upgrade_perk_to_level": "المستوى {{level}}",
"main_menu.basic": "", "main_menu.basic": "",
"main_menu.basic_help": "", "main_menu.basic_help": "",
"main_menu.colorful_coins": "", "main_menu.colorful_coins": "",
@ -161,8 +157,8 @@
"play.stats.levelTime": "وقت المستوى", "play.stats.levelTime": "وقت المستوى",
"play.stats.levelWallBounces": "ارتدادات الحائط", "play.stats.levelWallBounces": "ارتدادات الحائط",
"score_panel.close_to_unlock": "فتح المستوى التالي:", "score_panel.close_to_unlock": "فتح المستوى التالي:",
"score_panel.extra_lives_count": "",
"score_panel.get_upgrades_to_unlock": "احصل على {{missingUpgrades}} واحصل على {{points}} نقطة إضافية لفتح المستوى \"{{level}}\"", "score_panel.get_upgrades_to_unlock": "احصل على {{missingUpgrades}} واحصل على {{points}} نقطة إضافية لفتح المستوى \"{{level}}\"",
"score_panel.rerolls_count": "لقد جمعت {{rerolls}} إعادة تسجيل",
"score_panel.score_to_unlock": "احصل على {{points}} نقطة إضافية لفتح المستوى \"{{level}}\"", "score_panel.score_to_unlock": "احصل على {{points}} نقطة إضافية لفتح المستوى \"{{level}}\"",
"score_panel.title": "{{score}} نقطة في المستوى {{level}}/{{max}} ", "score_panel.title": "{{score}} نقطة في المستوى {{level}}/{{max}} ",
"score_panel.upcoming_levels": "المستويات القادمة :", "score_panel.upcoming_levels": "المستويات القادمة :",
@ -305,9 +301,6 @@
"upgrades.extra_levels.name": "5 دقائق إضافية", "upgrades.extra_levels.name": "5 دقائق إضافية",
"upgrades.extra_levels.tooltip": "العب {{count}} مستوى بدلاً من 7", "upgrades.extra_levels.tooltip": "العب {{count}} مستوى بدلاً من 7",
"upgrades.extra_levels.verbose_description": "يمكن أن تستمر اللعبة الافتراضية لسبعة مستويات كحد أقصى، تنتهي بعدها.\n\nيتيح لك كل مستوى من هذه الميزة الانتقال إلى مستوى أعلى. غالبًا ما تكون المستويات الأخيرة هي التي تحقق فيها أعلى النقاط، لذا قد يكون الفرق كبيرًا.", "upgrades.extra_levels.verbose_description": "يمكن أن تستمر اللعبة الافتراضية لسبعة مستويات كحد أقصى، تنتهي بعدها.\n\nيتيح لك كل مستوى من هذه الميزة الانتقال إلى مستوى أعلى. غالبًا ما تكون المستويات الأخيرة هي التي تحقق فيها أعلى النقاط، لذا قد يكون الفرق كبيرًا.",
"upgrades.extra_life.name": "حياة إضافية",
"upgrades.extra_life.tooltip": "سترتد الكرة مرة واحدة على الخط السفلي قبل أن تضيع.",
"upgrades.extra_life.verbose_description": "عادةً، لديك كرة واحدة، وتنتهي اللعبة بمجرد إسقاطها.\n\nتضيف هذه الميزة شريطًا أبيض أسفل الشاشة يحفظ الكرة مرة واحدة، ثم ينكسر أثناء ذلك.\n\nستخسر مستوى واحدًا من هذه الميزة في كل مرة ترتد فيها كرة أسفل الشاشة.",
"upgrades.forgiving.name": "غفور", "upgrades.forgiving.name": "غفور",
"upgrades.forgiving.tooltip": "يؤدي فقدان الفواصل إلى تقليل المجموعة تدريجيًا بدلاً من تقليلها دفعة واحدة.", "upgrades.forgiving.tooltip": "يؤدي فقدان الفواصل إلى تقليل المجموعة تدريجيًا بدلاً من تقليلها دفعة واحدة.",
"upgrades.forgiving.verbose_description": "أول خطأ في كل مستوى مجاني، ثم 10% من المجموعة، ثم 20% ..", "upgrades.forgiving.verbose_description": "أول خطأ في كل مستوى مجاني، ثم 10% من المجموعة، ثم 20% ..",

View file

@ -2493,7 +2493,42 @@
<name>level_up</name> <name>level_up</name>
<children> <children>
<concept_node> <concept_node>
<name>after_buttons</name> <name>go</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>instructions</name>
<description/> <description/>
<comment/> <comment/>
<translations> <translations>
@ -2528,7 +2563,7 @@
</translations> </translations>
</concept_node> </concept_node>
<concept_node> <concept_node>
<name>before_buttons</name> <name>maxed_upgrade</name>
<description/> <description/>
<comment/> <comment/>
<translations> <translations>
@ -2538,11 +2573,11 @@
</translation> </translation>
<translation> <translation>
<language>de-DE</language> <language>de-DE</language>
<approved>true</approved> <approved>false</approved>
</translation> </translation>
<translation> <translation>
<language>en-US</language> <language>en-US</language>
<approved>true</approved> <approved>false</approved>
</translation> </translation>
<translation> <translation>
<language>es-CL</language> <language>es-CL</language>
@ -2550,7 +2585,7 @@
</translation> </translation>
<translation> <translation>
<language>fr-FR</language> <language>fr-FR</language>
<approved>true</approved> <approved>false</approved>
</translation> </translation>
<translation> <translation>
<language>ru-RU</language> <language>ru-RU</language>
@ -2563,7 +2598,7 @@
</translations> </translations>
</concept_node> </concept_node>
<concept_node> <concept_node>
<name>compliment_advice</name> <name>no_points</name>
<description/> <description/>
<comment/> <comment/>
<translations> <translations>
@ -2573,11 +2608,11 @@
</translation> </translation>
<translation> <translation>
<language>de-DE</language> <language>de-DE</language>
<approved>true</approved> <approved>false</approved>
</translation> </translation>
<translation> <translation>
<language>en-US</language> <language>en-US</language>
<approved>true</approved> <approved>false</approved>
</translation> </translation>
<translation> <translation>
<language>es-CL</language> <language>es-CL</language>
@ -2585,7 +2620,7 @@
</translation> </translation>
<translation> <translation>
<language>fr-FR</language> <language>fr-FR</language>
<approved>true</approved> <approved>false</approved>
</translation> </translation>
<translation> <translation>
<language>ru-RU</language> <language>ru-RU</language>
@ -2598,7 +2633,7 @@
</translations> </translations>
</concept_node> </concept_node>
<concept_node> <concept_node>
<name>compliment_good</name> <name>pick_upgrade</name>
<description/> <description/>
<comment/> <comment/>
<translations> <translations>
@ -2608,11 +2643,11 @@
</translation> </translation>
<translation> <translation>
<language>de-DE</language> <language>de-DE</language>
<approved>true</approved> <approved>false</approved>
</translation> </translation>
<translation> <translation>
<language>en-US</language> <language>en-US</language>
<approved>true</approved> <approved>false</approved>
</translation> </translation>
<translation> <translation>
<language>es-CL</language> <language>es-CL</language>
@ -2620,7 +2655,7 @@
</translation> </translation>
<translation> <translation>
<language>fr-FR</language> <language>fr-FR</language>
<approved>true</approved> <approved>false</approved>
</translation> </translation>
<translation> <translation>
<language>ru-RU</language> <language>ru-RU</language>
@ -2633,182 +2668,7 @@
</translations> </translations>
</concept_node> </concept_node>
<concept_node> <concept_node>
<name>compliment_perfect</name> <name>title</name>
<description/>
<comment/>
<translations>
<translation>
<language>ar-LB</language>
<approved>false</approved>
</translation>
<translation>
<language>de-DE</language>
<approved>true</approved>
</translation>
<translation>
<language>en-US</language>
<approved>true</approved>
</translation>
<translation>
<language>es-CL</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>true</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>pick_upgrade_title</name>
<description/>
<comment/>
<translations>
<translation>
<language>ar-LB</language>
<approved>false</approved>
</translation>
<translation>
<language>de-DE</language>
<approved>true</approved>
</translation>
<translation>
<language>en-US</language>
<approved>true</approved>
</translation>
<translation>
<language>es-CL</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>true</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>plus_one_upgrade</name>
<description/>
<comment/>
<translations>
<translation>
<language>ar-LB</language>
<approved>false</approved>
</translation>
<translation>
<language>de-DE</language>
<approved>true</approved>
</translation>
<translation>
<language>en-US</language>
<approved>true</approved>
</translation>
<translation>
<language>es-CL</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>true</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>plus_one_upgrade_and_reroll</name>
<description/>
<comment/>
<translations>
<translation>
<language>ar-LB</language>
<approved>false</approved>
</translation>
<translation>
<language>de-DE</language>
<approved>true</approved>
</translation>
<translation>
<language>en-US</language>
<approved>true</approved>
</translation>
<translation>
<language>es-CL</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>true</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>reroll</name>
<description/>
<comment/>
<translations>
<translation>
<language>ar-LB</language>
<approved>false</approved>
</translation>
<translation>
<language>de-DE</language>
<approved>true</approved>
</translation>
<translation>
<language>en-US</language>
<approved>true</approved>
</translation>
<translation>
<language>es-CL</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>true</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>reroll_help</name>
<description/> <description/>
<comment/> <comment/>
<translations> <translations>
@ -5768,7 +5628,7 @@
</translations> </translations>
</concept_node> </concept_node>
<concept_node> <concept_node>
<name>get_upgrades_to_unlock</name> <name>extra_lives_count</name>
<description/> <description/>
<comment/> <comment/>
<translations> <translations>
@ -5778,11 +5638,11 @@
</translation> </translation>
<translation> <translation>
<language>de-DE</language> <language>de-DE</language>
<approved>true</approved> <approved>false</approved>
</translation> </translation>
<translation> <translation>
<language>en-US</language> <language>en-US</language>
<approved>true</approved> <approved>false</approved>
</translation> </translation>
<translation> <translation>
<language>es-CL</language> <language>es-CL</language>
@ -5790,7 +5650,7 @@
</translation> </translation>
<translation> <translation>
<language>fr-FR</language> <language>fr-FR</language>
<approved>true</approved> <approved>false</approved>
</translation> </translation>
<translation> <translation>
<language>ru-RU</language> <language>ru-RU</language>
@ -5803,7 +5663,7 @@
</translations> </translations>
</concept_node> </concept_node>
<concept_node> <concept_node>
<name>rerolls_count</name> <name>get_upgrades_to_unlock</name>
<description/> <description/>
<comment/> <comment/>
<translations> <translations>
@ -10927,116 +10787,6 @@
</concept_node> </concept_node>
</children> </children>
</folder_node> </folder_node>
<folder_node>
<name>extra_life</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>true</approved>
</translation>
<translation>
<language>en-US</language>
<approved>true</approved>
</translation>
<translation>
<language>es-CL</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>true</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>true</approved>
</translation>
<translation>
<language>en-US</language>
<approved>true</approved>
</translation>
<translation>
<language>es-CL</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>true</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>true</approved>
</translation>
<translation>
<language>en-US</language>
<approved>true</approved>
</translation>
<translation>
<language>es-CL</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>true</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> <folder_node>
<name>forgiving</name> <name>forgiving</name>
<children> <children>

View file

@ -68,17 +68,13 @@
"lab.reset": "Zurücksetzen", "lab.reset": "Zurücksetzen",
"lab.select_level": "Wähle ein Level zum Spielen", "lab.select_level": "Wähle ein Level zum Spielen",
"lab.unlocks_at": "Wird bei Gesamtpunktzahl {{score}} freigeschaltet", "lab.unlocks_at": "Wird bei Gesamtpunktzahl {{score}} freigeschaltet",
"level_up.after_buttons": "Du hast gerade Level {{level}}/{{max}} beendet.", "level_up.go": "",
"level_up.before_buttons": "Du hast {{score}} Münzen {{catchGain}} aus {{levelSpawnedCoins}} in {{time}} Sekunden {{timeGain}} gefangen.\n\nDu hast {{levelMisses}} Mal danebengeschossen {{missesGain}} und {{levelWallBounces}} Mal die Wände oder die Decke getroffen {{wallHitsGain}}.\n\n{{compliment}}", "level_up.instructions": "",
"level_up.compliment_advice": "Versuche, alle Münzen zu fangen, verpasse nie die Steine, stoße nie an die Wände/Decke oder schaffe das Level unter 30 Sekunden, um zusätzliche Upgrades zu erhalten.", "level_up.maxed_upgrade": "",
"level_up.compliment_good": "Gut gemacht!", "level_up.no_points": "",
"level_up.compliment_perfect": "Beeindruckend, machen Sie weiter so!", "level_up.pick_upgrade": "",
"level_up.pick_upgrade_title": "Wählen Sie ein Upgrade", "level_up.title": "Du hast gerade Level {{level}}/{{max}} beendet.",
"level_up.plus_one_upgrade": "(+1 Upgrade)", "level_up.upgrade_perk_to_level": "",
"level_up.plus_one_upgrade_and_reroll": "(+1 Upgrade und +1 Neuwurf)",
"level_up.reroll": "Neu würfeln ({{count}})",
"level_up.reroll_help": "Bietet neue Auswahl",
"level_up.upgrade_perk_to_level": " lvl {{level}}",
"main_menu.basic": "", "main_menu.basic": "",
"main_menu.basic_help": "", "main_menu.basic_help": "",
"main_menu.colorful_coins": "", "main_menu.colorful_coins": "",
@ -161,8 +157,8 @@
"play.stats.levelTime": "Zeit pro Level", "play.stats.levelTime": "Zeit pro Level",
"play.stats.levelWallBounces": "Wandaufpralle", "play.stats.levelWallBounces": "Wandaufpralle",
"score_panel.close_to_unlock": "Nächstes Level freischalten:", "score_panel.close_to_unlock": "Nächstes Level freischalten:",
"score_panel.extra_lives_count": "",
"score_panel.get_upgrades_to_unlock": "Hole {{missingUpgrades}} und erziele {{points}} mehr Punkte, um Level \"{{level}}\" freizuschalten.", "score_panel.get_upgrades_to_unlock": "Hole {{missingUpgrades}} und erziele {{points}} mehr Punkte, um Level \"{{level}}\" freizuschalten.",
"score_panel.rerolls_count": "Du hast {{rerolls}} Upgrades neugewürfelt",
"score_panel.score_to_unlock": "Erziele {{points}} mehr Punkte, um Level \"{{level}}\" freizuschalten.", "score_panel.score_to_unlock": "Erziele {{points}} mehr Punkte, um Level \"{{level}}\" freizuschalten.",
"score_panel.title": "{{score}} Punkte in Level {{level}}/{{max}} ", "score_panel.title": "{{score}} Punkte in Level {{level}}/{{max}} ",
"score_panel.upcoming_levels": "Kommende Level:", "score_panel.upcoming_levels": "Kommende Level:",
@ -305,9 +301,6 @@
"upgrades.extra_levels.name": "5 min mehr", "upgrades.extra_levels.name": "5 min mehr",
"upgrades.extra_levels.tooltip": "Spielen Sie {{count}} Stufen statt 7", "upgrades.extra_levels.tooltip": "Spielen Sie {{count}} Stufen statt 7",
"upgrades.extra_levels.verbose_description": "Das Standardspiel kann maximal 7 Stufen dauern, danach ist das Spiel vorbei.\n\nMit jeder Stufe dieses Vorteils können Sie eine Stufe höher gehen. Die letzten Level sind oft diejenigen, in denen man die meisten Punkte macht, so dass der Unterschied dramatisch sein kann.", "upgrades.extra_levels.verbose_description": "Das Standardspiel kann maximal 7 Stufen dauern, danach ist das Spiel vorbei.\n\nMit jeder Stufe dieses Vorteils können Sie eine Stufe höher gehen. Die letzten Level sind oft diejenigen, in denen man die meisten Punkte macht, so dass der Unterschied dramatisch sein kann.",
"upgrades.extra_life.name": "Extraleben",
"upgrades.extra_life.tooltip": "Der Ball prallt einmal auf der unteren Linie auf, bevor er verloren ist.",
"upgrades.extra_life.verbose_description": "Normalerweise hat man nur einen Ball, und das Spiel ist vorbei, sobald man ihn fallen lässt.\n\nDieser Vorteil fügt eine weiße Leiste am unteren Rand des Bildschirms hinzu, die einen Ball einmal speichert und dabei zerbricht.\n\nJedes Mal, wenn ein Ball am unteren Rand des Bildschirms aufprallt, verlierst du eine Stufe dieses Vorteils.",
"upgrades.forgiving.name": "Verzeihen", "upgrades.forgiving.name": "Verzeihen",
"upgrades.forgiving.tooltip": "Durch fehlende Pausen wird die Kombo schrittweise reduziert, anstatt auf einmal.", "upgrades.forgiving.tooltip": "Durch fehlende Pausen wird die Kombo schrittweise reduziert, anstatt auf einmal.",
"upgrades.forgiving.verbose_description": "Der erste Fehlschuss pro Level ist kostenlos, dann 10% der Combo, dann 20% ...", "upgrades.forgiving.verbose_description": "Der erste Fehlschuss pro Level ist kostenlos, dann 10% der Combo, dann 20% ...",

View file

@ -68,17 +68,13 @@
"lab.reset": "Reset", "lab.reset": "Reset",
"lab.select_level": "Select a level to play on", "lab.select_level": "Select a level to play on",
"lab.unlocks_at": "Unlocks at total score {{score}}", "lab.unlocks_at": "Unlocks at total score {{score}}",
"level_up.after_buttons": "You just finished level {{level}}/{{max}}.", "level_up.go": "Continue to level \"{{name}}\"",
"level_up.before_buttons": "You caught {{score}} coins {{catchGain}} out of {{levelSpawnedCoins}} in {{time}} seconds {{timeGain}}.\n\nYou missed {{levelMisses}} times {{missesGain}} and hit the walls or ceiling {{levelWallBounces}} times{{wallHitsGain}}.\n\n{{compliment}}", "level_up.instructions": "You can upgrade perks below using your {{count}} extra lives. ",
"level_up.compliment_advice": "Try to catch all coins, never miss the bricks, never hit the walls/ceiling or clear the level under 30s to gain additional upgrades.", "level_up.maxed_upgrade": "\"{{name}}\" is at max level",
"level_up.compliment_good": "Well done !", "level_up.no_points": "You've spent all your extra lives.",
"level_up.compliment_perfect": "Impressive, keep it up !", "level_up.pick_upgrade": "Get \"{{name}}\"",
"level_up.pick_upgrade_title": "Pick an upgrade", "level_up.title": "You just finished level {{level}}/{{max}}.",
"level_up.plus_one_upgrade": "(+1 upgrade)", "level_up.upgrade_perk_to_level": "Upgrade \"{{name}}\" to level {{level}}",
"level_up.plus_one_upgrade_and_reroll": "(+1 upgrade and +1 re-roll)",
"level_up.reroll": "Re-roll ({{count}})",
"level_up.reroll_help": "Offer new choices",
"level_up.upgrade_perk_to_level": " lvl {{level}}",
"main_menu.basic": "", "main_menu.basic": "",
"main_menu.basic_help": "", "main_menu.basic_help": "",
"main_menu.colorful_coins": "", "main_menu.colorful_coins": "",
@ -161,12 +157,12 @@
"play.stats.levelTime": "Level time", "play.stats.levelTime": "Level time",
"play.stats.levelWallBounces": "Wall bounces", "play.stats.levelWallBounces": "Wall bounces",
"score_panel.close_to_unlock": "Next level unlock :", "score_panel.close_to_unlock": "Next level unlock :",
"score_panel.extra_lives_count": "You have accumulated {{count}} upgrade points.",
"score_panel.get_upgrades_to_unlock": "Get {{missingUpgrades}} and score {{points}} more points to unlock level \"{{level}}\"", "score_panel.get_upgrades_to_unlock": "Get {{missingUpgrades}} and score {{points}} more points to unlock level \"{{level}}\"",
"score_panel.rerolls_count": "You have accumulated {{rerolls}} rerolls",
"score_panel.score_to_unlock": "Score {{points}} more points to unlock level \"{{level}}\"", "score_panel.score_to_unlock": "Score {{points}} more points to unlock level \"{{level}}\"",
"score_panel.title": "{{score}} points at level {{level}}/{{max}} ", "score_panel.title": "{{score}} points at level {{level}}/{{max}} ",
"score_panel.upcoming_levels": "Upcoming levels :", "score_panel.upcoming_levels": "Upcoming levels :",
"score_panel.upgrades_picked": "Upgrades picked in this game run : ", "score_panel.upgrades_picked": "Upgrades picked : ",
"settings.autoplay": "Auto play", "settings.autoplay": "Auto play",
"settings.autoplay_help": "Start a session with random upgrades and a computer controlled paddle", "settings.autoplay_help": "Start a session with random upgrades and a computer controlled paddle",
"settings.basic": "Basic graphics", "settings.basic": "Basic graphics",
@ -298,16 +294,13 @@
"upgrades.corner_shot.verbose_description": "Helps with aiming in the corners. Further levels let you go further out. ", "upgrades.corner_shot.verbose_description": "Helps with aiming in the corners. Further levels let you go further out. ",
"upgrades.double_or_nothing.name": "Double or nothing", "upgrades.double_or_nothing.name": "Double or nothing",
"upgrades.double_or_nothing.tooltip": "Combo climbs {{multiplier}} times faster, but you'll loose {{percent}}% of your score at each reset.", "upgrades.double_or_nothing.tooltip": "Combo climbs {{multiplier}} times faster, but you'll loose {{percent}}% of your score at each reset.",
"upgrades.double_or_nothing.verbose_description": "", "upgrades.double_or_nothing.verbose_description": "The combo reset only counts when your combo was above the minimum",
"upgrades.etherealcoins.name": "Coins, in Space", "upgrades.etherealcoins.name": "Coins, in Space",
"upgrades.etherealcoins.tooltip": "Coins are no longer affected by gravity", "upgrades.etherealcoins.tooltip": "Coins are no longer affected by gravity",
"upgrades.etherealcoins.verbose_description": "The coins will maintain their speed even after several bounces, and will no longer be affected by gravity.", "upgrades.etherealcoins.verbose_description": "The coins will maintain their speed even after several bounces, and will no longer be affected by gravity.",
"upgrades.extra_levels.name": "5 min more", "upgrades.extra_levels.name": "5 min more",
"upgrades.extra_levels.tooltip": "Play {{count}} levels instead of 7", "upgrades.extra_levels.tooltip": "Play {{count}} levels instead of 7",
"upgrades.extra_levels.verbose_description": "The default game can last a max of 7 levels, after which the game is over. \n\nEach level of this perk lets you go one level higher. The last levels are often the ones where you make the most score, so the difference can be dramatic.", "upgrades.extra_levels.verbose_description": "The default game can last a max of 7 levels, after which the game is over. \n\nEach level of this perk lets you go one level higher. The last levels are often the ones where you make the most score, so the difference can be dramatic.",
"upgrades.extra_life.name": "Extra Life",
"upgrades.extra_life.tooltip": "Saves your ball once",
"upgrades.extra_life.verbose_description": "Normally, you have one ball, and the game is over as soon as you drop it.\n\nThis perk adds a white bar at the bottom of the screen that will save a ball once, and break in the process. \n\nYou'll lose one level of that perk every time a ball bounces at the bottom of the screen.\n\nIf you have multiple balls, only the last one will be saved by the extra life. ",
"upgrades.forgiving.name": "Forgiving", "upgrades.forgiving.name": "Forgiving",
"upgrades.forgiving.tooltip": "Keep most of your combo when missing", "upgrades.forgiving.tooltip": "Keep most of your combo when missing",
"upgrades.forgiving.verbose_description": "The first miss per level is free, then 10% of the combo, then 20% .. ", "upgrades.forgiving.verbose_description": "The first miss per level is free, then 10% of the combo, then 20% .. ",

View file

@ -68,17 +68,13 @@
"lab.reset": "Reiniciar", "lab.reset": "Reiniciar",
"lab.select_level": "Selecciona un nivel para jugar", "lab.select_level": "Selecciona un nivel para jugar",
"lab.unlocks_at": "Desbloqueado a partir de una puntuación total de {{score}}.", "lab.unlocks_at": "Desbloqueado a partir de una puntuación total de {{score}}.",
"level_up.after_buttons": "Acabas de completar el nivel {{level}}/{{max}}.", "level_up.go": "",
"level_up.before_buttons": "Has cogido {{score}} monedas {{catchGain}} en {{levelSpawnedCoins}} en {{time}} segundos {{timeGain}}.\n\nHas fallado los ladrillos {{levelMisses}} veces {{missesGain}} y tocado los bordes del área de juego {{levelWallBounces}} veces {{wallHitsGain}}.\n\n{{compliment}}", "level_up.instructions": "",
"level_up.compliment_advice": "Intenta coger todas las piezas, no fallar nunca con los ladrillos, no tocar nunca las paredes o terminar el nivel en menos de 30 segundos para conseguir opciones extra y mejoras.", "level_up.maxed_upgrade": "",
"level_up.compliment_good": "¡Bien hecho!", "level_up.no_points": "",
"level_up.compliment_perfect": "Impresionante, ¡seguid así!", "level_up.pick_upgrade": "",
"level_up.pick_upgrade_title": "Elija una mejora", "level_up.title": "Acabas de completar el nivel {{level}}/{{max}}.",
"level_up.plus_one_upgrade": "(+1 mejora)", "level_up.upgrade_perk_to_level": "",
"level_up.plus_one_upgrade_and_reroll": "(+1 mejora y +1 relanzamiento)",
"level_up.reroll": "Relanzamiento ({{count}})",
"level_up.reroll_help": "Nuevas opciones",
"level_up.upgrade_perk_to_level": " nivel {{level}}",
"main_menu.basic": "Gráficos simplificados", "main_menu.basic": "Gráficos simplificados",
"main_menu.basic_help": "Mejor rendimiento.", "main_menu.basic_help": "Mejor rendimiento.",
"main_menu.colorful_coins": "Piezas de color", "main_menu.colorful_coins": "Piezas de color",
@ -161,8 +157,8 @@
"play.stats.levelTime": "Duración del nivel", "play.stats.levelTime": "Duración del nivel",
"play.stats.levelWallBounces": "Rebota en las paredes", "play.stats.levelWallBounces": "Rebota en las paredes",
"score_panel.close_to_unlock": "Siguiente nivel desbloqueado:", "score_panel.close_to_unlock": "Siguiente nivel desbloqueado:",
"score_panel.extra_lives_count": "",
"score_panel.get_upgrades_to_unlock": "Consigue {{missingUpgrades}} y coge {{points}} monedas extra para desbloquear el nivel \"{{level}}\".", "score_panel.get_upgrades_to_unlock": "Consigue {{missingUpgrades}} y coge {{points}} monedas extra para desbloquear el nivel \"{{level}}\".",
"score_panel.rerolls_count": "Has acumulado {{rerolls}} rerolls",
"score_panel.score_to_unlock": "Coge {{points}} monedas más para desbloquear el nivel \"{{level}}\".", "score_panel.score_to_unlock": "Coge {{points}} monedas más para desbloquear el nivel \"{{level}}\".",
"score_panel.title": "{{score}} puntos en {{level}}/{{max}} nivel", "score_panel.title": "{{score}} puntos en {{level}}/{{max}} nivel",
"score_panel.upcoming_levels": "Niveles de partido :", "score_panel.upcoming_levels": "Niveles de partido :",
@ -305,9 +301,6 @@
"upgrades.extra_levels.name": "5 minutos más", "upgrades.extra_levels.name": "5 minutos más",
"upgrades.extra_levels.tooltip": "Juega {{count}} niveles en lugar de 7", "upgrades.extra_levels.tooltip": "Juega {{count}} niveles en lugar de 7",
"upgrades.extra_levels.verbose_description": "El juego suele durar 7 niveles, tras los cuales se acaba la partida y la puntuación que hayas alcanzado es tu puntuación del juego.\n\nElegir esta mejora te permite prolongar el juego un nivel. Los últimos niveles suelen ser en los que más puntos consigues, así que la diferencia puede ser espectacular.", "upgrades.extra_levels.verbose_description": "El juego suele durar 7 niveles, tras los cuales se acaba la partida y la puntuación que hayas alcanzado es tu puntuación del juego.\n\nElegir esta mejora te permite prolongar el juego un nivel. Los últimos niveles suelen ser en los que más puntos consigues, así que la diferencia puede ser espectacular.",
"upgrades.extra_life.name": "Segunda oportunidad",
"upgrades.extra_life.tooltip": "La pelota rebota una vez antes de perderse.",
"upgrades.extra_life.verbose_description": "Normalmente, sólo tienes una bola por ronda, y la ronda termina en cuanto la sueltas.\n\nEsta habilidad añade una barra blanca en la parte inferior de la pantalla que guardará una bola una vez, y se romperá en el proceso.\n\nPuedes coger varias vidas por adelantado, que se usan cada vez que una bola está a punto de perderse.",
"upgrades.forgiving.name": "Errar es humano", "upgrades.forgiving.name": "Errar es humano",
"upgrades.forgiving.tooltip": "Perder los ladrillos significa perder una porción progresivamente mayor del combo", "upgrades.forgiving.tooltip": "Perder los ladrillos significa perder una porción progresivamente mayor del combo",
"upgrades.forgiving.verbose_description": " El primer ladrillo perdido por nivel no cuesta nada, el siguiente 10%, 20% y así sucesivamente.", "upgrades.forgiving.verbose_description": " El primer ladrillo perdido por nivel no cuesta nada, el siguiente 10%, 20% y así sucesivamente.",

View file

@ -68,17 +68,13 @@
"lab.reset": "Réinitialiser", "lab.reset": "Réinitialiser",
"lab.select_level": "Sélectionnez un niveau sur lequel jouer", "lab.select_level": "Sélectionnez un niveau sur lequel jouer",
"lab.unlocks_at": "Déverrouillé à partir d'un score total de {{score}}", "lab.unlocks_at": "Déverrouillé à partir d'un score total de {{score}}",
"level_up.after_buttons": "Vous venez de terminer le niveau {{level}}/{{max}}.", "level_up.go": "",
"level_up.before_buttons": "Vous avez attrapé {{score}} pièces {{catchGain}} sur {{levelSpawnedCoins}} en {{time}} secondes {{timeGain}}.\n\nVous avez raté les briques {{levelMisses}} fois {{missesGain}} et touché les bords de la zone de jeu {{levelWallBounces}} fois {{wallHitsGain}}.\n\n{{compliment}}", "level_up.instructions": "",
"level_up.compliment_advice": "Essayez d'attraper toutes les pièces, de ne jamais rater les briques, de ne pas toucher les murs ou de terminer le niveau en moins de 30 secondes pour obtenir des choix supplémentaires et des améliorations.", "level_up.maxed_upgrade": "",
"level_up.compliment_good": "Bravo !", "level_up.no_points": "",
"level_up.compliment_perfect": "Impressionnant, continuez comme ça !", "level_up.pick_upgrade": "",
"level_up.pick_upgrade_title": "Choisir une amélioration", "level_up.title": "Vous venez de terminer le niveau {{level}}/{{max}}.",
"level_up.plus_one_upgrade": "(+1 upgrade)", "level_up.upgrade_perk_to_level": "",
"level_up.plus_one_upgrade_and_reroll": "(+1 amélioration et +1 relance)",
"level_up.reroll": "Relancer ({{count}})",
"level_up.reroll_help": "Nouveaux choix",
"level_up.upgrade_perk_to_level": " niveau {{level}}",
"main_menu.basic": "", "main_menu.basic": "",
"main_menu.basic_help": "", "main_menu.basic_help": "",
"main_menu.colorful_coins": "", "main_menu.colorful_coins": "",
@ -161,12 +157,12 @@
"play.stats.levelTime": "Durée du niveau", "play.stats.levelTime": "Durée du niveau",
"play.stats.levelWallBounces": "Rebonds sur les murs", "play.stats.levelWallBounces": "Rebonds sur les murs",
"score_panel.close_to_unlock": "Prochain niveau débloqué : ", "score_panel.close_to_unlock": "Prochain niveau débloqué : ",
"score_panel.extra_lives_count": "",
"score_panel.get_upgrades_to_unlock": "Obtenez {{missingUpgrades}} et attrapez {{points}} pièces supplémentaires pour débloquer le niveau « {{level}} »", "score_panel.get_upgrades_to_unlock": "Obtenez {{missingUpgrades}} et attrapez {{points}} pièces supplémentaires pour débloquer le niveau « {{level}} »",
"score_panel.rerolls_count": "Vous avez accumulé {{rerolls}} rerolls",
"score_panel.score_to_unlock": "Attrapez {{points}} pièces supplémentaires pour débloquer le niveau « {{level}} »", "score_panel.score_to_unlock": "Attrapez {{points}} pièces supplémentaires pour débloquer le niveau « {{level}} »",
"score_panel.title": "{{score}} points au niveau {{level}}/{{max}} ", "score_panel.title": "{{score}} points au niveau {{level}}/{{max}} ",
"score_panel.upcoming_levels": "Niveaux de la parties : ", "score_panel.upcoming_levels": "Niveaux de la parties : ",
"score_panel.upgrades_picked": "Améliorations choisies pendant la partie :", "score_panel.upgrades_picked": "Améliorations choisies :",
"settings.autoplay": "Lecture automatique", "settings.autoplay": "Lecture automatique",
"settings.autoplay_help": "Démarrez une session avec des mises à niveau aléatoires et une pagaie contrôlée par ordinateur", "settings.autoplay_help": "Démarrez une session avec des mises à niveau aléatoires et une pagaie contrôlée par ordinateur",
"settings.basic": "Graphismes simplifiés", "settings.basic": "Graphismes simplifiés",
@ -305,9 +301,6 @@
"upgrades.extra_levels.name": "Encore 5 minutes", "upgrades.extra_levels.name": "Encore 5 minutes",
"upgrades.extra_levels.tooltip": "Jouer {{count}} niveaux au lieu de 7", "upgrades.extra_levels.tooltip": "Jouer {{count}} niveaux au lieu de 7",
"upgrades.extra_levels.verbose_description": "La partie dure normalement 7 niveaux, après quoi le jeu est terminé et le score que vous avez atteint est votre score de partie.\n\nChoisir cette amélioration vous permet de prolonger la partie d'un niveau. Les derniers niveaux sont souvent ceux où vous faites le plus de points, la différence peut donc être spectaculaire.", "upgrades.extra_levels.verbose_description": "La partie dure normalement 7 niveaux, après quoi le jeu est terminé et le score que vous avez atteint est votre score de partie.\n\nChoisir cette amélioration vous permet de prolonger la partie d'un niveau. Les derniers niveaux sont souvent ceux où vous faites le plus de points, la différence peut donc être spectaculaire.",
"upgrades.extra_life.name": "Seconde chance",
"upgrades.extra_life.tooltip": "La balle rebondit une fois avant d'être perdue.",
"upgrades.extra_life.verbose_description": "Normalement, vous n'avez qu'une seule balle par manche, et la manche est terminée dès que vous la laissez tomber.\n\nCette compétence ajoute une barre blanche en bas de l'écran qui sauvera une balle une fois, et se brisera au cours du processus.\n\nVous pouvez prendre plusieurs vies d'avances, elle seront utilisées à chaque fois qu'une balle est sur le point d'être perdue. ",
"upgrades.forgiving.name": "L'erreur est humaine", "upgrades.forgiving.name": "L'erreur est humaine",
"upgrades.forgiving.tooltip": "Rater les briques fait perdre un portion progressivement plu importante du combo", "upgrades.forgiving.tooltip": "Rater les briques fait perdre un portion progressivement plu importante du combo",
"upgrades.forgiving.verbose_description": " La première brique ratée par niveau ne coûte rien, la suivante 10%, 20%, etc.", "upgrades.forgiving.verbose_description": " La première brique ratée par niveau ne coûte rien, la suivante 10%, 20%, etc.",

View file

@ -68,17 +68,13 @@
"lab.reset": "Перезагрузить", "lab.reset": "Перезагрузить",
"lab.select_level": "Выберите уровень для игры", "lab.select_level": "Выберите уровень для игры",
"lab.unlocks_at": "Открывается при общем количестве очков {{score}}", "lab.unlocks_at": "Открывается при общем количестве очков {{score}}",
"level_up.after_buttons": "Вы только что закончили уровень {{level}}/{{max}}.", "level_up.go": "",
"level_up.before_buttons": "Вы поймали {{score}} монет {{catchGain}} из {{levelSpawnedCoins}} за {{time}} секунды {{timeGain}}.\n\nВы промахнулись {{levelMisses}} раз {{missesGain}} и ударились о стены или потолок {{levelWallBounces}} раз{{wallHitsGain}}.\n\n{{compliment}}", "level_up.instructions": "",
"level_up.compliment_advice": "Постарайтесь поймать все монеты, не промахнуться мимо кирпичей, не удариться о стены/потолок или пройти уровень за 30 секунд, чтобы получить дополнительные улучшения.", "level_up.maxed_upgrade": "",
"level_up.compliment_good": "Молодцы!", "level_up.no_points": "",
"level_up.compliment_perfect": "Впечатляет, продолжайте в том же духе!", "level_up.pick_upgrade": "",
"level_up.pick_upgrade_title": "Выберите обновление", "level_up.title": "Вы только что закончили уровень {{level}}/{{max}}.",
"level_up.plus_one_upgrade": "(+1 обновление)", "level_up.upgrade_perk_to_level": "",
"level_up.plus_one_upgrade_and_reroll": "(+1 улучшение и +1 повторный бросок)",
"level_up.reroll": "Повторный бросок ({{count}})",
"level_up.reroll_help": "Предложите новые варианты",
"level_up.upgrade_perk_to_level": " lvl {{level}}",
"main_menu.basic": "", "main_menu.basic": "",
"main_menu.basic_help": "", "main_menu.basic_help": "",
"main_menu.colorful_coins": "", "main_menu.colorful_coins": "",
@ -161,8 +157,8 @@
"play.stats.levelTime": "Время уровня", "play.stats.levelTime": "Время уровня",
"play.stats.levelWallBounces": "Отскоки от стены", "play.stats.levelWallBounces": "Отскоки от стены",
"score_panel.close_to_unlock": "Разблокировка следующего уровня:", "score_panel.close_to_unlock": "Разблокировка следующего уровня:",
"score_panel.extra_lives_count": "",
"score_panel.get_upgrades_to_unlock": "Наберите {{missingUpgrades}} и наберите {{points}} больше очков, чтобы разблокировать уровень \"{{level}}\"", "score_panel.get_upgrades_to_unlock": "Наберите {{missingUpgrades}} и наберите {{points}} больше очков, чтобы разблокировать уровень \"{{level}}\"",
"score_panel.rerolls_count": "Вы накопили {{rerolls}} повторных бросков",
"score_panel.score_to_unlock": "Наберите {{points}} больше очков, чтобы разблокировать уровень \"{{level}}\"", "score_panel.score_to_unlock": "Наберите {{points}} больше очков, чтобы разблокировать уровень \"{{level}}\"",
"score_panel.title": "{{score}} очков на уровне {{level}}/{{max}} ", "score_panel.title": "{{score}} очков на уровне {{level}}/{{max}} ",
"score_panel.upcoming_levels": "Предстоящие уровни :", "score_panel.upcoming_levels": "Предстоящие уровни :",
@ -305,9 +301,6 @@
"upgrades.extra_levels.name": "Еще 5 минут", "upgrades.extra_levels.name": "Еще 5 минут",
"upgrades.extra_levels.tooltip": "Играйте {{count}} уровней вместо 7", "upgrades.extra_levels.tooltip": "Играйте {{count}} уровней вместо 7",
"upgrades.extra_levels.verbose_description": "По умолчанию игра может длиться максимум 7 уровней, после чего игра заканчивается.\n\nКаждый уровень этой привилегии позволяет вам подняться на один уровень выше. Последние уровни часто являются теми, где вы набираете больше всего очков, так что разница может быть значительной.", "upgrades.extra_levels.verbose_description": "По умолчанию игра может длиться максимум 7 уровней, после чего игра заканчивается.\n\nКаждый уровень этой привилегии позволяет вам подняться на один уровень выше. Последние уровни часто являются теми, где вы набираете больше всего очков, так что разница может быть значительной.",
"upgrades.extra_life.name": "Экстра жизнь",
"upgrades.extra_life.tooltip": "Мяч отскочит один раз на нижнюю линию, после чего будет потерян.",
"upgrades.extra_life.verbose_description": "Обычно у вас один шар, и игра заканчивается, как только вы его бросите.\n\nЭто преимущество добавляет белую полоску в нижней части экрана, которая сохранит шарик один раз и разобьется в процессе.\n\nВы будете терять один уровень этого перка каждый раз, когда мяч будет отскакивать в нижнюю часть экрана.",
"upgrades.forgiving.name": "Прощение", "upgrades.forgiving.name": "Прощение",
"upgrades.forgiving.tooltip": "Пропущенные паузы уменьшают комбо постепенно, а не все сразу.", "upgrades.forgiving.tooltip": "Пропущенные паузы уменьшают комбо постепенно, а не все сразу.",
"upgrades.forgiving.verbose_description": "Первый промах за уровень - бесплатно, затем 10% от комбо, затем 20%.", "upgrades.forgiving.verbose_description": "Первый промах за уровень - бесплатно, затем 10% от комбо, затем 20%.",

View file

@ -68,17 +68,13 @@
"lab.reset": "Sıfırla", "lab.reset": "Sıfırla",
"lab.select_level": "Oynamak için bir seviye seçin", "lab.select_level": "Oynamak için bir seviye seçin",
"lab.unlocks_at": "Toplam puan {{score}}olduğunda açılır", "lab.unlocks_at": "Toplam puan {{score}}olduğunda açılır",
"level_up.after_buttons": " {{level}}/{{max}}seviyesini yeni bitirdiniz.", "level_up.go": "",
"level_up.before_buttons": " {{time}} saniyede {{levelSpawnedCoins}} üzerinden {{score}} jeton {{catchGain}} yakaladın {{timeGain}}.\n {{levelMisses}} kez {{missesGain}} ıskaladın ve {{levelWallBounces}} kez duvarlara veya tavana çarptın{{wallHitsGain}}.\n{{compliment}}", "level_up.instructions": "",
"level_up.compliment_advice": "Tüm paraları toplamaya çalışın, tuğlaları asla kaçırmayın, duvarlara/tavana çarpmayın veya ek yükseltmeler kazanmak için 30 saniyenin altındaki seviyeyi temizlemeyin.", "level_up.maxed_upgrade": "",
"level_up.compliment_good": "Tebrikler !", "level_up.no_points": "",
"level_up.compliment_perfect": "Çok etkileyici, böyle devam edin!", "level_up.pick_upgrade": "",
"level_up.pick_upgrade_title": "Bir yükseltme seçin", "level_up.title": " {{level}}/{{max}}seviyesini yeni bitirdiniz.",
"level_up.plus_one_upgrade": "(+1 yükseltme)", "level_up.upgrade_perk_to_level": "",
"level_up.plus_one_upgrade_and_reroll": "(+1 yükseltme ve +1 yeniden atma)",
"level_up.reroll": "Tekrar at ({{count}})",
"level_up.reroll_help": "Yeni seçenekler sunun",
"level_up.upgrade_perk_to_level": "Seviye {{level}}",
"main_menu.basic": "", "main_menu.basic": "",
"main_menu.basic_help": "", "main_menu.basic_help": "",
"main_menu.colorful_coins": "", "main_menu.colorful_coins": "",
@ -161,8 +157,8 @@
"play.stats.levelTime": "Seviye zamanı", "play.stats.levelTime": "Seviye zamanı",
"play.stats.levelWallBounces": "Duvar sıçramaları", "play.stats.levelWallBounces": "Duvar sıçramaları",
"score_panel.close_to_unlock": "Sonraki seviyenin kilidini aç:", "score_panel.close_to_unlock": "Sonraki seviyenin kilidini aç:",
"score_panel.extra_lives_count": "",
"score_panel.get_upgrades_to_unlock": " {{missingUpgrades}} alın ve \"{{level}}\" seviyesinin kilidini açmak için {{points}} puan daha kazanın", "score_panel.get_upgrades_to_unlock": " {{missingUpgrades}} alın ve \"{{level}}\" seviyesinin kilidini açmak için {{points}} puan daha kazanın",
"score_panel.rerolls_count": " {{rerolls}} yeniden atma biriktirdiniz",
"score_panel.score_to_unlock": "\"{{level}}\" seviyesini açmak için {{points}} puan daha kazanın", "score_panel.score_to_unlock": "\"{{level}}\" seviyesini açmak için {{points}} puan daha kazanın",
"score_panel.title": " {{level}}/{{max}} seviyesinde{{score}} puan", "score_panel.title": " {{level}}/{{max}} seviyesinde{{score}} puan",
"score_panel.upcoming_levels": "Yaklaşan seviyeler :", "score_panel.upcoming_levels": "Yaklaşan seviyeler :",
@ -305,9 +301,6 @@
"upgrades.extra_levels.name": "5 dakika daha", "upgrades.extra_levels.name": "5 dakika daha",
"upgrades.extra_levels.tooltip": "7 yerine {{count}} seviye oyna", "upgrades.extra_levels.tooltip": "7 yerine {{count}} seviye oyna",
"upgrades.extra_levels.verbose_description": "Varsayılan oyun en fazla 7 seviye sürebilir, ardından oyun biter. \n\nBu avantajın her seviyesi bir seviye daha yukarı çıkmanızı sağlar. Son seviyeler genellikle en fazla puanı aldığınız seviyelerdir, bu yüzden fark dramatik olabilir.", "upgrades.extra_levels.verbose_description": "Varsayılan oyun en fazla 7 seviye sürebilir, ardından oyun biter. \n\nBu avantajın her seviyesi bir seviye daha yukarı çıkmanızı sağlar. Son seviyeler genellikle en fazla puanı aldığınız seviyelerdir, bu yüzden fark dramatik olabilir.",
"upgrades.extra_life.name": "Ekstra Hayat",
"upgrades.extra_life.tooltip": "Top, kaybedilmeden önce alt çizgide bir kez sekecektir.",
"upgrades.extra_life.verbose_description": "Normalde bir topunuz vardır ve oyun onu bıraktığınız anda biter.\n\nBu yetenek, ekranın altına bir kez topu kurtaracak ve bu süreçte kırılacak beyaz bir çubuk ekler. \n\nEkranın altında bir top her zıpladığında bu yeteneğin bir seviyesini kaybedersiniz.",
"upgrades.forgiving.name": "Bağışlayıcı", "upgrades.forgiving.name": "Bağışlayıcı",
"upgrades.forgiving.tooltip": "Molaları kaçırmak, komboyu bir kerede azaltmak yerine kademeli olarak azaltır.", "upgrades.forgiving.tooltip": "Molaları kaçırmak, komboyu bir kerede azaltmak yerine kademeli olarak azaltır.",
"upgrades.forgiving.verbose_description": "Her seviyede ilk ıskalama bedava, sonra kombonun %10'u, sonra %20'si...", "upgrades.forgiving.verbose_description": "Her seviyede ilk ıskalama bedava, sonra kombonun %10'u, sonra %20'si...",

View file

@ -8,7 +8,7 @@ import {
makeEmptyPerksMap, makeEmptyPerksMap,
sumOfValues, sumOfValues,
} from "./game_utils"; } from "./game_utils";
import { dontOfferTooSoon, resetBalls } from "./gameStateMutators"; import { resetBalls } from "./gameStateMutators";
import { isOptionOn } from "./options"; import { isOptionOn } from "./options";
import { getHistory } from "./gameOver"; import { getHistory } from "./gameOver";
import { getSettingValue, getTotalScore } from "./settings"; import { getSettingValue, getTotalScore } from "./settings";
@ -17,6 +17,7 @@ import {
isLevelLocked, isLevelLocked,
reasonLevelIsLocked, reasonLevelIsLocked,
} from "./get_level_unlock_condition"; } from "./get_level_unlock_condition";
import {dontOfferTooSoon} from "./openUpgradesPicker";
export function getRunLevels( export function getRunLevels(
params: RunParams, params: RunParams,
@ -143,7 +144,7 @@ export function newGameState(params: RunParams): GameState {
needsRender: true, needsRender: true,
autoCleanUses: 0, autoCleanUses: 0,
...defaultSounds(), ...defaultSounds(),
rerolls: 0, extra_lives: 0,
creative: creative:
params?.computer_controlled || params?.computer_controlled ||
sumOfValues(params.perks) > 1 || sumOfValues(params.perks) > 1 ||

View file

@ -7,11 +7,7 @@ import { pause } from "./game";
import {allLevels, icons} from "./loadGameData"; import {allLevels, icons} from "./loadGameData";
import {firstWhere} from "./pure_functions"; import {firstWhere} from "./pure_functions";
import {getSettingValue, getTotalScore} from "./settings"; import {getSettingValue, getTotalScore} from "./settings";
import { import {getLevelUnlockCondition, reasonLevelIsLocked, upgradeName,} from "./get_level_unlock_condition";
getLevelUnlockCondition,
reasonLevelIsLocked,
upgradeName,
} from "./get_level_unlock_condition";
export async function openScorePanel(gameState: GameState) { export async function openScorePanel(gameState: GameState) {
pause(true); pause(true);
@ -28,8 +24,8 @@ export async function openScorePanel(gameState: GameState) {
pickedUpgradesHTMl(gameState), pickedUpgradesHTMl(gameState),
levelsListHTMl(gameState, gameState.currentLevel), levelsListHTMl(gameState, gameState.currentLevel),
getNearestUnlockHTML(gameState), getNearestUnlockHTML(gameState),
gameState.rerolls gameState.extra_lives
? t("score_panel.rerolls_count", { rerolls: gameState.rerolls }) ? t("score_panel.extra_lives_count", { count: gameState.extra_lives })
: "", : "",
], ],
allowClose: true, allowClose: true,
@ -100,3 +96,4 @@ export function getNearestUnlockHTML(gameState: GameState) {
`; `;
} }

142
src/openUpgradesPicker.ts Normal file
View file

@ -0,0 +1,142 @@
import {GameState, PerkId} from "./types";
import {
catchRateBest,
catchRateGood,
levelTimeBest,
levelTimeGood,
missesBest,
missesGood,
wallBouncedBest,
wallBouncedGood
} from "./pure_functions";
import {t} from "./i18n/i18n";
import {icons, upgrades} from "./loadGameData";
import {asyncAlert} from "./asyncAlert";
import {
getPossibleUpgrades,
levelsListHTMl,
max_levels,
pickedUpgradesHTMl,
upgradeLevelAndMaxDisplay
} from "./game_utils";
import {getNearestUnlockHTML} from "./openScorePanel";
export async function openUpgradesPicker(gameState: GameState) {
const catchRate =
gameState.levelCoughtCoins / (gameState.levelSpawnedCoins || 1);
gameState.extra_lives++
let choices = 3 + gameState.perks.one_more_choice
if (gameState.levelWallBounces < wallBouncedGood) {
choices++;
gameState.extra_lives++;
if (gameState.levelWallBounces < wallBouncedBest) {
choices++;
}
}
if (gameState.levelTime < levelTimeGood * 1000) {
choices++;
gameState.extra_lives++;
if (gameState.levelTime < levelTimeBest * 1000) {
choices++;
}
}
if (catchRate > catchRateGood / 100) {
choices++;
gameState.extra_lives++;
if (catchRate > catchRateBest / 100) {
choices++;
}
}
if (gameState.levelMisses < missesGood) {
choices++;
gameState.extra_lives++;
if (gameState.levelMisses < missesBest) {
choices++;
}
}
let offered:PerkId[]= getPossibleUpgrades(gameState)
.map((u) => ({
...u,
score: Math.random() + (gameState.lastOffered[u.id] || 0),
}))
.sort((a, b) => a.score - b.score)
.filter((u) => gameState.perks[u.id] < u.max + gameState.perks.limitless)
.slice(0, choices)
.map(u=>u.id)
offered.forEach((id) => {
dontOfferTooSoon(gameState, id);
});
let list = upgrades.filter(u=>offered.includes(u.id)||gameState.perks[u.id])
while (true) {
let actions: Array<{
text: string;
icon: string;
value: PerkId | null;
help: string;
className: string;
tooltip: string;
}> = list.map((u) => {
const disabled= !gameState.extra_lives || gameState.perks[u.id] >= u.max + gameState.perks.limitless
const lvl= gameState.perks[u.id]
return ({
text: u.name + (lvl ? upgradeLevelAndMaxDisplay(u, gameState):''),
help: u.help(Math.max(1, lvl)),
tooltip: u.fullHelp(Math.max(1, lvl)),
icon: icons["icon:" + u.id],
value: u.id as PerkId,
className: "upgrade " + (disabled && lvl ? 'no-border ':' ') + ( lvl ? '':'grey-out-unless-hovered ') ,
disabled:disabled ,
})
})
actions = [
...actions.filter(a=>gameState.perks[a.value]),
...actions.filter(a=>!gameState.perks[a.value]),
]
const upgradeId = await asyncAlert<PerkId | null>({
title:
t("level_up.title", {
level: gameState.currentLevel ,
max: max_levels(gameState),
}),
content: [
{
text: t('level_up.go',{name:gameState.level.name}),
icon: icons[gameState.level.name],
value:null,
},
// pickedUpgradesHTMl(gameState),
gameState.extra_lives ? `<p>${t("level_up.instructions", {
count:gameState.extra_lives
})}</p>` :`<p>${t("level_up.no_points")}</p>` ,
...actions,
levelsListHTMl(gameState, gameState.currentLevel ),
getNearestUnlockHTML(gameState),
`<div id="level-recording-container"></div>`,
],
});
if (upgradeId ) {
gameState.perks[upgradeId]++;
gameState.runStatistics.upgrades_picked++;
gameState.extra_lives--
}else{
return
}
}
}
export function dontOfferTooSoon(gameState: GameState, id: PerkId) {
gameState.lastOffered[id] = Math.round(Date.now() / 1000);
}

View file

@ -108,10 +108,9 @@ export function render(gameState: GameState) {
: "") + : "") +
`<span class="score" data-tooltip="${t("play.score_tooltip")}">$${gameState.score}</span>`; `<span class="score" data-tooltip="${t("play.score_tooltip")}">$${gameState.score}</span>`;
scoreDisplay.className = scoreDisplay.classList[gameState.startParams.computer_controlled ? 'add':'remove']('computer_controlled');
(gameState.startParams.computer_controlled && "computer_controlled") || scoreDisplay.classList[gameState.lastScoreIncrease > gameState.levelTime - 500 ? 'add':'remove']('active');
(gameState.lastScoreIncrease > gameState.levelTime - 500 && "active") ||
"";
// Clear // Clear
if (!isOptionOn("basic") && level.svg && level.color === "#000000") { if (!isOptionOn("basic") && level.svg && level.color === "#000000") {
const skipN = const skipN =
@ -363,13 +362,13 @@ export function render(gameState: GameState) {
ctx.globalCompositeOperation = "screen"; ctx.globalCompositeOperation = "screen";
drawBall(ctx, color, size, x, y); drawBall(ctx, color, size, x, y);
}); });
//
startWork("render:extra_life"); startWork("render:extra_life");
if (gameState.perks.extra_life) { if (gameState.extra_lives) {
ctx.globalAlpha = gameState.balls.length > 1 ? 0.2 : 1; ctx.globalAlpha = gameState.balls.length > 1 ? 0.2 : 1;
ctx.globalCompositeOperation = "source-over"; ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = gameState.puckColor; ctx.fillStyle = gameState.puckColor;
for (let i = 0; i < gameState.perks.extra_life; i++) { for (let i = 0; i < gameState.extra_lives; i++) {
ctx.fillRect( ctx.fillRect(
gameState.offsetXRoundedDown, gameState.offsetXRoundedDown,
gameState.gameZoneHeight - gameState.puckHeight / 2 + 2 * i, gameState.gameZoneHeight - gameState.puckHeight / 2 + 2 * i,

View file

@ -3,7 +3,6 @@ import { isOptionOn } from "./options";
const tooltip = document.getElementById("tooltip") as HTMLDivElement; const tooltip = document.getElementById("tooltip") as HTMLDivElement;
export function setupTooltips() { export function setupTooltips() {
return
if (isOptionOn("mobile-mode")) { if (isOptionOn("mobile-mode")) {
setupMobileTooltips(tooltip); setupMobileTooltips(tooltip);
} else { } else {

2
src/types.d.ts vendored
View file

@ -280,7 +280,7 @@ export type GameState = {
plouf: { vol: number; x: number }; plouf: { vol: number; x: number };
colorChange: { vol: number; x: number }; colorChange: { vol: number; x: number };
}; };
rerolls: number; extra_lives: number;
creative: boolean; creative: boolean;
startParams: RunParams; startParams: RunParams;
}; };

View file

@ -44,18 +44,6 @@ export const rawUpgrades = [
t("upgrades.bigger_puck.verbose_description", { lvl }), t("upgrades.bigger_puck.verbose_description", { lvl }),
}, },
{
category: categories.beginner,
requires: "",
threshold: 0,
gift: false,
id: "extra_life",
max: 7,
name: t("upgrades.extra_life.name"),
help: (lvl: number) => t("upgrades.extra_life.tooltip"),
fullHelp: (lvl: number) =>
t("upgrades.extra_life.verbose_description", { lvl }),
},
{ {
category: categories.beginner, category: categories.beginner,
requires: "", requires: "",
@ -548,7 +536,7 @@ export const rawUpgrades = [
}, },
{ {
category: categories.advanced, category: categories.advanced,
requires: "extra_life", requires: "",
threshold: 110000, threshold: 110000,
gift: false, gift: false,
id: "sacrifice", id: "sacrifice",