mirror of
https://gitlab.com/lecarore/breakout71.git
synced 2025-04-21 12:36:15 -04:00
wip
This commit is contained in:
parent
a38b9481e0
commit
0ff6ae1fdf
2 changed files with 132 additions and 22 deletions
|
@ -14,6 +14,7 @@ At the end of each level, you get to select an upgrade.
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- Fdroid
|
- Fdroid
|
||||||
|
- pause/resume audio context
|
||||||
- show total score on end screen (score added to total)
|
- show total score on end screen (score added to total)
|
||||||
- show stats on end screen compared to other runs
|
- show stats on end screen compared to other runs
|
||||||
- handle back bouton in menu
|
- handle back bouton in menu
|
||||||
|
|
|
@ -88,6 +88,22 @@ function decreaseCombo(by, x, y) {
|
||||||
let gridSize = 12;
|
let gridSize = 12;
|
||||||
|
|
||||||
let running = false, puck = 400;
|
let running = false, puck = 400;
|
||||||
|
function play(){
|
||||||
|
if(running) return
|
||||||
|
running = true
|
||||||
|
if(audioContext){
|
||||||
|
audioContext.resume()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function pause(){
|
||||||
|
if(!running) return
|
||||||
|
running = false
|
||||||
|
needsRender=true
|
||||||
|
if(audioContext){
|
||||||
|
audioContext.suspend()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
let offsetX, gameZoneWidth, gameZoneHeight, brickWidth, needsRender = true;
|
let offsetX, gameZoneWidth, gameZoneHeight, brickWidth, needsRender = true;
|
||||||
|
|
||||||
|
@ -115,8 +131,7 @@ const fitSize = () => {
|
||||||
setMousePos(puck);
|
setMousePos(puck);
|
||||||
coins = [];
|
coins = [];
|
||||||
flashes = [];
|
flashes = [];
|
||||||
running = false;
|
pause()
|
||||||
needsRender = true;
|
|
||||||
putBallsAtPuck();
|
putBallsAtPuck();
|
||||||
};
|
};
|
||||||
window.addEventListener("resize", fitSize);
|
window.addEventListener("resize", fitSize);
|
||||||
|
@ -317,8 +332,7 @@ async function openUpgradesPicker() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setLevel(l) {
|
function setLevel(l) {
|
||||||
running = false;
|
pause()
|
||||||
needsRender = true
|
|
||||||
if (l > 0) {
|
if (l > 0) {
|
||||||
openUpgradesPicker().then();
|
openUpgradesPicker().then();
|
||||||
}
|
}
|
||||||
|
@ -366,6 +380,12 @@ function reset_perks() {
|
||||||
|
|
||||||
const randomGift = isSettingOn('easy') ? 'slow_down' : giftable[Math.floor(Math.random() * giftable.length)].id;
|
const randomGift = isSettingOn('easy') ? 'slow_down' : giftable[Math.floor(Math.random() * giftable.length)].id;
|
||||||
perks[randomGift] = 1;
|
perks[randomGift] = 1;
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// perks.puck_repulse_ball = 3
|
||||||
|
// perks.multiball = 1
|
||||||
|
// perks.ball_repulse_ball = 1
|
||||||
|
|
||||||
return randomGift
|
return randomGift
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,7 +564,20 @@ const upgrades = [{
|
||||||
name: "Bigger puck",
|
name: "Bigger puck",
|
||||||
max: 2,
|
max: 2,
|
||||||
help: `Catches more coins.`,
|
help: `Catches more coins.`,
|
||||||
}]
|
}, {
|
||||||
|
minimumTotalScore: 2000,
|
||||||
|
id: 'ball_repulse_ball',
|
||||||
|
name: "Balls repulse balls",
|
||||||
|
max: 3,
|
||||||
|
help: `Only has an effect when 2+ balls.`,
|
||||||
|
}, {
|
||||||
|
minimumTotalScore: 4000,
|
||||||
|
id: 'puck_repulse_ball',
|
||||||
|
name: "Puck repulse balls",
|
||||||
|
max: 3,
|
||||||
|
help: `Prevents the puck from touching the balls.`,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
function computeUpgradeCurrentMaxLevel(u, ts) {
|
function computeUpgradeCurrentMaxLevel(u, ts) {
|
||||||
let max = 0
|
let max = 0
|
||||||
|
@ -701,7 +734,11 @@ function setMousePos(x) {
|
||||||
|
|
||||||
canvas.addEventListener("mouseup", (e) => {
|
canvas.addEventListener("mouseup", (e) => {
|
||||||
if (e.button !== 0) return;
|
if (e.button !== 0) return;
|
||||||
running = !running;
|
if(running) {
|
||||||
|
pause()
|
||||||
|
}else {
|
||||||
|
play()
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
canvas.addEventListener("mousemove", (e) => {
|
canvas.addEventListener("mousemove", (e) => {
|
||||||
|
@ -712,15 +749,15 @@ canvas.addEventListener("touchstart", (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (!e.touches?.length) return;
|
if (!e.touches?.length) return;
|
||||||
setMousePos(e.touches[0].pageX);
|
setMousePos(e.touches[0].pageX);
|
||||||
running = true;
|
play()
|
||||||
});
|
});
|
||||||
canvas.addEventListener("touchend", (e) => {
|
canvas.addEventListener("touchend", (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
running = false;
|
pause()
|
||||||
});
|
});
|
||||||
canvas.addEventListener("touchcancel", (e) => {
|
canvas.addEventListener("touchcancel", (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
running = false;
|
pause()
|
||||||
needsRender = true
|
needsRender = true
|
||||||
});
|
});
|
||||||
canvas.addEventListener("touchmove", (e) => {
|
canvas.addEventListener("touchmove", (e) => {
|
||||||
|
@ -969,16 +1006,38 @@ function ballTick(ball, delta) {
|
||||||
|
|
||||||
if (isTelekinesisActive(ball)) {
|
if (isTelekinesisActive(ball)) {
|
||||||
ball.vx += ((puck - ball.x) / 1000) * delta * perks.telekinesis;
|
ball.vx += ((puck - ball.x) / 1000) * delta * perks.telekinesis;
|
||||||
} else if (ball.vx * ball.vx + ball.vy * ball.vy < baseSpeed * baseSpeed * 2) {
|
}
|
||||||
ball.vx *= 1.01;
|
|
||||||
ball.vy *= 1.01;
|
const speedLimitDampener =1+ perks.telekinesis+perks.ball_repulse_ball +perks.puck_repulse_ball
|
||||||
|
if (ball.vx * ball.vx + ball.vy * ball.vy < baseSpeed * baseSpeed * 2) {
|
||||||
|
ball.vx *= (1 + .02/speedLimitDampener);
|
||||||
|
ball.vy *= (1 + .02/speedLimitDampener);
|
||||||
} else {
|
} else {
|
||||||
ball.vx *= 0.99;
|
ball.vx *= (1 - .02/speedLimitDampener);;
|
||||||
if (Math.abs(ball.vy) > 0.5 * baseSpeed) {
|
if (Math.abs(ball.vy) > 0.5 * baseSpeed) {
|
||||||
ball.vy *= 0.99;
|
ball.vy *= (1 - .02/speedLimitDampener);;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(perks.ball_repulse_ball){
|
||||||
|
for(b2 of balls){
|
||||||
|
// avoid computing this twice, and repulsing itself
|
||||||
|
if(b2.x>=ball.x) continue
|
||||||
|
repulse(ball,b2,15* perks.ball_repulse_ball )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(perks.puck_repulse_ball){
|
||||||
|
repulse(ball,{
|
||||||
|
x:puck,
|
||||||
|
y:gameZoneHeight,
|
||||||
|
vx:0,
|
||||||
|
vy:0,
|
||||||
|
color:currentLevelInfo().black_puck ? '#000' : '#FFF' ,
|
||||||
|
},15* perks.puck_repulse_ball )
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const borderHitCode = bordersHitCheck(ball, ballSize / 2, delta);
|
const borderHitCode = bordersHitCheck(ball, ballSize / 2, delta);
|
||||||
if (borderHitCode) {
|
if (borderHitCode) {
|
||||||
if (perks.sides_are_lava && borderHitCode % 2) {
|
if (perks.sides_are_lava && borderHitCode % 2) {
|
||||||
|
@ -1025,7 +1084,8 @@ function ballTick(ball, delta) {
|
||||||
// segement
|
// segement
|
||||||
const start= ball.bouncesList[si]
|
const start= ball.bouncesList[si]
|
||||||
const end= ball.bouncesList[si+1]
|
const end= ball.bouncesList[si+1]
|
||||||
const distance= Math.sqrt(Math.pow(start.x-end.x,2)+ Math.pow(start.y-end.y,2))
|
const distance= distanceBetween(start,end)
|
||||||
|
|
||||||
const parts = distance/30
|
const parts = distance/30
|
||||||
for(var i = 0; i <parts;i++ ){
|
for(var i = 0; i <parts;i++ ){
|
||||||
flashes.push({
|
flashes.push({
|
||||||
|
@ -1061,7 +1121,7 @@ function ballTick(ball, delta) {
|
||||||
perks.extra_life--;
|
perks.extra_life--;
|
||||||
resetBalls();
|
resetBalls();
|
||||||
sounds.revive();
|
sounds.revive();
|
||||||
running = false;
|
pause()
|
||||||
coins = [];
|
coins = [];
|
||||||
flashes.push({
|
flashes.push({
|
||||||
type: "ball",
|
type: "ball",
|
||||||
|
@ -1143,8 +1203,7 @@ function addToTotalScore(points) {
|
||||||
|
|
||||||
function gameOver(title, intro) {
|
function gameOver(title, intro) {
|
||||||
if (!running) return;
|
if (!running) return;
|
||||||
running = false;
|
pause()
|
||||||
needsRender = true
|
|
||||||
|
|
||||||
runStatistics.ended = Date.now()
|
runStatistics.ended = Date.now()
|
||||||
|
|
||||||
|
@ -1958,8 +2017,7 @@ setInterval(() => {
|
||||||
|
|
||||||
window.addEventListener("visibilitychange", () => {
|
window.addEventListener("visibilitychange", () => {
|
||||||
if (document.hidden) {
|
if (document.hidden) {
|
||||||
running = false;
|
pause()
|
||||||
needsRender = true
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2123,8 +2181,7 @@ const options = {
|
||||||
};
|
};
|
||||||
|
|
||||||
async function openSettingsPanel() {
|
async function openSettingsPanel() {
|
||||||
running = false;
|
pause()
|
||||||
needsRender = true
|
|
||||||
|
|
||||||
const optionsList = [];
|
const optionsList = [];
|
||||||
for (const key in options) {
|
for (const key in options) {
|
||||||
|
@ -2197,6 +2254,58 @@ async function openSettingsPanel() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function distance2(a,b){
|
||||||
|
return Math.pow(a.x-b.x,2)+ Math.pow(a.y-b.y,2)
|
||||||
|
}
|
||||||
|
function distanceBetween(a,b){
|
||||||
|
return Math.sqrt(distance2(a,b))
|
||||||
|
}
|
||||||
|
|
||||||
|
function repulse(a,b,power){
|
||||||
|
|
||||||
|
const distance = distanceBetween(a,b)
|
||||||
|
// Ensure we don't get soft locked
|
||||||
|
if(distance>gameZoneWidth/2) return
|
||||||
|
// Unit vector
|
||||||
|
const dx= (a.x-b.x)/distance
|
||||||
|
const dy= (a.y-b.y)/distance
|
||||||
|
|
||||||
|
const fact= - power / (1+Math.max(1, distance))
|
||||||
|
b.vx+=dx*fact
|
||||||
|
b.vy+=dy*fact
|
||||||
|
a.vx-=dx*fact
|
||||||
|
a.vy-=dy*fact
|
||||||
|
|
||||||
|
if(!isSettingOn('basic')){
|
||||||
|
const speed= 10
|
||||||
|
const rand= 2
|
||||||
|
flashes.push({
|
||||||
|
type: "particle",
|
||||||
|
duration:150,
|
||||||
|
time: levelTime,
|
||||||
|
size:coinSize/2,
|
||||||
|
color:b.color,
|
||||||
|
ethereal:true,
|
||||||
|
x:a.x,
|
||||||
|
y:a.y,
|
||||||
|
vx:-dx*speed+a.vx+(Math.random()-0.5)*rand,
|
||||||
|
vy:-dy*speed+a.vy+(Math.random()-0.5)*rand,
|
||||||
|
})
|
||||||
|
flashes.push({
|
||||||
|
type: "particle",
|
||||||
|
duration:150,
|
||||||
|
time: levelTime,
|
||||||
|
size:coinSize/2,
|
||||||
|
color:a.color,
|
||||||
|
ethereal:true,
|
||||||
|
x:b.x,
|
||||||
|
y:b.y,
|
||||||
|
vx:dx*speed+b.vx+(Math.random()-0.5)*rand,
|
||||||
|
vy:dy*speed+b.vy+(Math.random()-0.5)*rand,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
fitSize()
|
fitSize()
|
||||||
restart()
|
restart()
|
||||||
tick();
|
tick();
|
Loading…
Add table
Add a link
Reference in a new issue