This commit is contained in:
Renan LE CARO 2025-04-20 13:12:10 +02:00
parent 4d7d57f17f
commit b3949d8c41
11 changed files with 139 additions and 79 deletions

View file

@ -29,8 +29,8 @@ android {
applicationId = "me.lecaro.breakout" applicationId = "me.lecaro.breakout"
minSdk = 21 minSdk = 21
targetSdk = 34 targetSdk = 34
versionCode = 29085612 versionCode = 29085783
versionName = "29085612" versionName = "29085783"
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

79
dist/index.html vendored

File diff suppressed because one or more lines are too long

View file

@ -1,5 +1,5 @@
// The version of the cache. // The version of the cache.
const VERSION = "29085612"; const VERSION = "29085783";
// The name of the cache // The name of the cache
const CACHE_NAME = `breakout-71-${VERSION}`; const CACHE_NAME = `breakout-71-${VERSION}`;

View file

@ -1 +1 @@
"29085612" "29085783"

View file

@ -37,7 +37,8 @@ import { getCurrentLang, languages, t } from "./i18n/i18n";
import { import {
commitSettingsChangesToLocalStorage, commitSettingsChangesToLocalStorage,
cycleMaxCoins, cycleMaxCoins,
getCurrentMaxCoins, getCurrentMaxParticles, getCurrentMaxCoins,
getCurrentMaxParticles,
getSettingValue, getSettingValue,
getTotalScore, getTotalScore,
setSettingValue, setSettingValue,
@ -496,7 +497,6 @@ export function startWork(what) {
doing = what; doing = what;
} }
setInterval(() => { setInterval(() => {
lastMeasuredFPS = FPSCounter; lastMeasuredFPS = FPSCounter;
FPSCounter = 0; FPSCounter = 0;
@ -512,7 +512,7 @@ setInterval(() => {
<div> <div>
${lastMeasuredFPS} FPS - ${lastMeasuredFPS} FPS -
${liveCount(gameState.coins)} / ${getCurrentMaxCoins()} Coins - ${liveCount(gameState.coins)} / ${getCurrentMaxCoins()} Coins -
${liveCount(gameState.particles) + liveCount(gameState.lights) + liveCount(gameState.texts)} / ${getCurrentMaxParticles()*3} particles ${liveCount(gameState.particles) + liveCount(gameState.lights) + liveCount(gameState.texts)} / ${getCurrentMaxParticles() * 3} particles
</div> </div>

View file

@ -9,7 +9,12 @@ import {
pickedUpgradesHTMl, pickedUpgradesHTMl,
reasonLevelIsLocked, reasonLevelIsLocked,
} from "./game_utils"; } from "./game_utils";
import {askForPersistentStorage, getSettingValue, getTotalScore, setSettingValue} from "./settings"; import {
askForPersistentStorage,
getSettingValue,
getTotalScore,
setSettingValue,
} from "./settings";
import { stopRecording } from "./recording"; import { stopRecording } from "./recording";
import { asyncAlert } from "./asyncAlert"; import { asyncAlert } from "./asyncAlert";
import { rawUpgrades } from "./upgrades"; import { rawUpgrades } from "./upgrades";
@ -30,7 +35,7 @@ export function gameOver(title: string, intro: string) {
gameState.isGameOver = true; gameState.isGameOver = true;
pause(true); pause(true);
askForPersistentStorage() askForPersistentStorage();
stopRecording(); stopRecording();
addToTotalPlayTime(gameState.runStatistics.runTime); addToTotalPlayTime(gameState.runStatistics.runTime);

View file

@ -423,3 +423,4 @@ export function getCornerOffset(gameState: GameState) {
} }
export const isInWebView = !!window.location.href.includes("isInWebView=true"); export const isInWebView = !!window.location.href.includes("isInWebView=true");
console.log({isInWebView})

View file

@ -4,6 +4,7 @@ import { getAudioRecordingTrack } from "./sounds";
import { t } from "./i18n/i18n"; import { t } from "./i18n/i18n";
import { GameState } from "./types"; import { GameState } from "./types";
import { isOptionOn } from "./options"; import { isOptionOn } from "./options";
import { toast } from "./toast";
let mediaRecorder: MediaRecorder | null, let mediaRecorder: MediaRecorder | null,
captureStream: MediaStream, captureStream: MediaStream,
@ -12,7 +13,7 @@ let mediaRecorder: MediaRecorder | null,
recordCanvasCtx: CanvasRenderingContext2D; recordCanvasCtx: CanvasRenderingContext2D;
export function recordOneFrame(gameState: GameState) { export function recordOneFrame(gameState: GameState) {
if (!isOptionOn("record") ) { if (!isOptionOn("record")) {
return; return;
} }
// if (!gameState.running) return; // if (!gameState.running) return;
@ -59,7 +60,7 @@ export function drawMainCanvasOnSmallCanvas(gameState: GameState) {
} }
export function startRecordingGame(gameState: GameState) { export function startRecordingGame(gameState: GameState) {
if (!isOptionOn("record") ) { if (!isOptionOn("record")) {
return; return;
} }
if (mediaRecorder) return; if (mediaRecorder) return;
@ -107,6 +108,7 @@ export function startRecordingGame(gameState: GameState) {
) { ) {
await new Promise((r) => setTimeout(r, 200)); await new Promise((r) => setTimeout(r, 200));
} }
const video = document.createElement("video"); const video = document.createElement("video");
video.autoplay = true; video.autoplay = true;
video.controls = false; video.controls = false;
@ -125,15 +127,38 @@ export function startRecordingGame(gameState: GameState) {
a.download = captureFileName("webm"); a.download = captureFileName("webm");
a.target = "_blank"; a.target = "_blank";
if (isInWebView) {
a.href = await blobToBase64(blob);
} else {
a.href = video.src; a.href = video.src;
}
a.textContent = t("settings.record_download", { a.textContent = t("settings.record_download", {
size: (blob.size / 1000000).toFixed(2), size: (blob.size / 1000000).toFixed(2),
}); });
targetDiv.appendChild(a); targetDiv.appendChild(a);
}; };
} }
function blobToBase64(blob: Blob): Promise<string> {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.onload = function () {
console.log(reader.result);
resolve(reader.result);
};
reader.onerror = function () {
const e = reader.error;
console.error(e);
toast(e?.message || "Failed to convert the video to a data url");
reject(new Error("Failed to readAsDataURL of the video "));
};
reader.readAsDataURL(blob);
});
}
export function pauseRecording() { export function pauseRecording() {
if (!isOptionOn("record")) { if (!isOptionOn("record")) {
return; return;

View file

@ -23,6 +23,7 @@ export function getSettingValue<T>(key: string, defaultValue: T) {
// We avoid using localstorage synchronously for perf reasons // We avoid using localstorage synchronously for perf reasons
let needsSaving: Set<string> = new Set(); let needsSaving: Set<string> = new Set();
export function setSettingValue<T>(key: string, value: T) { export function setSettingValue<T>(key: string, value: T) {
needsSaving.add(key); needsSaving.add(key);
cachedSettings[key] = value; cachedSettings[key] = value;
@ -38,6 +39,7 @@ export function commitSettingsChangesToLocalStorage() {
console.warn(e); console.warn(e);
} }
} }
setInterval(() => commitSettingsChangesToLocalStorage(), 500); setInterval(() => commitSettingsChangesToLocalStorage(), 500);
export function getTotalScore() { export function getTotalScore() {
@ -47,25 +49,29 @@ export function getTotalScore() {
export function getCurrentMaxCoins() { export function getCurrentMaxCoins() {
return Math.pow(2, getSettingValue("max_coins", 2)) * 200; return Math.pow(2, getSettingValue("max_coins", 2)) * 200;
} }
export function getCurrentMaxParticles() { export function getCurrentMaxParticles() {
return getCurrentMaxCoins(); return getCurrentMaxCoins();
} }
export function cycleMaxCoins() { export function cycleMaxCoins() {
setSettingValue("max_coins", (getSettingValue("max_coins", 2) + 1) % 7); setSettingValue("max_coins", (getSettingValue("max_coins", 2) + 1) % 7);
} }
let asked=false
export function askForPersistentStorage(){
if(asked) return
asked=true
if (navigator.storage && navigator.storage.persist) {
navigator.storage.persist().then((persistent) => {
if (persistent) {
toast(t('settings.storage_granted'))
} else {
toast(t('settings.storage_refused'))
}
});
}
let asked = false;
export async function askForPersistentStorage() {
if (asked) return;
asked = true;
if (!navigator.storage) return
if (!navigator.storage.persist) return
if (!navigator.storage.persisted) return
if (await navigator.storage.persisted()) {
return
}
const persistent = await navigator.storage.persist()
if (!persistent) {
toast(t("settings.storage_refused"));
}
} }

View file

@ -2,7 +2,7 @@ let div = document.createElement("div");
div.classList = "hidden toast"; div.classList = "hidden toast";
document.body.appendChild(div); document.body.appendChild(div);
let timeout: NodeJS.Timeout | undefined; let timeout: NodeJS.Timeout | undefined;
export function toast(html) { export function toast(html: string) {
div.classList = "toast visible"; div.classList = "toast visible";
div.innerHTML = html; div.innerHTML = html;
if (timeout) { if (timeout) {