mirror of
https://gitlab.com/lecarore/breakout71.git
synced 2025-05-04 18:59:13 -04:00
wip
This commit is contained in:
parent
4c66cc820c
commit
cee5c6bc60
28 changed files with 948 additions and 344 deletions
20
Readme.md
20
Readme.md
|
@ -13,25 +13,25 @@ Break colourful bricks, catch bouncing coins and select powerful upgrades !
|
||||||
|
|
||||||
# Changelog
|
# Changelog
|
||||||
## To do
|
## To do
|
||||||
|
- instead of bouncing the ball,loosing a life pauses the game (with coins still in the air)
|
||||||
|
|
||||||
- rewoks perks choices
|
## Done
|
||||||
- goal : limit perk fatigue, avoid wall of texts, clarify challenges, allow users to skip
|
- rewoked perks choices to limit perk fatigue, avoid wall of texts, allow users to skip
|
||||||
- remove rerolls
|
- removed rerolls
|
||||||
- offer to pick 1 upgrade out of 3 choices
|
- offer to pick 1 upgrade out of 3 choices
|
||||||
- playing well adds 1 upgrade and 1 choice
|
- playing well adds 1 upgrade and 1 choice
|
||||||
- playing even better adds 1 choice
|
- playing even better adds 1 choice
|
||||||
- "more choices" perk adds 1 choice
|
- "more choices" perk adds 1 choice
|
||||||
- you can skip the upgrades and they'll be saved for later
|
- you can skip the upgrades and they'll be saved for later as extra lives
|
||||||
- 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).
|
- bigger "level X of Y cleared"
|
||||||
- bigger "level X or Y cleared", continue to level X/Y as button
|
- continue to level X/Y as button
|
||||||
- lives = upgrade points
|
- lives = upgrade points
|
||||||
- instead of bouncing the ball,loosing a life pauses the game (with coins still in the air)
|
- clarify challenges
|
||||||
|
- missed challenges show as greyed out choices (with unlock condition).
|
||||||
|
|
||||||
## Done
|
|
||||||
|
|
||||||
- somehow score clicks didn't register while the game was playing, that's solved
|
|
||||||
- upgrades list now uses numbers instead of bars, looks better with limitless
|
- upgrades list now uses numbers instead of bars, looks better with limitless
|
||||||
|
- somehow score clicks didn't register while the game was playing, that's solved
|
||||||
- Fix : click tooltip to open on mobile, click anywhere to close
|
- Fix : click tooltip to open on mobile, click anywhere to close
|
||||||
- Can't press help buttons in Creative Menu
|
- Can't press help buttons in Creative Menu
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,8 @@ android {
|
||||||
applicationId = "me.lecaro.breakout"
|
applicationId = "me.lecaro.breakout"
|
||||||
minSdk = 21
|
minSdk = 21
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 29097764
|
versionCode = 29099215
|
||||||
versionName = "29097764"
|
versionName = "29099215"
|
||||||
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
119
dist/index.html
vendored
119
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 = "29097764";
|
const VERSION = "29099215";
|
||||||
|
|
||||||
// The name of the cache
|
// The name of the cache
|
||||||
const CACHE_NAME = `breakout-71-${VERSION}`;
|
const CACHE_NAME = `breakout-71-${VERSION}`;
|
||||||
|
|
|
@ -101,8 +101,8 @@ export async function asyncAlert<t>({
|
||||||
popup.appendChild(addto);
|
popup.appendChild(addto);
|
||||||
}
|
}
|
||||||
|
|
||||||
const buttonWrap = document.createElement("div")
|
const buttonWrap = document.createElement("div");
|
||||||
addto.appendChild(buttonWrap)
|
addto.appendChild(buttonWrap);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
text,
|
text,
|
||||||
|
@ -136,7 +136,9 @@ ${icon}
|
||||||
}
|
}
|
||||||
|
|
||||||
button.className =
|
button.className =
|
||||||
className + (lastClickedItemIndex === index ? " needs-focus" : "")+' choice-button';
|
className +
|
||||||
|
(lastClickedItemIndex === index ? " needs-focus" : "") +
|
||||||
|
" choice-button";
|
||||||
|
|
||||||
buttonWrap.appendChild(button);
|
buttonWrap.appendChild(button);
|
||||||
|
|
||||||
|
|
|
@ -1392,66 +1392,71 @@
|
||||||
"credit": "Suggested by Big Goober. The red ghost, Blinky, from the arcade game \"Pac Man\""
|
"credit": "Suggested by Big Goober. The red ghost, Blinky, from the arcade game \"Pac Man\""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": "#000000",
|
"name": "Fish",
|
||||||
"size": 11,
|
"size": 11,
|
||||||
"bricks": "______________________________________________bbbb______tttttt___btgttbttt_bbtttttbtttb___ttbttt_bb_tttttt___b___________",
|
"bricks": "______________________________________________bbbb______tttttt___btgttbttt_bbtttttbtttb___ttbttt_bb_tttttt___b___________",
|
||||||
"name": "Fish",
|
|
||||||
"credit": "A fish based on the fish discord emoji. Suggested by Big Goober. "
|
"credit": "A fish based on the fish discord emoji. Suggested by Big Goober. "
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": "#115988",
|
"name": "Spider",
|
||||||
"size": 7,
|
"size": 7,
|
||||||
"bricks": "_l_____Sgg____ggSgBB_gSgBBBBSgggggg_gg___g_g_g_g_",
|
"bricks": "_l_____Sgg____ggSgBB_gSgBBBBSgggggg_gg___g_g_g_g_",
|
||||||
"name": "Spider",
|
|
||||||
"credit": "Suggested by obigre."
|
"credit": "Suggested by obigre."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": "#115988",
|
"name": "Gliders",
|
||||||
"size": 8,
|
"size": 8,
|
||||||
"bricks": "g_g______gg___l__g__l_l______ll__c________cc__W__cc____W_____WWW",
|
"bricks": "g_g______gg___l__g__l_l______ll__c________cc__W__cc____W_____WWW",
|
||||||
"name": "Gliders",
|
|
||||||
"credit": "iSuggested by obigre. Inspired by Conway's gliders"
|
"credit": "iSuggested by obigre. Inspired by Conway's gliders"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": "#000000",
|
"name": "Lone island",
|
||||||
"size": 8,
|
"size": 8,
|
||||||
"bricks": "C__________kkk____kkOkk___kkkO_k_k_k_O_______O______CC__tttCCCCt",
|
"bricks": "C__________kkk____kkOkk___kkkO_k_k_k_O_______O______CC__tttCCCCt",
|
||||||
"name": "Lone island",
|
|
||||||
"credit": "Suggested by obigre. Which game would you take there ?"
|
"credit": "Suggested by obigre. Which game would you take there ?"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": "#000000",
|
"name": "Spacewyrm Jon",
|
||||||
"size": 8,
|
"size": 8,
|
||||||
"bricks": "___PPP____PPPP____SSSP____WPWP_P__PPP_PP___PP_____yPPy__bWWyyWWb",
|
"bricks": "___PPP____PPPP____SSSP____WPWP_P__PPP_PP___PP_____yPPy__bWWyyWWb",
|
||||||
"name": "Spacewyrm Jon",
|
|
||||||
"credit": "Suggested by obigre. The invertebrate hero with a gun"
|
"credit": "Suggested by obigre. The invertebrate hero with a gun"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": "#115988",
|
"name": "Taijitu",
|
||||||
"size": 7,
|
"size": 7,
|
||||||
"bricks": "_WWWWW_W__WWWWgg__WBWggg_WWWgBg__WWgggg__g_ggggg_",
|
"bricks": "_WWWWW_W__WWWWgg__WBWggg_WWWgBg__WWgggg__g_ggggg_",
|
||||||
"name": "Taijitu",
|
|
||||||
"credit": "Suggested by obigre. Yin and yang fishes"
|
"credit": "Suggested by obigre. Yin and yang fishes"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": "#115988",
|
"name": "Egg pan",
|
||||||
"size": 5,
|
"size": 5,
|
||||||
"bricks": "WWWWgWWyWggWWWggggg____g_",
|
"bricks": "WWWWgWWyWggWWWggggg____g_",
|
||||||
"name": "Egg pan",
|
|
||||||
"credit": "Suggested by obigre. Fried and tasty"
|
"credit": "Suggested by obigre. Fried and tasty"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": "#000000",
|
"name": "Inception",
|
||||||
"size": 20,
|
"size": 20,
|
||||||
"bricks": "____llllllllllll________lbbbbbb____l________lbbbbbb____l________l____bbtt__l________l____bbtt__l________l__bbtttt__l________l__bbtttt__l________l______tt__l________l____y_tt__l________l______ttttl________l_____yttttl________l__W_______l________l_____y____l________l__y_y_____l________l_y___y_y__l________l__________l________l___WWW____l________llllllllllll____________________________________________",
|
"bricks": "____llllllllllll________lbbbbbb____l________lbbbbbb____l________l____bbtt__l________l____bbtt__l________l__bbtttt__l________l__bbtttt__l________l______tt__l________l____y_tt__l________l______ttttl________l_____yttttl________l__W_______l________l_____y____l________l__y_y_____l________l_y___y_y__l________l__________l________l___WWW____l________llllllllllll____________________________________________",
|
||||||
"name": "Inception",
|
|
||||||
"credit": "Breakout 71 within Breakout 71. By Noodlemire"
|
"credit": "Breakout 71 within Breakout 71. By Noodlemire"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": "#000000",
|
"name": "Chess",
|
||||||
"size": 21,
|
"size": 21,
|
||||||
"bricks": "_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_",
|
"bricks": "_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_W_",
|
||||||
"name": "Chess",
|
|
||||||
"credit": "White n black by Topenvy"
|
"credit": "White n black by Topenvy"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "icon:locked",
|
||||||
|
"size": 8,
|
||||||
|
"bricks": "__eeee____e__e____e__e____e__e___llllll__llllll__llllll__llllll_",
|
||||||
|
"svg": null,
|
||||||
|
"color": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": "#000000",
|
||||||
|
"size": 8,
|
||||||
|
"bricks": "_________GGWWrr__GGWWrr__GGWWrr__GGWWrr_________________________",
|
||||||
|
"name": "italy",
|
||||||
|
"credit": "italia by Topenvy"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -767,5 +767,10 @@
|
||||||
"required": ["respawn", "wrap_left", "sapper"],
|
"required": ["respawn", "wrap_left", "sapper"],
|
||||||
"forbidden": ["shocks", "metamorphosis", "pierce"],
|
"forbidden": ["shocks", "metamorphosis", "pierce"],
|
||||||
"minScore": 14200
|
"minScore": 14200
|
||||||
|
},
|
||||||
|
"italy": {
|
||||||
|
"required": ["sticky_coins", "pierce_color", "left_is_lava"],
|
||||||
|
"forbidden": ["transparency", "etherealcoins", "three_cushion"],
|
||||||
|
"minScore": 14300
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
"29097764"
|
"29099215"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
* {
|
* {
|
||||||
font-family: Courier New,
|
font-family:
|
||||||
|
Courier New,
|
||||||
Courier,
|
Courier,
|
||||||
Lucida Sans Typewriter,
|
Lucida Sans Typewriter,
|
||||||
Lucida Typewriter,
|
Lucida Typewriter,
|
||||||
|
@ -73,7 +74,6 @@ canvas:not(#game) {
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
box-shadow: 0 2px #fff;
|
box-shadow: 0 2px #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#score {
|
#score {
|
||||||
|
@ -210,7 +210,6 @@ body:not(.has-alert-open) #popup {
|
||||||
opacity: 0.2;
|
opacity: 0.2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
> button[data-help-content] {
|
> button[data-help-content] {
|
||||||
|
@ -425,7 +424,7 @@ h2.histogram-title strong {
|
||||||
|
|
||||||
.level {
|
.level {
|
||||||
color: #000;
|
color: #000;
|
||||||
background: #FFF;
|
background: #fff;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
@ -435,7 +434,7 @@ h2.histogram-title strong {
|
||||||
position: relative;
|
position: relative;
|
||||||
//top: -3px;
|
//top: -3px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
border: 1px solid #FFF;
|
border: 1px solid #fff;
|
||||||
//margin-left: 5px;
|
//margin-left: 5px;
|
||||||
|
|
||||||
> span {
|
> span {
|
||||||
|
@ -443,38 +442,34 @@ h2.histogram-title strong {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
|
|
||||||
padding: 3px 6px 0 2px;
|
padding: 3px 6px 0 2px;
|
||||||
color: #000;
|
color: #000;
|
||||||
background: #FFF;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
|
|
||||||
padding: 3px 3px 0 2px;
|
padding: 3px 3px 0 2px;
|
||||||
color: #FFF;
|
color: #fff;
|
||||||
background: #000;
|
background: #000;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
content: "";
|
content: "";
|
||||||
display: block;
|
display: block;
|
||||||
background: black;;
|
background: black;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -2px;
|
left: -2px;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 4px;
|
width: 4px;
|
||||||
transform: skewX(-10deg)
|
transform: skewX(-10deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.capped {
|
&.capped {
|
||||||
> span:first-child {
|
> span:first-child {
|
||||||
|
color: #fff;
|
||||||
color: #FFF;
|
|
||||||
background: #000;
|
background: #000;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
> span:last-child::before {
|
> span:last-child::before {
|
||||||
|
@ -511,16 +506,22 @@ h2.histogram-title strong {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
box-shadow: 0 4px 0 gold, 0 4px 10px black;
|
box-shadow:
|
||||||
|
0 4px 0 gold,
|
||||||
|
0 4px 10px black;
|
||||||
border: 2px solid white;
|
border: 2px solid white;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-shadow: 0 0 4px rgba(0, 0, 0, 0.3);
|
text-shadow: 0 0 4px rgba(0, 0, 0, 0.3);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
&:active {
|
&:active {
|
||||||
transform: translate(0, 4px);
|
transform: translate(0, 4px);
|
||||||
box-shadow: 0 0px 0 gold, 0 0px 10px black;
|
box-shadow:
|
||||||
|
0 0px 0 gold,
|
||||||
|
0 0px 10px black;
|
||||||
}
|
}
|
||||||
transition: transform 0.2s, box-shadow 0.2s;
|
transition:
|
||||||
|
transform 0.2s,
|
||||||
|
box-shadow 0.2s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -614,7 +615,8 @@ h2.histogram-title strong {
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
transition: opacity 200ms,
|
transition:
|
||||||
|
opacity 200ms,
|
||||||
transform 200ms;
|
transform 200ms;
|
||||||
z-index: 7;
|
z-index: 7;
|
||||||
|
|
||||||
|
|
67
src/game.ts
67
src/game.ts
|
@ -1,5 +1,21 @@
|
||||||
import {allLevels, allLevelsAndIcons, appVersion, icons, upgrades,} from "./loadGameData";
|
import {
|
||||||
import {Ball, Coin, GameState, LightFlash, OptionId, ParticleFlash, PerksMap, RunParams, TextFlash,} from "./types";
|
allLevels,
|
||||||
|
allLevelsAndIcons,
|
||||||
|
appVersion,
|
||||||
|
icons,
|
||||||
|
upgrades,
|
||||||
|
} from "./loadGameData";
|
||||||
|
import {
|
||||||
|
Ball,
|
||||||
|
Coin,
|
||||||
|
GameState,
|
||||||
|
LightFlash,
|
||||||
|
OptionId,
|
||||||
|
ParticleFlash,
|
||||||
|
PerksMap,
|
||||||
|
RunParams,
|
||||||
|
TextFlash,
|
||||||
|
} from "./types";
|
||||||
import { getAudioContext, playPendingSounds } from "./sounds";
|
import { getAudioContext, playPendingSounds } from "./sounds";
|
||||||
import {
|
import {
|
||||||
currentLevelInfo,
|
currentLevelInfo,
|
||||||
|
@ -30,12 +46,29 @@ import {
|
||||||
setLevel,
|
setLevel,
|
||||||
setMousePos,
|
setMousePos,
|
||||||
} from "./gameStateMutators";
|
} from "./gameStateMutators";
|
||||||
import {backgroundCanvas, gameCanvas, getHaloScale, haloCanvas, render, scoreDisplay,} from "./render";
|
import {
|
||||||
import {pauseRecording, recordOneFrame, resumeRecording, startRecordingGame,} from "./recording";
|
backgroundCanvas,
|
||||||
|
gameCanvas,
|
||||||
|
getHaloScale,
|
||||||
|
haloCanvas,
|
||||||
|
render,
|
||||||
|
scoreDisplay,
|
||||||
|
} from "./render";
|
||||||
|
import {
|
||||||
|
pauseRecording,
|
||||||
|
recordOneFrame,
|
||||||
|
resumeRecording,
|
||||||
|
startRecordingGame,
|
||||||
|
} from "./recording";
|
||||||
import { newGameState } from "./newGameState";
|
import { newGameState } from "./newGameState";
|
||||||
import {alertsOpen, asyncAlert, AsyncAlertAction, closeModal,} from "./asyncAlert";
|
import {
|
||||||
|
alertsOpen,
|
||||||
|
asyncAlert,
|
||||||
|
AsyncAlertAction,
|
||||||
|
closeModal,
|
||||||
|
} from "./asyncAlert";
|
||||||
import { isOptionOn, options, toggleOption } from "./options";
|
import { isOptionOn, options, toggleOption } from "./options";
|
||||||
import {clamp, miniMarkDown,} from "./pure_functions";
|
import { clamp, miniMarkDown } 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";
|
||||||
|
@ -369,43 +402,37 @@ setInterval(() => {
|
||||||
monitorLevelsUnlocks(gameState);
|
monitorLevelsUnlocks(gameState);
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
|
|
||||||
document.addEventListener("visibilitychange", () => {
|
document.addEventListener("visibilitychange", () => {
|
||||||
if (document.hidden) {
|
if (document.hidden) {
|
||||||
pause(true);
|
pause(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if(getSettingValue('score-opened',0 )<3){
|
if (getSettingValue("score-opened", 0) < 3) {
|
||||||
scoreDisplay.classList.add('button-look')
|
scoreDisplay.classList.add("button-look");
|
||||||
}
|
}
|
||||||
const menuDisplay = document.getElementById("menu") as HTMLButtonElement;
|
const menuDisplay = document.getElementById("menu") as HTMLButtonElement;
|
||||||
if(getSettingValue('menu-opened',0 )<3){
|
if (getSettingValue("menu-opened", 0) < 3) {
|
||||||
menuDisplay.classList.add('button-look')
|
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 )
|
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);
|
||||||
|
|
||||||
menuDisplay.addEventListener(
|
menuDisplay.addEventListener("click", (e) => {
|
||||||
"click",
|
|
||||||
(e) => {
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (!alertsOpen) {
|
if (!alertsOpen) {
|
||||||
|
setSettingValue("menu-opened", getSettingValue("menu-opened", 0) + 1);
|
||||||
setSettingValue('menu-opened',getSettingValue('menu-opened',0 )+1 )
|
|
||||||
openMainMenu();
|
openMainMenu();
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
export const creativeModeThreshold = Math.max(
|
export const creativeModeThreshold = Math.max(
|
||||||
...upgrades.map((u) => u.threshold),
|
...upgrades.map((u) => u.threshold),
|
||||||
|
|
|
@ -34,10 +34,23 @@ import {t} from "./i18n/i18n";
|
||||||
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 {brickIndex, fitSize, gameState, hasBrick, hitsSomething, pause, startComputerControlledGame,} from "./game";
|
import {
|
||||||
|
brickIndex,
|
||||||
|
fitSize,
|
||||||
|
gameState,
|
||||||
|
hasBrick,
|
||||||
|
hitsSomething,
|
||||||
|
pause,
|
||||||
|
startComputerControlledGame,
|
||||||
|
} from "./game";
|
||||||
import { stopRecording } from "./recording";
|
import { stopRecording } from "./recording";
|
||||||
import { isOptionOn } from "./options";
|
import { isOptionOn } from "./options";
|
||||||
import {ballTransparency, clamp, coinsBoostedCombo, comboKeepingRate,} from "./pure_functions";
|
import {
|
||||||
|
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";
|
import { openUpgradesPicker } from "./openUpgradesPicker";
|
||||||
|
@ -606,7 +619,6 @@ export async function setLevel(gameState: GameState, l: number) {
|
||||||
gameState.currentLevel = l;
|
gameState.currentLevel = l;
|
||||||
gameState.level = gameState.runLevels[l % gameState.runLevels.length];
|
gameState.level = gameState.runLevels[l % gameState.runLevels.length];
|
||||||
|
|
||||||
|
|
||||||
if (l > 0) {
|
if (l > 0) {
|
||||||
await openUpgradesPicker(gameState);
|
await openUpgradesPicker(gameState);
|
||||||
}
|
}
|
||||||
|
@ -956,7 +968,8 @@ export function gameStateTick(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (( window.location.search.includes("skipplaying") ||
|
if (
|
||||||
|
(window.location.search.includes("skipplaying") ||
|
||||||
remainingBricks <= gameState.perks.skip_last) &&
|
remainingBricks <= gameState.perks.skip_last) &&
|
||||||
!gameState.autoCleanUses
|
!gameState.autoCleanUses
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
import {Ball, Coin, GameState, Level, PerkId, PerksMap, Upgrade} 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,10 +107,13 @@ 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) {
|
export function upgradeLevelAndMaxDisplay(
|
||||||
|
upgrade: Upgrade,
|
||||||
|
gameState: GameState,
|
||||||
|
) {
|
||||||
const lvl = gameState.perks[upgrade.id];
|
const lvl = gameState.perks[upgrade.id];
|
||||||
const max = upgrade.max + gameState.perks.limitless
|
const max = upgrade.max + gameState.perks.limitless;
|
||||||
return `<span class="level ${lvl < max ? 'can-upgrade' : 'capped'}"><span>${lvl}</span><span>${max}</span></span>`
|
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) {
|
||||||
|
@ -111,7 +122,6 @@ export function pickedUpgradesHTMl(gameState: GameState) {
|
||||||
.map((u) => {
|
.map((u) => {
|
||||||
const newMax = Math.max(0, u.max + gameState.perks.limitless);
|
const newMax = Math.max(0, u.max + gameState.perks.limitless);
|
||||||
|
|
||||||
|
|
||||||
const state = (gameState.perks[u.id] && 1) || (!newMax && 2) || 3;
|
const state = (gameState.perks[u.id] && 1) || (!newMax && 2) || 3;
|
||||||
return {
|
return {
|
||||||
state,
|
state,
|
||||||
|
@ -321,5 +331,9 @@ export function hoursSpentPlaying() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function escapeAttribute(str: String) {
|
export function escapeAttribute(str: String) {
|
||||||
return str.replace(/&/gi,'&').replace(/</gi,'<').replace(/"/gi,'"').replace(/'/gi,''')
|
return str
|
||||||
|
.replace(/&/gi, "&")
|
||||||
|
.replace(/</gi, "<")
|
||||||
|
.replace(/"/gi, """)
|
||||||
|
.replace(/'/gi, "'");
|
||||||
}
|
}
|
|
@ -71,6 +71,16 @@
|
||||||
"level_up.go": "",
|
"level_up.go": "",
|
||||||
"level_up.instructions": "",
|
"level_up.instructions": "",
|
||||||
"level_up.maxed_upgrade": "",
|
"level_up.maxed_upgrade": "",
|
||||||
|
"level_up.missed.best": "",
|
||||||
|
"level_up.missed.catchRate.best": "",
|
||||||
|
"level_up.missed.catchRate.good": "",
|
||||||
|
"level_up.missed.good": "",
|
||||||
|
"level_up.missed.levelMisses.best": "",
|
||||||
|
"level_up.missed.levelMisses.good": "",
|
||||||
|
"level_up.missed.levelTime.best": "",
|
||||||
|
"level_up.missed.levelTime.good": "",
|
||||||
|
"level_up.missed.levelWallBounces.best": "",
|
||||||
|
"level_up.missed.levelWallBounces.good": "",
|
||||||
"level_up.no_points": "",
|
"level_up.no_points": "",
|
||||||
"level_up.pick": "",
|
"level_up.pick": "",
|
||||||
"level_up.pick_upgrade": "",
|
"level_up.pick_upgrade": "",
|
||||||
|
|
|
@ -2597,6 +2597,381 @@
|
||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<folder_node>
|
||||||
|
<name>missed</name>
|
||||||
|
<children>
|
||||||
|
<concept_node>
|
||||||
|
<name>best</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>
|
||||||
|
<folder_node>
|
||||||
|
<name>catchRate</name>
|
||||||
|
<children>
|
||||||
|
<concept_node>
|
||||||
|
<name>best</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>good</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>good</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>
|
||||||
|
<folder_node>
|
||||||
|
<name>levelMisses</name>
|
||||||
|
<children>
|
||||||
|
<concept_node>
|
||||||
|
<name>best</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>good</name>
|
||||||
|
<description/>
|
||||||
|
<comment/>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>ar-LB</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>de-DE</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-CL</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-FR</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>ru-RU</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>tr-TR</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
|
</children>
|
||||||
|
</folder_node>
|
||||||
|
<folder_node>
|
||||||
|
<name>levelTime</name>
|
||||||
|
<children>
|
||||||
|
<concept_node>
|
||||||
|
<name>best</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>good</name>
|
||||||
|
<description/>
|
||||||
|
<comment/>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>ar-LB</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>de-DE</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-CL</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-FR</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>ru-RU</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>tr-TR</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
|
</children>
|
||||||
|
</folder_node>
|
||||||
|
<folder_node>
|
||||||
|
<name>levelWallBounces</name>
|
||||||
|
<children>
|
||||||
|
<concept_node>
|
||||||
|
<name>best</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>good</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>
|
||||||
|
</children>
|
||||||
|
</folder_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>no_points</name>
|
<name>no_points</name>
|
||||||
<description/>
|
<description/>
|
||||||
|
|
|
@ -71,6 +71,16 @@
|
||||||
"level_up.go": "",
|
"level_up.go": "",
|
||||||
"level_up.instructions": "",
|
"level_up.instructions": "",
|
||||||
"level_up.maxed_upgrade": "",
|
"level_up.maxed_upgrade": "",
|
||||||
|
"level_up.missed.best": "",
|
||||||
|
"level_up.missed.catchRate.best": "",
|
||||||
|
"level_up.missed.catchRate.good": "",
|
||||||
|
"level_up.missed.good": "",
|
||||||
|
"level_up.missed.levelMisses.best": "",
|
||||||
|
"level_up.missed.levelMisses.good": "",
|
||||||
|
"level_up.missed.levelTime.best": "",
|
||||||
|
"level_up.missed.levelTime.good": "",
|
||||||
|
"level_up.missed.levelWallBounces.best": "",
|
||||||
|
"level_up.missed.levelWallBounces.good": "",
|
||||||
"level_up.no_points": "",
|
"level_up.no_points": "",
|
||||||
"level_up.pick": "",
|
"level_up.pick": "",
|
||||||
"level_up.pick_upgrade": "",
|
"level_up.pick_upgrade": "",
|
||||||
|
|
|
@ -69,8 +69,18 @@
|
||||||
"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.go": "Continue to level \"{{name}}\"",
|
"level_up.go": "Continue to level \"{{name}}\"",
|
||||||
"level_up.instructions": "You gained {{gain}} extra lives. You can use your {{count}} extra lives to buy upgrades below, or keep them to be safe. ",
|
"level_up.instructions": "You can use your {{count}} lives to buy upgrades below or keep them to be safe. ",
|
||||||
"level_up.maxed_upgrade": "\"{{name}}\" is at max level",
|
"level_up.maxed_upgrade": "\"{{name}}\" is at max level",
|
||||||
|
"level_up.missed.best": "Expert challenge",
|
||||||
|
"level_up.missed.catchRate.best": "Catch {{target}}% of coins to gain one more choice.",
|
||||||
|
"level_up.missed.catchRate.good": "Catch {{target}}% of coins to gain one more life and choice.",
|
||||||
|
"level_up.missed.good": "Enthusiast challenge",
|
||||||
|
"level_up.missed.levelMisses.best": "Miss the bricks less than {{target}} times to gain one more choice.",
|
||||||
|
"level_up.missed.levelMisses.good": "Miss the bricks less than {{target}} times to gain one more life and choice.",
|
||||||
|
"level_up.missed.levelTime.best": "Clear the level in less than {{target}} seconds to gain one more choice.",
|
||||||
|
"level_up.missed.levelTime.good": "Clear the level in less than {{target}} seconds to gain one more life and choice.",
|
||||||
|
"level_up.missed.levelWallBounces.best": "Hit the walls less than {{target}} times to gain one more choice.",
|
||||||
|
"level_up.missed.levelWallBounces.good": "Hit the walls less than {{target}} times to gain one more life and choice.",
|
||||||
"level_up.no_points": "You've spent all your extra lives.",
|
"level_up.no_points": "You've spent all your extra lives.",
|
||||||
"level_up.pick": "Pick",
|
"level_up.pick": "Pick",
|
||||||
"level_up.pick_upgrade": "Get \"{{name}}\"",
|
"level_up.pick_upgrade": "Get \"{{name}}\"",
|
||||||
|
@ -433,8 +443,8 @@
|
||||||
"upgrades.trampoline.tooltip": "More coins if you bounce on bricks and the paddle only",
|
"upgrades.trampoline.tooltip": "More coins if you bounce on bricks and the paddle only",
|
||||||
"upgrades.trampoline.verbose_description": "+{{lvl}} combo per paddle bounce,-{{lvl}} combo per bounce on any border. One of the rare combo upgrades that don't add a reset condition",
|
"upgrades.trampoline.verbose_description": "+{{lvl}} combo per paddle bounce,-{{lvl}} combo per bounce on any border. One of the rare combo upgrades that don't add a reset condition",
|
||||||
"upgrades.transparency.name": "Transparency",
|
"upgrades.transparency.name": "Transparency",
|
||||||
"upgrades.transparency.tooltip": "+50% coins but the ball is sometimes invisible",
|
"upgrades.transparency.tooltip": "+50% coins. The ball is invisible at the top of the screen.",
|
||||||
"upgrades.transparency.verbose_description": "Ball becomes transparent at the top of the screen.\n +{{percent}} % coins when all balls are at full transparency. \nHigher levels make the ball transparent sooner and increase the point bonus.",
|
"upgrades.transparency.verbose_description": "Ball becomes transparent at the top of the screen.\n +{{percent}} % coins. \nHigher levels make the ball transparent sooner and increase the point bonus.",
|
||||||
"upgrades.trickledown.name": "Trickle down",
|
"upgrades.trickledown.name": "Trickle down",
|
||||||
"upgrades.trickledown.tooltip": "Coins appear at the top of the screen.",
|
"upgrades.trickledown.tooltip": "Coins appear at the top of the screen.",
|
||||||
"upgrades.trickledown.verbose_description": "The coins might sit on top of a brick if there are bricks on the top row, in that case they will fall down after you break that brick. ",
|
"upgrades.trickledown.verbose_description": "The coins might sit on top of a brick if there are bricks on the top row, in that case they will fall down after you break that brick. ",
|
||||||
|
|
|
@ -71,6 +71,16 @@
|
||||||
"level_up.go": "",
|
"level_up.go": "",
|
||||||
"level_up.instructions": "",
|
"level_up.instructions": "",
|
||||||
"level_up.maxed_upgrade": "",
|
"level_up.maxed_upgrade": "",
|
||||||
|
"level_up.missed.best": "",
|
||||||
|
"level_up.missed.catchRate.best": "",
|
||||||
|
"level_up.missed.catchRate.good": "",
|
||||||
|
"level_up.missed.good": "",
|
||||||
|
"level_up.missed.levelMisses.best": "",
|
||||||
|
"level_up.missed.levelMisses.good": "",
|
||||||
|
"level_up.missed.levelTime.best": "",
|
||||||
|
"level_up.missed.levelTime.good": "",
|
||||||
|
"level_up.missed.levelWallBounces.best": "",
|
||||||
|
"level_up.missed.levelWallBounces.good": "",
|
||||||
"level_up.no_points": "",
|
"level_up.no_points": "",
|
||||||
"level_up.pick": "",
|
"level_up.pick": "",
|
||||||
"level_up.pick_upgrade": "",
|
"level_up.pick_upgrade": "",
|
||||||
|
|
|
@ -71,6 +71,16 @@
|
||||||
"level_up.go": "",
|
"level_up.go": "",
|
||||||
"level_up.instructions": "",
|
"level_up.instructions": "",
|
||||||
"level_up.maxed_upgrade": "",
|
"level_up.maxed_upgrade": "",
|
||||||
|
"level_up.missed.best": "",
|
||||||
|
"level_up.missed.catchRate.best": "",
|
||||||
|
"level_up.missed.catchRate.good": "",
|
||||||
|
"level_up.missed.good": "",
|
||||||
|
"level_up.missed.levelMisses.best": "",
|
||||||
|
"level_up.missed.levelMisses.good": "",
|
||||||
|
"level_up.missed.levelTime.best": "",
|
||||||
|
"level_up.missed.levelTime.good": "",
|
||||||
|
"level_up.missed.levelWallBounces.best": "",
|
||||||
|
"level_up.missed.levelWallBounces.good": "",
|
||||||
"level_up.no_points": "",
|
"level_up.no_points": "",
|
||||||
"level_up.pick": "",
|
"level_up.pick": "",
|
||||||
"level_up.pick_upgrade": "",
|
"level_up.pick_upgrade": "",
|
||||||
|
|
|
@ -71,6 +71,16 @@
|
||||||
"level_up.go": "",
|
"level_up.go": "",
|
||||||
"level_up.instructions": "",
|
"level_up.instructions": "",
|
||||||
"level_up.maxed_upgrade": "",
|
"level_up.maxed_upgrade": "",
|
||||||
|
"level_up.missed.best": "",
|
||||||
|
"level_up.missed.catchRate.best": "",
|
||||||
|
"level_up.missed.catchRate.good": "",
|
||||||
|
"level_up.missed.good": "",
|
||||||
|
"level_up.missed.levelMisses.best": "",
|
||||||
|
"level_up.missed.levelMisses.good": "",
|
||||||
|
"level_up.missed.levelTime.best": "",
|
||||||
|
"level_up.missed.levelTime.good": "",
|
||||||
|
"level_up.missed.levelWallBounces.best": "",
|
||||||
|
"level_up.missed.levelWallBounces.good": "",
|
||||||
"level_up.no_points": "",
|
"level_up.no_points": "",
|
||||||
"level_up.pick": "",
|
"level_up.pick": "",
|
||||||
"level_up.pick_upgrade": "",
|
"level_up.pick_upgrade": "",
|
||||||
|
|
|
@ -71,6 +71,16 @@
|
||||||
"level_up.go": "",
|
"level_up.go": "",
|
||||||
"level_up.instructions": "",
|
"level_up.instructions": "",
|
||||||
"level_up.maxed_upgrade": "",
|
"level_up.maxed_upgrade": "",
|
||||||
|
"level_up.missed.best": "",
|
||||||
|
"level_up.missed.catchRate.best": "",
|
||||||
|
"level_up.missed.catchRate.good": "",
|
||||||
|
"level_up.missed.good": "",
|
||||||
|
"level_up.missed.levelMisses.best": "",
|
||||||
|
"level_up.missed.levelMisses.good": "",
|
||||||
|
"level_up.missed.levelTime.best": "",
|
||||||
|
"level_up.missed.levelTime.good": "",
|
||||||
|
"level_up.missed.levelWallBounces.best": "",
|
||||||
|
"level_up.missed.levelWallBounces.good": "",
|
||||||
"level_up.no_points": "",
|
"level_up.no_points": "",
|
||||||
"level_up.pick": "",
|
"level_up.pick": "",
|
||||||
"level_up.pick_upgrade": "",
|
"level_up.pick_upgrade": "",
|
||||||
|
|
|
@ -7,7 +7,11 @@ 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 {getLevelUnlockCondition, reasonLevelIsLocked, upgradeName,} from "./get_level_unlock_condition";
|
import {
|
||||||
|
getLevelUnlockCondition,
|
||||||
|
reasonLevelIsLocked,
|
||||||
|
upgradeName,
|
||||||
|
} from "./get_level_unlock_condition";
|
||||||
|
|
||||||
export async function openScorePanel(gameState: GameState) {
|
export async function openScorePanel(gameState: GameState) {
|
||||||
pause(true);
|
pause(true);
|
||||||
|
@ -96,4 +100,3 @@ export function getNearestUnlockHTML(gameState: GameState) {
|
||||||
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
missesBest,
|
missesBest,
|
||||||
missesGood,
|
missesGood,
|
||||||
wallBouncedBest,
|
wallBouncedBest,
|
||||||
wallBouncedGood
|
wallBouncedGood,
|
||||||
} from "./pure_functions";
|
} from "./pure_functions";
|
||||||
import { t } from "./i18n/i18n";
|
import { t } from "./i18n/i18n";
|
||||||
import { icons, upgrades } from "./loadGameData";
|
import { icons, upgrades } from "./loadGameData";
|
||||||
|
@ -17,7 +17,7 @@ import {
|
||||||
getPossibleUpgrades,
|
getPossibleUpgrades,
|
||||||
levelsListHTMl,
|
levelsListHTMl,
|
||||||
max_levels,
|
max_levels,
|
||||||
upgradeLevelAndMaxDisplay
|
upgradeLevelAndMaxDisplay,
|
||||||
} from "./game_utils";
|
} from "./game_utils";
|
||||||
import { getNearestUnlockHTML } from "./openScorePanel";
|
import { getNearestUnlockHTML } from "./openScorePanel";
|
||||||
|
|
||||||
|
@ -25,41 +25,101 @@ export async function openUpgradesPicker(gameState: GameState) {
|
||||||
const catchRate =
|
const catchRate =
|
||||||
gameState.levelCoughtCoins / (gameState.levelSpawnedCoins || 1);
|
gameState.levelCoughtCoins / (gameState.levelSpawnedCoins || 1);
|
||||||
|
|
||||||
let choices = 3
|
let choices = 3;
|
||||||
let livesWon=1
|
let livesWon = 1;
|
||||||
|
let missedOpportunities = [];
|
||||||
|
const good = ""; // '<strong>'+t('level_up.missed.good')+'</strong>: '
|
||||||
|
const best = ""; //'<strong>'+t('level_up.missed.best')+'</strong>: '
|
||||||
|
|
||||||
if (gameState.levelWallBounces < wallBouncedGood) {
|
if (gameState.levelWallBounces < wallBouncedGood) {
|
||||||
choices++;
|
choices++;
|
||||||
|
|
||||||
livesWon++;
|
livesWon++;
|
||||||
|
} else {
|
||||||
|
missedOpportunities.push(
|
||||||
|
good +
|
||||||
|
t("level_up.missed.levelWallBounces.good", {
|
||||||
|
target: wallBouncedGood,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
if (gameState.levelWallBounces < wallBouncedBest) {
|
if (gameState.levelWallBounces < wallBouncedBest) {
|
||||||
choices++;
|
choices++;
|
||||||
}
|
} else {
|
||||||
|
missedOpportunities.push(
|
||||||
|
best +
|
||||||
|
t("level_up.missed.levelWallBounces.best", {
|
||||||
|
target: wallBouncedBest,
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gameState.levelTime < levelTimeGood * 1000) {
|
if (gameState.levelTime < levelTimeGood * 1000) {
|
||||||
choices++;
|
choices++;
|
||||||
livesWon++;
|
livesWon++;
|
||||||
|
} else {
|
||||||
|
missedOpportunities.push(
|
||||||
|
good +
|
||||||
|
t("level_up.missed.levelTime.good", {
|
||||||
|
target: levelTimeGood,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
if (gameState.levelTime < levelTimeBest * 1000) {
|
if (gameState.levelTime < levelTimeBest * 1000) {
|
||||||
choices++;
|
choices++;
|
||||||
|
} else {
|
||||||
|
missedOpportunities.push(
|
||||||
|
best +
|
||||||
|
t("level_up.missed.levelTime.best", {
|
||||||
|
target: levelTimeBest,
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (catchRate > catchRateGood / 100) {
|
if (catchRate > catchRateGood / 100) {
|
||||||
choices++;
|
choices++;
|
||||||
livesWon++;
|
livesWon++;
|
||||||
|
} else {
|
||||||
|
missedOpportunities.push(
|
||||||
|
good +
|
||||||
|
t("level_up.missed.catchRate.good", {
|
||||||
|
target: catchRateGood,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
if (catchRate > catchRateBest / 100) {
|
if (catchRate > catchRateBest / 100) {
|
||||||
choices++;
|
choices++;
|
||||||
|
} else {
|
||||||
|
missedOpportunities.push(
|
||||||
|
best +
|
||||||
|
t("level_up.missed.catchRate.best", {
|
||||||
|
target: catchRateBest,
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (gameState.levelMisses < missesGood) {
|
if (gameState.levelMisses < missesGood) {
|
||||||
choices++;
|
choices++;
|
||||||
livesWon++;
|
livesWon++;
|
||||||
|
} else {
|
||||||
|
missedOpportunities.push(
|
||||||
|
good +
|
||||||
|
t("level_up.missed.levelMisses.good", {
|
||||||
|
target: missesGood,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
if (gameState.levelMisses < missesBest) {
|
if (gameState.levelMisses < missesBest) {
|
||||||
choices++;
|
choices++;
|
||||||
}
|
} else {
|
||||||
|
missedOpportunities.push(
|
||||||
|
best +
|
||||||
|
t("level_up.missed.levelMisses.best", {
|
||||||
|
target: missesBest,
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
gameState.extra_lives+=livesWon
|
gameState.extra_lives += livesWon;
|
||||||
|
|
||||||
let offered: PerkId[] = getPossibleUpgrades(gameState)
|
let offered: PerkId[] = getPossibleUpgrades(gameState)
|
||||||
.map((u) => ({
|
.map((u) => ({
|
||||||
|
@ -68,54 +128,62 @@ gameState.extra_lives+=livesWon
|
||||||
}))
|
}))
|
||||||
.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)
|
||||||
.map(u => u.id)
|
.map((u) => u.id);
|
||||||
|
|
||||||
const fromStart = upgrades.map(u => u.id).filter(id => gameState.perks[id])
|
const fromStart = upgrades
|
||||||
|
.map((u) => u.id)
|
||||||
|
.filter((id) => gameState.perks[id]);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
const updatedChoices = gameState.perks.one_more_choice + choices;
|
||||||
|
let list = upgrades.filter(
|
||||||
|
(u) =>
|
||||||
|
offered.slice(0, updatedChoices).includes(u.id) ||
|
||||||
|
gameState.perks[u.id],
|
||||||
|
);
|
||||||
|
|
||||||
const updatedChoices = gameState.perks.one_more_choice + choices
|
list = list
|
||||||
let list = upgrades.filter(u => offered.slice(0, updatedChoices).includes(u.id) || gameState.perks[u.id])
|
.filter((u) => fromStart.includes(u.id))
|
||||||
|
.concat(list.filter((u) => !fromStart.includes(u.id)));
|
||||||
list = list.filter(u => fromStart.includes(u.id))
|
|
||||||
.concat(list.filter(u => !fromStart.includes(u.id)))
|
|
||||||
|
|
||||||
list.forEach((u) => {
|
list.forEach((u) => {
|
||||||
dontOfferTooSoon(gameState, u.id);
|
dontOfferTooSoon(gameState, u.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const upgradeId = await asyncAlert<PerkId | null>({
|
const upgradeId = await asyncAlert<PerkId | null>({
|
||||||
title:
|
title: t("level_up.title", {
|
||||||
t("level_up.title", {
|
|
||||||
level: gameState.currentLevel,
|
level: gameState.currentLevel,
|
||||||
max: max_levels(gameState),
|
max: max_levels(gameState),
|
||||||
}),
|
}),
|
||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
text: t('level_up.go', {name: gameState.level.name}),
|
text: t("level_up.go", { name: gameState.level.name }),
|
||||||
icon: icons[gameState.level.name],
|
icon: icons[gameState.level.name],
|
||||||
value: null,
|
value: null,
|
||||||
},
|
},
|
||||||
|
|
||||||
gameState.extra_lives ? `<p>${t("level_up.instructions", {
|
gameState.extra_lives
|
||||||
|
? `<p>${t("level_up.instructions", {
|
||||||
count: gameState.extra_lives,
|
count: gameState.extra_lives,
|
||||||
gain:livesWon
|
gain: livesWon,
|
||||||
})}</p>` : `<p>${t("level_up.no_points")}</p>`,
|
})}</p>`
|
||||||
|
: `<p>${t("level_up.no_points")}</p>`,
|
||||||
...list.map((u) => {
|
...list.map((u) => {
|
||||||
const max = u.max + gameState.perks.limitless
|
const max = u.max + gameState.perks.limitless;
|
||||||
const lvl = gameState.perks[u.id]
|
const lvl = gameState.perks[u.id];
|
||||||
|
|
||||||
const button = !gameState.extra_lives || gameState.perks[u.id] >= max ?
|
const button =
|
||||||
'' : ` <button data-resolve-to="${u.id}">${
|
!gameState.extra_lives || gameState.perks[u.id] >= max
|
||||||
lvl ? t('level_up.upgrade') : t('level_up.pick')
|
? ""
|
||||||
}</button>`
|
: ` <button data-resolve-to="${u.id}">${
|
||||||
|
lvl ? t("level_up.upgrade") : t("level_up.pick")
|
||||||
|
}</button>`;
|
||||||
|
|
||||||
const lvlInfo = lvl ? upgradeLevelAndMaxDisplay(u, gameState) : ''
|
const lvlInfo = lvl ? upgradeLevelAndMaxDisplay(u, gameState) : "";
|
||||||
return `<div class="upgrade choice ${
|
return `<div class="upgrade choice ${
|
||||||
(!lvl && gameState.extra_lives && 'free') ||
|
(!lvl && gameState.extra_lives && "free") ||
|
||||||
(lvl && 'used') ||
|
(lvl && "used") ||
|
||||||
'greyed-out'
|
"greyed-out"
|
||||||
}" >
|
}" >
|
||||||
${icons["icon:" + u.id]}
|
${icons["icon:" + u.id]}
|
||||||
<p data-tooltip="${escapeAttribute(u.fullHelp(Math.max(1, lvl)))}">
|
<p data-tooltip="${escapeAttribute(u.fullHelp(Math.max(1, lvl)))}">
|
||||||
|
@ -123,9 +191,17 @@ gameState.extra_lives+=livesWon
|
||||||
${u.help(Math.max(1, lvl))}
|
${u.help(Math.max(1, lvl))}
|
||||||
</p>
|
</p>
|
||||||
${button}
|
${button}
|
||||||
</div>`
|
</div>`;
|
||||||
})
|
}),
|
||||||
,
|
...missedOpportunities.map(
|
||||||
|
(reason) =>
|
||||||
|
`<div class="upgrade choice greyed-out" >
|
||||||
|
${icons["icon:locked"]}
|
||||||
|
<p>
|
||||||
|
${reason}
|
||||||
|
</p>
|
||||||
|
</div>`,
|
||||||
|
),
|
||||||
levelsListHTMl(gameState, gameState.currentLevel),
|
levelsListHTMl(gameState, gameState.currentLevel),
|
||||||
getNearestUnlockHTML(gameState),
|
getNearestUnlockHTML(gameState),
|
||||||
`<div id="level-recording-container"></div>`,
|
`<div id="level-recording-container"></div>`,
|
||||||
|
@ -135,9 +211,9 @@ gameState.extra_lives+=livesWon
|
||||||
if (upgradeId) {
|
if (upgradeId) {
|
||||||
gameState.perks[upgradeId]++;
|
gameState.perks[upgradeId]++;
|
||||||
gameState.runStatistics.upgrades_picked++;
|
gameState.runStatistics.upgrades_picked++;
|
||||||
gameState.extra_lives--
|
gameState.extra_lives--;
|
||||||
} else {
|
} else {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,17 +20,11 @@ export function ballTransparency(ball: Ball, gameState: GameState) {
|
||||||
|
|
||||||
export function coinsBoostedCombo(gameState: GameState) {
|
export function coinsBoostedCombo(gameState: GameState) {
|
||||||
let boost =
|
let boost =
|
||||||
1 + gameState.perks.sturdy_bricks / 2 + gameState.perks.smaller_puck / 2;
|
1 +
|
||||||
if (gameState.perks.transparency) {
|
gameState.perks.sturdy_bricks / 2 +
|
||||||
let min = 1;
|
gameState.perks.smaller_puck / 2 +
|
||||||
gameState.balls.forEach((ball) => {
|
gameState.perks.transparency / 2;
|
||||||
const bt = ballTransparency(ball, gameState);
|
|
||||||
if (bt < min) {
|
|
||||||
min = bt;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
boost += (min * gameState.perks.transparency) / 2;
|
|
||||||
}
|
|
||||||
if (gameState.perks.minefield) {
|
if (gameState.perks.minefield) {
|
||||||
gameState.bricks.forEach((brick) => {
|
gameState.bricks.forEach((brick) => {
|
||||||
if (brick === "black") {
|
if (brick === "black") {
|
||||||
|
@ -101,13 +95,13 @@ export function firstWhere<Input, Output>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const wallBouncedBest = 3,
|
export const wallBouncedBest = 2,
|
||||||
wallBouncedGood = 10,
|
wallBouncedGood = 7,
|
||||||
levelTimeBest = 30,
|
levelTimeBest = 10,
|
||||||
levelTimeGood = 60,
|
levelTimeGood = 45,
|
||||||
catchRateBest = 95,
|
catchRateBest = 99,
|
||||||
catchRateGood = 90,
|
catchRateGood = 90,
|
||||||
missesBest = 3,
|
missesBest = 1,
|
||||||
missesGood = 6;
|
missesGood = 6;
|
||||||
|
|
||||||
export const MAX_LEVEL_SIZE = 21;
|
export const MAX_LEVEL_SIZE = 21;
|
||||||
|
|
|
@ -108,8 +108,12 @@ 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.classList[gameState.startParams.computer_controlled ? 'add':'remove']('computer_controlled');
|
scoreDisplay.classList[
|
||||||
scoreDisplay.classList[gameState.lastScoreIncrease > gameState.levelTime - 500 ? 'add':'remove']('active');
|
gameState.startParams.computer_controlled ? "add" : "remove"
|
||||||
|
]("computer_controlled");
|
||||||
|
scoreDisplay.classList[
|
||||||
|
gameState.lastScoreIncrease > gameState.levelTime - 500 ? "add" : "remove"
|
||||||
|
]("active");
|
||||||
|
|
||||||
// Clear
|
// Clear
|
||||||
if (!isOptionOn("basic") && level.svg && level.color === "#000000") {
|
if (!isOptionOn("basic") && level.svg && level.color === "#000000") {
|
||||||
|
|
|
@ -13,11 +13,10 @@ export function hideAnyTooltip() {
|
||||||
tooltip.style.display = "none";
|
tooltip.style.display = "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function setupMobileTooltips(tooltip: HTMLDivElement) {
|
function setupMobileTooltips(tooltip: HTMLDivElement) {
|
||||||
tooltip.className = "mobile";
|
tooltip.className = "mobile";
|
||||||
function openTooltip(e: Event) {
|
function openTooltip(e: Event) {
|
||||||
console.log('openTooltip',e)
|
console.log("openTooltip", e);
|
||||||
hideAnyTooltip();
|
hideAnyTooltip();
|
||||||
const hovering = e.target as HTMLElement;
|
const hovering = e.target as HTMLElement;
|
||||||
if (!hovering?.hasAttribute("data-help-content")) {
|
if (!hovering?.hasAttribute("data-help-content")) {
|
||||||
|
@ -33,7 +32,6 @@ function setupMobileTooltips(tooltip: HTMLDivElement) {
|
||||||
|
|
||||||
document.body.addEventListener("click", openTooltip, true);
|
document.body.addEventListener("click", openTooltip, true);
|
||||||
document.addEventListener("scroll", hideAnyTooltip);
|
document.addEventListener("scroll", hideAnyTooltip);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupDesktopTooltips(tooltip: HTMLDivElement) {
|
function setupDesktopTooltips(tooltip: HTMLDivElement) {
|
||||||
|
|
|
@ -914,7 +914,10 @@ export const rawUpgrades = [
|
||||||
max: 4,
|
max: 4,
|
||||||
name: t("upgrades.passive_income.name"),
|
name: t("upgrades.passive_income.name"),
|
||||||
help: (lvl: number) =>
|
help: (lvl: number) =>
|
||||||
t("upgrades.passive_income.tooltip", { time: (lvl * 0.1 - 0.05).toFixed(2), lvl }),
|
t("upgrades.passive_income.tooltip", {
|
||||||
|
time: (lvl * 0.1 - 0.05).toFixed(2),
|
||||||
|
lvl,
|
||||||
|
}),
|
||||||
fullHelp: (lvl: number) =>
|
fullHelp: (lvl: number) =>
|
||||||
t("upgrades.passive_income.verbose_description", {
|
t("upgrades.passive_income.verbose_description", {
|
||||||
time: (lvl * 0.1 - 0.05).toFixed(2),
|
time: (lvl * 0.1 - 0.05).toFixed(2),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue