mirror of
https://gitlab.com/lecarore/breakout71.git
synced 2025-05-05 03:07:14 -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
|
## Done
|
||||||
|
|
||||||
|
- performance tweaks suggestions
|
||||||
|
|
||||||
|
## 29106110
|
||||||
- reworked level up screen :
|
- reworked level up screen :
|
||||||
- bigger "level X / Y cleared"
|
- bigger "level X / Y cleared"
|
||||||
- upgardes need to all be spent on the same list of perks (to avoid reading too much)
|
- 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"
|
applicationId = "me.lecaro.breakout"
|
||||||
minSdk = 21
|
minSdk = 21
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 29106110
|
versionCode = 29106448
|
||||||
versionName = "29106110"
|
versionName = "29106448"
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables {
|
vectorDrawables {
|
||||||
useSupportLibrary = true
|
useSupportLibrary = true
|
||||||
|
|
File diff suppressed because one or more lines are too long
372
dist/index.html
vendored
372
dist/index.html
vendored
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
||||||
// The version of the cache.
|
// The version of the cache.
|
||||||
const VERSION = "29106110";
|
const VERSION = "29106448";
|
||||||
|
|
||||||
// The name of the cache
|
// The name of the cache
|
||||||
const CACHE_NAME = `breakout-71-${VERSION}`;
|
const CACHE_NAME = `breakout-71-${VERSION}`;
|
||||||
|
|
|
@ -1497,72 +1497,61 @@
|
||||||
"name": "FTL",
|
"name": "FTL",
|
||||||
"size": 10,
|
"size": 10,
|
||||||
"bricks": "WWW_WWW_W_W____W__W_WW___W__W_W____W__WW__O_______gOaOOOOOOa_OOaaaaaaO_gOOOOOOO___Oa________________",
|
"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"
|
"credit": "https://www.gog.com/en/game/faster_than_light"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Nova drift",
|
"name": "Nova drift",
|
||||||
"size": 9,
|
"size": 9,
|
||||||
"bricks": "___WWW_____WWgWW___pWgggWp_pWgggggWppWBBgBBWpvpBBgBBpvvBBWWWBBvvvvpWpvvvvvvvpvvvv",
|
"bricks": "___WWW_____WWgWW___pWgggWp_pWgggggWppWBBgBBWpvpBBgBBpvvBBWWWBBvvvvpWpvvvvvvvpvvvv",
|
||||||
"svg": null,
|
|
||||||
"color": "",
|
|
||||||
"credit": "https://www.gog.com/fr/game/nova_drift"
|
"credit": "https://www.gog.com/fr/game/nova_drift"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Heat Signature",
|
"name": "Heat Signature",
|
||||||
"size": 19,
|
"size": 19,
|
||||||
"bricks": "__ggg________________ggg________________ggg________________ggg_______________WWgWWWWWWWWWWBBBW__WgggWgggWaggWrrrW__WggggggaWaggggBrW__WgagWgggWaggWggrW__WWWWWWgWWWWWWWgWW__WgggWrgrWgaaWaggW__WagggggggggaWaagW__WgggWrgrWgggWaggW__WWgWWWgWWWgWWWgWW__WagaWrgrWgggWggrB__WagaWgBgWaggggBrB__WaaaWrgrWgggWrrrB__WWWWWBBBWWWWWWWWW_______________________________________",
|
"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"
|
"credit": "https://www.humblebundle.com/store/heat-signature"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Noita",
|
"name": "Noita",
|
||||||
"size": 8,
|
"size": 8,
|
||||||
"bricks": "_B_______l_vvv___l_BBv___l_vvv___leeev___l_vvv___l_vvvv_eeeeeeee",
|
"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"
|
"credit": "https://www.gog.com/en/game/noita"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Enter the gungeon",
|
"name": "Enter the gungeon",
|
||||||
"size": 11,
|
"size": 11,
|
||||||
"bricks": "________ll___lll__l__l_lllll__l___yyyyy_rrr__yyyyy_rrr__yyyyy_rrr__yyyyy_rrr__yByBy_rrr__yyyyy_rrr__y___y_rrr____________",
|
"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"
|
"credit": "https://www.gog.com/en/game/enter_the_gungeon"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ZERO Sievert",
|
"name": "ZERO Sievert",
|
||||||
"size": 10,
|
"size": 10,
|
||||||
"bricks": "___________yyyyyy____yyaaaa____yyaaaa____yyaaaa____yyyyyy_____OOgggggg__yyygyyg___OOOO_____O___O____",
|
"bricks": "___________yyyyyy____yyaaaa____yyaaaa____yyaaaa____yyyyyy_____OOgggggg__yyygyyg___OOOO_____O___O____",
|
||||||
"svg": null,
|
|
||||||
"color": "",
|
|
||||||
"credit": "https://store.steampowered.com/app/1782120/ZERO_Sievert/"
|
"credit": "https://store.steampowered.com/app/1782120/ZERO_Sievert/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Factorio",
|
"name": "Factorio",
|
||||||
"size": 8,
|
"size": 8,
|
||||||
"bricks": "________yyyy_ylly__Byy__y____yll_yB_______y______yyy____y___y___",
|
"bricks": "________yyyy_ylly__Byy__y____yll_yB_______y______yyy____y___y___",
|
||||||
"svg": null,
|
|
||||||
"color": "",
|
|
||||||
"credit": "https://www.factorio.com"
|
"credit": "https://www.factorio.com"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Brigador",
|
"name": "Brigador",
|
||||||
"size": 13,
|
"size": 13,
|
||||||
"bricks": "__________g________BBgggg__________yy__BBggggggggyy_____yglygggl_____yglygggl_______llllll_____ggllggll_____gg__gg________Bg__Bg_______gg__gg________B___B_______ggg_ggg_",
|
"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"
|
"credit": "https://www.gog.com/en/game/brigador"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Teleglitch",
|
"name": "Teleglitch",
|
||||||
"size": 11,
|
"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__",
|
"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"
|
"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 { levelEditorMenuEntry } from "./levelEditor";
|
||||||
import { categories } from "./upgrades";
|
import { categories } from "./upgrades";
|
||||||
import { reasonLevelIsLocked } from "./get_level_unlock_condition";
|
import { reasonLevelIsLocked } from "./get_level_unlock_condition";
|
||||||
|
import { frameStarted, getWorstFPSAndReset, startWork } from "./fps";
|
||||||
|
|
||||||
export async function play() {
|
export async function play() {
|
||||||
if (await applyFullScreenChoice()) return;
|
if (await applyFullScreenChoice()) return;
|
||||||
|
@ -332,6 +333,7 @@ export function hitsSomething(x: number, y: number, radius: number) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function tick() {
|
export function tick() {
|
||||||
|
frameStarted();
|
||||||
startWork("physics");
|
startWork("physics");
|
||||||
const currentTick = performance.now();
|
const currentTick = performance.now();
|
||||||
const timeDeltaMs = currentTick - gameState.lastTick;
|
const timeDeltaMs = currentTick - gameState.lastTick;
|
||||||
|
@ -382,62 +384,8 @@ export function tick() {
|
||||||
startWork("idle");
|
startWork("idle");
|
||||||
|
|
||||||
requestAnimationFrame(tick);
|
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(() => {
|
setInterval(() => {
|
||||||
monitorLevelsUnlocks(gameState);
|
monitorLevelsUnlocks(gameState);
|
||||||
}, 500);
|
}, 500);
|
||||||
|
@ -1013,6 +961,7 @@ document.addEventListener("keyup", async (e) => {
|
||||||
export const gameState = newGameState({});
|
export const gameState = newGameState({});
|
||||||
|
|
||||||
export function restart(params: RunParams) {
|
export function restart(params: RunParams) {
|
||||||
|
getWorstFPSAndReset();
|
||||||
Object.assign(gameState, newGameState(params));
|
Object.assign(gameState, newGameState(params));
|
||||||
// Recompute brick size according to level
|
// Recompute brick size according to level
|
||||||
fitSize(gameState);
|
fitSize(gameState);
|
||||||
|
@ -1033,7 +982,7 @@ export function startComputerControlledGame(stress: boolean = false) {
|
||||||
const perks: Partial<PerksMap> = { base_combo: 20, pierce: 3 };
|
const perks: Partial<PerksMap> = { base_combo: 20, pierce: 3 };
|
||||||
if (stress) {
|
if (stress) {
|
||||||
Object.assign(perks, {
|
Object.assign(perks, {
|
||||||
base_combo: 5000,
|
base_combo: 150,
|
||||||
pierce: 20,
|
pierce: 20,
|
||||||
rainbow: 3,
|
rainbow: 3,
|
||||||
sapper: 2,
|
sapper: 2,
|
||||||
|
@ -1045,6 +994,9 @@ export function startComputerControlledGame(stress: boolean = false) {
|
||||||
for (let i = 0; i < 10; i++) {
|
for (let i = 0; i < 10; i++) {
|
||||||
const u = sample(upgrades);
|
const u = sample(upgrades);
|
||||||
perks[u.id] ||= Math.floor(Math.random() * u.max) + 1;
|
perks[u.id] ||= Math.floor(Math.random() * u.max) + 1;
|
||||||
|
if (u.requires) {
|
||||||
|
perks[u.requires] ||= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
perks.superhot = 0;
|
perks.superhot = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,11 @@ import {
|
||||||
isLevelLocked,
|
isLevelLocked,
|
||||||
reasonLevelIsLocked,
|
reasonLevelIsLocked,
|
||||||
} from "./get_level_unlock_condition";
|
} from "./get_level_unlock_condition";
|
||||||
|
import { getWorstFPSAndReset } from "./fps";
|
||||||
|
import {
|
||||||
|
applySettingsChangeReco,
|
||||||
|
settingsChangeRecommendations,
|
||||||
|
} from "./openUpgradesPicker";
|
||||||
|
|
||||||
export function addToTotalPlayTime(ms: number) {
|
export function addToTotalPlayTime(ms: number) {
|
||||||
setSettingValue(
|
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;
|
if (!gameState.running) return;
|
||||||
|
|
||||||
// Ignore duplicated calls, can happen when ticking is split in multiple updates because the ball goes fast
|
// Ignore duplicated calls, can happen when ticking is split in multiple updates because the ball goes fast
|
||||||
if (gameState.isGameOver) return;
|
if (gameState.isGameOver) return;
|
||||||
|
|
||||||
gameState.isGameOver = true;
|
gameState.isGameOver = true;
|
||||||
|
|
||||||
pause(false);
|
pause(false);
|
||||||
askForPersistentStorage();
|
askForPersistentStorage();
|
||||||
stopRecording();
|
stopRecording();
|
||||||
|
@ -84,7 +90,7 @@ export function gameOver(title: string, intro: string) {
|
||||||
// Avoid the sad sound right as we restart a new games
|
// Avoid the sad sound right as we restart a new games
|
||||||
gameState.combo = 1;
|
gameState.combo = 1;
|
||||||
|
|
||||||
asyncAlert({
|
const choice = await asyncAlert({
|
||||||
allowClose: true,
|
allowClose: true,
|
||||||
title,
|
title,
|
||||||
content: [
|
content: [
|
||||||
|
@ -93,6 +99,7 @@ export function gameOver(title: string, intro: string) {
|
||||||
<p>${intro}</p>
|
<p>${intro}</p>
|
||||||
<p>${t("gameOver.cumulative_total", { startTs, endTs })}</p>
|
<p>${t("gameOver.cumulative_total", { startTs, endTs })}</p>
|
||||||
`,
|
`,
|
||||||
|
settingsChangeRecommendations(),
|
||||||
{
|
{
|
||||||
icon: icons["icon:new_run"],
|
icon: icons["icon:new_run"],
|
||||||
value: null,
|
value: null,
|
||||||
|
@ -105,11 +112,11 @@ export function gameOver(title: string, intro: string) {
|
||||||
getHistograms(gameState),
|
getHistograms(gameState),
|
||||||
pickedUpgradesHTMl(gameState),
|
pickedUpgradesHTMl(gameState),
|
||||||
],
|
],
|
||||||
}).then(() =>
|
});
|
||||||
|
applySettingsChangeReco(choice);
|
||||||
restart({
|
restart({
|
||||||
levelToAvoid: currentLevelInfo(gameState).name,
|
levelToAvoid: currentLevelInfo(gameState).name,
|
||||||
}),
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCreativeModeWarning(gameState: GameState) {
|
export function getCreativeModeWarning(gameState: GameState) {
|
||||||
|
|
|
@ -2178,6 +2178,9 @@ function makeParticle(
|
||||||
size = 8,
|
size = 8,
|
||||||
duration = 150,
|
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>) => {
|
append(gameState.particles, (p: Partial<ParticleFlash>) => {
|
||||||
p.time = gameState.levelTime;
|
p.time = gameState.levelTime;
|
||||||
p.x = x;
|
p.x = x;
|
||||||
|
|
|
@ -228,6 +228,12 @@
|
||||||
"settings.sounds_help": "أصوات صفير وبلبل و برررر",
|
"settings.sounds_help": "أصوات صفير وبلبل و برررر",
|
||||||
"settings.stress_test": "اختبار الإجهاد",
|
"settings.stress_test": "اختبار الإجهاد",
|
||||||
"settings.stress_test_help": "ابدأ لعبة يتم التحكم فيها بواسطة روبوت باستخدام عدد كبير جدًا من العملات المعدنية، لاختبار حدود أداء جهازك.",
|
"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": "تأخر البدء على الهاتف المحمول",
|
||||||
"settings.touch_delayed_start_help": "3،2،1،اذهب في بداية المستوى",
|
"settings.touch_delayed_start_help": "3،2،1،اذهب في بداية المستوى",
|
||||||
"starting_perks.checked": "عند بدء لعبة جديدة، ستُمنح إحدى هذه المزايا. انقر على أي ميزة لاستبعادها.",
|
"starting_perks.checked": "عند بدء لعبة جديدة، ستُمنح إحدى هذه المزايا. انقر على أي ميزة لاستبعادها.",
|
||||||
|
|
|
@ -8137,6 +8137,221 @@
|
||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</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>
|
<concept_node>
|
||||||
<name>touch_delayed_start</name>
|
<name>touch_delayed_start</name>
|
||||||
<description/>
|
<description/>
|
||||||
|
|
|
@ -228,6 +228,12 @@
|
||||||
"settings.sounds_help": "Piepsen, Bloops und Brrrr",
|
"settings.sounds_help": "Piepsen, Bloops und Brrrr",
|
||||||
"settings.stress_test": "Stresstest",
|
"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.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": "Verzögerter Start auf Mobilgeräten",
|
||||||
"settings.touch_delayed_start_help": "3,2,1,Los zu Beginn eines Levels",
|
"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.",
|
"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.sounds_help": "Beeps, bloops and brrrr",
|
||||||
"settings.stress_test": "Stress test",
|
"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.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": "Delayed start on mobile",
|
||||||
"settings.touch_delayed_start_help": "3,2,1,Go at the start of a level",
|
"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. ",
|
"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.sounds_help": "Pitidos, bloops y brrrr",
|
||||||
"settings.stress_test": "Prueba de estrés",
|
"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.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": "Inicio retrasado en el móvil",
|
||||||
"settings.touch_delayed_start_help": "3,2,1,Ve al inicio de un nivel",
|
"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.",
|
"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.sounds_help": "Bips, bloops et brrrr",
|
||||||
"settings.stress_test": "Test de stress",
|
"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.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": "Démarrage différé sur mobile",
|
||||||
"settings.touch_delayed_start_help": "3,2,1,Allez au début d'un niveau",
|
"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.",
|
"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.sounds_help": "Бипы, блепы и брррр",
|
||||||
"settings.stress_test": "Стресс-тест",
|
"settings.stress_test": "Стресс-тест",
|
||||||
"settings.stress_test_help": "Запустите игру, управляемую ботом, с очень большим количеством монет, чтобы проверить пределы производительности вашего устройства.",
|
"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": "Отложенный старт на мобильном устройстве",
|
||||||
"settings.touch_delayed_start_help": "3,2,1,Перейти к началу уровня",
|
"settings.touch_delayed_start_help": "3,2,1,Перейти к началу уровня",
|
||||||
"starting_perks.checked": "Когда вы начнете новую игру, вам будет дано одно из этих преимуществ. Щелкните по перку, чтобы исключить его.",
|
"starting_perks.checked": "Когда вы начнете новую игру, вам будет дано одно из этих преимуществ. Щелкните по перку, чтобы исключить его.",
|
||||||
|
|
|
@ -228,6 +228,12 @@
|
||||||
"settings.sounds_help": "Bipler, blooplar ve brrrr",
|
"settings.sounds_help": "Bipler, blooplar ve brrrr",
|
||||||
"settings.stress_test": "Stres testi",
|
"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.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": "Mobilde gecikmeli başlatma",
|
||||||
"settings.touch_delayed_start_help": "3,2,1,Bir seviyenin başlangıcında git",
|
"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.",
|
"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 {
|
import {
|
||||||
catchRateBest,
|
catchRateBest,
|
||||||
catchRateGood,
|
catchRateGood,
|
||||||
|
@ -24,6 +24,13 @@ import {
|
||||||
} from "./game_utils";
|
} from "./game_utils";
|
||||||
import { getFirstUnlockable, getNearestUnlockHTML } from "./openScorePanel";
|
import { getFirstUnlockable, getNearestUnlockHTML } from "./openScorePanel";
|
||||||
import { isOptionOn } from "./options";
|
import { isOptionOn } from "./options";
|
||||||
|
import { getWorstFPSAndReset } from "./fps";
|
||||||
|
import {
|
||||||
|
getCurrentMaxCoins,
|
||||||
|
getSettingValue,
|
||||||
|
setSettingValue,
|
||||||
|
} from "./settings";
|
||||||
|
import { toast } from "./toast";
|
||||||
|
|
||||||
export async function openUpgradesPicker(gameState: GameState) {
|
export async function openUpgradesPicker(gameState: GameState) {
|
||||||
const catchRate =
|
const catchRate =
|
||||||
|
@ -129,7 +136,7 @@ export async function openUpgradesPicker(gameState: GameState) {
|
||||||
}))
|
}))
|
||||||
.sort((a, b) => a.score - b.score)
|
.sort((a, b) => a.score - b.score)
|
||||||
.filter((u) => gameState.perks[u.id] < u.max + gameState.perks.limitless);
|
.filter((u) => gameState.perks[u.id] < u.max + gameState.perks.limitless);
|
||||||
|
let recommendation = settingsChangeRecommendations();
|
||||||
while (true) {
|
while (true) {
|
||||||
// refresh the list if you pick extra one_more_choice
|
// refresh the list if you pick extra one_more_choice
|
||||||
const offered = sorted.slice(
|
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", {
|
title: t("level_up.title", {
|
||||||
level: gameState.currentLevel,
|
level: gameState.currentLevel,
|
||||||
max: max_levels(gameState),
|
max: max_levels(gameState),
|
||||||
|
@ -191,21 +200,106 @@ export async function openUpgradesPicker(gameState: GameState) {
|
||||||
...upgradesActions,
|
...upgradesActions,
|
||||||
levelsListHTMl(gameState, gameState.currentLevel),
|
levelsListHTMl(gameState, gameState.currentLevel),
|
||||||
unlockRelatedUpgradesOffered ? getNearestUnlockHTML(gameState) : "",
|
unlockRelatedUpgradesOffered ? getNearestUnlockHTML(gameState) : "",
|
||||||
|
recommendation,
|
||||||
...medals,
|
...medals,
|
||||||
pickedUpgradesHTMl(gameState),
|
pickedUpgradesHTMl(gameState),
|
||||||
`<div id="level-recording-container"></div>`,
|
`<div id="level-recording-container"></div>`,
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (applySettingsChangeReco(choice)) {
|
||||||
|
recommendation = "";
|
||||||
|
} else {
|
||||||
upgradePoints--;
|
upgradePoints--;
|
||||||
gameState.perks[upgradeId]++;
|
gameState.perks[choice]++;
|
||||||
gameState.runStatistics.upgrades_picked++;
|
gameState.runStatistics.upgrades_picked++;
|
||||||
if (!upgradePoints) {
|
if (!upgradePoints) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function dontOfferTooSoon(gameState: GameState, id: PerkId) {
|
export function dontOfferTooSoon(gameState: GameState, id: PerkId) {
|
||||||
gameState.lastOffered[id] = Math.round(Date.now() / 1000);
|
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";
|
} from "./game_utils";
|
||||||
import { colorString, GameState } from "./types";
|
import { colorString, GameState } from "./types";
|
||||||
import { t } from "./i18n/i18n";
|
import { t } from "./i18n/i18n";
|
||||||
import { gameState, lastMeasuredFPS, startWork } from "./game";
|
import { gameState } from "./game";
|
||||||
import { isOptionOn } from "./options";
|
import { isOptionOn } from "./options";
|
||||||
import {
|
import {
|
||||||
ballTransparency,
|
ballTransparency,
|
||||||
|
@ -29,6 +29,7 @@ import {
|
||||||
missesBest,
|
missesBest,
|
||||||
missesGood,
|
missesGood,
|
||||||
} from "./pure_functions";
|
} from "./pure_functions";
|
||||||
|
import { lastMeasuredFPS, startWork } from "./fps";
|
||||||
|
|
||||||
export const gameCanvas = document.getElementById("game") as HTMLCanvasElement;
|
export const gameCanvas = document.getElementById("game") as HTMLCanvasElement;
|
||||||
export const ctx = gameCanvas.getContext("2d", {
|
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
|
# we don't add a version tag to let fdroid ignore this build
|
||||||
|
|
||||||
# upload to breakout-v3-staging.lecaro.me
|
# upload to b72.lecaro.me
|
||||||
DOMAIN="breakout-v3-staging.lecaro.me"
|
DOMAIN="b72.lecaro.me"
|
||||||
PUBLIC_CONTENT="./build/*"
|
PUBLIC_CONTENT="./build/*"
|
||||||
|
|
||||||
ssh staging "mkdir -p /opt/mup-nginx-proxy/config/html/static_sites/$DOMAIN"
|
ssh staging "mkdir -p /opt/mup-nginx-proxy/config/html/static_sites/$DOMAIN"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue