diff --git a/examples/syndicate-html-example-flappy-bird/index.html b/examples/syndicate-html-example-flappy-bird/index.html index 79677d0..fa16fc7 100644 --- a/examples/syndicate-html-example-flappy-bird/index.html +++ b/examples/syndicate-html-example-flappy-bird/index.html @@ -12,6 +12,6 @@ - + diff --git a/examples/syndicate-html-example-flappy-bird/src/index.ts b/examples/syndicate-html-example-flappy-bird/src/index.ts index 4bf7d20..f63bd93 100644 --- a/examples/syndicate-html-example-flappy-bird/src/index.ts +++ b/examples/syndicate-html-example-flappy-bird/src/index.ts @@ -1,9 +1,9 @@ /// SPDX-License-Identifier: GPL-3.0-or-later /// SPDX-FileCopyrightText: Copyright © 2016-2021 Tony Garnock-Jones -import { $QuitDataspace, Double, Facet, Inbound, Outbound, floatValue } from '@syndicate-lang/core'; -activate import { WindowEvent, template, Anchor } from '@syndicate-lang/html'; -activate import { PeriodicTick } from '@syndicate-lang/timer'; +import { Record, Dataspace, Double, floatValue, Ref, stringify } from '@syndicate-lang/core'; +import { boot as bootHtml, WindowEvent, template, Anchor } from '@syndicate-lang/html'; +import { boot as bootTimer, PeriodicTick } from '@syndicate-lang/timer'; assertion type Position(x, y); assertion type GameOver(); @@ -20,127 +20,168 @@ const PILLAR_GAP = 158; const FIELD_HEIGHT = 561; const PILLAR_HEAD_HEIGHT = 40; -boot { - spawn named 'game-factory' { - on start spawnGame(thisFacet); - during GameOver() => { - on stop spawnGame(thisFacet); - on message WindowEvent('+keypress', $_e) => send message Reset(); - on message WindowEvent('+click', $_e) => send message Reset(); +export function main() { + Dataspace.boot(mainDs => { + bootHtml(mainDs); + bootTimer(mainDs); + spawn named 'game-factory' { + spawnGame(mainDs); + at mainDs { + during GameOver() => { + on stop spawnGame(mainDs); + on message WindowEvent('+keypress', $_e) => send message Reset(); + on message WindowEvent('+click', $_e) => send message Reset(); + } + } } - } + }); } -function spawnGame(thisFacet: Facet) { - spawn dataspace named 'GameInstance' { - spawn named 'game-instance-control' { - during GameOver() => assert Outbound(GameOver()); - on message Inbound(Reset()) => send message $QuitDataspace; +function spawnGame(mainDs: Ref) { + spawn named 'GameInstance' { + const gameDs = create new Dataspace(); + + at gameDs { + during GameOver() => at mainDs { + assert GameOver(); + } + } + at mainDs { + stop on message Reset(); } - spawn named 'score' { + spawn linked named 'score' { let ui = new Anchor(); field score: number = 0; - assert Score(this.score); - - on start react { - assert Outbound(ui.html('#board-area', - template`

${this.score}

`)); - stop on asserted GameOver() => react { - assert Outbound(ui.html('#board-area', - template`

${this.score}
GAME OVER

`)); - } + at gameDs { + assert Score(score.value); + on message IncreaseScore() => score.value++; } - on message IncreaseScore() => this.score++; + react { + at mainDs { + assert ui.html('#board-area', template`

${score.value}

`); + } + at gameDs { + stop on asserted GameOver() => react { + at mainDs { + assert ui.html( + '#board-area', + template`

${score.value}
GAME OVER

