mirror of
https://gitlab.com/lecarore/breakout71.git
synced 2025-04-20 12:15:06 -04:00
wip
This commit is contained in:
parent
6d0ad5e675
commit
e9d58d6140
13 changed files with 4479 additions and 961 deletions
147
Readme.md
147
Readme.md
|
@ -6,7 +6,6 @@ Break colourful bricks, catch bouncing coins and select powerful upgrades !
|
||||||
- [Post your comments on itch.io](https://renanlecaro.itch.io/breakout71)
|
- [Post your comments on itch.io](https://renanlecaro.itch.io/breakout71)
|
||||||
- [Help and tips about the game](./Help.md)
|
- [Help and tips about the game](./Help.md)
|
||||||
- [Credits](./Credits.md)
|
- [Credits](./Credits.md)
|
||||||
- [Project Roadmap](./Roadmap.md)
|
|
||||||
- [Open source android version on F-Droid](https://f-droid.org/en/packages/me.lecaro.breakout/)
|
- [Open source android version on F-Droid](https://f-droid.org/en/packages/me.lecaro.breakout/)
|
||||||
- [Google Play](https://play.google.com/store/apps/details?id=me.lecaro.breakout)
|
- [Google Play](https://play.google.com/store/apps/details?id=me.lecaro.breakout)
|
||||||
- [GitLab](https://gitlab.com/lecarore/breakout71)
|
- [GitLab](https://gitlab.com/lecarore/breakout71)
|
||||||
|
@ -21,4 +20,148 @@ It's very lean and does not take much storage space (Roughly 0.1MB).
|
||||||
If the app stutters, turn on "fast mode" in the settings to render a simplified view that should be faster.
|
If the app stutters, turn on "fast mode" in the settings to render a simplified view that should be faster.
|
||||||
There's also an easy mode for kids (slower ball).
|
There's also an easy mode for kids (slower ball).
|
||||||
|
|
||||||
The web version is known to work on firefox
|
# bugs
|
||||||
|
|
||||||
|
- having Hot Start and Single puck hit streak perks in a run resets combo from start [29014379]
|
||||||
|
- The ball goes through Sturdy bricks sometimes, but it does not break
|
||||||
|
nor bounce back after hitting them (and indeed this does not cause a
|
||||||
|
miss). In the video you can clearly witness it several time, and it
|
||||||
|
becomes especially apparent towards the end. I guess this is somehow
|
||||||
|
related to Color Piercing or Piercing (or both).
|
||||||
|
- Easy Cleanup activates twice if the latest Respawn happens before all
|
||||||
|
the coins have been caught or fallen off screen. As you can see, I had
|
||||||
|
Lv 1 on both the perks: the ball hit the second to last brick, the last
|
||||||
|
one is automatically destroyed, but then another one gets respawned and
|
||||||
|
quickly destroyed again.
|
||||||
|
- Boring cheat – I found out a way to farm points: if you have Respawn
|
||||||
|
Lv 3 or 4 you can endlessly hit the same cluster of bricks, and if you
|
||||||
|
manage to put the pluck in a comfortable position (i.e. straight line)
|
||||||
|
it's very easy to farm plenty of coins with the aid of appropriate combo
|
||||||
|
perks. No video though, this happened on the app while I was playing
|
||||||
|
casually (it's quite easy to reproduce, though). I wouldn't do that
|
||||||
|
because it's mind-numbingly dull, but still I'm not sure this kind of
|
||||||
|
play is intended or if it should even be allowed.
|
||||||
|
- Combo balancing – one thing that makes the best strategy overly
|
||||||
|
dominant is the way combo resets abruptly with everything other than
|
||||||
|
Compound Interest, which pairs exceptionally well to Coin Magnet (which
|
||||||
|
is in itself instrumental to scoring high). If the other combos would
|
||||||
|
scale down accordingly (i.e. 1 coin less when you hit the
|
||||||
|
walls/ceiling/puck – or at least drop some percentage, but not all of
|
||||||
|
the combo at once). This would instantly make many more strategies and
|
||||||
|
combinations viable, because right now it doesn't make much sense to
|
||||||
|
pair Compound Interest to any other combo perks (except in very specific
|
||||||
|
circumstances).
|
||||||
|
|
||||||
|
|
||||||
|
# Game engine features
|
||||||
|
|
||||||
|
- the onboarding feels weird, missing a tutorial
|
||||||
|
- Players can't choose the initial perk
|
||||||
|
- apk version soft locks at start.
|
||||||
|
- shinier coins by applying glow to them ?
|
||||||
|
- ask for permanent storage
|
||||||
|
- It's a bit confusing at first to grasp that one upgrade is applied randomly at the start of the game
|
||||||
|
- on mobile, add an element that feels like it can be "grabbed" and make it shine while writing "Push here to play"
|
||||||
|
- add a clickable button to allow sound to play in chrome android
|
||||||
|
- offline mode with service worker
|
||||||
|
- add pwe manifest
|
||||||
|
- see how to do fullscreen on ios, or at least explain to do aA/hide toolbars
|
||||||
|
- experiment with showing the combo somewhere else, maybe top center, maybe instead of score.
|
||||||
|
- more help somewhere accessible
|
||||||
|
- limit GC by reusing coins and particles
|
||||||
|
- convert captures to mp4 unsing ffmpeg wasm because reddit refuses webm files
|
||||||
|
- few puck bounces = more choices / upgrades
|
||||||
|
- disable zooming (for ios double tap)
|
||||||
|
- particles when bouncing on sides / top
|
||||||
|
- show total score on end screen (score added to total)
|
||||||
|
- show stats on end screen compared to other runs
|
||||||
|
- handle back bouton in menu
|
||||||
|
- mouvement relatif du puck
|
||||||
|
- balls should collide with each other
|
||||||
|
- when game resumes near bottom, be unvulnerable for .5s ? , once per level
|
||||||
|
- apply global curve / brightness to canvas when things blow, or just always to make neon effect better
|
||||||
|
- manifest for PWA (android and apple)
|
||||||
|
- lights shadows
|
||||||
|
- Offline mode web for iphone
|
||||||
|
- controller support on web/mobile
|
||||||
|
- webgl rendering
|
||||||
|
- enable export of gameplay capture in webview
|
||||||
|
- endgame histograms could work as filters, when you hover a bar, all other histograms would show the stats of those runs only, without changing reference of categories
|
||||||
|
- sound when ball changes color
|
||||||
|
- option : don't pause on mobile when lifting finger
|
||||||
|
- option : accelerated relative movements on mobile
|
||||||
|
- maybe just have 10 background, and always use the same one for the nth level of each run ?
|
||||||
|
- would be nice to have a leaderboard for not using each perk too. Like "best runs without hot start"
|
||||||
|
- restart run on r
|
||||||
|
- when missing, redo particle trail, but give speed to particle that matches ball direction
|
||||||
|
|
||||||
|
# Perks ideas
|
||||||
|
|
||||||
|
- second puck (symmeric to the first one)
|
||||||
|
- keep combo between level, loose half your run score when missing any bricks
|
||||||
|
- offer next level choice after upgrade pick
|
||||||
|
- ban 3 random perks from pool, doesn't tell you which ones, gain 2 upgrades
|
||||||
|
- 3 random perks immediately, or maybe "all level get twice as many upgrades, but they are applied randomly, and you aren't told which ones you have."
|
||||||
|
- wrap left / right
|
||||||
|
- pause and cheat again
|
||||||
|
- wrap top / bottom : coins fall back from top of screen, ball flies to the top and comes back from the screen bottom ?
|
||||||
|
- faster coins, double value
|
||||||
|
- +1 upgrade per level but -2 choices
|
||||||
|
- n% of the broken bricks respawn when the ball touches the puck
|
||||||
|
- bricks break 50% of the time but drop 50% more coins
|
||||||
|
- wind (puck positions adds force to coins and balls)
|
||||||
|
- balls repulse coins
|
||||||
|
- n% of coins missed respawn at the top
|
||||||
|
- lightning : missing triggers and explosive lighting strike around ball path
|
||||||
|
- coins repulse coins (could get really laggy)
|
||||||
|
- balls repulse coins
|
||||||
|
- balls attract coins
|
||||||
|
- twice as many coins after a wall bounce, twice as little otherwise ?
|
||||||
|
- fusion reactor (gather coins in one spot to triple their value)
|
||||||
|
- missing makes you loose all score of level, but otherwise multiplier goes up after each breaking
|
||||||
|
- soft reset, cut combo in half instead of zero
|
||||||
|
- missile goes when you catch coin
|
||||||
|
- missile goes when you break a brick
|
||||||
|
- puck bounce +1 combo, hit nothing resets
|
||||||
|
- multiple hits on the same brick (show remaining resistance as number)
|
||||||
|
- bricks attract ball
|
||||||
|
- replay last level (remove score, restores lives if any, and rebuild )
|
||||||
|
- accelerometer controls coins and balls
|
||||||
|
- bricks attract coins
|
||||||
|
- breaking bricks stains neighbours
|
||||||
|
- extra kick after bouncing on puck
|
||||||
|
- transparent coins
|
||||||
|
- coins of different colors repulse
|
||||||
|
- bricks follow game of life pattern with one update every second
|
||||||
|
- 2x coins when ball goes downward / upward, half that amount otherwise ?
|
||||||
|
- new ball spawns when reaching combo X
|
||||||
|
- missing with combo triggers explosive lightning strike
|
||||||
|
- correction : pick one past upgrade to remove and replace by something else
|
||||||
|
- puck bounce predictions rendered with particles or lines (requires big refactor)
|
||||||
|
- the more balls are close to a brick, the more coins she spawns when breaking
|
||||||
|
|
||||||
|
# extra levels
|
||||||
|
|
||||||
|
- famous games
|
||||||
|
- letters
|
||||||
|
- fruits
|
||||||
|
- animals
|
||||||
|
- countries flags and shapes, with name as background
|
||||||
|
|
||||||
|
# big features
|
||||||
|
|
||||||
|
- use ts and a bundler to get fewer bugs and compatibility with old browsers / webviews
|
||||||
|
- final bosses (large vertical level that scrolls down faster and faster)
|
||||||
|
- split screen multiplayer
|
||||||
|
- translation
|
||||||
|
- Add color schemes into the game (ex : Catppuccin, Dracula, Terminal, etc)
|
||||||
|
- add a toggle to switch between the “coin” design and colored bubbles
|
||||||
|
- sandbox mode
|
||||||
|
- hard mode : bricks take many hits, perks more rare, missing clears level score, missing coins deducts score..
|
||||||
|
- stats by lack of perk, like "best score without using hot start".
|
||||||
|
|
||||||
|
Instead of automatically unlocking things at the end of each run, add the coins to the user's account,
|
||||||
|
and let them spend those coins on upgrades. The upgrades would then be explained. They could have a condition like
|
||||||
|
"reach high score of 1000" or 'reach high score of 99999 without using "hot start"'.
|
||||||
|
This requires recording a bit more info about each run.
|
||||||
|
I could unlock the "pro stand" at $999 that just holds the play area higher.
|
||||||
|
|
|
@ -1,115 +0,0 @@
|
||||||
# bugs
|
|
||||||
- having Hot Start and Single puck hit streak perks in a run resets combo from start [29014379]
|
|
||||||
|
|
||||||
# Game engine features
|
|
||||||
|
|
||||||
- the onboarding feels weird, missing a tutorial
|
|
||||||
- Players can't choose the initial perk
|
|
||||||
- apk version soft locks at start.
|
|
||||||
- shinier coins by applying glow to them ?
|
|
||||||
- ask for permanent storage
|
|
||||||
- It's a bit confusing at first to grasp that one upgrade is applied randomly at the start of the game
|
|
||||||
- on mobile, add an element that feels like it can be "grabbed" and make it shine while writing "Push here to play"
|
|
||||||
- add a clickable button to allow sound to play in chrome android
|
|
||||||
- offline mode with service worker
|
|
||||||
- add pwe manifest
|
|
||||||
- see how to do fullscreen on ios, or at least explain to do aA/hide toolbars
|
|
||||||
- experiment with showing the combo somewhere else, maybe top center, maybe instead of score.
|
|
||||||
- more help somewhere accessible
|
|
||||||
- limit GC by reusing coins and particles
|
|
||||||
- convert captures to mp4 unsing ffmpeg wasm because reddit refuses webm files
|
|
||||||
- few puck bounces = more choices / upgrades
|
|
||||||
- disable zooming (for ios double tap)
|
|
||||||
- particles when bouncing on sides / top
|
|
||||||
- show total score on end screen (score added to total)
|
|
||||||
- show stats on end screen compared to other runs
|
|
||||||
- handle back bouton in menu
|
|
||||||
- mouvement relatif du puck
|
|
||||||
- balls should collide with each other
|
|
||||||
- when game resumes near bottom, be unvulnerable for .5s ? , once per level
|
|
||||||
- apply global curve / brightness to canvas when things blow, or just always to make neon effect better
|
|
||||||
- manifest for PWA (android and apple)
|
|
||||||
- lights shadows
|
|
||||||
- Offline mode web for iphone
|
|
||||||
- controller support on web/mobile
|
|
||||||
- webgl rendering
|
|
||||||
- enable export of gameplay capture in webview
|
|
||||||
- endgame histograms could work as filters, when you hover a bar, all other histograms would show the stats of those runs only, without changing reference of categories
|
|
||||||
- sound when ball changes color
|
|
||||||
- option : don't pause on mobile when lifting finger
|
|
||||||
- option : accelerated relative movements on mobile
|
|
||||||
- maybe just have 10 background, and always use the same one for the nth level of each run ?
|
|
||||||
- would be nice to have a leaderboard for not using each perk too. Like "best runs without hot start"
|
|
||||||
- restart run on r
|
|
||||||
- when missing, redo particle trail, but give speed to particle that matches ball direction
|
|
||||||
|
|
||||||
# Perks ideas
|
|
||||||
|
|
||||||
- second puck (symmeric to the first one)
|
|
||||||
- keep combo between level, loose half your run score when missing any bricks
|
|
||||||
- offer next level choice after upgrade pick
|
|
||||||
- ban 3 random perks from pool, doesn't tell you which ones, gain 2 upgrades
|
|
||||||
- 3 random perks immediately, or maybe "all level get twice as many upgrades, but they are applied randomly, and you aren't told which ones you have."
|
|
||||||
- wrap left / right
|
|
||||||
- pause and cheat again
|
|
||||||
- wrap top / bottom : coins fall back from top of screen, ball flies to the top and comes back from the screen bottom ?
|
|
||||||
- faster coins, double value
|
|
||||||
- +1 upgrade per level but -2 choices
|
|
||||||
- n% of the broken bricks respawn when the ball touches the puck
|
|
||||||
- bricks break 50% of the time but drop 50% more coins
|
|
||||||
- wind (puck positions adds force to coins and balls)
|
|
||||||
- balls repulse coins
|
|
||||||
- n% of coins missed respawn at the top
|
|
||||||
- lightning : missing triggers and explosive lighting strike around ball path
|
|
||||||
- coins repulse coins (could get really laggy)
|
|
||||||
- balls repulse coins
|
|
||||||
- balls attract coins
|
|
||||||
- twice as many coins after a wall bounce, twice as little otherwise ?
|
|
||||||
- fusion reactor (gather coins in one spot to triple their value)
|
|
||||||
- missing makes you loose all score of level, but otherwise multiplier goes up after each breaking
|
|
||||||
- soft reset, cut combo in half instead of zero
|
|
||||||
- missile goes when you catch coin
|
|
||||||
- missile goes when you break a brick
|
|
||||||
- puck bounce +1 combo, hit nothing resets
|
|
||||||
- multiple hits on the same brick (show remaining resistance as number)
|
|
||||||
- bricks attract ball
|
|
||||||
- replay last level (remove score, restores lives if any, and rebuild )
|
|
||||||
- accelerometer controls coins and balls
|
|
||||||
- bricks attract coins
|
|
||||||
- breaking bricks stains neighbours
|
|
||||||
- extra kick after bouncing on puck
|
|
||||||
- transparent coins
|
|
||||||
- coins of different colors repulse
|
|
||||||
- bricks follow game of life pattern with one update every second
|
|
||||||
- 2x coins when ball goes downward / upward, half that amount otherwise ?
|
|
||||||
- new ball spawns when reaching combo X
|
|
||||||
- missing with combo triggers explosive lightning strike
|
|
||||||
- correction : pick one past upgrade to remove and replace by something else
|
|
||||||
- puck bounce predictions rendered with particles or lines (requires big refactor)
|
|
||||||
|
|
||||||
|
|
||||||
# extra levels
|
|
||||||
|
|
||||||
- famous games
|
|
||||||
- letters
|
|
||||||
- fruits
|
|
||||||
- animals
|
|
||||||
- countries flags and shapes, with name as background
|
|
||||||
|
|
||||||
# big features
|
|
||||||
|
|
||||||
- use ts and a bundler to get fewer bugs and compatibility with old browsers / webviews
|
|
||||||
- final bosses (large vertical level that scrolls down faster and faster)
|
|
||||||
- split screen multiplayer
|
|
||||||
- translation
|
|
||||||
- Add color schemes into the game (ex : Catppuccin, Dracula, Terminal, etc)
|
|
||||||
- add a toggle to switch between the “coin” design and colored bubbles
|
|
||||||
- sandbox mode
|
|
||||||
- hard mode : bricks take many hits, perks more rare, missing clears level score, missing coins deducts score..
|
|
||||||
- stats by lack of perk, like "best score without using hot start".
|
|
||||||
|
|
||||||
Instead of automatically unlocking things at the end of each run, add the coins to the user's account,
|
|
||||||
and let them spend those coins on upgrades. The upgrades would then be explained. They could have a condition like
|
|
||||||
"reach high score of 1000" or 'reach high score of 99999 without using "hot start"'.
|
|
||||||
This requires recording a bit more info about each run.
|
|
||||||
I could unlock the "pro stand" at $999 that just holds the play area higher.
|
|
3682
dist/index.html
vendored
3682
dist/index.html
vendored
File diff suppressed because one or more lines are too long
|
@ -47,14 +47,7 @@ function addLevelEditorToList(level, levelIndex) {
|
||||||
<button data-offset-x="0" data-offset-y="1" data-level="${levelIndex}">D</button>
|
<button data-offset-x="0" data-offset-y="1" data-level="${levelIndex}">D</button>
|
||||||
<input type="color" value="${level.color || ''}" data-level="${levelIndex}" />
|
<input type="color" value="${level.color || ''}" data-level="${levelIndex}" />
|
||||||
<button data-level="${levelIndex}" data-set-bg-svg="true" >${svg?'replace':'set'}</button>
|
<button data-level="${levelIndex}" data-set-bg-svg="true" >${svg?'replace':'set'}</button>
|
||||||
<label>
|
|
||||||
<input type="checkbox" data-field="focus" ${level.focus ? 'checked':''} data-level="${levelIndex}" />
|
|
||||||
focus
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" data-field="black_puck" ${level.black_puck ? 'checked':''} data-level="${levelIndex}" />
|
|
||||||
black_puck
|
|
||||||
</label>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -182,14 +175,14 @@ document.getElementById('levels').addEventListener('click', e => {
|
||||||
let applying = ''
|
let applying = ''
|
||||||
|
|
||||||
function colorPixel(e) {
|
function colorPixel(e) {
|
||||||
if ( applying == '') return
|
if ( applying === '') return
|
||||||
|
console.log('colorPixel',applying)
|
||||||
const index = e.target.getAttribute('data-set-color-of')
|
const index = e.target.getAttribute('data-set-color-of')
|
||||||
const level = e.target.getAttribute('data-level')
|
const level = e.target.getAttribute('data-level')
|
||||||
if (index && level) {
|
if (index && level) {
|
||||||
const levelIndex = parseInt(level)
|
const levelIndex = parseInt(level)
|
||||||
e.target.style.background = palette[applying]
|
e.target.style.background = palette[applying]||'transparent'
|
||||||
setBrick(levelIndex,parseInt(index),applying)
|
setBrick(levelIndex,parseInt(index),applying)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function setBrick(levelIndex,index,chr) {
|
function setBrick(levelIndex,index,chr) {
|
||||||
|
@ -199,9 +192,10 @@ function setBrick(levelIndex,index,chr) {
|
||||||
document.getElementById('levels').addEventListener('mousedown', e => {
|
document.getElementById('levels').addEventListener('mousedown', e => {
|
||||||
const index = parseInt(e.target.getAttribute('data-set-color-of'))
|
const index = parseInt(e.target.getAttribute('data-set-color-of'))
|
||||||
const level = e.target.getAttribute('data-level')
|
const level = e.target.getAttribute('data-level')
|
||||||
if (index && level) {
|
if (typeof index !=="undefined" && level) {
|
||||||
const before = allLevels[parseInt(level)].bricks[parseInt(index)] || '_'
|
const before = allLevels[parseInt(level)].bricks[index] || ''
|
||||||
applying = before === currentCode ? '_' : currentCode
|
applying = before === currentCode ? '_' : currentCode
|
||||||
|
console.log({before, applying, currentCode})
|
||||||
colorPixel(e)
|
colorPixel(e)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -226,7 +220,7 @@ document.getElementById('new-level').addEventListener('click', e => {
|
||||||
allLevels.push({
|
allLevels.push({
|
||||||
name,
|
name,
|
||||||
size: 8,
|
size: 8,
|
||||||
bricks: ['white'],
|
bricks: '',
|
||||||
svg: '',
|
svg: '',
|
||||||
})
|
})
|
||||||
const levelIndex = allLevels.length - 1
|
const levelIndex = allLevels.length - 1
|
||||||
|
|
|
@ -32,15 +32,14 @@ app.get('/', (req, res) => {
|
||||||
${fs.readFileSync('./editclient.css').toString()}
|
${fs.readFileSync('./editclient.css').toString()}
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
const allLevels = ${fs.readFileSync(srcPath).toString()};
|
let allLevels = ${fs.readFileSync(srcPath).toString()};
|
||||||
const palette = ${fs.readFileSync('src/palette.json').toString()};
|
let palette = ${fs.readFileSync('src/palette.json').toString()};
|
||||||
${fs.readFileSync('./editclient.js').toString()}
|
${fs.readFileSync('./editclient.js').toString()}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
app.post('/', (req, res) => {
|
app.post('/', (req, res) => {
|
||||||
console.log(req.body)
|
|
||||||
if(req.body?.trim()) {
|
if(req.body?.trim()) {
|
||||||
fs.writeFileSync(srcPath, req.body)
|
fs.writeFileSync(srcPath, req.body)
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -19,7 +19,7 @@
|
||||||
<button id="score"></button>
|
<button id="score"></button>
|
||||||
<canvas id="game"></canvas>
|
<canvas id="game"></canvas>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import "./game.js";
|
import "./game.ts";
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
454
src/levels.json
454
src/levels.json
File diff suppressed because one or more lines are too long
74
src/loadGameData.ts
Normal file
74
src/loadGameData.ts
Normal file
File diff suppressed because one or more lines are too long
344
src/rawUpgrades.ts
Normal file
344
src/rawUpgrades.ts
Normal file
|
@ -0,0 +1,344 @@
|
||||||
|
export const rawUpgrades = [{
|
||||||
|
requires: '',
|
||||||
|
"threshold": 0,
|
||||||
|
giftable: false,
|
||||||
|
"id": "extra_life",
|
||||||
|
"name": "+1 life",
|
||||||
|
"max": 7,
|
||||||
|
help: lvl => `Survive dropping the ball ${lvl} time${lvl > 1 ? 's' : ''}.`,
|
||||||
|
fullHelp: `Normally, you just have one life, and the run is over as soon as you drop it.
|
||||||
|
With this perk, you can survive dropping the ball once. A heart in the top right corner will remind you of how many extra lives you have. `
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 0,
|
||||||
|
"id": "streak_shots",
|
||||||
|
"giftable": true,
|
||||||
|
"name": "Single puck hit streak",
|
||||||
|
"max": 1,
|
||||||
|
help: lvl => `More coins if you break many bricks at once`,
|
||||||
|
fullHelp: `Every time you break a brick, your combo (number of coins per bricks) increases by one. However, as soon as the ball touches your puck,
|
||||||
|
the combo is reset to its default value, and you'll just get one coin per brick. So you should try to hit many bricks in one go for more score.
|
||||||
|
Once your combo rises above the base value, your puck will become red to remind you that it will destroy your combo to touch it with the ball.
|
||||||
|
This can stack with other combo related perks, the combo will rise faster but reset more easily as any of the conditions is enough to reset it. `
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
requires: '',
|
||||||
|
"threshold": 0,
|
||||||
|
"id": "base_combo",
|
||||||
|
"giftable": true,
|
||||||
|
"name": "+3 base combo",
|
||||||
|
"max": 7,
|
||||||
|
help: lvl => `Every brick drops at least ${1 + lvl * 3} coins.`,
|
||||||
|
fullHelp: `Your combo (number of coins per bricks) normally starts at 1 at the beginning of the level, and resets to one when you bounce around without hitting anything.
|
||||||
|
With this perk, the combo starts 3 points higher, so you'll always get at least 4 coins per brick. Whenever your combo reset, it will go back to 4 and not 1.
|
||||||
|
Your ball will glitter a bit to indicate that its combo is higher than one.`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 0,
|
||||||
|
giftable: false,
|
||||||
|
"id": "slow_down",
|
||||||
|
"name": "Slower ball",
|
||||||
|
"max": 2,
|
||||||
|
help: lvl => `Ball moves ${lvl > 1 ? 'even' : ''} more slowly.`,
|
||||||
|
|
||||||
|
fullHelp: `The ball starts relatively slow, but every level of your run it will start a bit faster, and it will also accelerate if you spend a lot of time in one level. This perk makes it
|
||||||
|
more manageable. You can get it at the start every time by enabling kid mode in the menu.`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 0,
|
||||||
|
giftable: false,
|
||||||
|
"id": "bigger_puck",
|
||||||
|
"name": "Bigger puck",
|
||||||
|
"max": 2,
|
||||||
|
help: lvl => `Easily catch ${lvl > 1 ? 'even' : ''} more coins.`,
|
||||||
|
fullHelp: `A bigger puck makes it easier to never miss the ball and to catch more coins, and also to precisely angle the bounces (the ball's angle only depends on where it hits the puck).
|
||||||
|
However, a large puck is harder to use around the sides of the level, and will make it sometimes unavoidable to miss (not hit anything) which comes with downsides. `
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 0,
|
||||||
|
giftable: false,
|
||||||
|
"id": "viscosity",
|
||||||
|
"name": "Viscosity",
|
||||||
|
"max": 3,
|
||||||
|
help: lvl => `${lvl > 1 ? 'Even slower' : 'Slower'} coins fall.`,
|
||||||
|
|
||||||
|
fullHelp: `Coins normally accelerate with gravity and explosions to pretty high speeds. This perk constantly makes them slow down, as if they were in some sort of viscous liquid.
|
||||||
|
This makes catching them easier, and combines nicely with perks that influence the coin's movement. `
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 0,
|
||||||
|
"id": "sides_are_lava",
|
||||||
|
"giftable": true,
|
||||||
|
"name": "Shoot straight",
|
||||||
|
"max": 1,
|
||||||
|
help: lvl => `More coins if you don't touch the sides.`,
|
||||||
|
|
||||||
|
fullHelp: `Whenever you break a brick, your combo will increase by one, so you'll get one more coin all the next bricks you break.
|
||||||
|
However, your combo will reset as soon as your ball hits the left or right side.
|
||||||
|
As soon as your combo rises, the sides become red to remind you that you should avoid hitting them. The effect stacks with other combo perks, combo rises faster with more upgrades but will also reset if any
|
||||||
|
of the reset conditions are met.`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 0,
|
||||||
|
"id": "top_is_lava",
|
||||||
|
"giftable": true,
|
||||||
|
"name": "Sky is the limit",
|
||||||
|
"max": 1,
|
||||||
|
help: lvl => `More coins if you don't touch the top.`,
|
||||||
|
|
||||||
|
fullHelp: `Whenever you break a brick, your combo will increase by one. However, your combo will reset as soon as your ball hit the top of the screen.
|
||||||
|
When your combo is above the minimum, a red bar will appear at the top to remind you that you should avoid hitting it.
|
||||||
|
The effect stacks with other combo perks.`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 0,
|
||||||
|
giftable: false,
|
||||||
|
"id": "skip_last",
|
||||||
|
"name": "Easy Cleanup",
|
||||||
|
"max": 7,
|
||||||
|
help: lvl => `The last ${lvl > 1 ? lvl + ' bricks' : 'brick'} left will self-destruct.`,
|
||||||
|
fullHelp: `You need to break all bricks to go to the next level. However, it can be hard to get the last ones.
|
||||||
|
Clearing a level early brings extra choices when upgrading. Never missing the bricks is also very beneficial.
|
||||||
|
So if you find it difficult to break the last bricks, getting this perk a few time can help.`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 500,
|
||||||
|
"id": "telekinesis",
|
||||||
|
"giftable": true,
|
||||||
|
"name": "Puck controls ball",
|
||||||
|
"max": 2,
|
||||||
|
help: lvl => lvl == 1 ? `Control the ball's trajectory.` : `Stronger effect on the ball`,
|
||||||
|
fullHelp: `Right after the ball hits your puck, you'll be able to direct it left and right by moving your puck.
|
||||||
|
The effect stops when the ball hits a brick and resets the next time it touches the puck. It also does nothing when the ball is going downward after bouncing at the top. `
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 1000,
|
||||||
|
giftable: false,
|
||||||
|
"id": "coin_magnet",
|
||||||
|
"name": "Coins magnet",
|
||||||
|
"max": 3,
|
||||||
|
help: lvl => lvl == 1 ? `Puck attracts coins.` : `Stronger effect on the coins`,
|
||||||
|
|
||||||
|
fullHelp: `Directs the coins to the puck. The effect is stronger if the coin is close to it already. Catching 90% or 100% of coins bring special bonuses in the game.
|
||||||
|
Another way to catch more coins is to hit bricks from the bottom. The ball's speed and direction impacts the spawned coin's velocity. `
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 1500,
|
||||||
|
"id": "multiball",
|
||||||
|
"giftable": true,
|
||||||
|
"name": "+1 ball",
|
||||||
|
"max": 6,
|
||||||
|
help: lvl => `Start every levels with ${lvl + 1} balls.`,
|
||||||
|
fullHelp: `As soon as you drop the ball in Breakout 71, you loose. With this perk, you get two balls, and so you can afford to lose one.
|
||||||
|
The lost balls come back on the next level or whenever you use one of your extra lives, if you picked that perk. Having more than one balls makes
|
||||||
|
some further perks available, and of course clears the level faster.`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 2000,
|
||||||
|
giftable: false,
|
||||||
|
"id": "smaller_puck",
|
||||||
|
"name": "Smaller puck",
|
||||||
|
"max": 2,
|
||||||
|
help: lvl => lvl == 1 ? `Also gives +5 base combo.` : `Even smaller puck and higher base combo`,
|
||||||
|
fullHelp: `This makes the puck smaller, which in theory makes some corner shots easier, but really just raises the difficulty.
|
||||||
|
That's why you also get a nice bonus of +5 coins per brick for all bricks you'll break after picking this. `
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 3000,
|
||||||
|
"id": "pierce",
|
||||||
|
"giftable": true,
|
||||||
|
"name": "Piercing",
|
||||||
|
"max": 3,
|
||||||
|
help: lvl => `Ball pierces ${3 * lvl} bricks after a puck bounce.`,
|
||||||
|
fullHelp: `The ball normally bounces as soon as it touches something. With this perk, it will continue its trajectory for up to 3 bricks broken.
|
||||||
|
After that, it will bounce on the 4th brick, and you'll need to touch the puck to reset the counter. This combines particularly well with Sapper. `
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 4000,
|
||||||
|
"id": "picky_eater",
|
||||||
|
"giftable": true,
|
||||||
|
"name": "Picky eater",
|
||||||
|
"max": 1,
|
||||||
|
help: lvl => `More coins if you break bricks color by color.`,
|
||||||
|
|
||||||
|
fullHelp: `Whenever you break a brick the same color as your ball, your combo increases by one.
|
||||||
|
If it's a different color, the ball takes that new color, but the combo resets.
|
||||||
|
The bricks with the right color will get a white border.
|
||||||
|
Once you get a combo higher than your minimum, the bricks of the wrong color will get a red halo.
|
||||||
|
If you have more than one ball, they all change color whenever one of them hits a brick.
|
||||||
|
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 5000,
|
||||||
|
giftable: false,
|
||||||
|
"id": "metamorphosis",
|
||||||
|
"name": "Stain",
|
||||||
|
"max": 1,
|
||||||
|
help: lvl => `Coins color the bricks they touch.`,
|
||||||
|
|
||||||
|
fullHelp: `With this perk, coins will be of the color of the brick they come from, and will color the first brick they touch in the same color. Coins spawn with the speed
|
||||||
|
of the ball that broke them, which means you can aim a bit in the direction of the bricks you want to "paint".
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 6000,
|
||||||
|
"id": "compound_interest",
|
||||||
|
"giftable": true,
|
||||||
|
"name": "Compound interest",
|
||||||
|
"max": 3,
|
||||||
|
help: lvl => `+${lvl} combo / brick broken, -${lvl} combo per coin lost`,
|
||||||
|
|
||||||
|
fullHelp: `Your combo will grow by one every time you break a brick, spawning more and more coin with every brick you break. Be sure however to catch every one of those coins
|
||||||
|
with your puck, as any lost coin will decrease your combo by one point. One your combo is above the minimum, the bottom of the play area will
|
||||||
|
have a red line to remind you that coins should not go there. This perk combines with other combo perks, the combo will rise faster but reset more easily.
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 7000,
|
||||||
|
"id": "hot_start",
|
||||||
|
"giftable": true,
|
||||||
|
"name": "Hot start",
|
||||||
|
"max": 3,
|
||||||
|
help: lvl => `Start at combo ${lvl * 15 + 1}, -${lvl} combo per second`,
|
||||||
|
fullHelp: `At the start of every level, your combo will start at +15 points, but then every second it will be decreased by one. This means the first 15 seconds in a level will spawn
|
||||||
|
many more coins than the following ones, and you should make sure that you clear the level quickly. The effect stacks with other combo related perks, so you might be able to raise
|
||||||
|
the combo after the 15s timeout, but it will keep ticking down. Every time you take the perk again, the effect will be more dramatic.
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 9000,
|
||||||
|
"id": "sapper",
|
||||||
|
"giftable": true,
|
||||||
|
"name": "Sapper",
|
||||||
|
"max": 7,
|
||||||
|
help: lvl => lvl === 1 ? 'The first brick broken becomes a bomb.' : `The first ${lvl} bricks broken become bombs.`,
|
||||||
|
fullHelp: `Instead of just disappearing, the first brick you break will be replaced by a bomb brick. Bouncing the ball on the puck re-arms the effect. "Piercing" will instantly
|
||||||
|
detonate the bomb that was just placed. Leveling-up this perk will allow you to place more bombs. Remember that bombs impact the velocity of nearby coins, so too many explosions
|
||||||
|
could make it hard to catch the fruits of your hard work.
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 11000,
|
||||||
|
"id": "bigger_explosions",
|
||||||
|
"name": "Kaboom",
|
||||||
|
"max": 1,
|
||||||
|
giftable: false,
|
||||||
|
|
||||||
|
help: lvl => 'Bigger explosions',
|
||||||
|
|
||||||
|
fullHelp: `The default explosion clears a 3x3 square, with this it becomes a 5x5 square, and the blowback on the coins is also significantly stronger. `
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 13000,
|
||||||
|
giftable: false,
|
||||||
|
"id": "extra_levels",
|
||||||
|
"name": "+1 level",
|
||||||
|
"max": 3,
|
||||||
|
help: lvl => `Play ${lvl + 7} levels instead of 7`,
|
||||||
|
fullHelp: `The default run can last a max of 7 levels, after which the game is over and whatever score you reached is your run score.
|
||||||
|
Each level of this perk lets you go one level higher. The last levels are often the ones where you make the most score, so the difference can be dramatic.`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 15000,
|
||||||
|
giftable: false,
|
||||||
|
"id": "pierce_color",
|
||||||
|
"name": "Color pierce",
|
||||||
|
"max": 1,
|
||||||
|
help: lvl => `Balls pierce bricks of their color.`,
|
||||||
|
fullHelp: `Whenever a ball hits a brick of the same color, it will just go through unimpeded.
|
||||||
|
Once it reaches a brick of a different color, it will break it, take its color and bounce.`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 18000,
|
||||||
|
giftable: false,
|
||||||
|
"id": "soft_reset",
|
||||||
|
"name": "Soft reset",
|
||||||
|
"max": 2,
|
||||||
|
help: lvl => `Combo grows ${lvl > 1 ? 'even' : ''} slower but resets less.`,
|
||||||
|
fullHelp: `The combo normally climbs every time you break a brick. This will sometimes cancel that climb, but also limit the impact of a combo reset.`
|
||||||
|
}, {
|
||||||
|
requires: 'multiball',
|
||||||
|
"threshold": 21000,
|
||||||
|
giftable: false,
|
||||||
|
"id": "ball_repulse_ball",
|
||||||
|
"name": "Personal space",
|
||||||
|
"max": 3,
|
||||||
|
help: lvl => lvl === 1 ? `Balls repulse balls.` : 'Stronger repulsion force',
|
||||||
|
|
||||||
|
fullHelp: `Balls that are less than half a screen width away will start repulsing each other. The repulsion force is stronger if they are close to each other.
|
||||||
|
Particles will jet out to symbolize this force being applied. This perk is only offered if you have more than one ball already.`
|
||||||
|
}, {
|
||||||
|
requires: 'multiball',
|
||||||
|
"threshold": 25000,
|
||||||
|
giftable: false,
|
||||||
|
"id": "ball_attract_ball",
|
||||||
|
"name": "Gravity",
|
||||||
|
"max": 3,
|
||||||
|
help: lvl => lvl === 1 ? `Balls attract balls.` : 'Stronger attraction force',
|
||||||
|
|
||||||
|
fullHelp: `Balls that are more than half a screen width away will start attracting each other. The attraction force is stronger when they are furthest away from each other.
|
||||||
|
Rainbow particles will fly to symbolize the attraction force. This perk is only offered if you have more than one ball already.`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 30000,
|
||||||
|
giftable: false,
|
||||||
|
"id": "puck_repulse_ball",
|
||||||
|
"name": "Soft landing",
|
||||||
|
"max": 3,
|
||||||
|
help: lvl => lvl === 1 ? `Puck repulses balls.` : 'Stronger repulsion force',
|
||||||
|
fullHelp: `When a ball gets close to the puck, it will start slowing down, and even potentially bouncing without touching the puck.`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 35000,
|
||||||
|
giftable: false,
|
||||||
|
"id": "wind",
|
||||||
|
"name": "Wind",
|
||||||
|
"max": 3,
|
||||||
|
help: lvl => lvl === 1 ? `Puck position creates wind.` : 'Stronger wind force',
|
||||||
|
fullHelp: `The wind depends on where your puck is, if it's in the center of the screen nothing happens, if it's on the left it will blow leftwise, if it's on the right of the screen
|
||||||
|
then it will blow rightwise. The wind affects both the balls and coins.`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 40000,
|
||||||
|
giftable: false,
|
||||||
|
"id": "sturdy_bricks",
|
||||||
|
"name": "Sturdy bricks",
|
||||||
|
"max": 4,
|
||||||
|
help: lvl => lvl === 1 ? `Bricks sometimes resist hits but drop more coins.` : 'Bricks resist more and drop more coins',
|
||||||
|
fullHelp: `With level one of this perk, the ball has a 20% chance to bounce harmlessly on bricks,
|
||||||
|
but generates 10% more coins when it does break one.
|
||||||
|
This +10% is not shown in the combo number. At level 4 the ball has 80% chance of bouncing and brings 40% more coins.`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 45000,
|
||||||
|
giftable: false,
|
||||||
|
"id": "respawn",
|
||||||
|
"name": "Respawn",
|
||||||
|
"max": 4,
|
||||||
|
help: lvl => lvl === 1 ? `The first brick hit of two+ will respawn.` : 'More bricks can respawn',
|
||||||
|
fullHelp: `After breaking two or more bricks, when the ball hits the puck, the first brick will be put back in place, provided that space is free and the brick wasn't a bomb.
|
||||||
|
Some particle effect will let you know where bricks will appear. Levelling this up lets you respawn up to 4 bricks at a time, but there should always be at least one destroyed.
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 50000,
|
||||||
|
giftable: false,
|
||||||
|
"id": "one_more_choice",
|
||||||
|
"name": "+1 choice until run end",
|
||||||
|
"max": 3,
|
||||||
|
help: lvl => lvl === 1 ? `Further level ups will offer one more option in the list.` : 'Even more options',
|
||||||
|
fullHelp: `Every upgrade menu will have one more option.
|
||||||
|
Doesn't increase the number of upgrades you can pick.
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
requires: '',
|
||||||
|
"threshold": 55000,
|
||||||
|
giftable: false,
|
||||||
|
"id": "instant_upgrade",
|
||||||
|
"name": "+2 upgrades now",
|
||||||
|
"max": 2,
|
||||||
|
help: lvl => lvl === 1 ? `-1 choice until run end.` : 'Even fewer options',
|
||||||
|
fullHelp: `Immediately pick two upgrades, so that you get one free one and one to repay the one used to get this perk. Every further menu to pick upgrades will have fewer options to choose from.`
|
||||||
|
}] as const;
|
|
@ -46,10 +46,6 @@ body {
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.black_puck #score,
|
|
||||||
body.black_puck #menu {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
#score:hover,
|
#score:hover,
|
||||||
#score:focus,
|
#score:focus,
|
||||||
|
|
38
src/types.d.ts
vendored
Normal file
38
src/types.d.ts
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import {rawUpgrades} from "./rawUpgrades";
|
||||||
|
|
||||||
|
export type RawLevel = {
|
||||||
|
name: string;
|
||||||
|
size: number;
|
||||||
|
bricks: string;
|
||||||
|
svg: string;
|
||||||
|
color: string;
|
||||||
|
};
|
||||||
|
export type Level = {
|
||||||
|
name: string;
|
||||||
|
size: number;
|
||||||
|
bricks: string[];
|
||||||
|
svg: string;
|
||||||
|
color: string;
|
||||||
|
threshold?: number;
|
||||||
|
sortKey?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Palette = { [k: string]: string }
|
||||||
|
|
||||||
|
export type Upgrade={
|
||||||
|
threshold: number;
|
||||||
|
giftable: boolean;
|
||||||
|
"id": string;
|
||||||
|
"name": string;
|
||||||
|
"max": number;
|
||||||
|
help: (lvl:string) => string;
|
||||||
|
fullHelp: string;
|
||||||
|
requires:PerkId|''
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export type PerkId = typeof rawUpgrades[number]['id']
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window { webkitAudioContext: typeof AudioContext; }
|
||||||
|
}
|
10
tsconfig.json
Normal file
10
tsconfig.json
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2015",
|
||||||
|
"rootDir": "src",
|
||||||
|
"strict": false,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"resolveJsonModule": true
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue