diff --git a/Readme.md b/Readme.md index d9a48b4..e962551 100644 --- a/Readme.md +++ b/Readme.md @@ -35,13 +35,11 @@ already maxed out. - [jaceys] A visual indication of whether a ball has hit a brick this serve - Top down /reach: punishing now, maybe only reset if you hit the lowest populate row of the level, if it's not a full width row - - # Todo before next release - -# 29 march 2025 +# Next +- disabled auto-release on fdroid of every web version, as there's a big delay and bugs woudl stay for a long time - [jaceys] Counters for coins lost, misses, and boundary bounces, as well as a timer. - added a white border around all coins, to make dark ones visible on dark bg - Removed all previous loop only hazards @@ -66,13 +64,20 @@ already maxed out. - shocks lvl 2+ make bigger explosions - Make fullscreen an option and turn it back on when playing - Made the "combo lost" text last 500ms instead of the pointless 150ms - -# 28 march 2025 - -- loop : added red/blue coins (red kill you, blue freeze puck) (removed later) -- added more hazard that were then removed - add a toggle to switch between the “coin” design and colored bubbles +# 29049575 + +- added rerolls +- Sacrifice : clear screen instead of doubling coins + +# 29048147 + +- Ascetism : render coins with red border if there's a combo +- Warn about unbounded +- Red border dashes + + # UX / gameplay - on mobile, relative movement of the touch would be amplified and added to the puck diff --git a/deploy.sh b/deploy.sh index 9d39e40..013b60f 100755 --- a/deploy.sh +++ b/deploy.sh @@ -13,11 +13,12 @@ versionCode=$(($(date +%s) / 60)) bash ./build.sh $versionCode -# Create a release commit and tag +# Create a release commit git add . git commit -m "Build $versionCode" -git tag -a $versionCode -m $versionCode git push +# Auto tagging created random releases on fdroid, not great. +# git tag -a $versionCode -m $versionCode # upload to breakout.lecaro.me DOMAIN="breakout.lecaro.me" diff --git a/dist/index.html b/dist/index.html index 67cc90e..e36eb86 100644 --- a/dist/index.html +++ b/dist/index.html @@ -76,7 +76,7 @@ body { color: #90ee90; } -#score span.good { +#score span.good, #score span.bad { color: #fff; } @@ -84,22 +84,6 @@ body { left: 0; } -#FPSDisplay { - z-index: 1; - white-space: nowrap; - pointer-events: none; - user-select: none; - opacity: .8; - color: #fff; - transform-origin: 0 0; - padding: 0; - line-height: 20px; - position: fixed; - bottom: 0; - left: 0; - transform: rotate(-90deg); -} - body.has-alert-open { height: auto; overflow: visible; @@ -629,6 +613,7 @@ parcelHelpers.export(exports, "brickIndex", ()=>brickIndex); parcelHelpers.export(exports, "hasBrick", ()=>hasBrick); parcelHelpers.export(exports, "hitsSomething", ()=>hitsSomething); parcelHelpers.export(exports, "tick", ()=>tick); +parcelHelpers.export(exports, "lastMeasuredFPS", ()=>lastMeasuredFPS); parcelHelpers.export(exports, "openMainMenu", ()=>openMainMenu); parcelHelpers.export(exports, "confirmRestart", ()=>confirmRestart); parcelHelpers.export(exports, "setKeyPressed", ()=>setKeyPressed); @@ -881,10 +866,9 @@ function tick() { FPSCounter++; } let FPSCounter = 0; -let FPSDisplay = document.getElementById("FPSDisplay"); +let lastMeasuredFPS = 60; setInterval(()=>{ - if ((0, _options.isOptionOn)("show_fps")) FPSDisplay.innerText = FPSCounter + " FPS " + (0, _gameStateMutators.liveCount)(gameState.coins) + " COINS " + ((0, _gameStateMutators.liveCount)(gameState.particles) + (0, _gameStateMutators.liveCount)(gameState.texts) + (0, _gameStateMutators.liveCount)(gameState.lights)) + " PARTICLES "; - else FPSDisplay.innerText = ""; + lastMeasuredFPS = FPSCounter; FPSCounter = 0; }, 1000); window.addEventListener("visibilitychange", ()=>{ @@ -2173,7 +2157,7 @@ function getRowColIndex(gameState, row, col) { return row * gameState.gridSize + col; } function getPossibleUpgrades(gameState) { - return (0, _loadGameData.upgrades).filter((u)=>gameState.totalScoreAtRunStart >= u.threshold).filter((u)=>!u?.requires || gameState.perks[u?.requires]); + return (0, _loadGameData.upgrades).filter((u)=>gameState.totalScoreAtRunStart >= u.threshold || gameState.loop > 0).filter((u)=>!u?.requires || gameState.perks[u?.requires]); } function max_levels(gameState) { return gameState.levelsPerLoop + gameState.perks.extra_levels; @@ -3549,7 +3533,12 @@ function render(gameState) { }); else menuLabel.innerText = (0, _i18N.t)("play.menu_label"); const catchRate = gameState.levelSpawnedCoins ? (gameState.levelSpawnedCoins - gameState.levelLostCoins) / gameState.levelSpawnedCoins : 1; - scoreDisplay.innerHTML = ((0, _options.isOptionOn)('show_stats') ? ` + scoreDisplay.innerHTML = ((0, _options.isOptionOn)("show_fps") ? ` + + ${0, _game.lastMeasuredFPS} FPS + / + + ` : '') + ((0, _options.isOptionOn)('show_stats') ? ` ${Math.floor(catchRate * 100)}% / diff --git a/src/game.less b/src/game.less index 602a33f..e10657f 100644 --- a/src/game.less +++ b/src/game.less @@ -1,10 +1,9 @@ * { - font-family: - Courier New, - Courier, - Lucida Sans Typewriter, - Lucida Typewriter, - monospace; + font-family: Courier New, + Courier, + Lucida Sans Typewriter, + Lucida Typewriter, + monospace; box-sizing: border-box; } @@ -45,11 +44,13 @@ body { min-width: 40px; min-height: 40px; line-height: 20px; + &:hover, &:focus { background: rgba(0, 0, 0, 0.3); cursor: pointer; } + text-shadow: 0 0 4px rgba(0, 0, 0, 0.8); } @@ -57,20 +58,25 @@ body { right: 0; color: white; transition: color 0.3s; + &.active { color: gold; transition: color 0.01s; } - span{ + span { color: #333; - &.great{ - color: lightgreen; - } - &.good{ - color: white; - } + &.great { + color: lightgreen; + } + + &.good { + color: white; + } + &.bad { + color: white; + } } } @@ -78,32 +84,15 @@ body { left: 0; } -#FPSDisplay { - z-index: 1; - white-space: nowrap; - padding: 10px; - line-height: 20px; - pointer-events: none; - user-select: none; - opacity: 0.8; - - color: white; - padding: 0; - position: fixed; - - bottom: 0; - left: 0; - transform-origin: top left; - transform: rotate(-90deg); -} - body.has-alert-open { height: auto; overflow: visible; } + body:not(.has-alert-open) #popup { display: none; } + #popup { &::before { z-index: 10; @@ -342,6 +331,7 @@ body:not(.has-alert-open) #popup { } } } + & > span:not(:hover):not(.active) > span > span { opacity: 0; } @@ -358,6 +348,7 @@ h2.histogram-title strong { .red-icon { background: red; + img { filter: saturate(0); mix-blend-mode: luminosity; diff --git a/src/game.ts b/src/game.ts index 88e17db..0d45177 100644 --- a/src/game.ts +++ b/src/game.ts @@ -386,21 +386,10 @@ export function tick() { } let FPSCounter = 0; -let FPSDisplay = document.getElementById("FPSDisplay") as HTMLDivElement; +export let lastMeasuredFPS = 60; + setInterval(() => { - if (isOptionOn("show_fps")) { - FPSDisplay.innerText = - FPSCounter + - " FPS " + - liveCount(gameState.coins) + - " COINS " + - (liveCount(gameState.particles) + - liveCount(gameState.texts) + - liveCount(gameState.lights)) + - " PARTICLES "; - } else { - FPSDisplay.innerText = ""; - } + lastMeasuredFPS = FPSCounter FPSCounter = 0; }, 1000); diff --git a/src/game_utils.ts b/src/game_utils.ts index 6872854..0738313 100644 --- a/src/game_utils.ts +++ b/src/game_utils.ts @@ -55,7 +55,7 @@ export function getRowColIndex(gameState: GameState, row: number, col: number) { export function getPossibleUpgrades(gameState: GameState) { return upgrades - .filter((u) => gameState.totalScoreAtRunStart >= u.threshold) + .filter((u) => gameState.totalScoreAtRunStart >= u.threshold || gameState.loop>0) .filter((u) => !u?.requires || gameState.perks[u?.requires]); } diff --git a/src/render.ts b/src/render.ts index 5abedd8..dc6582b 100644 --- a/src/render.ts +++ b/src/render.ts @@ -11,7 +11,7 @@ import { } from "./game_utils"; import {colorString, GameState} from "./types"; import {t} from "./i18n/i18n"; -import {gameState} from "./game"; +import {gameState, lastMeasuredFPS} from "./game"; import {isOptionOn} from "./options"; export const gameCanvas = document.getElementById("game") as HTMLCanvasElement; @@ -54,7 +54,17 @@ export function render(gameState: GameState) { const catchRate = gameState.levelSpawnedCoins ? (gameState.levelSpawnedCoins - gameState.levelLostCoins)/gameState.levelSpawnedCoins :1 - scoreDisplay.innerHTML= (isOptionOn('show_stats') ? ` + scoreDisplay.innerHTML= + (isOptionOn("show_fps") ? ` + + ${lastMeasuredFPS} FPS + / + + `:'')+ + + + + (isOptionOn('show_stats') ? ` ${Math.floor(catchRate*100)}% /