`); + } + } + } + } } - spawn named 'flappy' { + spawn linked named 'flappy' { let ui = new Anchor(); field xpos: number = 0; field ypos: number = 312; field yvel: number = 0; - assert Position(Double(this.xpos), Double(this.ypos)); + at gameDs { + assert Position(Double(xpos.value), Double(ypos.value)); - assert Outbound( - ui.html('#board-area', - template`
`)); - - on (this.ypos > BOARD_HEIGHT - FLAPPY_HEIGHT) { - this.ypos = BOARD_HEIGHT - FLAPPY_HEIGHT; - react { - assert GameOver(); + on (ypos.value > BOARD_HEIGHT - FLAPPY_HEIGHT) { + ypos.value = BOARD_HEIGHT - FLAPPY_HEIGHT; + react { + assert GameOver(); + } } } - on start react { - stop on asserted GameOver(); + at mainDs { + assert ui.html( + '#board-area', + template`
`); + } - on message Inbound(WindowEvent('+keypress', $_e)) => this.yvel = -10; - on message Inbound(WindowEvent('+click', $_e)) => this.yvel = -10; + react { + at gameDs { + stop on asserted GameOver(); + } - const ms_per_tick = 1000.0 / 60; - on message Inbound(PeriodicTick(Double(ms_per_tick))) => { - this.xpos += 0.15 * ms_per_tick; - this.ypos = (this.ypos + this.yvel); - this.yvel += ms_per_tick * 0.05; + at mainDs { + on message WindowEvent('+keypress', $_e) => yvel.value = -10; + on message WindowEvent('+click', $_e) => yvel.value = -10; + + const ms_per_tick = 1000.0 / 60; + const ms_per_tick_d = Double(ms_per_tick); + on message PeriodicTick(ms_per_tick_d) => { + xpos.value += 0.15 * ms_per_tick; + ypos.value = (ypos.value + yvel.value); + yvel.value += ms_per_tick * 0.05; + } } } } - spawn named 'border-scroll' { + spawn linked named 'border-scroll' { let ui = new Anchor(); field pos: number = 0; - on asserted Position($xpos, _) => this.pos = floatValue(xpos) % 23; - assert Outbound(ui.html( - '#board-area', - template`
`, - 0)); + at gameDs { + on asserted Position($xpos, _) => pos.value = floatValue(xpos) % 23; + } + at mainDs { + assert ui.html( + '#board-area', + template`
`, + 0); + } } - spawn named 'pipe-factory' { + spawn linked named 'pipe-factory' { field nextPipe: number = 0; - on asserted Score(this.nextPipe) => spawnPipe(thisFacet, this.nextPipe++); + at gameDs { + on asserted Score(nextPipe.value) => spawnPipe(nextPipe.value++); + } } - function spawnPipe(thisFacet: Facet, i: number) { - spawn named ['pipe', i] { - let ui = new Anchor(); + function spawnPipe(i: number) { + const xlocation = (i + 1) * 324; - 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 (this.xpos < -(PILLAR_WIDTH + FLAPPY_XPOS)); + stop on (xpos.value < -(PILLAR_WIDTH + FLAPPY_XPOS)); - on start react { stop on (this.xpos <= 0) send message IncreaseScore(); }; + at gameDs { + react { + stop on (xpos.value <= 0) send message IncreaseScore(); + } - field xpos: number = xlocation; - on asserted Position($xpos, _) => this.xpos = xlocation - floatValue(xpos); + on asserted Position($flappyXpos, _) => + xpos.value = xlocation - floatValue(flappyXpos); - on asserted Position($xpos, $ypos) => { - if (touchingPillar(floatValue(xpos), floatValue(ypos))) { - react { - assert GameOver(); + on asserted Position($xpos, $ypos) => { + if (touchingPillar(floatValue(xpos), floatValue(ypos))) { + react { + assert GameOver(); + } } } } - assert Outbound(ui.html( - '#board-area', - template`
-
-
-
`)); + at mainDs { + assert ui.html( + '#board-area', + template`
+
+
+
`); + } function touchingPillar(xpos: number, ypos: number): boolean { const inHorizontalRange =