mirror of
https://gitlab.com/lecarore/breakout71.git
synced 2025-04-20 12:15:06 -04:00
Automatic deploy 29011519
This commit is contained in:
parent
d3329c0d1e
commit
84f4b3155e
4 changed files with 44 additions and 47 deletions
19
Readme.md
19
Readme.md
|
@ -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/
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue