Automatic deploy 29011519

This commit is contained in:
Renan LE CARO 2025-02-27 22:19:50 +01:00
parent d3329c0d1e
commit 84f4b3155e
4 changed files with 44 additions and 47 deletions

View file

@ -127,18 +127,13 @@ There's also an easy mode for kids (slower ball) and a color-blind mode (no colo
# Roadmap # Roadmap
The "engine" could be better The "engine" could be better
- shift text on puck when too large
- shinier coins by applying glow to them ?
- It's a bit confusing at first to grasp that one upgrade is applied randomly at the start of the game - It's a bit confusing at first to grasp that one upgrade is applied randomly at the start of the game
- on mobile, add an element that feels like it can be "grabbed" and make it shine while writing "Push here to play" - on mobile, add an element that feels like it can be "grabbed" and make it shine while writing "Push here to play"
- add a clickable button to allow sound to play in chrome android - add a clickable button to allow sound to play in chrome android
- offline mode with service worker - offline mode with service worker
- add pwe manifest - add pwe manifest
- keyboard support
- start/stop with space
- left and right arrow for moving the puck
- up down for choosing menu entry
- space to click entry
- escape to close menu
- see how to do fullscreen on ios, or at least explain to do aA/hide toolbars - see how to do fullscreen on ios, or at least explain to do aA/hide toolbars
- experiment with showing the combo somewhere else, maybe top center, maybe instead of score. - experiment with showing the combo somewhere else, maybe top center, maybe instead of score.
- more help somewhere accessible - more help somewhere accessible
@ -163,9 +158,10 @@ The "engine" could be better
- endgame histograms could work as filters, when you hover a bar, all other histograms would show the stats of those runs only, without changing reference of categories - endgame histograms could work as filters, when you hover a bar, all other histograms would show the stats of those runs only, without changing reference of categories
There are many possible perks left to implement :
There are many possible perks left to implement :
- wrap left / right - wrap left / right
- faster coins, double value
- +1 upgrade per level but -2 choices - +1 upgrade per level but -2 choices
- n% of the broken bricks respawn when the ball touches the puck - n% of the broken bricks respawn when the ball touches the puck
- bricks break 50% of the time but drop 50% more coins - bricks break 50% of the time but drop 50% more coins
@ -212,13 +208,6 @@ Potential big features
- final bosses (large vertical level that scrolls down faster and faster) - final bosses (large vertical level that scrolls down faster and faster)
- split screen multiplayer - split screen multiplayer
# done
- add pointer lock when game is running (lock to play area )https://mdn.github.io/dom-examples/pointer-lock/
- hide cursor options
- the more the user pauses in a run, the more time it should take for the pause to happen.
- F for fullscreen
- keyboard support (Left/Right arrow, Spacebar, and Shift+arrow to move puck 3 times faster, M for menu, S for score, up/down navigation in menus)
# Credits # Credits
I pulled many background patterns from https://pattern.monster/ I pulled many background patterns from https://pattern.monster/

View file

