This commit is contained in:
Renan LE CARO 2025-05-04 15:43:58 +02:00
parent 06aac98954
commit 4df70f6591
6 changed files with 2613 additions and 2550 deletions

View file

@ -14,10 +14,11 @@ Break colourful bricks, catch bouncing coins and select powerful upgrades !
# Changelog
## To do
- easy cleanup special effect
## Done
- boosted perk : stronger foundation (+3 combo, then +4, then +5..)
- easy cleanup special effect (and X made of particles)
- added a few levels
- level end countdown (on mobile and desktop)
- level start countdown (on mobile)

839
dist/index.html vendored

File diff suppressed because one or more lines are too long

View file

@ -11,6 +11,7 @@ import {
} from "./types";
import {
base_combo_from_stronger_foundation,
brickCenterX,
brickCenterY,
canvasCenterX,
@ -32,31 +33,18 @@ import {
zoneLeftBorderX,
zoneRightBorderX,
} from "./game_utils";
import { t } from "./i18n/i18n";
import {t} from "./i18n/i18n";
import { getCurrentMaxCoins, getCurrentMaxParticles } from "./settings";
import { background } from "./render";
import { gameOver } from "./gameOver";
import {
brickIndex,
fitSize,
gameState,
hasBrick,
hitsSomething,
pause,
startComputerControlledGame,
} from "./game";
import { stopRecording } from "./recording";
import { isOptionOn } from "./options";
import {
ballTransparency,
clamp,
coinsBoostedCombo,
comboKeepingRate,
} from "./pure_functions";
import { addToTotalScore } from "./addToTotalScore";
import { hashCode } from "./getLevelBackground";
import { openUpgradesPicker } from "./openUpgradesPicker";
import {getCurrentMaxCoins, getCurrentMaxParticles} from "./settings";
import {background} from "./render";
import {gameOver} from "./gameOver";
import {brickIndex, fitSize, gameState, hasBrick, hitsSomething, pause, startComputerControlledGame,} from "./game";
import {stopRecording} from "./recording";
import {isOptionOn} from "./options";
import {ballTransparency, clamp, coinsBoostedCombo, comboKeepingRate,} from "./pure_functions";
import {addToTotalScore} from "./addToTotalScore";
import {hashCode} from "./getLevelBackground";
import {openUpgradesPicker} from "./openUpgradesPicker";
export function setMousePos(gameState: GameState, x: number) {
if (gameState.startParams.computer_controlled) return;
@ -215,7 +203,7 @@ export function normalizeGameState(gameState: GameState) {
}
export function baseCombo(gameState: GameState) {
return 1 + gameState.perks.base_combo * 3;
return base_combo_from_stronger_foundation(gameState.perks.base_combo);
}
export function resetCombo(
@ -311,6 +299,45 @@ export function spawnParticlesExplosion(
}
}
export function spawnXShapedParticlesExplosion(
gameState: GameState,
count: number,
x: number,
y: number,
color: string,
) {
if (!!isOptionOn("basic")) return;
if (liveCount(gameState.particles) > getCurrentMaxParticles()) {
// Avoid freezing when lots of explosion happen at once
return;
}
spawnInLine(gameState, count, x, y, -5, -5, color)
spawnInLine(gameState, count, x, y, -5, 5, color)
spawnInLine(gameState, count, x, y, 5, 5, color)
spawnInLine(gameState, count, x, y, -5, -5, color)
}
function spawnInLine(gameState: GameState, count: number,
x: number,
y: number,
dx: number,
dy: number,
color: string) {
for (let i = 1; i <= count; i++) {
makeParticle(
gameState,
x + i * dx,
y + i * dy,
dx,
dy,
color,
true,
8,400
);
}
}
export function spawnParticlesImplosion(
gameState: GameState,
count: number,
@ -435,7 +462,7 @@ export function explodeBrick(
while (coinsToSpawn > 0) {
const points = Math.min(pointsPerCoin, coinsToSpawn);
if (points < 0 || isNaN(points)) {
console.error({ points });
console.error({points});
debugger;
}
@ -581,7 +608,8 @@ export function addToScore(gameState: GameState, coin: Coin) {
gameState.highScore = gameState.score;
try {
localStorage.setItem("breakout-3-hs-short", gameState.score.toString());
} catch (e) {}
} catch (e) {
}
}
if (!isOptionOn("basic")) {
makeParticle(
@ -814,7 +842,7 @@ export function attract(gameState: GameState, a: Ball, b: Ball, power: number) {
export function coinBrickHitCheck(gameState: GameState, coin: Coin) {
// Make ball/coin bonce, and return bricks that were hit
const radius = coin.size / 2;
const { x, y, previousX, previousY } = coin;
const {x, y, previousX, previousY} = coin;
const vhit = hitsSomething(previousX, y, radius);
const hhit = hitsSomething(x, previousY, radius);
@ -978,6 +1006,8 @@ export function gameStateTick(
gameState.bricks.forEach((type, index) => {
if (type) {
explodeBrick(gameState, index, gameState.balls[0], true);
spawnXShapedParticlesExplosion(gameState, 10, brickCenterX(gameState,index),brickCenterY(gameState,index),
type)
}
});
gameState.autoCleanUses++;
@ -1011,7 +1041,7 @@ export function gameStateTick(
} else {
gameOver(
t("gameOver.win.title"),
t("gameOver.win.summary", { score: gameState.score }),
t("gameOver.win.summary", {score: gameState.score}),
);
}
} else {
@ -1569,7 +1599,7 @@ export function gameStateTick(
setBrick(gameState, r.index, r.color);
destroy(gameState.respawns, ri);
} else {
const { index, color } = r;
const {index, color} = r;
const vertical = Math.random() > 0.5;
const dx = Math.random() > 0.5 ? 1 : -1;
const dy = Math.random() > 0.5 ? 1 : -1;
@ -1915,14 +1945,14 @@ export function ballTick(gameState: GameState, ball: Ball, frames: number) {
} else {
gameOver(
t("gameOver.lost.title"),
t("gameOver.lost.summary", { score: gameState.score }),
t("gameOver.lost.summary", {score: gameState.score}),
);
}
}
}
const radius = gameState.ballSize / 2;
// Make ball/coin bonce, and return bricks that were hit
const { x, y, previousX, previousY } = ball;
const {x, y, previousX, previousY} = ball;
const vhit = hitsSomething(previousX, y, radius);
const hhit = hitsSomething(x, previousY, radius);
@ -2198,7 +2228,7 @@ export function append<T>(
makeItem(where.list[where.indexMin]);
where.indexMin++;
} else {
const p = { destroyed: false };
const p = {destroyed: false};
makeItem(p);
where.list.push(p);
}

View file

@ -355,3 +355,11 @@ export function zoneLeftBorderX(gameState: GameState) {
export function zoneRightBorderX(gameState: GameState) {
return gameState.canvasWidth - gameState.offsetXRoundedDown + 1;
}
export function base_combo_from_stronger_foundation(perkLevel:number){
let base = 1
for(let i = 0;i<perkLevel;i++){
base+=3+i
}
return base
}

View file

@ -272,7 +272,7 @@
"upgrades.ball_repulse_ball.verbose_description": "Balls that are less than a quarter 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.",
"upgrades.base_combo.name": "Strong foundations",
"upgrades.base_combo.tooltip": "3 more coins per brick broken",
"upgrades.base_combo.verbose_description": "Your combo normally starts at 1 at the beginning of the level, and resets to 1 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.",
"upgrades.base_combo.verbose_description": "Your combo normally starts at 1 at the beginning of the level, and resets to 1 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. At level 2, it adds 4 coins, then 5,then 6...",
"upgrades.bigger_explosions.name": "Kaboom",
"upgrades.bigger_explosions.tooltip": "Bigger explosions",
"upgrades.bigger_explosions.verbose_description": "The default explosion clears a 3x3 square, with this it becomes a 5x5 square, and the blow on the coins is also significantly stronger. The screen will flash after each explosion (except in basic mode)",

View file

@ -2,6 +2,7 @@ import { t } from "./i18n/i18n";
import { comboKeepingRate } from "./pure_functions";
import { PerkId, Upgrade } from "./types";
import {base_combo_from_stronger_foundation} from "./game_utils";
// Those perks are excluded from creative mode
export const noCreative: PerkId[] = [
@ -768,7 +769,7 @@ export const rawUpgrades = [
max: 7,
name: t("upgrades.base_combo.name"),
help: (lvl: number) =>
t("upgrades.base_combo.tooltip", { coins: 1 + lvl * 3 }),
t("upgrades.base_combo.tooltip", { coins: base_combo_from_stronger_foundation(lvl) }),
fullHelp: (lvl: number) =>
t("upgrades.base_combo.verbose_description", { lvl }),
},