diff --git a/app/src/main/assets/game.js b/app/src/main/assets/game.js
index aca5d32..1eb2c27 100644
--- a/app/src/main/assets/game.js
+++ b/app/src/main/assets/game.js
@@ -9,8 +9,8 @@ const puckHeight = ballSize;
if (allLevels.find(l => l.focus)) {
allLevels = allLevels.filter(l => l.focus)
}
-allLevels.forEach((l,li)=>{
- l.threshold= li < 8 ? 0 : Math.round(Math.pow(10, 1 + (li + l.size) / 30) * (li)) * 10
+allLevels.forEach((l, li) => {
+ l.threshold = li < 8 ? 0 : Math.round(Math.pow(10, 1 + (li + l.size) / 30) * (li)) * 10
})
let runLevels = []
@@ -107,8 +107,7 @@ function pause() {
}
}
-
-let offsetX, gameZoneWidth, gameZoneHeight, brickWidth, needsRender = true;
+let offsetX, offsetXRoundedDown, gameZoneWidth, gameZoneWidthRoundedUp, gameZoneHeight, brickWidth, needsRender = true;
const background = document.createElement("img");
const backgroundCanvas = document.createElement("canvas");
@@ -129,6 +128,9 @@ const fitSize = () => {
brickWidth = Math.floor(baseWidth / gridSize / 2) * 2;
gameZoneWidth = brickWidth * gridSize;
offsetX = Math.floor((canvas.width - gameZoneWidth) / 2);
+ offsetXRoundedDown = offsetX
+ if (offsetX < ballSize) offsetXRoundedDown = 0
+ gameZoneWidthRoundedUp = width - 2 * offsetXRoundedDown
backgroundCanvas.title = 'resized'
// Ensure puck stays within bounds
setMousePos(puck);
@@ -576,14 +578,14 @@ const upgrades = [
"threshold": 87000,
"id": "ball_repulse_ball",
"name": "Balls repulse balls",
- requires:'multiball',
+ requires: 'multiball',
"max": 3,
"help": "Only has an effect with 2+ balls."
},
{
"threshold": 98000,
"id": "ball_attract_ball",
- requires:'multiball',
+ requires: 'multiball',
"name": "Balls attract balls",
"max": 3,
"help": "Only has an effect with 2+ balls."
@@ -602,7 +604,7 @@ function getPossibleUpgrades() {
const ts = getTotalScore()
return upgrades
.filter(u => !(isSettingOn('color_blind') && u.color_blind_exclude))
- .filter(u => ts>=u.threshold)
+ .filter(u => ts >= u.threshold)
.filter(u => !u.requires || perks[u.requires])
}
@@ -646,12 +648,13 @@ function getUpgraderUnlockPoints() {
}
-let lastOffered={}
+let lastOffered = {}
+
function pickRandomUpgrades(count) {
let list = getPossibleUpgrades()
- .map(u=>({...u, score:Math.random() + (lastOffered[u.id]||0) }))
- .sort((a,b) => a.score-b.score)
+ .map(u => ({...u, score: Math.random() + (lastOffered[u.id] || 0)}))
+ .sort((a, b) => a.score - b.score)
.filter(u => perks[u.id] < u.max)
.slice(0, count)
.sort((a, b) => a.id > b.id ? 1 : -1)
@@ -668,8 +671,8 @@ function pickRandomUpgrades(count) {
})
- list.forEach(u=> {
- lastOffered[u.key] = Math.round(Date.now()/1000)
+ list.forEach(u => {
+ lastOffered[u.key] = Math.round(Date.now() / 1000)
})
return list;
@@ -703,22 +706,12 @@ function setMousePos(x) {
needsRender = true;
puck = x;
- if (offsetX > ballSize) {
- // We have borders visible, enforce them
- if (puck < offsetX + puckWidth / 2) {
- puck = offsetX + puckWidth / 2;
- }
- if (puck > offsetX + gameZoneWidth - puckWidth / 2) {
- puck = offsetX + gameZoneWidth - puckWidth / 2;
- }
- } else {
- // Let puck touch the border of the screen
- if (puck < puckWidth / 2) {
- puck = puckWidth / 2;
- }
- if (puck > offsetX * 2 + gameZoneWidth - puckWidth / 2) {
- puck = offsetX * 2 + gameZoneWidth - puckWidth / 2;
- }
+ // We have borders visible, enforce them
+ if (puck < offsetXRoundedDown + puckWidth / 2) {
+ puck = offsetXRoundedDown + puckWidth / 2;
+ }
+ if (puck > offsetXRoundedDown + gameZoneWidthRoundedUp - puckWidth / 2) {
+ puck = offsetXRoundedDown + gameZoneWidthRoundedUp - puckWidth / 2;
}
if (!running && !levelTime) {
putBallsAtPuck();
@@ -850,8 +843,8 @@ function bordersHitCheck(coin, radius, delta) {
let vhit = 0, hhit = 0;
- if (coin.x < (offsetX > ballSize ? offsetX : 0) + radius) {
- coin.x = offsetX + radius;
+ if (coin.x < offsetXRoundedDown + radius) {
+ coin.x = offsetXRoundedDown + radius;
coin.vx *= -1;
hhit = 1;
}
@@ -860,8 +853,8 @@ function bordersHitCheck(coin, radius, delta) {
coin.vy *= -1;
vhit = 1;
}
- if (coin.x > canvas.width - (offsetX > ballSize ? offsetX : 0) - radius) {
- coin.x = canvas.width - offsetX - radius;
+ if (coin.x > canvas.width - offsetXRoundedDown - radius) {
+ coin.x = canvas.width - offsetXRoundedDown - radius;
coin.vx *= -1;
hhit = 1;
}
@@ -1406,18 +1399,13 @@ function render() {
if (!isSettingOn("basic") && !level.color && level.svg && !level.black_puck) {
+ // Without this the light trails everything
ctx.globalCompositeOperation = "source-over";
- ctx.globalAlpha = 0.7
+ ctx.globalAlpha = .4
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, width, height);
- ctx.globalCompositeOperation = "multiply";
- ctx.globalAlpha = 0.3;
- const gradient = ctx.createLinearGradient(offsetX, gameZoneHeight - puckHeight, offsetX, height - puckHeight * 3,);
- gradient.addColorStop(0, "black");
- gradient.addColorStop(1, "transparent");
- ctx.fillStyle = gradient;
- ctx.fillRect(offsetX, gameZoneHeight - puckHeight * 3, gameZoneWidth, puckHeight * 4,);
+
ctx.globalCompositeOperation = "screen";
ctx.globalAlpha = 0.6;
@@ -1446,11 +1434,16 @@ function render() {
}
});
-
- ctx.globalAlpha = 0.9;
+ // Decides how brights the bg black parts can get
+ ctx.globalAlpha = .2;
ctx.globalCompositeOperation = "multiply";
- if (level.svg && background.complete) {
- if (backgroundCanvas.title !== level.name) {
+ ctx.fillStyle = "black";
+ ctx.fillRect(0, 0, width, height);
+ // Decides how dark the background black parts are when lit (1=black)
+ ctx.globalAlpha = .8;
+ ctx.globalCompositeOperation = "multiply";
+ if (level.svg) {
+ if (backgroundCanvas.title !== level.name && background.complete) {
backgroundCanvas.title = level.name
backgroundCanvas.width = canvas.width
backgroundCanvas.height = canvas.height
@@ -1461,14 +1454,18 @@ function render() {
bgctx.fillRect(0, 0, width, height);
console.log("redrew context")
}
- ctx.drawImage(backgroundCanvas, 0, 0)
-
-
+ if(background.complete) {
+ ctx.drawImage(backgroundCanvas, 0, 0)
+ }else{
+ // Background not loaded yes
+ ctx.fillStyle = "#000";
+ ctx.fillRect(0, 0, width, height);
+ }
}
} else {
- ctx.globalCompositeOperation = "source-over";
ctx.globalAlpha = 1
+ ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = level.color || "#000";
ctx.fillRect(0, 0, width, height);
@@ -1484,18 +1481,18 @@ function render() {
if (combo > baseCombo()) {
// The red should still be visible on a white bg
- ctx.globalCompositeOperation = !level.color && level.svg ? "screen" : 'source-over';
+ ctx.globalCompositeOperation = !level.color && level.svg ? "screen" : 'source-over';
ctx.globalAlpha = (2 + combo - baseCombo()) / 50;
if (perks.top_is_lava) {
- drawRedGradientSquare(ctx, offsetX, 0, gameZoneWidth, ballSize, 0, 0, 0, ballSize,);
+ drawRedGradientSquare(ctx, offsetXRoundedDown, 0, gameZoneWidthRoundedUp, ballSize, 0, 0, 0, ballSize,);
}
if (perks.sides_are_lava) {
- drawRedGradientSquare(ctx, offsetX, 0, ballSize, gameZoneHeight, 0, 0, ballSize, 0,);
- drawRedGradientSquare(ctx, offsetX + gameZoneWidth - ballSize, 0, ballSize, gameZoneHeight, ballSize, 0, 0, 0,);
+ drawRedGradientSquare(ctx, offsetXRoundedDown, 0, ballSize, gameZoneHeight, 0, 0, ballSize, 0,);
+ drawRedGradientSquare(ctx, offsetXRoundedDown + gameZoneWidthRoundedUp - ballSize, 0, ballSize, gameZoneHeight, ballSize, 0, 0, 0,);
}
if (perks.catch_all_coins) {
- drawRedGradientSquare(ctx, offsetX, gameZoneHeight - ballSize, gameZoneWidth, ballSize, 0, ballSize, 0, 0,);
+ drawRedGradientSquare(ctx, offsetXRoundedDown, gameZoneHeight - ballSize, gameZoneWidthRoundedUp, ballSize, 0, ballSize, 0, 0,);
}
if (perks.streak_shots) {
drawRedGradientSquare(ctx, puck - puckWidth / 2, gameZoneHeight - puckHeight - ballSize, puckWidth, ballSize, 0, ballSize, 0, 0,);
@@ -1517,7 +1514,8 @@ function render() {
const lastExplosionDelay = Date.now() - lastexplosion + 5;
const shaked = lastExplosionDelay < 200;
if (shaked) {
- ctx.translate((Math.sin(Date.now()) * 50) / lastExplosionDelay, (Math.sin(Date.now() + 36) * 50) / lastExplosionDelay,);
+ const amplitude =( perks.bigger_explosions + 1) * 50 / lastExplosionDelay
+ ctx.translate(Math.sin(Date.now()) * amplitude , Math.sin(Date.now() + 36) * amplitude);
}
ctx.globalCompositeOperation = "source-over";
@@ -1586,12 +1584,12 @@ function render() {
// Borders
ctx.fillStyle = puckColor;
ctx.globalCompositeOperation = "source-over";
- if (offsetX > ballSize) {
+ if (offsetXRoundedDown) {
ctx.fillRect(offsetX, 0, 1, height);
ctx.fillRect(width - offsetX - 1, 0, 1, height);
}
if (isSettingOn("mobile-mode")) {
- ctx.fillRect(offsetX, gameZoneHeight, gameZoneWidth, 1);
+ ctx.fillRect(offsetXRoundedDown, gameZoneHeight, gameZoneWidthRoundedUp, 1);
if (!running) {
drawText(ctx, "Keep pressing here to play", puckColor, puckHeight, {
x: canvas.width / 2, y: gameZoneHeight + (canvas.height - gameZoneHeight) / 2,
@@ -1770,8 +1768,8 @@ function drawBrick(ctx, color, x, y, squared) {
// It's not easy to have a 1px gap between bricks without antialiasing
}
-function drawRedGradientSquare(ctx, x, y, width, height, redX, redY, blackX, blackY ) {
- const key = "gradient" + width + "_" + height + "_" + redX + "_" + redY + "_" + blackX + "_" + blackY ;
+function drawRedGradientSquare(ctx, x, y, width, height, redX, redY, blackX, blackY) {
+ const key = "gradient" + width + "_" + height + "_" + redX + "_" + redY + "_" + blackX + "_" + blackY;
if (!cachedGraphics[key]) {
const can = document.createElement("canvas");
@@ -2239,15 +2237,15 @@ async function openSettingsPanel() {
...allLevels
.sort((a, b) => a.threshold - b.threshold)
.map((l, li) => {
- const avaliable = ts >= l.threshold
- return ({
- text: l.name,
- help: `A ${l.size}x${l.size} level with ${l.bricks.filter(i => i).length} bricks` + (avaliable ? '' : `(${l.threshold} coins)`),
- disabled: !avaliable,
- value: {level: l.name}
+ const avaliable = ts >= l.threshold
+ return ({
+ text: l.name,
+ help: `A ${l.size}x${l.size} level with ${l.bricks.filter(i => i).length} bricks` + (avaliable ? '' : `(${l.threshold} coins)`),
+ disabled: !avaliable,
+ value: {level: l.name}
+ })
})
- })
]
diff --git a/app/src/main/assets/levels.js b/app/src/main/assets/levels.js
index 33e1534..78c2e00 100644
--- a/app/src/main/assets/levels.js
+++ b/app/src/main/assets/levels.js
@@ -30,7 +30,8 @@ let allLevels=[
"#e32119"
],
"svg": "",
- "color": ""
+ "color": "",
+ "focus": false
},
{
"name": "Butterfly",
@@ -1028,26 +1029,26 @@ let allLevels=[
null,
null,
null,
- "#6262EA",
- "white",
+ "#ffd300",
+ "#ffd300",
null,
null,
- "#6262EA",
- "white",
- null,
- null,
- "white",
- "white",
- null,
- null,
- "white",
- "white",
+ "#ffd300",
+ "#ffd300",
+ "",
+ null,
+ "#ffd300",
+ "#ffd300",
null,
null,
+ "#ffd300",
+ "#ffd300",
+ "",
null,
null,
null,
null,
+ "",
null,
null,
null,
@@ -1060,24 +1061,26 @@ let allLevels=[
"",
null,
null,
- "#e32119",
- "#e32119",
- "#e32119",
- "#e32119",
- "#e32119",
- "#e32119",
- null,
- null,
- null,
- "#e32119",
- "#e32119",
- "#e32119",
- "#e32119",
- null,
+ "#ffd300",
+ "#ffd300",
+ "#ffd300",
+ "#ffd300",
+ "#ffd300",
+ "#ffd300",
+ "",
+ null,
+ null,
+ "#ffd300",
+ "#ffd300",
+ "#ffd300",
+ "#ffd300",
+ "",
null,
null,
null,
"",
+ "",
+ "",
""
],
"svg": "",
@@ -2801,7 +2804,7 @@ let allLevels=[
"color": ""
},
{
- "name": "Gold chain",
+ "name": "Chain",
"size": 7,
"bricks": [
"#ffd300",
@@ -2862,30 +2865,21 @@ let allLevels=[
"name": "Marion",
"size": 9,
"bricks": [
- "#ab0c0c",
- "#ab0c0c",
- "",
- "",
- "",
- "",
- "",
- "#ab0c0c",
- "#ab0c0c",
- "",
"#e32119",
- "#ab0c0c",
- "",
- "",
- "",
- "#ab0c0c",
"#e32119",
- null,
+ "",
+ "",
+ "",
+ "",
"",
"#e32119",
"#e32119",
- "#ab0c0c",
"",
- "#ab0c0c",
+ "#e32119",
+ "#e32119",
+ "",
+ "",
+ "",
"#e32119",
"#e32119",
null,
@@ -2893,7 +2887,16 @@ let allLevels=[
"#e32119",
"#e32119",
"#e32119",
- "#ab0c0c",
+ "",
+ "#e32119",
+ "#e32119",
+ "#e32119",
+ null,
+ "",
+ "#e32119",
+ "#e32119",
+ "#e32119",
+ "#e32119",
"#e32119",
"#e32119",
"#e32119",
@@ -2934,7 +2937,7 @@ let allLevels=[
"#e32119",
"#e32119",
null,
- "#ab0c0c",
+ "#e32119",
"#e32119",
"#e32119",
null,
@@ -2942,7 +2945,7 @@ let allLevels=[
null,
"#e32119",
"#e32119",
- "#ab0c0c"
+ "#e32119"
],
"svg": "",
"focus": false,
@@ -4041,29 +4044,29 @@ let allLevels=[
"",
null,
"",
- "#e32119",
"#F44848",
"#F44848",
- "#ab0c0c",
+ "#F44848",
+ "#F44848",
"",
"",
"",
null,
"",
- "#e32119",
- "#e32119",
- "#ab0c0c",
- "#ab0c0c",
+ "#F44848",
+ "#F44848",
+ "#F44848",
+ "#F44848",
"",
"",
"",
null,
"",
"",
- "#e32119",
- "#ab0c0c",
+ "#F44848",
+ "#F44848",
"",
- "#A1F051",
+ "#618227",
"",
"",
null,
@@ -4072,7 +4075,7 @@ let allLevels=[
"",
"#618227",
"",
- "#A1F051",
+ "#618227",
"#618227",
"",
null,
@@ -4239,7 +4242,7 @@ let allLevels=[
"#F44848",
"#F44848",
"#F44848",
- "#A1F051",
+ "#F44848",
"#618227",
"",
"#F44848",
@@ -4253,14 +4256,14 @@ let allLevels=[
"black",
"#F44848",
"#F44848",
- "#A1F051",
- "#A1F051",
+ "#F44848",
+ "#F44848",
"#618227",
"",
"#618227",
- "#618227",
- "#A1F051",
- "#A1F051",
+ "#F44848",
+ "#F44848",
+ "#F44848",
"#618227",
"#618227",
"",
@@ -4453,79 +4456,79 @@ let allLevels=[
"#E67070",
"#E67070"
],
- "svg": "\n",
+ "svg": "",
"color": "",
"focus": false,
"squared": false
},
{
- "name": "Sunrise",
+ "name": "Ocean Sunrise",
"size": 8,
"bricks": [
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "#e32119",
- "#e32119",
- "",
- "",
- "",
- "",
- "",
- "#e32119",
+ "#F44848",
+ "#F44848",
+ "#F44848",
+ "#F44848",
+ "#F44848",
+ "#F44848",
+ "#F44848",
+ "#F44848",
+ "#F44848",
+ "#F44848",
+ "#F44848",
"#ffd300",
"#ffd300",
- "#e32119",
- "",
- "",
- "",
- "#e32119",
+ "#F44848",
+ "#F44848",
+ "#F44848",
+ "#F44848",
+ "#F44848",
+ "#ffd300",
+ "#ffd300",
+ "#ffd300",
+ "#ffd300",
+ "#F44848",
+ "#F44848",
+ "#F44848",
+ "#ffd300",
"#ffd300",
"white",
"white",
"#ffd300",
- "#e32119",
- "",
- "#6262EA",
+ "#ffd300",
+ "#F44848",
"#6262EA",
"#5DA3EA",
+ "#5DA3EA",
"#5BECEC",
"#5BECEC",
"#5DA3EA",
+ "#5DA3EA",
+ "#6262EA",
+ "#6262EA",
+ "#6262EA",
+ "#5DA3EA",
+ "#5DA3EA",
+ "#5DA3EA",
+ "#5DA3EA",
+ "#6262EA",
"#6262EA",
"#6262EA",
- "",
"#6262EA",
"#6262EA",
"#5DA3EA",
"#5DA3EA",
"#6262EA",
"#6262EA",
- "",
- "",
- "",
"#6262EA",
"#6262EA",
"#6262EA",
"#6262EA",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- ""
+ "#6262EA",
+ "#6262EA",
+ "#6262EA",
+ "#6262EA",
+ "#6262EA"
],
"svg": "",
"focus": false,
@@ -6002,7 +6005,8 @@ let allLevels=[
"",
""
],
- "svg": ""
+ "svg": "",
+ "focus": false
},
{
"name": "Pig",
@@ -6774,5 +6778,172 @@ let allLevels=[
],
"svg": "",
"focus": false
+ },
+ {
+ "name": "Baby Dog",
+ "size": 8,
+ "bricks": [
+ "",
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ "white",
+ "",
+ "",
+ "#e1c8b4",
+ "#e1c8b4",
+ "#e1c8b4",
+ "#e1c8b4",
+ "white",
+ "white",
+ "white",
+ "white",
+ "#e1c8b4",
+ "#e1c8b4",
+ "white",
+ "#e1c8b4",
+ "white",
+ "white",
+ "white",
+ "#e1c8b4",
+ "#333",
+ "white",
+ "#e1c8b4",
+ "#333",
+ "#e1c8b4",
+ "#e1c8b4",
+ "#e1c8b4",
+ "#e1c8b4",
+ "white",
+ "white",
+ "white",
+ "white",
+ "#e1c8b4",
+ "#e1c8b4",
+ null,
+ "#e1c8b4",
+ "white",
+ "#333",
+ "#333",
+ "white",
+ "#e1c8b4",
+ null,
+ null,
+ "#e1c8b4",
+ "white",
+ "white",
+ "white",
+ "white",
+ "#e1c8b4",
+ null,
+ null,
+ null,
+ null,
+ "white",
+ "white"
+ ],
+ "svg": "",
+ "focus": false
+ },
+ {
+ "name": "Cute dog",
+ "size": 9,
+ "bricks": [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ "",
+ "#F29E4A",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "#F29E4A",
+ "",
+ "#F29E4A",
+ "#F29E4A",
+ "#F29E4A",
+ "white",
+ "white",
+ "white",
+ "#F29E4A",
+ "#F29E4A",
+ "#F29E4A",
+ "#F29E4A",
+ "#F29E4A",
+ "white",
+ "white",
+ "white",
+ "white",
+ "white",
+ "#F29E4A",
+ "#F29E4A",
+ "#F29E4A",
+ "#F29E4A",
+ "#e1c8b4",
+ "white",
+ "white",
+ "white",
+ "white",
+ "#F29E4A",
+ "#F29E4A",
+ "",
+ "#e1c8b4",
+ "black",
+ "#e1c8b4",
+ "white",
+ "white",
+ "black",
+ "white",
+ "",
+ "",
+ "#e1c8b4",
+ "black",
+ "#e1c8b4",
+ "white",
+ "white",
+ "black",
+ "white",
+ "",
+ "",
+ "",
+ "#e1c8b4",
+ "white",
+ "black",
+ "white",
+ "white",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "white",
+ "#ab0c0c",
+ "white",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""
+ ],
+ "svg": "",
+ "focus": false
}
]
\ No newline at end of file
diff --git a/editclient.js b/editclient.js
index d5a9320..eacef8a 100644
--- a/editclient.js
+++ b/editclient.js
@@ -138,7 +138,12 @@ document.getElementById('levels').addEventListener('change', e => {
level.svg = ''
updateLevelBackground(levelIndex)
}else if( e.target.getAttribute('type') === 'checkbox' && e.target.hasAttribute('data-field')){
- level[e.target.getAttribute('data-field')] = !!e.target.checked
+ const field=e.target.getAttribute('data-field')
+ if(field==='focus'){
+ allLevels.forEach(l=>l.focus=false)
+ }
+ level[field] = !!e.target.checked
+
}
save()
diff --git a/gifs/1.gif b/gifs/1.gif
new file mode 100644
index 0000000..6655638
Binary files /dev/null and b/gifs/1.gif differ