diff --git a/Readme.md b/Readme.md index a8cce2a..57d6fc2 100644 --- a/Readme.md +++ b/Readme.md @@ -17,11 +17,15 @@ Break colourful bricks, catch bouncing coins and select powerful upgrades ! ## Done +- added particle effect for wrap + +## 29087440 + +- zen : now you gain one combo per bomb on screen when breaking a brick (so no bombs, no gain) - sticky coins : coins stay stuck when there's an explosion -- split level unlock and perks unlocks -- wrap_left -- wrap_right -- rework passive income +- wrap_left / wrap_right : teleport the ball to the other side of the screen when it hits a border +- passive income : now moving the puck makes it transparent to coins and balls, but not reset the combo +- main menu : split level unlock and perks unlocks ## 29087252 - apply percentage boost to combo shown on brick diff --git a/dist/index.html b/dist/index.html index 1980893..eb76df3 100644 --- a/dist/index.html +++ b/dist/index.html @@ -4112,17 +4112,18 @@ frames = 1) { if (gameState.perks.helium && !(0, _options.isOptionOn)("basic") && Math.random() < 0.1 * frames) makeParticle(gameState, coin.x, coin.y, 0, dvy * 10, (0, _gameUtils.getCoinRenderColor)(gameState, coin), true, 5, 250); const speed = (Math.abs(coin.vx) + Math.abs(coin.vy)) * 10; const hitBorder = bordersHitCheck(gameState, coin, coin.size / 2, frames); - if (gameState.perks.wrap_left > 1 && hitBorder % 2 && coin.x < gameState.offsetX + gameState.gameZoneWidth / 2) { + if (gameState.perks.wrap_left > 1 && hitBorder % 2 && coin.previousX < gameState.offsetX + gameState.gameZoneWidth / 2) { schedulGameSound(gameState, "plouf", coin.x, 1); - coin.x = gameState.offsetX + gameState.gameZoneWidth - gameState.coinSize / 2; + coin.x = gameState.offsetX + gameState.gameZoneWidth - gameState.coinSize; if (coin.vx > 0) coin.vx *= -1; if (!(0, _options.isOptionOn)("basic")) { spawnExplosion(gameState, 3, coin.x, coin.y, "#6262EA"); spawnImplosion(gameState, 3, coin.previousX, coin.previousY, "#6262EA"); } - } else if (gameState.perks.wrap_right > 1 && hitBorder % 2 && coin.x > gameState.offsetX + gameState.gameZoneWidth / 2) { + } + if (gameState.perks.wrap_right > 1 && hitBorder % 2 && coin.previousX > gameState.offsetX + gameState.gameZoneWidth / 2) { schedulGameSound(gameState, "plouf", coin.x, 1); - coin.x = gameState.offsetX + gameState.coinSize / 2; + coin.x = gameState.offsetX + gameState.coinSize; if (coin.vx < 0) coin.vx *= -1; if (!(0, _options.isOptionOn)("basic")) { spawnExplosion(gameState, 3, coin.x, coin.y, "#6262EA"); @@ -4212,7 +4213,7 @@ frames = 1) { } }); } - if (gameState.combo > baseCombo(gameState) && !(0, _options.isOptionOn)("basic") && (gameState.combo - baseCombo(gameState)) * Math.random() > 5) { + if (gameState.combo > baseCombo(gameState) && !(0, _options.isOptionOn)("basic") && (gameState.combo - baseCombo(gameState)) * Math.random() * frames > 5) { // The red should still be visible on a white bg if (gameState.perks.top_is_lava == 1) makeParticle(gameState, gameState.offsetXRoundedDown + Math.random() * gameState.gameZoneWidthRoundedUp, 0, (Math.random() - 0.5) * 10, 5, "#FF0000", true, gameState.coinSize / 2, 100 * (Math.random() + 1)); if (gameState.perks.left_is_lava == 1) makeParticle(gameState, gameState.offsetXRoundedDown, Math.random() * gameState.gameZoneHeight, 5, (Math.random() - 0.5) * 10, "#FF0000", true, gameState.coinSize / 2, 100 * (Math.random() + 1)); @@ -4230,6 +4231,8 @@ frames = 1) { makeParticle(gameState, gameState.puckPosition + gameState.puckWidth * pos, gameState.gameZoneHeight - gameState.puckHeight, pos * 10, -5, "#FF0000", true, gameState.coinSize / 2, 100 * (Math.random() + 1)); } } + if (gameState.perks.wrap_left && gameState.perks.left_is_lava < 2 && Math.random() * frames > 0.1) makeParticle(gameState, gameState.offsetXRoundedDown, Math.random() * gameState.gameZoneHeight, 5, (Math.random() - 0.5) * 10, "#6262EA", true, gameState.coinSize / 2, 100 * (Math.random() + 1)); + if (gameState.perks.wrap_right && gameState.perks.right_is_lava < 2 && Math.random() * frames > 0.1) makeParticle(gameState, gameState.offsetXRoundedDown + gameState.gameZoneWidth, Math.random() * gameState.gameZoneHeight, -5, (Math.random() - 0.5) * 10, "#6262EA", true, gameState.coinSize / 2, 100 * (Math.random() + 1)); // Respawn what's needed, show particles forEachLiveOne(gameState.respawns, (r, ri)=>{ if (gameState.bricks[r.index]) destroy(gameState.respawns, ri); @@ -4294,25 +4297,30 @@ function ballTick(gameState, ball, frames) { if (borderHitCode) { ball.sidesHitsSinceBounce++; if (ball.sidesHitsSinceBounce <= gameState.perks.three_cushion * 3) increaseCombo(gameState, 1, ball.x, ball.y); - if (gameState.perks.left_is_lava && borderHitCode % 2 && ball.x < gameState.offsetX + gameState.gameZoneWidth / 2) resetCombo(gameState, ball.x, ball.y); - if (gameState.perks.wrap_left && borderHitCode % 2 && ball.x < gameState.offsetX + gameState.gameZoneWidth / 2) { + if (gameState.perks.wrap_left && borderHitCode % 2 && // x might be moved by wrap so we rely on previousX + ball.previousX < gameState.offsetX + gameState.gameZoneWidth / 2) { schedulGameSound(gameState, "plouf", ball.x, 1); - ball.x = gameState.offsetX + gameState.gameZoneWidth - gameState.ballSize / 2; + ball.x = gameState.offsetX + gameState.gameZoneWidth - gameState.ballSize; if (ball.vx > 0) ball.vx *= -1; if (!(0, _options.isOptionOn)("basic")) { spawnExplosion(gameState, 7, ball.x, ball.y, "#6262EA"); spawnImplosion(gameState, 7, ball.previousX, ball.previousY, "#6262EA"); } - } else if (gameState.perks.wrap_right && borderHitCode % 2 && ball.x > gameState.offsetX + gameState.gameZoneWidth / 2) { + } + if (gameState.perks.wrap_right && borderHitCode % 2 && // x might be moved by wrap so we rely on previousX + ball.previousX > gameState.offsetX + gameState.gameZoneWidth / 2) { schedulGameSound(gameState, "plouf", ball.x, 1); - ball.x = gameState.offsetX + gameState.ballSize / 2; + ball.x = gameState.offsetX + gameState.ballSize; if (ball.vx < 0) ball.vx *= -1; if (!(0, _options.isOptionOn)("basic")) { spawnExplosion(gameState, 7, ball.x, ball.y, "#6262EA"); spawnImplosion(gameState, 7, ball.previousX, ball.previousY, "#6262EA"); } } - if (gameState.perks.right_is_lava && borderHitCode % 2 && ball.x > gameState.offsetX + gameState.gameZoneWidth / 2) resetCombo(gameState, ball.x, ball.y); + if (gameState.perks.left_is_lava && borderHitCode % 2 && // x might be moved by wrap so we rely on previousX + ball.previousX < gameState.offsetX + gameState.gameZoneWidth / 2) resetCombo(gameState, ball.x, ball.y); + if (gameState.perks.right_is_lava && borderHitCode % 2 && // x might be moved by wrap so we rely on previousX + ball.previousX > gameState.offsetX + gameState.gameZoneWidth / 2) resetCombo(gameState, ball.x, ball.y); if (gameState.perks.top_is_lava && borderHitCode >= 2) resetCombo(gameState, ball.x, ball.y + gameState.ballSize * 3); if (gameState.perks.trampoline) decreaseCombo(gameState, gameState.perks.trampoline, ball.x, ball.y + gameState.ballSize); schedulGameSound(gameState, "wallBeep", ball.x, 1); @@ -6400,6 +6408,10 @@ migrate("clean_ls", ()=>{ console.warn("Removed invalid key " + key, e); } }); +migrate("set_user_id", ()=>{ + // Useful to identify a player when uploading his save file multiple times to a web service + if (!localStorage.getItem('breakout_71_user_id')) localStorage.setItem('breakout_71_user_id', JSON.stringify(self?.crypto?.randomUUID() || 'user_' + Math.random())); +}); afterMigration(); },{"./data/version.json":"iyP6E","./generateSaveFileContent":"iEcoB","./game_utils":"cEeac","./loadGameData":"l1B4x","./toast":"nAuvo","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"iEcoB":[function(require,module,exports,__globalThis) { diff --git a/src/gameStateMutators.ts b/src/gameStateMutators.ts index a2ea102..5ac07d2 100644 --- a/src/gameStateMutators.ts +++ b/src/gameStateMutators.ts @@ -1231,11 +1231,11 @@ export function gameStateTick( if ( gameState.perks.wrap_left > 1 && hitBorder % 2 && - coin.x < gameState.offsetX + gameState.gameZoneWidth / 2 + coin.previousX < gameState.offsetX + gameState.gameZoneWidth / 2 ) { schedulGameSound(gameState, "plouf", coin.x, 1); coin.x = - gameState.offsetX + gameState.gameZoneWidth - gameState.coinSize / 2; + gameState.offsetX + gameState.gameZoneWidth - gameState.coinSize; if (coin.vx > 0) { coin.vx *= -1; } @@ -1249,13 +1249,15 @@ export function gameStateTick( "#6262EA", ); } - } else if ( + } + + if ( gameState.perks.wrap_right > 1 && hitBorder % 2 && - coin.x > gameState.offsetX + gameState.gameZoneWidth / 2 + coin.previousX > gameState.offsetX + gameState.gameZoneWidth / 2 ) { schedulGameSound(gameState, "plouf", coin.x, 1); - coin.x = gameState.offsetX + gameState.coinSize / 2; + coin.x = gameState.offsetX + gameState.coinSize; if (coin.vx < 0) { coin.vx *= -1; @@ -1472,7 +1474,7 @@ export function gameStateTick( if ( gameState.combo > baseCombo(gameState) && !isOptionOn("basic") && - (gameState.combo - baseCombo(gameState)) * Math.random() > 5 + (gameState.combo - baseCombo(gameState)) * Math.random() * frames > 5 ) { // The red should still be visible on a white bg @@ -1563,6 +1565,40 @@ export function gameStateTick( } } + if( + gameState.perks.wrap_left && + gameState.perks.left_is_lava<2 && + Math.random()*frames > 0.1){ + makeParticle( + gameState, + gameState.offsetXRoundedDown, + Math.random() * gameState.gameZoneHeight, + 5, + (Math.random() - 0.5) * 10, + "#6262EA", + true, + gameState.coinSize / 2, + 100 * (Math.random() + 1), + ); + } + if( + gameState.perks.wrap_right && + gameState.perks.right_is_lava<2 && + Math.random()*frames > 0.1){ + makeParticle( + gameState, + gameState.offsetXRoundedDown+gameState.gameZoneWidth, + Math.random() * gameState.gameZoneHeight, + -5, + (Math.random() - 0.5) * 10, + "#6262EA", + true, + gameState.coinSize / 2, + 100 * (Math.random() + 1), + ); + } + + // Respawn what's needed, show particles forEachLiveOne(gameState.respawns, (r, ri) => { if (gameState.bricks[r.index]) { @@ -1704,24 +1740,16 @@ export function ballTick(gameState: GameState, ball: Ball, frames: number) { ball.sidesHitsSinceBounce++; if (ball.sidesHitsSinceBounce <= gameState.perks.three_cushion * 3) { increaseCombo(gameState, 1, ball.x, ball.y); - } - - if ( - gameState.perks.left_is_lava && - borderHitCode % 2 && - ball.x < gameState.offsetX + gameState.gameZoneWidth / 2 - ) { - resetCombo(gameState, ball.x, ball.y); - } - + } if ( gameState.perks.wrap_left && borderHitCode % 2 && - ball.x < gameState.offsetX + gameState.gameZoneWidth / 2 + // x might be moved by wrap so we rely on previousX + ball.previousX < gameState.offsetX + gameState.gameZoneWidth / 2 ) { schedulGameSound(gameState, "plouf", ball.x, 1); ball.x = - gameState.offsetX + gameState.gameZoneWidth - gameState.ballSize / 2; + gameState.offsetX + gameState.gameZoneWidth - gameState.ballSize ; if (ball.vx > 0) { ball.vx *= -1; } @@ -1730,13 +1758,16 @@ export function ballTick(gameState: GameState, ball: Ball, frames: number) { spawnExplosion(gameState, 7, ball.x, ball.y, "#6262EA"); spawnImplosion(gameState, 7, ball.previousX, ball.previousY, "#6262EA"); } - } else if ( + } + + if ( gameState.perks.wrap_right && borderHitCode % 2 && - ball.x > gameState.offsetX + gameState.gameZoneWidth / 2 + // x might be moved by wrap so we rely on previousX + ball.previousX > gameState.offsetX + gameState.gameZoneWidth / 2 ) { schedulGameSound(gameState, "plouf", ball.x, 1); - ball.x = gameState.offsetX + gameState.ballSize / 2; + ball.x = gameState.offsetX + gameState.ballSize ; if (ball.vx < 0) { ball.vx *= -1; @@ -1747,10 +1778,20 @@ export function ballTick(gameState: GameState, ball: Ball, frames: number) { } } + if ( + gameState.perks.left_is_lava && + borderHitCode % 2 && + // x might be moved by wrap so we rely on previousX + ball.previousX < gameState.offsetX + gameState.gameZoneWidth / 2 + ) { + resetCombo(gameState, ball.x, ball.y); + } + if ( gameState.perks.right_is_lava && borderHitCode % 2 && - ball.x > gameState.offsetX + gameState.gameZoneWidth / 2 + // x might be moved by wrap so we rely on previousX + ball.previousX > gameState.offsetX + gameState.gameZoneWidth / 2 ) { resetCombo(gameState, ball.x, ball.y); } diff --git a/src/migrations.ts b/src/migrations.ts index f75b53d..ac6819b 100644 --- a/src/migrations.ts +++ b/src/migrations.ts @@ -151,4 +151,14 @@ migrate("clean_ls", () => { } }); + +migrate("set_user_id", () => { + // Useful to identify a player when uploading his save file multiple times to a web service + if(!localStorage.getItem('breakout_71_user_id')){ + localStorage.setItem('breakout_71_user_id', JSON.stringify(self?.crypto?.randomUUID()||'user_'+Math.random())) + } +}); + + + afterMigration();