This commit is contained in:
Renan LE CARO 2025-04-29 10:31:56 +02:00
parent 567785ae19
commit 08a61d6967
8 changed files with 128 additions and 285 deletions

View file

@ -26,10 +26,19 @@ Break colourful bricks, catch bouncing coins and select powerful upgrades !
- missed challenges show as greyed out choices (with unlock condition). - missed challenges show as greyed out choices (with unlock condition).
- bigger "level X or Y cleared", continue to level X/Y as button - bigger "level X or Y cleared", continue to level X/Y as button
- Can't press ? buttons in Creative Menu.
## Done ## Done
- somehow score clicks didn't register while the game was playing, that's solved
- upgrades list now uses numbers instead of bars, looks better with limitless
- Fix : click tooltip to open on mobile, click anywhere to close
- Can't press help buttons in Creative Menu
## 29097764
- Added levels : Fish, Spider, GlidersLone island,Spacewyrm Jon, Taijitu, Egg pan, Inception, Chess
## 29095000 ## 29095000
- hardcoded the levels unlock conditions so that they wouldn't change at each update - hardcoded the levels unlock conditions so that they wouldn't change at each update

95
dist/index.html vendored
View file

@ -60,8 +60,9 @@ canvas:not(#game) {
} }
#score:hover, #menu:hover, #score:focus, #menu:focus { #score:hover, #menu:hover, #score:focus, #menu:focus {
color: #000;
cursor: pointer; cursor: pointer;
background: #0000004d; background: #fff;
} }
#score { #score {
@ -383,26 +384,48 @@ h2.histogram-title strong {
color: #fff; color: #fff;
} }
.upgrade > span { .upgrade .level {
flex-grow: 0; color: #000;
flex-shrink: 0; background: #fff;
align-self: center; border: 1px solid #fff;
width: 5px; border-radius: 3px;
height: 32px; font-size: 12px;
font-style: normal;
font-weight: bold;
line-height: 12px;
display: inline-block; display: inline-block;
position: relative;
top: -3px;
overflow: hidden;
} }
.upgrade > span.used { .upgrade .level > span {
display: inline-block;
position: relative;
}
.upgrade .level > span:first-child {
color: #000;
background: #fff; background: #fff;
padding: 3px 6px 0 2px;
} }
.upgrade > span.free { .upgrade .level > span:last-child {
opacity: .25; color: #fff;
background: #fff; background: #000;
padding: 3px 3px 0 2px;
} }
.upgrade > span.banned { .upgrade .level > span:last-child:before {
background: red; content: "";
background: #000;
width: 4px;
display: block;
position: absolute;
top: 0;
bottom: 0;
left: -2px;
transform: skewX(-10deg);
} }
.upgrade.used { .upgrade.used {
@ -1084,13 +1107,15 @@ setInterval(()=>{
setInterval(()=>{ setInterval(()=>{
(0, _monitorLevelsUnlocks.monitorLevelsUnlocks)(gameState); (0, _monitorLevelsUnlocks.monitorLevelsUnlocks)(gameState);
}, 500); }, 500);
(0, _render.scoreDisplay).addEventListener("click", (e)=>{
e.preventDefault();
if (!(0, _asyncAlert.alertsOpen)) (0, _openScorePanel.openScorePanel)(gameState);
});
document.addEventListener("visibilitychange", ()=>{ document.addEventListener("visibilitychange", ()=>{
if (document.hidden) pause(true); if (document.hidden) pause(true);
}); });
function scoreOpen(e) {
e.preventDefault();
if (!(0, _asyncAlert.alertsOpen)) (0, _openScorePanel.openScorePanel)(gameState);
}
(0, _render.scoreDisplay).addEventListener("click", scoreOpen);
(0, _render.scoreDisplay).addEventListener("mousedown", scoreOpen);
document.getElementById("menu").addEventListener("click", (e)=>{ document.getElementById("menu").addEventListener("click", (e)=>{
e.preventDefault(); e.preventDefault();
if (!(0, _asyncAlert.alertsOpen)) openMainMenu(); if (!(0, _asyncAlert.alertsOpen)) openMainMenu();
@ -3523,12 +3548,6 @@ function max_levels(gameState) {
function pickedUpgradesHTMl(gameState) { function pickedUpgradesHTMl(gameState) {
const upgradesList = getPossibleUpgrades(gameState).filter((u)=>gameState.perks[u.id]).map((u)=>{ const upgradesList = getPossibleUpgrades(gameState).filter((u)=>gameState.perks[u.id]).map((u)=>{
const newMax = Math.max(0, u.max + gameState.perks.limitless); const newMax = Math.max(0, u.max + gameState.perks.limitless);
let bars = [];
for(let i = 0; i < Math.max(u.max, newMax, gameState.perks[u.id]); i++){
if (i < gameState.perks[u.id]) bars.push('<span class="used"></span>');
else if (i < newMax) bars.push('<span class="free"></span>');
else bars.push('<span class="banned"></span>');
}
const state = gameState.perks[u.id] && 1 || !newMax && 2 || 3; const state = gameState.perks[u.id] && 1 || !newMax && 2 || 3;
return { return {
state, state,
@ -3542,9 +3561,9 @@ function pickedUpgradesHTMl(gameState) {
${(0, _loadGameData.icons)["icon:" + u.id]} ${(0, _loadGameData.icons)["icon:" + u.id]}
<p> <p>
<strong>${u.name}</strong> <strong>${u.name}</strong>
<span class="level"><span>${gameState.perks[u.id]}</span><span>${newMax}</span></span>
${u.help(Math.max(1, gameState.perks[u.id]))} ${u.help(Math.max(1, gameState.perks[u.id]))}
</p> </p>
${bars.reverse().join("")}
</div> </div>
` `
}; };
@ -5896,17 +5915,17 @@ parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "setupTooltips", ()=>setupTooltips); parcelHelpers.export(exports, "setupTooltips", ()=>setupTooltips);
parcelHelpers.export(exports, "hideAnyTooltip", ()=>hideAnyTooltip); parcelHelpers.export(exports, "hideAnyTooltip", ()=>hideAnyTooltip);
var _options = require("./options"); var _options = require("./options");
const tooltip = document.getElementById("tooltip");
function setupTooltips() { function setupTooltips() {
if ((0, _options.isOptionOn)("mobile-mode")) setupMobileTooltips(tooltip); return;
else setupDesktopTooltips(tooltip);
} }
function hideAnyTooltip() { function hideAnyTooltip() {
tooltip.style.display = "none"; tooltip.style.display = "none";
} }
const tooltip = document.getElementById("tooltip");
function setupMobileTooltips(tooltip) { function setupMobileTooltips(tooltip) {
tooltip.className = "mobile"; tooltip.className = "mobile";
function openTooltip(e) { function openTooltip(e) {
console.log('openTooltip', e);
hideAnyTooltip(); hideAnyTooltip();
const hovering = e.target; const hovering = e.target;
if (!hovering?.hasAttribute("data-help-content")) return; if (!hovering?.hasAttribute("data-help-content")) return;
@ -5917,26 +5936,8 @@ function setupMobileTooltips(tooltip) {
const { top } = hovering.getBoundingClientRect(); const { top } = hovering.getBoundingClientRect();
tooltip.style.transform = `translate(0,${top}px) translate(0,-100%)`; tooltip.style.transform = `translate(0,${top}px) translate(0,-100%)`;
} }
document.body.addEventListener("touchstart", openTooltip, true); document.body.addEventListener("click", openTooltip, true);
document.body.addEventListener("mousedown", openTooltip, true);
function closeTooltip(e) {
const hovering = e.target;
if (!hovering?.hasAttribute("data-help-content")) return;
e.stopPropagation();
e.preventDefault();
hideAnyTooltip();
}
document.body.addEventListener("touchend", closeTooltip, true);
document.body.addEventListener("mouseup", closeTooltip, true);
document.addEventListener("scroll", hideAnyTooltip); document.addEventListener("scroll", hideAnyTooltip);
function ignoreClick(e) {
const hovering = e.target;
if (!hovering?.hasAttribute("data-help-content")) return;
e.stopPropagation();
e.preventDefault();
}
document.body.addEventListener("click", ignoreClick, true);
document.body.addEventListener("contextmenu", ignoreClick, true);
} }
function setupDesktopTooltips(tooltip) { function setupDesktopTooltips(tooltip) {
tooltip.className = "desktop"; tooltip.className = "desktop";

View file

@ -4,7 +4,7 @@
"description": "A roguelite take on the breakout genre, optimised for short runs and replayability.", "description": "A roguelite take on the breakout genre, optimised for short runs and replayability.",
"scripts": { "scripts": {
"start": "bash start.sh", "start": "bash start.sh",
"dev:game-fe": "parcel src/*.html --lazy --no-hmr", "dev:game-fe": "rm -rf .parcel-cache && parcel src/*.html --lazy --no-hmr --no-cache",
"dev:editor-be": "nodemon editserver.js --watch editserver.js", "dev:editor-be": "nodemon editserver.js --watch editserver.js",
"test": "jest --watch" "test": "jest --watch"
}, },

File diff suppressed because one or more lines are too long

View file

@ -1,10 +1,9 @@
* { * {
font-family: font-family: Courier New,
Courier New, Courier,
Courier, Lucida Sans Typewriter,
Lucida Sans Typewriter, Lucida Typewriter,
Lucida Typewriter, monospace;
monospace;
box-sizing: border-box; box-sizing: border-box;
} }
@ -56,7 +55,8 @@ canvas:not(#game) {
&:hover, &:hover,
&:focus { &:focus {
background: rgba(0, 0, 0, 0.3); background: white;
color: black;
cursor: pointer; cursor: pointer;
} }
@ -399,27 +399,52 @@ h2.histogram-title strong {
color: white; color: white;
} }
& > span { .level {
flex-grow: 0; color: #000;
background: #FFF;
flex-shrink: 0; border-radius: 3px;
width: 5px; overflow: hidden;
font-size: 12px;
font-style: normal;
line-height: 12px;
display: inline-block; display: inline-block;
height: 32px; position: relative;
align-self: center; top: -3px;
font-weight: bold;
border: 1px solid #FFF;
> span {
display: inline-block;
position: relative;
&:first-child {
padding: 3px 6px 0 2px;
color: #000;
background: #FFF;
}
&:last-child {
padding: 3px 3px 0 2px;
color: #FFF;
background: #000;
&:before {
content: "";
display: block;
background: black;;
position: absolute;
left: -2px;
top: 0;
bottom: 0;
width: 4px;
transform: skewX(-10deg)
}
}
&.used {
background: #fff;
} }
&.free {
background: #fff;
opacity: 0.25;
}
&.banned {
background: red;
}
} }
&.used { &.used {
@ -450,9 +475,11 @@ h2.histogram-title strong {
user-select: none; user-select: none;
opacity: 1; opacity: 1;
border: 1px solid white; border: 1px solid white;
&.desktop { &.desktop {
max-width: 300px; max-width: 300px;
} }
&.mobile { &.mobile {
width: 95vw; width: 95vw;
left: 2.5vw; left: 2.5vw;
@ -523,9 +550,8 @@ h2.histogram-title strong {
border-radius: 2px; border-radius: 2px;
padding-right: 10px; padding-right: 10px;
pointer-events: none; pointer-events: none;
transition: transition: opacity 200ms,
opacity 200ms, transform 200ms;
transform 200ms;
z-index: 7; z-index: 7;
&.hidden { &.hidden {

View file

@ -537,12 +537,6 @@ setInterval(() => {
monitorLevelsUnlocks(gameState); monitorLevelsUnlocks(gameState);
}, 500); }, 500);
scoreDisplay.addEventListener("click", (e) => {
e.preventDefault();
if (!alertsOpen) {
openScorePanel(gameState);
}
});
document.addEventListener("visibilitychange", () => { document.addEventListener("visibilitychange", () => {
if (document.hidden) { if (document.hidden) {
@ -550,6 +544,15 @@ document.addEventListener("visibilitychange", () => {
} }
}); });
function scoreOpen(e){
e.preventDefault();
if (!alertsOpen) {
openScorePanel(gameState);
}
}
scoreDisplay.addEventListener("click",scoreOpen);
scoreDisplay.addEventListener("mousedown", scoreOpen);
(document.getElementById("menu") as HTMLButtonElement).addEventListener( (document.getElementById("menu") as HTMLButtonElement).addEventListener(
"click", "click",
(e) => { (e) => {

View file

@ -105,16 +105,6 @@ export function pickedUpgradesHTMl(gameState: GameState) {
.map((u) => { .map((u) => {
const newMax = Math.max(0, u.max + gameState.perks.limitless); const newMax = Math.max(0, u.max + gameState.perks.limitless);
let bars = [];
for (let i = 0; i < Math.max(u.max, newMax, gameState.perks[u.id]); i++) {
if (i < gameState.perks[u.id]) {
bars.push('<span class="used"></span>');
} else if (i < newMax) {
bars.push('<span class="free"></span>');
} else {
bars.push('<span class="banned"></span>');
}
}
const state = (gameState.perks[u.id] && 1) || (!newMax && 2) || 3; const state = (gameState.perks[u.id] && 1) || (!newMax && 2) || 3;
return { return {
@ -124,9 +114,9 @@ export function pickedUpgradesHTMl(gameState: GameState) {
${icons["icon:" + u.id]} ${icons["icon:" + u.id]}
<p> <p>
<strong>${u.name}</strong> <strong>${u.name}</strong>
<span class="level"><span>${gameState.perks[u.id]}</span><span>${newMax}</span></span>
${u.help(Math.max(1, gameState.perks[u.id]))} ${u.help(Math.max(1, gameState.perks[u.id]))}
</p> </p>
${bars.reverse().join("")}
</div> </div>
`, `,
}; };

View file

@ -1,6 +1,9 @@
import { isOptionOn } from "./options"; import { isOptionOn } from "./options";
const tooltip = document.getElementById("tooltip") as HTMLDivElement;
export function setupTooltips() { export function setupTooltips() {
return
if (isOptionOn("mobile-mode")) { if (isOptionOn("mobile-mode")) {
setupMobileTooltips(tooltip); setupMobileTooltips(tooltip);
} else { } else {
@ -11,11 +14,11 @@ export function hideAnyTooltip() {
tooltip.style.display = "none"; tooltip.style.display = "none";
} }
const tooltip = document.getElementById("tooltip") as HTMLDivElement;
function setupMobileTooltips(tooltip: HTMLDivElement) { function setupMobileTooltips(tooltip: HTMLDivElement) {
tooltip.className = "mobile"; tooltip.className = "mobile";
function openTooltip(e: Event) { function openTooltip(e: Event) {
console.log('openTooltip',e)
hideAnyTooltip(); hideAnyTooltip();
const hovering = e.target as HTMLElement; const hovering = e.target as HTMLElement;
if (!hovering?.hasAttribute("data-help-content")) { if (!hovering?.hasAttribute("data-help-content")) {
@ -29,35 +32,9 @@ function setupMobileTooltips(tooltip: HTMLDivElement) {
tooltip.style.transform = `translate(0,${top}px) translate(0,-100%)`; tooltip.style.transform = `translate(0,${top}px) translate(0,-100%)`;
} }
document.body.addEventListener("touchstart", openTooltip, true); document.body.addEventListener("click", openTooltip, true);
document.body.addEventListener("mousedown", openTooltip, true);
function closeTooltip(e: Event) {
const hovering = e.target as HTMLElement;
if (!hovering?.hasAttribute("data-help-content")) {
return;
}
e.stopPropagation();
e.preventDefault();
hideAnyTooltip();
}
document.body.addEventListener("touchend", closeTooltip, true);
document.body.addEventListener("mouseup", closeTooltip, true);
document.addEventListener("scroll", hideAnyTooltip); document.addEventListener("scroll", hideAnyTooltip);
function ignoreClick(e: Event) {
const hovering = e.target as HTMLElement;
if (!hovering?.hasAttribute("data-help-content")) {
return;
}
e.stopPropagation();
e.preventDefault();
}
document.body.addEventListener("click", ignoreClick, true);
document.body.addEventListener("contextmenu", ignoreClick, true);
} }
function setupDesktopTooltips(tooltip: HTMLDivElement) { function setupDesktopTooltips(tooltip: HTMLDivElement) {