Run pipes as linked actors in their own subfacets, to prevent a vanishing pipe from killing the game

This commit is contained in:
Tony Garnock-Jones 2021-12-13 20:21:21 +01:00
parent 90a6e2f41a
commit b92bbb9741
1 changed files with 50 additions and 45 deletions

View File

@ -137,60 +137,65 @@ function spawnGame(mainDs: Ref) {
spawn linked named 'pipe-factory' { spawn linked named 'pipe-factory' {
field nextPipe: number = 0; field nextPipe: number = 0;
at gameDs { at gameDs {
on asserted Score(nextPipe.value) => spawnPipe(nextPipe.value++); on asserted Score(nextPipe.value) => {
}
}
function spawnPipe(i: number) {
const xlocation = (i + 1) * 324;
spawn linked named ['pipe', i] {
let ui = new Anchor();
field xpos: number = xlocation;
const upperHeight =
Math.random() * (FIELD_HEIGHT - PILLAR_GAP - PILLAR_HEAD_HEIGHT * 6)
+ PILLAR_HEAD_HEIGHT * 3;
const lowerHeight = FIELD_HEIGHT - upperHeight - PILLAR_GAP;
stop on (xpos.value < -(PILLAR_WIDTH + FLAPPY_XPOS));
at gameDs {
react { react {
stop on (xpos.value <= 0) send message IncreaseScore(); const pipeNumber = nextPipe.value++;
} spawn linked named ['pipe', pipeNumber] {
runPipe(pipeNumber);
on asserted Position($flappyXpos, _) =>
xpos.value = xlocation - floatValue(flappyXpos);
on asserted Position($xpos, $ypos) => {
if (touchingPillar(floatValue(xpos), floatValue(ypos))) {
react {
assert GameOver();
}
} }
} }
} }
}
}
at mainDs { function runPipe(i: number) {
assert ui.html( const xlocation = (i + 1) * 324;
'#board-area',
template`<div class="pillars"> let ui = new Anchor();
<div class="pillar pillar-upper" field xpos: number = xlocation;
style="${`left: ${xpos.value + FLAPPY_XPOS}px; height: ${upperHeight}px;`}"></div>
<div class="pillar pillar-lower" const upperHeight =
style="${`left: ${xpos.value + FLAPPY_XPOS}px; height: ${lowerHeight}px;`}"></div> Math.random() * (FIELD_HEIGHT - PILLAR_GAP - PILLAR_HEAD_HEIGHT * 6)
</div>`); + PILLAR_HEAD_HEIGHT * 3;
const lowerHeight = FIELD_HEIGHT - upperHeight - PILLAR_GAP;
stop on (xpos.value < -(PILLAR_WIDTH + FLAPPY_XPOS));
at gameDs {
react {
stop on (xpos.value <= 0) send message IncreaseScore();
} }
function touchingPillar(xpos: number, ypos: number): boolean { on asserted Position($flappyXpos, _) =>
const inHorizontalRange = xpos.value = xlocation - floatValue(flappyXpos);
(xpos + FLAPPY_WIDTH >= xlocation) && (xpos <= xlocation + PILLAR_WIDTH);
const aboveGapTop = (ypos <= upperHeight); on asserted Position($xpos, $ypos) => {
const belowGapBottom = (ypos + FLAPPY_HEIGHT >= upperHeight + PILLAR_GAP); if (touchingPillar(floatValue(xpos), floatValue(ypos))) {
return inHorizontalRange && (aboveGapTop || belowGapBottom); react {
assert GameOver();
}
}
} }
} }
at mainDs {
assert ui.html(
'#board-area',
template`<div class="pillars">
<div class="pillar pillar-upper"
style="${`left: ${xpos.value + FLAPPY_XPOS}px; height: ${upperHeight}px;`}"></div>
<div class="pillar pillar-lower"
style="${`left: ${xpos.value + FLAPPY_XPOS}px; height: ${lowerHeight}px;`}"></div>
</div>`);
}
function touchingPillar(xpos: number, ypos: number): boolean {
const inHorizontalRange =
(xpos + FLAPPY_WIDTH >= xlocation) && (xpos <= xlocation + PILLAR_WIDTH);
const aboveGapTop = (ypos <= upperHeight);
const belowGapBottom = (ypos + FLAPPY_HEIGHT >= upperHeight + PILLAR_GAP);
return inHorizontalRange && (aboveGapTop || belowGapBottom);
}
} }
} }
} }