mirror of
https://gitlab.com/lecarore/breakout71.git
synced 2025-05-04 18:59:13 -04:00
wip
This commit is contained in:
parent
06aac98954
commit
4df70f6591
6 changed files with 2613 additions and 2550 deletions
|
@ -14,10 +14,11 @@ Break colourful bricks, catch bouncing coins and select powerful upgrades !
|
||||||
# Changelog
|
# Changelog
|
||||||
## To do
|
## To do
|
||||||
|
|
||||||
- easy cleanup special effect
|
|
||||||
|
|
||||||
## Done
|
## Done
|
||||||
|
|
||||||
|
- boosted perk : stronger foundation (+3 combo, then +4, then +5..)
|
||||||
|
- easy cleanup special effect (and X made of particles)
|
||||||
- added a few levels
|
- added a few levels
|
||||||
- level end countdown (on mobile and desktop)
|
- level end countdown (on mobile and desktop)
|
||||||
- level start countdown (on mobile)
|
- level start countdown (on mobile)
|
||||||
|
|
839
dist/index.html
vendored
839
dist/index.html
vendored
File diff suppressed because one or more lines are too long
|
@ -11,6 +11,7 @@ import {
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
base_combo_from_stronger_foundation,
|
||||||
brickCenterX,
|
brickCenterX,
|
||||||
brickCenterY,
|
brickCenterY,
|
||||||
canvasCenterX,
|
canvasCenterX,
|
||||||
|
@ -32,31 +33,18 @@ import {
|
||||||
zoneLeftBorderX,
|
zoneLeftBorderX,
|
||||||
zoneRightBorderX,
|
zoneRightBorderX,
|
||||||
} from "./game_utils";
|
} from "./game_utils";
|
||||||
import { t } from "./i18n/i18n";
|
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 {
|
import {brickIndex, fitSize, gameState, hasBrick, hitsSomething, pause, startComputerControlledGame,} from "./game";
|
||||||
brickIndex,
|
import {stopRecording} from "./recording";
|
||||||
fitSize,
|
import {isOptionOn} from "./options";
|
||||||
gameState,
|
import {ballTransparency, clamp, coinsBoostedCombo, comboKeepingRate,} from "./pure_functions";
|
||||||
hasBrick,
|
import {addToTotalScore} from "./addToTotalScore";
|
||||||
hitsSomething,
|
import {hashCode} from "./getLevelBackground";
|
||||||
pause,
|
import {openUpgradesPicker} from "./openUpgradesPicker";
|
||||||
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) {
|
export function setMousePos(gameState: GameState, x: number) {
|
||||||
if (gameState.startParams.computer_controlled) return;
|
if (gameState.startParams.computer_controlled) return;
|
||||||
|
@ -215,7 +203,7 @@ export function normalizeGameState(gameState: GameState) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function baseCombo(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(
|
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(
|
export function spawnParticlesImplosion(
|
||||||
gameState: GameState,
|
gameState: GameState,
|
||||||
count: number,
|
count: number,
|
||||||
|
@ -435,7 +462,7 @@ export function explodeBrick(
|
||||||
while (coinsToSpawn > 0) {
|
while (coinsToSpawn > 0) {
|
||||||
const points = Math.min(pointsPerCoin, coinsToSpawn);
|
const points = Math.min(pointsPerCoin, coinsToSpawn);
|
||||||
if (points < 0 || isNaN(points)) {
|
if (points < 0 || isNaN(points)) {
|
||||||
console.error({ points });
|
console.error({points});
|
||||||
debugger;
|
debugger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,7 +608,8 @@ export function addToScore(gameState: GameState, coin: Coin) {
|
||||||
gameState.highScore = gameState.score;
|
gameState.highScore = gameState.score;
|
||||||
try {
|
try {
|
||||||
localStorage.setItem("breakout-3-hs-short", gameState.score.toString());
|
localStorage.setItem("breakout-3-hs-short", gameState.score.toString());
|
||||||
} catch (e) {}
|
} catch (e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!isOptionOn("basic")) {
|
if (!isOptionOn("basic")) {
|
||||||
makeParticle(
|
makeParticle(
|
||||||
|
@ -814,7 +842,7 @@ export function attract(gameState: GameState, a: Ball, b: Ball, power: number) {
|
||||||
export function coinBrickHitCheck(gameState: GameState, coin: Coin) {
|
export function coinBrickHitCheck(gameState: GameState, coin: Coin) {
|
||||||
// Make ball/coin bonce, and return bricks that were hit
|
// Make ball/coin bonce, and return bricks that were hit
|
||||||
const radius = coin.size / 2;
|
const radius = coin.size / 2;
|
||||||
const { x, y, previousX, previousY } = coin;
|
const {x, y, previousX, previousY} = coin;
|
||||||
|
|
||||||
const vhit = hitsSomething(previousX, y, radius);
|
const vhit = hitsSomething(previousX, y, radius);
|
||||||
const hhit = hitsSomething(x, previousY, radius);
|
const hhit = hitsSomething(x, previousY, radius);
|
||||||
|
@ -978,6 +1006,8 @@ export function gameStateTick(
|
||||||
gameState.bricks.forEach((type, index) => {
|
gameState.bricks.forEach((type, index) => {
|
||||||
if (type) {
|
if (type) {
|
||||||
explodeBrick(gameState, index, gameState.balls[0], true);
|
explodeBrick(gameState, index, gameState.balls[0], true);
|
||||||
|
spawnXShapedParticlesExplosion(gameState, 10, brickCenterX(gameState,index),brickCenterY(gameState,index),
|
||||||
|
type)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
gameState.autoCleanUses++;
|
gameState.autoCleanUses++;
|
||||||
|
@ -1011,7 +1041,7 @@ export function gameStateTick(
|
||||||
} else {
|
} else {
|
||||||
gameOver(
|
gameOver(
|
||||||
t("gameOver.win.title"),
|
t("gameOver.win.title"),
|
||||||
t("gameOver.win.summary", { score: gameState.score }),
|
t("gameOver.win.summary", {score: gameState.score}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1569,7 +1599,7 @@ export function gameStateTick(
|
||||||
setBrick(gameState, r.index, r.color);
|
setBrick(gameState, r.index, r.color);
|
||||||
destroy(gameState.respawns, ri);
|
destroy(gameState.respawns, ri);
|
||||||
} else {
|
} else {
|
||||||
const { index, color } = r;
|
const {index, color} = r;
|
||||||
const vertical = Math.random() > 0.5;
|
const vertical = Math.random() > 0.5;
|
||||||
const dx = Math.random() > 0.5 ? 1 : -1;
|
const dx = Math.random() > 0.5 ? 1 : -1;
|
||||||
const dy = 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 {
|
} else {
|
||||||
gameOver(
|
gameOver(
|
||||||
t("gameOver.lost.title"),
|
t("gameOver.lost.title"),
|
||||||
t("gameOver.lost.summary", { score: gameState.score }),
|
t("gameOver.lost.summary", {score: gameState.score}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const radius = gameState.ballSize / 2;
|
const radius = gameState.ballSize / 2;
|
||||||
// Make ball/coin bonce, and return bricks that were hit
|
// 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 vhit = hitsSomething(previousX, y, radius);
|
||||||
const hhit = hitsSomething(x, previousY, radius);
|
const hhit = hitsSomething(x, previousY, radius);
|
||||||
|
@ -2198,7 +2228,7 @@ export function append<T>(
|
||||||
makeItem(where.list[where.indexMin]);
|
makeItem(where.list[where.indexMin]);
|
||||||
where.indexMin++;
|
where.indexMin++;
|
||||||
} else {
|
} else {
|
||||||
const p = { destroyed: false };
|
const p = {destroyed: false};
|
||||||
makeItem(p);
|
makeItem(p);
|
||||||
where.list.push(p);
|
where.list.push(p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -355,3 +355,11 @@ export function zoneLeftBorderX(gameState: GameState) {
|
||||||
export function zoneRightBorderX(gameState: GameState) {
|
export function zoneRightBorderX(gameState: GameState) {
|
||||||
return gameState.canvasWidth - gameState.offsetXRoundedDown + 1;
|
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
|
||||||
|
}
|
|
@ -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.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.name": "Strong foundations",
|
||||||
"upgrades.base_combo.tooltip": "3 more coins per brick broken",
|
"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.name": "Kaboom",
|
||||||
"upgrades.bigger_explosions.tooltip": "Bigger explosions",
|
"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)",
|
"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)",
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { t } from "./i18n/i18n";
|
||||||
|
|
||||||
import { comboKeepingRate } from "./pure_functions";
|
import { comboKeepingRate } from "./pure_functions";
|
||||||
import { PerkId, Upgrade } from "./types";
|
import { PerkId, Upgrade } from "./types";
|
||||||
|
import {base_combo_from_stronger_foundation} from "./game_utils";
|
||||||
|
|
||||||
// Those perks are excluded from creative mode
|
// Those perks are excluded from creative mode
|
||||||
export const noCreative: PerkId[] = [
|
export const noCreative: PerkId[] = [
|
||||||
|
@ -768,7 +769,7 @@ export const rawUpgrades = [
|
||||||
max: 7,
|
max: 7,
|
||||||
name: t("upgrades.base_combo.name"),
|
name: t("upgrades.base_combo.name"),
|
||||||
help: (lvl: number) =>
|
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) =>
|
fullHelp: (lvl: number) =>
|
||||||
t("upgrades.base_combo.verbose_description", { lvl }),
|
t("upgrades.base_combo.verbose_description", { lvl }),
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue