mirror of
https://gitlab.com/lecarore/breakout71.git
synced 2025-04-21 20:46:14 -04:00
Build 29074681
This commit is contained in:
parent
48ac639901
commit
19ee1d0d33
9 changed files with 152 additions and 40 deletions
|
@ -29,8 +29,8 @@ android {
|
||||||
applicationId = "me.lecaro.breakout"
|
applicationId = "me.lecaro.breakout"
|
||||||
minSdk = 21
|
minSdk = 21
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 29074419
|
versionCode = 29074681
|
||||||
versionName = "29074419"
|
versionName = "29074681"
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables {
|
vectorDrawables {
|
||||||
useSupportLibrary = true
|
useSupportLibrary = true
|
||||||
|
|
File diff suppressed because one or more lines are too long
73
dist/index.html
vendored
73
dist/index.html
vendored
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
||||||
// The version of the cache.
|
// The version of the cache.
|
||||||
const VERSION = "29074419";
|
const VERSION = "29074681";
|
||||||
|
|
||||||
// The name of the cache
|
// The name of the cache
|
||||||
const CACHE_NAME = `breakout-71-${VERSION}`;
|
const CACHE_NAME = `breakout-71-${VERSION}`;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
"29074419"
|
"29074681"
|
||||||
|
|
40
src/game.ts
40
src/game.ts
|
@ -7,6 +7,7 @@ import {
|
||||||
OptionId,
|
OptionId,
|
||||||
ParticleFlash,
|
ParticleFlash,
|
||||||
PerkId,
|
PerkId,
|
||||||
|
PerksMap,
|
||||||
RunParams,
|
RunParams,
|
||||||
TextFlash,
|
TextFlash,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
@ -20,6 +21,7 @@ import {
|
||||||
max_levels,
|
max_levels,
|
||||||
pickedUpgradesHTMl,
|
pickedUpgradesHTMl,
|
||||||
reasonLevelIsLocked,
|
reasonLevelIsLocked,
|
||||||
|
sample,
|
||||||
} from "./game_utils";
|
} from "./game_utils";
|
||||||
|
|
||||||
import "./PWA/sw_loader";
|
import "./PWA/sw_loader";
|
||||||
|
@ -103,6 +105,7 @@ export async function play() {
|
||||||
export function pause(playerAskedForPause: boolean) {
|
export function pause(playerAskedForPause: boolean) {
|
||||||
if (!gameState.running) return;
|
if (!gameState.running) return;
|
||||||
if (gameState.pauseTimeout) return;
|
if (gameState.pauseTimeout) return;
|
||||||
|
if (gameState.computer_controlled) return;
|
||||||
|
|
||||||
const stop = () => {
|
const stop = () => {
|
||||||
gameState.running = false;
|
gameState.running = false;
|
||||||
|
@ -580,6 +583,7 @@ function donationNag(gameState) {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
async function openSettingsMenu() {
|
async function openSettingsMenu() {
|
||||||
pause(true);
|
pause(true);
|
||||||
|
|
||||||
|
@ -999,22 +1003,30 @@ export function restart(params: RunParams) {
|
||||||
fitSize(gameState);
|
fitSize(gameState);
|
||||||
pauseRecording();
|
pauseRecording();
|
||||||
setLevel(gameState, 0);
|
setLevel(gameState, 0);
|
||||||
|
if (params?.computer_controlled) {
|
||||||
|
play();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
restart(
|
if (window.location.search.includes("autoplay")) {
|
||||||
window.location.search.includes("stress")
|
startComputerControlledGame();
|
||||||
? {
|
} else {
|
||||||
perks: {
|
restart({});
|
||||||
bricks_attract_ball: 2,
|
}
|
||||||
superhot: 1,
|
|
||||||
bricks_attract_coins: 3,
|
export function startComputerControlledGame() {
|
||||||
hot_start: 3,
|
const perks: Partial<PerksMap> = { base_combo: 7, pierce: 3 };
|
||||||
pierce: 3,
|
for (let i = 0; i < 10; i++) {
|
||||||
rainbow: 3,
|
const u = sample(upgrades);
|
||||||
},
|
perks[u.id] = Math.floor(Math.random() * u.max) + 1;
|
||||||
}
|
}
|
||||||
: {},
|
perks.superhot = 0;
|
||||||
);
|
restart({
|
||||||
|
level: sample(allLevels)?.name,
|
||||||
|
computer_controlled: true,
|
||||||
|
perks,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
tick();
|
tick();
|
||||||
setupTooltips();
|
setupTooltips();
|
||||||
|
|
|
@ -44,13 +44,16 @@ import {
|
||||||
hitsSomething,
|
hitsSomething,
|
||||||
openUpgradesPicker,
|
openUpgradesPicker,
|
||||||
pause,
|
pause,
|
||||||
|
startComputerControlledGame,
|
||||||
} from "./game";
|
} from "./game";
|
||||||
import { stopRecording } from "./recording";
|
import { stopRecording } from "./recording";
|
||||||
import { isOptionOn } from "./options";
|
import { isOptionOn } from "./options";
|
||||||
import { clamp, comboKeepingRate } from "./pure_functions";
|
import { clamp, comboKeepingRate } from "./pure_functions";
|
||||||
import { addToTotalScore } from "./addToTotalScore";
|
import { addToTotalScore } from "./addToTotalScore";
|
||||||
|
import { hashCode } from "./getLevelBackground";
|
||||||
|
|
||||||
export function setMousePos(gameState: GameState, x: number) {
|
export function setMousePos(gameState: GameState, x: number) {
|
||||||
|
if (gameState.computer_controlled) return;
|
||||||
gameState.puckPosition = x;
|
gameState.puckPosition = x;
|
||||||
|
|
||||||
// Sets the puck position, and updates the ball position if they are supposed to follow it
|
// Sets the puck position, and updates the ball position if they are supposed to follow it
|
||||||
|
@ -64,6 +67,48 @@ function getBallDefaultVx(gameState: GameState) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function computerControl(gameState: GameState) {
|
||||||
|
let targetX = gameState.puckPosition;
|
||||||
|
const ball = getClosestBall(
|
||||||
|
gameState,
|
||||||
|
gameState.puckPosition,
|
||||||
|
gameState.gameZoneHeight,
|
||||||
|
);
|
||||||
|
if (!ball) return;
|
||||||
|
const puckOffset =
|
||||||
|
(((hashCode(gameState.runStatistics.puck_bounces + "goeirjgoriejg") % 100) -
|
||||||
|
50) /
|
||||||
|
100) *
|
||||||
|
gameState.puckWidth;
|
||||||
|
|
||||||
|
if (ball.y > gameState.gameZoneHeight / 2 && ball.vy > 0) {
|
||||||
|
targetX = ball.x + puckOffset;
|
||||||
|
} else {
|
||||||
|
let coinsTotalX = 0,
|
||||||
|
coinsCount = 0;
|
||||||
|
forEachLiveOne(gameState.coins, (c) => {
|
||||||
|
if (c.vy > 0 && c.y > gameState.gameZoneHeight / 2) {
|
||||||
|
coinsTotalX += c.x;
|
||||||
|
coinsCount++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (coinsCount) {
|
||||||
|
targetX = coinsTotalX / coinsCount;
|
||||||
|
} else {
|
||||||
|
targetX = ball.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gameState.puckPosition += clamp(
|
||||||
|
(targetX - gameState.puckPosition) / 10,
|
||||||
|
-10,
|
||||||
|
10,
|
||||||
|
);
|
||||||
|
if (gameState.levelTime > 30000) {
|
||||||
|
startComputerControlledGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function resetBalls(gameState: GameState) {
|
export function resetBalls(gameState: GameState) {
|
||||||
// Always compute speed first
|
// Always compute speed first
|
||||||
normalizeGameState(gameState);
|
normalizeGameState(gameState);
|
||||||
|
@ -592,6 +637,7 @@ export function schedulGameSound(
|
||||||
) {
|
) {
|
||||||
if (!vol) return;
|
if (!vol) return;
|
||||||
if (!isOptionOn("sound")) return;
|
if (!isOptionOn("sound")) return;
|
||||||
|
if (gameState.computer_controlled) return;
|
||||||
x ??= gameState.offsetX + gameState.gameZoneWidth / 2;
|
x ??= gameState.offsetX + gameState.gameZoneWidth / 2;
|
||||||
const ex = gameState.aboutToPlaySound[sound] as { vol: number; x: number };
|
const ex = gameState.aboutToPlaySound[sound] as { vol: number; x: number };
|
||||||
|
|
||||||
|
@ -945,6 +991,9 @@ export function gameStateTick(
|
||||||
// How many frames to compute at once, can go above 1 to compensate lag
|
// How many frames to compute at once, can go above 1 to compensate lag
|
||||||
frames = 1,
|
frames = 1,
|
||||||
) {
|
) {
|
||||||
|
// Ai movement of puck
|
||||||
|
if (gameState.computer_controlled) computerControl(gameState);
|
||||||
|
|
||||||
gameState.runStatistics.max_combo = Math.max(
|
gameState.runStatistics.max_combo = Math.max(
|
||||||
gameState.runStatistics.max_combo,
|
gameState.runStatistics.max_combo,
|
||||||
gameState.combo,
|
gameState.combo,
|
||||||
|
@ -1019,7 +1068,9 @@ export function gameStateTick(
|
||||||
// instant win condition
|
// instant win condition
|
||||||
(gameState.levelTime && !remainingBricks && !liveCount(gameState.coins))
|
(gameState.levelTime && !remainingBricks && !liveCount(gameState.coins))
|
||||||
) {
|
) {
|
||||||
if (gameState.currentLevel + 1 < max_levels(gameState)) {
|
if (gameState.computer_controlled) {
|
||||||
|
startComputerControlledGame();
|
||||||
|
} else if (gameState.currentLevel + 1 < max_levels(gameState)) {
|
||||||
setLevel(gameState, gameState.currentLevel + 1);
|
setLevel(gameState, gameState.currentLevel + 1);
|
||||||
} else {
|
} else {
|
||||||
gameOver(
|
gameOver(
|
||||||
|
@ -1659,10 +1710,14 @@ export function ballTick(gameState: GameState, ball: Ball, frames: number) {
|
||||||
ball.destroyed = true;
|
ball.destroyed = true;
|
||||||
gameState.runStatistics.balls_lost++;
|
gameState.runStatistics.balls_lost++;
|
||||||
if (!gameState.balls.find((b) => !b.destroyed)) {
|
if (!gameState.balls.find((b) => !b.destroyed)) {
|
||||||
gameOver(
|
if (gameState.computer_controlled) {
|
||||||
t("gameOver.lost.title"),
|
startComputerControlledGame();
|
||||||
t("gameOver.lost.summary", { score: gameState.score }),
|
} else {
|
||||||
);
|
gameOver(
|
||||||
|
t("gameOver.lost.title"),
|
||||||
|
t("gameOver.lost.summary", { score: gameState.score }),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const radius = gameState.ballSize / 2;
|
const radius = gameState.ballSize / 2;
|
||||||
|
|
|
@ -139,8 +139,10 @@ export function newGameState(params: RunParams): GameState {
|
||||||
...defaultSounds(),
|
...defaultSounds(),
|
||||||
rerolls: 0,
|
rerolls: 0,
|
||||||
creative:
|
creative:
|
||||||
|
params?.computer_controlled ||
|
||||||
sumOfValues(params.perks) > 1 ||
|
sumOfValues(params.perks) > 1 ||
|
||||||
(params.level && !params.level.startsWith("icon:")),
|
(params.level && !params.level.startsWith("icon:")),
|
||||||
|
computer_controlled: params?.computer_controlled || false,
|
||||||
};
|
};
|
||||||
resetBalls(gameState);
|
resetBalls(gameState);
|
||||||
|
|
||||||
|
|
2
src/types.d.ts
vendored
2
src/types.d.ts
vendored
|
@ -281,6 +281,7 @@ export type GameState = {
|
||||||
};
|
};
|
||||||
rerolls: number;
|
rerolls: number;
|
||||||
creative: boolean;
|
creative: boolean;
|
||||||
|
computer_controlled: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type RunParams = {
|
export type RunParams = {
|
||||||
|
@ -288,6 +289,7 @@ export type RunParams = {
|
||||||
levelToAvoid?: string;
|
levelToAvoid?: string;
|
||||||
perkToAvoid?: PerkId;
|
perkToAvoid?: PerkId;
|
||||||
perks?: Partial<PerksMap>;
|
perks?: Partial<PerksMap>;
|
||||||
|
computer_controlled?: boolean;
|
||||||
};
|
};
|
||||||
export type OptionDef = {
|
export type OptionDef = {
|
||||||
default: boolean;
|
default: boolean;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue