mirror of
https://gitlab.com/lecarore/breakout71.git
synced 2025-05-04 18:59:13 -04:00
Build 29106448
This commit is contained in:
parent
ea13142f1d
commit
381bd1cef9
22 changed files with 745 additions and 223 deletions
|
@ -16,6 +16,10 @@ Break colourful bricks, catch bouncing coins and select powerful upgrades !
|
|||
|
||||
|
||||
## Done
|
||||
|
||||
- performance tweaks suggestions
|
||||
|
||||
## 29106110
|
||||
- reworked level up screen :
|
||||
- bigger "level X / Y cleared"
|
||||
- upgardes need to all be spent on the same list of perks (to avoid reading too much)
|
||||
|
|
|
@ -29,8 +29,8 @@ android {
|
|||
applicationId = "me.lecaro.breakout"
|
||||
minSdk = 21
|
||||
targetSdk = 34
|
||||
versionCode = 29106110
|
||||
versionName = "29106110"
|
||||
versionCode = 29106448
|
||||
versionName = "29106448"
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables {
|
||||
useSupportLibrary = true
|
||||
|
|
File diff suppressed because one or more lines are too long
380
dist/index.html
vendored
380
dist/index.html
vendored
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
|||
// The version of the cache.
|
||||
const VERSION = "29106110";
|
||||
const VERSION = "29106448";
|
||||
|
||||
// The name of the cache
|
||||
const CACHE_NAME = `breakout-71-${VERSION}`;
|
||||
|
|
|
@ -1497,72 +1497,61 @@
|
|||
"name": "FTL",
|
||||
"size": 10,
|
||||
"bricks": "WWW_WWW_W_W____W__W_WW___W__W_W____W__WW__O_______gOaOOOOOOa_OOaaaaaaO_gOOOOOOO___Oa________________",
|
||||
"svg": null,
|
||||
"color": "",
|
||||
"credit": "https://www.gog.com/en/game/faster_than_light"
|
||||
},
|
||||
{
|
||||
"name": "Nova drift",
|
||||
"size": 9,
|
||||
"bricks": "___WWW_____WWgWW___pWgggWp_pWgggggWppWBBgBBWpvpBBgBBpvvBBWWWBBvvvvpWpvvvvvvvpvvvv",
|
||||
"svg": null,
|
||||
"color": "",
|
||||
"credit": "https://www.gog.com/fr/game/nova_drift"
|
||||
},
|
||||
{
|
||||
"name": "Heat Signature",
|
||||
"size": 19,
|
||||
"bricks": "__ggg________________ggg________________ggg________________ggg_______________WWgWWWWWWWWWWBBBW__WgggWgggWaggWrrrW__WggggggaWaggggBrW__WgagWgggWaggWggrW__WWWWWWgWWWWWWWgWW__WgggWrgrWgaaWaggW__WagggggggggaWaagW__WgggWrgrWgggWaggW__WWgWWWgWWWgWWWgWW__WagaWrgrWgggWggrB__WagaWgBgWaggggBrB__WaaaWrgrWgggWrrrB__WWWWWBBBWWWWWWWWW_______________________________________",
|
||||
"svg": null,
|
||||
"color": "",
|
||||
"credit": "https://www.humblebundle.com/store/heat-signature"
|
||||
},
|
||||
{
|
||||
"name": "Noita",
|
||||
"size": 8,
|
||||
"bricks": "_B_______l_vvv___l_BBv___l_vvv___leeev___l_vvv___l_vvvv_eeeeeeee",
|
||||
"svg": null,
|
||||
"color": "",
|
||||
"credit": "https://www.gog.com/en/game/noita"
|
||||
},
|
||||
{
|
||||
"name": "Enter the gungeon",
|
||||
"size": 11,
|
||||
"bricks": "________ll___lll__l__l_lllll__l___yyyyy_rrr__yyyyy_rrr__yyyyy_rrr__yyyyy_rrr__yByBy_rrr__yyyyy_rrr__y___y_rrr____________",
|
||||
"svg": null,
|
||||
"color": "",
|
||||
"credit": "https://www.gog.com/en/game/enter_the_gungeon"
|
||||
},
|
||||
{
|
||||
"name": "ZERO Sievert",
|
||||
"size": 10,
|
||||
"bricks": "___________yyyyyy____yyaaaa____yyaaaa____yyaaaa____yyyyyy_____OOgggggg__yyygyyg___OOOO_____O___O____",
|
||||
"svg": null,
|
||||
"color": "",
|
||||
"credit": "https://store.steampowered.com/app/1782120/ZERO_Sievert/"
|
||||
},
|
||||
{
|
||||
"name": "Factorio",
|
||||
"size": 8,
|
||||
"bricks": "________yyyy_ylly__Byy__y____yll_yB_______y______yyy____y___y___",
|
||||
"svg": null,
|
||||
"color": "",
|
||||
"credit": "https://www.factorio.com"
|
||||
},
|
||||
{
|
||||
"name": "Brigador",
|
||||
"size": 13,
|
||||
"bricks": "__________g________BBgggg__________yy__BBggggggggyy_____yglygggl_____yglygggl_______llllll_____ggllggll_____gg__gg________Bg__Bg_______gg__gg________B___B_______ggg_ggg_",
|
||||
"svg": null,
|
||||
"color": "",
|
||||
"credit": "https://www.gog.com/en/game/brigador"
|
||||
},
|
||||
{
|
||||
"name": "Teleglitch",
|
||||
"size": 11,
|
||||
"bricks": "___l___l______lB__l____l__l_lB____l__l_l_____BllOOOB_______OOOyyyy___lOOOB____Bl__l_l__k_l___l_l__k_l__lB_Bl______l___l__",
|
||||
"svg": null,
|
||||
"color": "",
|
||||
"credit": "https://www.gog.com/en/game/teleglitch_die_more_edition"
|
||||
},
|
||||
{
|
||||
"name": "icon:slow",
|
||||
"size": 8,
|
||||
"bricks": "___________gg____Sggggg_gSSgggggggSSgggggggSSggg________________",
|
||||
"svg": null,
|
||||
"color": ""
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1 +1 @@
|
|||
"29106110"
|
||||
"29106448"
|
||||
|
|
87
src/fps.ts
Normal file
87
src/fps.ts
Normal file
|
@ -0,0 +1,87 @@
|
|||
import { gameState } from "./game";
|
||||
import { sumOfValues } from "./game_utils";
|
||||
import { liveCount } from "./gameStateMutators";
|
||||
import { getCurrentMaxCoins, getCurrentMaxParticles } from "./settings";
|
||||
import { clamp } from "./pure_functions";
|
||||
|
||||
export let total: Record<string, number> = {};
|
||||
let lastTick = performance.now();
|
||||
let doing = "idle";
|
||||
export let lastMeasuredFPS = 60;
|
||||
// Worst FPS we saw
|
||||
export let worstFPS = 60,
|
||||
worstInstantFPS = 60;
|
||||
// Coins at which fps dipped below 55
|
||||
export let coinsForLag = Infinity;
|
||||
|
||||
let lastFrame = Date.now();
|
||||
export function frameStarted() {
|
||||
FPSCounter++;
|
||||
const instantFPS = 1000 / (Date.now() - lastFrame);
|
||||
lastFrame = Date.now();
|
||||
if (isNaN(instantFPS)) return;
|
||||
if (instantFPS < 50) {
|
||||
coinsForLag = Math.min(coinsForLag, liveCount(gameState.coins));
|
||||
}
|
||||
worstInstantFPS = Math.min(worstInstantFPS, instantFPS);
|
||||
worstFPS = Math.min(worstFPS, lastMeasuredFPS);
|
||||
}
|
||||
|
||||
export function getWorstFPSAndReset() {
|
||||
const result = { worstFPS, coinsForLag, worstInstantFPS };
|
||||
worstFPS = 60;
|
||||
worstInstantFPS = 60;
|
||||
coinsForLag = Infinity;
|
||||
return result;
|
||||
}
|
||||
|
||||
export function startWork(what) {
|
||||
if (!gameState.startParams.stress) return;
|
||||
const newNow = performance.now();
|
||||
if (doing) {
|
||||
total[doing] = (total[doing] || 0) + (newNow - lastTick);
|
||||
}
|
||||
lastTick = newNow;
|
||||
doing = what;
|
||||
}
|
||||
|
||||
export let FPSCounter = 0;
|
||||
export const stats = document.getElementById("stats") as HTMLDivElement;
|
||||
|
||||
setInterval(() => {
|
||||
lastMeasuredFPS = FPSCounter;
|
||||
FPSCounter = 0;
|
||||
|
||||
if (!gameState.startParams.stress) {
|
||||
stats.style.display = "none";
|
||||
return;
|
||||
}
|
||||
|
||||
stats.style.display = "block";
|
||||
const totalTime = sumOfValues(total);
|
||||
stats.innerHTML =
|
||||
`
|
||||
<div>
|
||||
${lastMeasuredFPS} FPS -
|
||||
${liveCount(gameState.coins)} / ${getCurrentMaxCoins()} Coins -
|
||||
${liveCount(gameState.particles) + liveCount(gameState.lights) + liveCount(gameState.texts)} / ${getCurrentMaxParticles() * 3} particles
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
` +
|
||||
Object.entries(total)
|
||||
// .sort((a, b) => b[1] - a[1])
|
||||
.map(
|
||||
(t) =>
|
||||
` <div>
|
||||
<div style="transform: scale(${clamp(t[1] / totalTime, 0, 1)},1)"></div>
|
||||
<strong>${t[0]} : ${Math.floor(t[1])} ms</strong>
|
||||
</div>
|
||||
`,
|
||||
)
|
||||
.join("\n");
|
||||
|
||||
total = {};
|
||||
}, 1000);
|
62
src/game.ts
62
src/game.ts
|
@ -82,6 +82,7 @@ import { monitorLevelsUnlocks } from "./monitorLevelsUnlocks";
|
|||
import { levelEditorMenuEntry } from "./levelEditor";
|
||||
import { categories } from "./upgrades";
|
||||
import { reasonLevelIsLocked } from "./get_level_unlock_condition";
|
||||
import { frameStarted, getWorstFPSAndReset, startWork } from "./fps";
|
||||
|
||||
export async function play() {
|
||||
if (await applyFullScreenChoice()) return;
|
||||
|
@ -332,6 +333,7 @@ export function hitsSomething(x: number, y: number, radius: number) {
|
|||
}
|
||||
|
||||
export function tick() {
|
||||
frameStarted();
|
||||
startWork("physics");
|
||||
const currentTick = performance.now();
|
||||
const timeDeltaMs = currentTick - gameState.lastTick;
|
||||
|
@ -382,62 +384,8 @@ export function tick() {
|
|||
startWork("idle");
|
||||
|
||||
requestAnimationFrame(tick);
|
||||
FPSCounter++;
|
||||
}
|
||||
|
||||
const stats = document.getElementById("stats") as HTMLDivElement;
|
||||
let total = {};
|
||||
let lastTick = performance.now();
|
||||
let doing = "idle";
|
||||
let FPSCounter = 0;
|
||||
export let lastMeasuredFPS = 60;
|
||||
export function startWork(what) {
|
||||
if (!gameState.startParams.stress) return;
|
||||
const newNow = performance.now();
|
||||
if (doing) {
|
||||
total[doing] = (total[doing] || 0) + (newNow - lastTick);
|
||||
}
|
||||
lastTick = newNow;
|
||||
doing = what;
|
||||
}
|
||||
setInterval(() => {
|
||||
lastMeasuredFPS = FPSCounter;
|
||||
FPSCounter = 0;
|
||||
|
||||
if (!gameState.startParams.stress) {
|
||||
stats.style.display = "none";
|
||||
return;
|
||||
}
|
||||
|
||||
stats.style.display = "block";
|
||||
const totalTime = sumOfValues(total);
|
||||
stats.innerHTML =
|
||||
`
|
||||
<div>
|
||||
${lastMeasuredFPS} FPS -
|
||||
${liveCount(gameState.coins)} / ${getCurrentMaxCoins()} Coins -
|
||||
${liveCount(gameState.particles) + liveCount(gameState.lights) + liveCount(gameState.texts)} / ${getCurrentMaxParticles() * 3} particles
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
` +
|
||||
Object.entries(total)
|
||||
// .sort((a, b) => b[1] - a[1])
|
||||
.map(
|
||||
(t) =>
|
||||
` <div>
|
||||
<div style="transform: scale(${clamp(t[1] / totalTime, 0, 1)},1)"></div>
|
||||
<strong>${t[0]} : ${Math.floor(t[1])} ms</strong>
|
||||
</div>
|
||||
`,
|
||||
)
|
||||
.join("\n");
|
||||
|
||||
total = {};
|
||||
}, 1000);
|
||||
|
||||
setInterval(() => {
|
||||
monitorLevelsUnlocks(gameState);
|
||||
}, 500);
|
||||
|
@ -1013,6 +961,7 @@ document.addEventListener("keyup", async (e) => {
|
|||
export const gameState = newGameState({});
|
||||
|
||||
export function restart(params: RunParams) {
|
||||
getWorstFPSAndReset();
|
||||
Object.assign(gameState, newGameState(params));
|
||||
// Recompute brick size according to level
|
||||
fitSize(gameState);
|
||||
|
@ -1033,7 +982,7 @@ export function startComputerControlledGame(stress: boolean = false) {
|
|||
const perks: Partial<PerksMap> = { base_combo: 20, pierce: 3 };
|
||||
if (stress) {
|
||||
Object.assign(perks, {
|
||||
base_combo: 5000,
|
||||
base_combo: 150,
|
||||
pierce: 20,
|
||||
rainbow: 3,
|
||||
sapper: 2,
|
||||
|
@ -1045,6 +994,9 @@ export function startComputerControlledGame(stress: boolean = false) {
|
|||
for (let i = 0; i < 10; i++) {
|
||||
const u = sample(upgrades);
|
||||
perks[u.id] ||= Math.floor(Math.random() * u.max) + 1;
|
||||
if (u.requires) {
|
||||
perks[u.requires] ||= 1;
|
||||
}
|
||||
}
|
||||
perks.superhot = 0;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,11 @@ import {
|
|||
isLevelLocked,
|
||||
reasonLevelIsLocked,
|
||||
} from "./get_level_unlock_condition";
|
||||
import { getWorstFPSAndReset } from "./fps";
|
||||
import {
|
||||
applySettingsChangeReco,
|
||||
settingsChangeRecommendations,
|
||||
} from "./openUpgradesPicker";
|
||||
|
||||
export function addToTotalPlayTime(ms: number) {
|
||||
setSettingValue(
|
||||
|
@ -29,13 +34,14 @@ export function addToTotalPlayTime(ms: number) {
|
|||
);
|
||||
}
|
||||
|
||||
export function gameOver(title: string, intro: string) {
|
||||
export async function gameOver(title: string, intro: string) {
|
||||
if (!gameState.running) return;
|
||||
|
||||
// Ignore duplicated calls, can happen when ticking is split in multiple updates because the ball goes fast
|
||||
if (gameState.isGameOver) return;
|
||||
|
||||
gameState.isGameOver = true;
|
||||
|
||||
pause(false);
|
||||
askForPersistentStorage();
|
||||
stopRecording();
|
||||
|
@ -84,7 +90,7 @@ export function gameOver(title: string, intro: string) {
|
|||
// Avoid the sad sound right as we restart a new games
|
||||
gameState.combo = 1;
|
||||
|
||||
asyncAlert({
|
||||
const choice = await asyncAlert({
|
||||
allowClose: true,
|
||||
title,
|
||||
content: [
|
||||
|
@ -93,6 +99,7 @@ export function gameOver(title: string, intro: string) {
|
|||
<p>${intro}</p>
|
||||
<p>${t("gameOver.cumulative_total", { startTs, endTs })}</p>
|
||||
`,
|
||||
settingsChangeRecommendations(),
|
||||
{
|
||||
icon: icons["icon:new_run"],
|
||||
value: null,
|
||||
|
@ -105,11 +112,11 @@ export function gameOver(title: string, intro: string) {
|
|||
getHistograms(gameState),
|
||||
pickedUpgradesHTMl(gameState),
|
||||
],
|
||||
}).then(() =>
|
||||
restart({
|
||||
levelToAvoid: currentLevelInfo(gameState).name,
|
||||
}),
|
||||
);
|
||||
});
|
||||
applySettingsChangeReco(choice);
|
||||
restart({
|
||||
levelToAvoid: currentLevelInfo(gameState).name,
|
||||
});
|
||||
}
|
||||
|
||||
export function getCreativeModeWarning(gameState: GameState) {
|
||||
|
|
|
@ -2178,6 +2178,9 @@ function makeParticle(
|
|||
size = 8,
|
||||
duration = 150,
|
||||
) {
|
||||
if (!color.match(/^#[a-f0-9]{6}$/gi)) {
|
||||
throw new Error("Particle creation ignored, invalid color : " + color);
|
||||
}
|
||||
append(gameState.particles, (p: Partial<ParticleFlash>) => {
|
||||
p.time = gameState.levelTime;
|
||||
p.x = x;
|
||||
|
|
|
@ -228,6 +228,12 @@
|
|||
"settings.sounds_help": "أصوات صفير وبلبل و برررر",
|
||||
"settings.stress_test": "اختبار الإجهاد",
|
||||
"settings.stress_test_help": "ابدأ لعبة يتم التحكم فيها بواسطة روبوت باستخدام عدد كبير جدًا من العملات المعدنية، لاختبار حدود أداء جهازك.",
|
||||
"settings.suggestions.applied": "تم تطبيق اقتراح الأداء!",
|
||||
"settings.suggestions.basic_mode": "الاقتراح: قم بتشغيل الوضع الأساسي لتحسين الأداء.",
|
||||
"settings.suggestions.record": "اقتراح: قم بتعطيل تسجيل الفيديو لتحسين الأداء.",
|
||||
"settings.suggestions.reduce_brightness": "الاقتراح: تقليل حجم الهالة لتحسين الأداء.",
|
||||
"settings.suggestions.reduce_coins": "اقتراح: تحسين الأداء عن طريق تحديد الحد الأقصى للعملات المعدنية على الشاشة إلى {{max}}.",
|
||||
"settings.suggestions.simpler_lights": "الاقتراح: تبسيط حسابات الضوء لتحسين الأداء.",
|
||||
"settings.touch_delayed_start": "تأخر البدء على الهاتف المحمول",
|
||||
"settings.touch_delayed_start_help": "3،2،1،اذهب في بداية المستوى",
|
||||
"starting_perks.checked": "عند بدء لعبة جديدة، ستُمنح إحدى هذه المزايا. انقر على أي ميزة لاستبعادها.",
|
||||
|
|
|
@ -8137,6 +8137,221 @@
|
|||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<folder_node>
|
||||
<name>suggestions</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>applied</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>basic_mode</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>record</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>reduce_brightness</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>reduce_coins</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>simpler_lights</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>
|
||||
<concept_node>
|
||||
<name>touch_delayed_start</name>
|
||||
<description/>
|
||||
|
|
|
@ -228,6 +228,12 @@
|
|||
"settings.sounds_help": "Piepsen, Bloops und Brrrr",
|
||||
"settings.stress_test": "Stresstest",
|
||||
"settings.stress_test_help": "Starte ein Bot-gesteuertes Spiel mit einer sehr hohen Anzahl an Münzen, um die Leistungsgrenzen deines Geräts zu testen.",
|
||||
"settings.suggestions.applied": "Leistungsvorschlag angewendet!",
|
||||
"settings.suggestions.basic_mode": "Vorschlag: Aktivieren Sie den Basismodus, um die Leistung zu verbessern.",
|
||||
"settings.suggestions.record": "Vorschlag: Deaktivieren Sie die Videoaufzeichnung, um die Leistung zu verbessern.",
|
||||
"settings.suggestions.reduce_brightness": "Vorschlag: Reduzieren Sie die Halo-Größe, um die Leistung zu verbessern.",
|
||||
"settings.suggestions.reduce_coins": "Vorschlag: Verbessern Sie die Leistung, indem Sie die Anzahl der Münzen auf dem Bildschirm auf {{max}}begrenzen.",
|
||||
"settings.suggestions.simpler_lights": "Vorschlag: Vereinfachen Sie die Lichtberechnungen, um die Leistung zu verbessern.",
|
||||
"settings.touch_delayed_start": "Verzögerter Start auf Mobilgeräten",
|
||||
"settings.touch_delayed_start_help": "3,2,1,Los zu Beginn eines Levels",
|
||||
"starting_perks.checked": "Wenn du ein neues Spiel beginnst, wird dir eine dieser Vergünstigungen angeboten. Klicke auf eine Vergünstigung, um sie auszuschließen.",
|
||||
|
|
|
@ -228,6 +228,12 @@
|
|||
"settings.sounds_help": "Beeps, bloops and brrrr",
|
||||
"settings.stress_test": "Stress test",
|
||||
"settings.stress_test_help": "Start a bot controlled game with a very high number of coins, to test the performance limits of your device.",
|
||||
"settings.suggestions.applied": "Performance suggestion applied !",
|
||||
"settings.suggestions.basic_mode": "Suggestion : turn basic mode on to improve performance.",
|
||||
"settings.suggestions.record": "Suggestion : Disable video recording to improve performance.",
|
||||
"settings.suggestions.reduce_brightness": "Suggestion : reduce the halo size to improve performance. ",
|
||||
"settings.suggestions.reduce_coins": "Suggestion : improve performance by capping coins on screen to {{max}}.",
|
||||
"settings.suggestions.simpler_lights": "Suggestion : simplify light calculations to improve performance. ",
|
||||
"settings.touch_delayed_start": "Delayed start on mobile",
|
||||
"settings.touch_delayed_start_help": "3,2,1,Go at the start of a level",
|
||||
"starting_perks.checked": "When you start a new game, one of those perks will be given to you. Click a perk to exclude it. ",
|
||||
|
|
|
@ -228,6 +228,12 @@
|
|||
"settings.sounds_help": "Pitidos, bloops y brrrr",
|
||||
"settings.stress_test": "Prueba de estrés",
|
||||
"settings.stress_test_help": "Inicie un juego controlado por bot con una cantidad muy alta de monedas para probar los límites de rendimiento de su dispositivo.",
|
||||
"settings.suggestions.applied": "¡Sugerencia de rendimiento aplicada!",
|
||||
"settings.suggestions.basic_mode": "Sugerencia: active el modo básico para mejorar el rendimiento.",
|
||||
"settings.suggestions.record": "Sugerencia: deshabilite la grabación de video para mejorar el rendimiento.",
|
||||
"settings.suggestions.reduce_brightness": "Sugerencia: reducir el tamaño del halo para mejorar el rendimiento.",
|
||||
"settings.suggestions.reduce_coins": "Sugerencia: mejorar el rendimiento limitando la cantidad de monedas en pantalla a {{max}}.",
|
||||
"settings.suggestions.simpler_lights": "Sugerencia: simplificar los cálculos de luz para mejorar el rendimiento.",
|
||||
"settings.touch_delayed_start": "Inicio retrasado en el móvil",
|
||||
"settings.touch_delayed_start_help": "3,2,1,Ve al inicio de un nivel",
|
||||
"starting_perks.checked": "Al empezar una partida nueva, recibirás una de esas ventajas. Haz clic en una ventaja para excluirla.",
|
||||
|
|
|
@ -228,6 +228,12 @@
|
|||
"settings.sounds_help": "Bips, bloops et brrrr",
|
||||
"settings.stress_test": "Test de stress",
|
||||
"settings.stress_test_help": "Démarrez un jeu contrôlé par un bot avec un nombre très élevé de pièces, pour tester les limites de performances de votre appareil.",
|
||||
"settings.suggestions.applied": "Suggestion de performance appliquée !",
|
||||
"settings.suggestions.basic_mode": "Suggestion : activez le mode de base pour améliorer les performances.",
|
||||
"settings.suggestions.record": "Suggestion : Désactivez l'enregistrement vidéo pour améliorer les performances.",
|
||||
"settings.suggestions.reduce_brightness": "Suggestion : réduire la taille du halo pour améliorer les performances.",
|
||||
"settings.suggestions.reduce_coins": "Suggestion : améliorez les performances en plafonnant les pièces à l'écran à {{max}}.",
|
||||
"settings.suggestions.simpler_lights": "Suggestion : simplifier les calculs de lumière pour améliorer les performances.",
|
||||
"settings.touch_delayed_start": "Démarrage différé sur mobile",
|
||||
"settings.touch_delayed_start_help": "3,2,1,Allez au début d'un niveau",
|
||||
"starting_perks.checked": "Lorsque vous démarrez une nouvelle partie, l'un de ces avantages vous sera attribué. Cliquez sur un avantage pour l'exclure.",
|
||||
|
|
|
@ -228,6 +228,12 @@
|
|||
"settings.sounds_help": "Бипы, блепы и брррр",
|
||||
"settings.stress_test": "Стресс-тест",
|
||||
"settings.stress_test_help": "Запустите игру, управляемую ботом, с очень большим количеством монет, чтобы проверить пределы производительности вашего устройства.",
|
||||
"settings.suggestions.applied": "Предложение по производительности применено!",
|
||||
"settings.suggestions.basic_mode": "Предложение: включите базовый режим, чтобы повысить производительность.",
|
||||
"settings.suggestions.record": "Предложение: отключите запись видео для повышения производительности.",
|
||||
"settings.suggestions.reduce_brightness": "Предложение: уменьшите размер ореола, чтобы улучшить производительность.",
|
||||
"settings.suggestions.reduce_coins": "Предложение: улучшить производительность, ограничив количество монет на экране до {{max}}.",
|
||||
"settings.suggestions.simpler_lights": "Предложение: упростить расчеты освещения для повышения производительности.",
|
||||
"settings.touch_delayed_start": "Отложенный старт на мобильном устройстве",
|
||||
"settings.touch_delayed_start_help": "3,2,1,Перейти к началу уровня",
|
||||
"starting_perks.checked": "Когда вы начнете новую игру, вам будет дано одно из этих преимуществ. Щелкните по перку, чтобы исключить его.",
|
||||
|
|
|
@ -228,6 +228,12 @@
|
|||
"settings.sounds_help": "Bipler, blooplar ve brrrr",
|
||||
"settings.stress_test": "Stres testi",
|
||||
"settings.stress_test_help": "Cihazınızın performans sınırlarını test etmek için çok sayıda jetonla bot kontrollü bir oyun başlatın.",
|
||||
"settings.suggestions.applied": "Performans önerisi uygulandı!",
|
||||
"settings.suggestions.basic_mode": "Öneri: Performansı artırmak için temel modu açın.",
|
||||
"settings.suggestions.record": "Öneri : Performansı artırmak için video kaydını devre dışı bırakın.",
|
||||
"settings.suggestions.reduce_brightness": "Öneri : Performansı artırmak için halo boyutunu küçültün.",
|
||||
"settings.suggestions.reduce_coins": "Öneri: Ekrandaki jeton sayısını {{max}}olarak sınırlayarak performansı artırın.",
|
||||
"settings.suggestions.simpler_lights": "Öneri : Performansı artırmak için hafif hesaplamaları basitleştirin.",
|
||||
"settings.touch_delayed_start": "Mobilde gecikmeli başlatma",
|
||||
"settings.touch_delayed_start_help": "3,2,1,Bir seviyenin başlangıcında git",
|
||||
"starting_perks.checked": "Yeni bir oyuna başladığınızda, bu avantajlardan biri size verilecektir. Bir avantajı hariç tutmak için tıklayın.",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { GameState, PerkId } from "./types";
|
||||
import { GameState, OptionId, PerkId } from "./types";
|
||||
import {
|
||||
catchRateBest,
|
||||
catchRateGood,
|
||||
|
@ -24,6 +24,13 @@ import {
|
|||
} from "./game_utils";
|
||||
import { getFirstUnlockable, getNearestUnlockHTML } from "./openScorePanel";
|
||||
import { isOptionOn } from "./options";
|
||||
import { getWorstFPSAndReset } from "./fps";
|
||||
import {
|
||||
getCurrentMaxCoins,
|
||||
getSettingValue,
|
||||
setSettingValue,
|
||||
} from "./settings";
|
||||
import { toast } from "./toast";
|
||||
|
||||
export async function openUpgradesPicker(gameState: GameState) {
|
||||
const catchRate =
|
||||
|
@ -129,7 +136,7 @@ export async function openUpgradesPicker(gameState: GameState) {
|
|||
}))
|
||||
.sort((a, b) => a.score - b.score)
|
||||
.filter((u) => gameState.perks[u.id] < u.max + gameState.perks.limitless);
|
||||
|
||||
let recommendation = settingsChangeRecommendations();
|
||||
while (true) {
|
||||
// refresh the list if you pick extra one_more_choice
|
||||
const offered = sorted.slice(
|
||||
|
@ -178,7 +185,9 @@ export async function openUpgradesPicker(gameState: GameState) {
|
|||
};
|
||||
});
|
||||
|
||||
const upgradeId = await requiredAsyncAlert<PerkId>({
|
||||
const choice = await requiredAsyncAlert<
|
||||
PerkId | { changeSettings: Record<string, any> }
|
||||
>({
|
||||
title: t("level_up.title", {
|
||||
level: gameState.currentLevel,
|
||||
max: max_levels(gameState),
|
||||
|
@ -191,17 +200,22 @@ export async function openUpgradesPicker(gameState: GameState) {
|
|||
...upgradesActions,
|
||||
levelsListHTMl(gameState, gameState.currentLevel),
|
||||
unlockRelatedUpgradesOffered ? getNearestUnlockHTML(gameState) : "",
|
||||
|
||||
recommendation,
|
||||
...medals,
|
||||
pickedUpgradesHTMl(gameState),
|
||||
`<div id="level-recording-container"></div>`,
|
||||
],
|
||||
});
|
||||
upgradePoints--;
|
||||
gameState.perks[upgradeId]++;
|
||||
gameState.runStatistics.upgrades_picked++;
|
||||
if (!upgradePoints) {
|
||||
return;
|
||||
|
||||
if (applySettingsChangeReco(choice)) {
|
||||
recommendation = "";
|
||||
} else {
|
||||
upgradePoints--;
|
||||
gameState.perks[choice]++;
|
||||
gameState.runStatistics.upgrades_picked++;
|
||||
if (!upgradePoints) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -209,3 +223,83 @@ export async function openUpgradesPicker(gameState: GameState) {
|
|||
export function dontOfferTooSoon(gameState: GameState, id: PerkId) {
|
||||
gameState.lastOffered[id] = Math.round(Date.now() / 1000);
|
||||
}
|
||||
|
||||
export function applySettingsChangeReco(choice: unknown) {
|
||||
if (!choice) return;
|
||||
if (typeof choice == "object" && "changeSettings" in choice) {
|
||||
for (let key in choice.changeSettings) {
|
||||
setSettingValue(key, choice.changeSettings[key]);
|
||||
}
|
||||
toast(t("settings.suggestions.applied"));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
export function settingsChangeRecommendations() {
|
||||
const { worstFPS, coinsForLag } = getWorstFPSAndReset();
|
||||
const maxCoinsSetting = getSettingValue("max_coins", 2);
|
||||
|
||||
if (worstFPS > 55) return "";
|
||||
if (coinsForLag > 200 && getCurrentMaxCoins() > 200) {
|
||||
// Limit the coins
|
||||
const limit = Math.floor(Math.log2(coinsForLag / 200));
|
||||
if (limit < maxCoinsSetting) {
|
||||
return {
|
||||
icon: icons["icon:slow"],
|
||||
text: t("settings.suggestions.reduce_coins", {
|
||||
max: Math.pow(2, limit) * 200,
|
||||
}),
|
||||
value: {
|
||||
changeSettings: { max_coins: limit },
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (isOptionOn("record"))
|
||||
return {
|
||||
icon: icons["icon:slow"],
|
||||
text: t("settings.suggestions.record"),
|
||||
value: {
|
||||
changeSettings: { "breakout-settings-enable-record": false },
|
||||
},
|
||||
};
|
||||
|
||||
if (isOptionOn("basic")) return "";
|
||||
|
||||
if (
|
||||
isOptionOn("smooth_lighting") ||
|
||||
isOptionOn("precise_lighting") ||
|
||||
!isOptionOn("probabilistic_lighting") ||
|
||||
isOptionOn("contrast")
|
||||
)
|
||||
return {
|
||||
icon: icons["icon:slow"],
|
||||
text: t("settings.suggestions.simpler_lights"),
|
||||
value: {
|
||||
changeSettings: {
|
||||
"breakout-settings-enable-smooth_lighting": false,
|
||||
"breakout-settings-enable-precise_lighting": false,
|
||||
"breakout-settings-enable-probabilistic_lighting": true,
|
||||
"breakout-settings-enable-contrast": false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
if (isOptionOn("extra_bright"))
|
||||
return {
|
||||
icon: icons["icon:slow"],
|
||||
text: t("settings.suggestions.reduce_brightness"),
|
||||
value: {
|
||||
changeSettings: { "breakout-settings-enable-extra_bright": false },
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
icon: icons["icon:slow"],
|
||||
text: t("settings.suggestions.basic_mode"),
|
||||
value: {
|
||||
changeSettings: { "breakout-settings-enable-basic": true },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
} from "./game_utils";
|
||||
import { colorString, GameState } from "./types";
|
||||
import { t } from "./i18n/i18n";
|
||||
import { gameState, lastMeasuredFPS, startWork } from "./game";
|
||||
import { gameState } from "./game";
|
||||
import { isOptionOn } from "./options";
|
||||
import {
|
||||
ballTransparency,
|
||||
|
@ -29,6 +29,7 @@ import {
|
|||
missesBest,
|
||||
missesGood,
|
||||
} from "./pure_functions";
|
||||
import { lastMeasuredFPS, startWork } from "./fps";
|
||||
|
||||
export const gameCanvas = document.getElementById("game") as HTMLCanvasElement;
|
||||
export const ctx = gameCanvas.getContext("2d", {
|
||||
|
|
|
@ -8,8 +8,8 @@ bash ./build.sh $versionCode
|
|||
|
||||
# we don't add a version tag to let fdroid ignore this build
|
||||
|
||||
# upload to breakout-v3-staging.lecaro.me
|
||||
DOMAIN="breakout-v3-staging.lecaro.me"
|
||||
# upload to b72.lecaro.me
|
||||
DOMAIN="b72.lecaro.me"
|
||||
PUBLIC_CONTENT="./build/*"
|
||||
|
||||
ssh staging "mkdir -p /opt/mup-nginx-proxy/config/html/static_sites/$DOMAIN"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue