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 \n \n \n \n\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