@ -11,8 +11,8 @@ android {
applicationId = "me.lecaro.breakout" applicationId = "me.lecaro.breakout"
minSdk = 21 minSdk = 21
targetSdk = 34 targetSdk = 34
versionCode = 29011397 versionCode = 29011519
versionName = "29011397" versionName = "29011519"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables { vectorDrawables {
useSupportLibrary = true useSupportLibrary = true

View file

@ -1698,8 +1698,7 @@ function render() {
scoreInfo += score.toString(); scoreInfo += score.toString();
scoreDisplay.innerText = scoreInfo; scoreDisplay.innerText = scoreInfo;
// Clear
if (!isSettingOn("basic") && !level.color && level.svg && !level.black_puck) { if (!isSettingOn("basic") && !level.color && level.svg && !level.black_puck) {
// Without this the light trails everything // Without this the light trails everything
@ -1889,7 +1888,6 @@ function render() {
if (!coin.destroyed) drawCoin(ctx, coin.color, coinSize, coin.x,coin.y, level.color || 'black', coin.a); if (!coin.destroyed) drawCoin(ctx, coin.color, coinSize, coin.x,coin.y, level.color || 'black', coin.a);
}); });
// Black shadow around balls // Black shadow around balls
if (coins.length > 10 && !isSettingOn('basic')) { if (coins.length > 10 && !isSettingOn('basic')) {
ctx.globalAlpha = Math.min(0.8, (coins.length - 10) / 50); ctx.globalAlpha = Math.min(0.8, (coins.length - 10) / 50);
@ -1903,7 +1901,7 @@ function render() {
ctx.globalCompositeOperation = "source-over"; ctx.globalCompositeOperation = "source-over";
const puckColor = level.black_puck ? '#000' : '#FFF' const puckColor = level.black_puck ? '#000' : '#FFF'
balls.forEach((ball) => { balls.forEach((ball) => {
drawBall(ctx, ball.color, ballSize, ball.x, ball.y); drawBall(ctx, ball.color, ballSize, ball.x, ball.y, puckColor);
// effect // effect
if (isTelekinesisActive(ball)) { if (isTelekinesisActive(ball)) {
ctx.strokeStyle = puckColor; ctx.strokeStyle = puckColor;
@ -1920,9 +1918,11 @@ function render() {
if (combo > 1) { if (combo > 1) {
ctx.globalCompositeOperation = "source-over"; ctx.globalCompositeOperation = "source-over";
drawCoin(ctx, 'gold', coinSize, puck-coinSize, gameZoneHeight - puckHeight / 2, !level.black_puck ? '#FFF' : '#000', 0 ) const comboText="x " + combo
drawText(ctx, "x " + combo, !level.black_puck ? '#000' : '#FFF', puckHeight, const comboTextWidth=comboText.length*puckHeight/2.6
puck, gameZoneHeight - puckHeight / 2,true); drawCoin(ctx, 'gold', coinSize, puck-coinSize*1.5-comboTextWidth/2, gameZoneHeight - puckHeight / 2, !level.black_puck ? '#FFF' : '#000', 0 )
drawText(ctx, comboText, !level.black_puck ? '#000' : '#FFF', puckHeight,
puck-comboTextWidth/2, gameZoneHeight - puckHeight / 2,true);
} }
// Borders // Borders
ctx.fillStyle = puckColor; ctx.fillStyle = puckColor;
@ -2010,27 +2010,33 @@ function drawPuck(ctx, color, puckWidth, puckHeight) {
} }
function drawBall(ctx, color, width, x, y) { function drawBall(ctx, color, width, x, y, borderColor='') {
const key = "ball" + color + "_" + width; const key = "ball" + color + "_" + width+'_'+borderColor;
const size = Math.round(width);
if (!cachedGraphics[key]) { if (!cachedGraphics[key]) {
const can = document.createElement("canvas"); const can = document.createElement("canvas");
const size = Math.round(width);
can.width = size; can.width = size;
can.height = size; can.height = size;
const canctx = can.getContext("2d"); const canctx = can.getContext("2d");
canctx.beginPath(); canctx.beginPath();
canctx.arc(size / 2, size / 2, Math.round(size / 2), 0, 2 * Math.PI); canctx.arc(size / 2, size / 2, Math.round(size / 2)-1, 0, 2 * Math.PI);
canctx.fillStyle = color; canctx.fillStyle = color;
canctx.fill(); canctx.fill();
if(borderColor){
canctx.lineWidth=2
canctx.strokeStyle=borderColor
canctx.stroke()
}
cachedGraphics[key] = can; cachedGraphics[key] = can;
} }
ctx.drawImage(cachedGraphics[key], Math.round(x - width / 2), Math.round(y - width / 2),); ctx.drawImage(cachedGraphics[key], Math.round(x - size / 2), Math.round(y - size / 2),);
} }
function drawCoin(ctx, color, size, x,y, bg,rawAngle) { function drawCoin(ctx, color, size, x,y, bg,rawAngle) {
if(isNaN(rawAngle)) debugger
const angle= (Math.round(rawAngle/Math.PI*2 * 16 ) % 16 + 16 ) % 16 const angle= (Math.round(rawAngle/Math.PI*2 * 16 ) % 16 + 16 ) % 16
const key = "coin with halo" + "_" + color + "_" + size + '_' + bg + '_'+angle; const key = "coin with halo" + "_" + color + "_" + size + '_' + bg + '_'+angle;
@ -2047,23 +2053,25 @@ if(isNaN(rawAngle)) debugger
canctx.fillStyle = color; canctx.fillStyle = color;
canctx.fill(); canctx.fill();
canctx.strokeStyle = bg; if(color=== 'gold'){
canctx.stroke();
canctx.beginPath(); canctx.strokeStyle = bg;
canctx.arc(size / 2, size / 2, size / 2 * 0.6, 0, 2 * Math.PI); canctx.stroke();
canctx.fillStyle = 'rgba(255,255,255,0.5)';
canctx.fill();
canctx.beginPath();
canctx.arc(size / 2, size / 2, size / 2 * 0.6, 0, 2 * Math.PI);
canctx.fillStyle = 'rgba(255,255,255,0.5)';
canctx.fill();
canctx.translate(size / 2, size / 2); canctx.translate(size / 2, size / 2);
canctx.rotate(angle/ 16); canctx.rotate(angle/ 16);
canctx.translate(-size / 2, -size / 2); canctx.translate(-size / 2, -size / 2);
canctx.globalCompositeOperation='multiply' canctx.globalCompositeOperation='multiply'
drawText(canctx, '$', color, size-2,size / 2, size / 2+1) drawText(canctx, '$', color, size-2,size / 2, size / 2+1)
drawText(canctx, '$', color, size-2,size / 2, size / 2+1) drawText(canctx, '$', color, size-2,size / 2, size / 2+1)
cachedGraphics[key] = can; }
cachedGraphics[key] = can;
} }
ctx.drawImage(cachedGraphics[key], Math.round(x - size / 2), Math.round(y - size / 2)); ctx.drawImage(cachedGraphics[key], Math.round(x - size / 2), Math.round(y - size / 2));
} }

View file

@ -8,17 +8,17 @@
/> />
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Breakout 71</title> <title>Breakout 71</title>
<link rel="stylesheet" href="style.css?v=29011397" /> <link rel="stylesheet" href="style.css?v=29011519" />
<link rel="icon" href="./icon.svg" /> <link rel="icon" href="./icon.svg" />
</head> </head>
<body> <body>
<button id="menu"><span> menu</span></button> <button id="menu"><span> menu</span></button>
<button id="score"></button> <button id="score"></button>
<canvas id="game"></canvas> <canvas id="game"></canvas>
<script>window.appVersion="?v=29011397".slice(3)</script> <script>window.appVersion="?v=29011519".slice(3)</script>
<script src="gif.js"></script> <script src="gif.js"></script>
<script src="levels.js?v=29011397"></script> <script src="levels.js?v=29011519"></script>
<script src="game.js?v=29011397"></script> <script src="game.js?v=29011519"></script>
</body> </body>