From 18ab5db4609f134cfb67c597410fcd5f4e2bc593 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Sun, 11 Nov 2018 17:34:59 +0000 Subject: [PATCH] Use nested dataspaces to clean up restarts --- packages/flappy-bird-demo/src/index.js | 267 ++++++++++++------------- 1 file changed, 131 insertions(+), 136 deletions(-) diff --git a/packages/flappy-bird-demo/src/index.js b/packages/flappy-bird-demo/src/index.js index 48fa803..10c291d 100644 --- a/packages/flappy-bird-demo/src/index.js +++ b/packages/flappy-bird-demo/src/index.js @@ -17,6 +17,8 @@ // along with this program. If not, see . //--------------------------------------------------------------------------- +import { $QuitDataspace, Inbound, Outbound, Dataspace } from "@syndicate-lang/core"; + let UI = activate require("@syndicate-lang/driver-browser-ui"); // @jsx UI.html // @jsxFrag UI.htmlFragment @@ -27,7 +29,6 @@ assertion type Position(x, y); assertion type GameOver(); assertion type Score(count); message type IncreaseScore(); - message type Reset(); const BOARD_HEIGHT = 567; @@ -39,143 +40,10 @@ const PILLAR_GAP = 158; const FIELD_HEIGHT = 561; const PILLAR_HEAD_HEIGHT = 40; -function newGame() { - spawn named 'score' { - let ui = new UI.Anchor(); - field this.score = 0; - - stop on message Reset(); - - assert Score(this.score); - - on start react { - assert ui.html('#board-area',

{this.score}

); - stop on asserted GameOver() react { - assert ui.html('#board-area',

{this.score}
GAME OVER

); - } - } - - on message IncreaseScore() { - this.score++; - } - } - - spawn named 'flappy' { - let ui = new UI.Anchor(); - field this.xpos = 0; - field this.ypos = 312; - field this.yvel = 0; - - stop on message Reset(); - - assert Position(this.xpos, this.ypos); - - assert ui.html('#board-area',
); - - on (this.ypos > BOARD_HEIGHT - FLAPPY_HEIGHT) { - this.ypos = BOARD_HEIGHT - FLAPPY_HEIGHT; - react { - assert GameOver(); - } - } - - on start react { - stop on asserted GameOver(); - - on message UI.WindowEvent('+keypress', $e) { - this.yvel = -10; - } - - const ms_per_tick = 1000.0 / 60; - on message PeriodicTick(ms_per_tick) { - this.xpos += 0.15 * ms_per_tick; - this.ypos = (this.ypos + this.yvel); - this.yvel += ms_per_tick * 0.05; - } - } - } - - spawn named 'border-scroll' { - let ui = new UI.Anchor(); - field this.pos = 0; - on asserted Position($xpos, _) this.pos = xpos % 23; - assert ui.html( - '#board-area', -
, 0); - - stop on message Reset(); - } - - spawn named 'pipe-factory' { - on start spawnPipe(0); - field this.nextPipe = 1; - - stop on message Reset(); - - on asserted Score(this.nextPipe) { - spawnPipe(this.nextPipe++); - } - } - - function spawnPipe(i) { - spawn named ['pipe', i] { - stop on message Reset(); - - let ui = new UI.Anchor(); - - const xlocation = (i + 1) * 324; - - 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)); - - on start react stop on (this.xpos <= 0) { - ^ IncreaseScore(); - } - - field this.xpos = xlocation; - on asserted Position($xpos, _) this.xpos = xlocation - xpos; - - on asserted Position($xpos, $ypos) { - if (touchingPillar(xpos, ypos)) { - react { - assert GameOver(); - } - } - } - - assert ui.html( - '#board-area', -
-
-
-
); - - function touchingPillar(xpos, ypos) { - 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); - } - } - } -} - spawn named 'game-factory' { - on start newGame(); - - // TODO: Use nested dataspaces to clean up restarts - + on start spawnGame(); during GameOver() { - on stop newGame(); + on stop spawnGame(); on message UI.WindowEvent('+keypress', $e) { if (e.key !== ' ') { ^ Reset(); @@ -183,3 +51,130 @@ spawn named 'game-factory' { } } } + +function spawnGame() { + spawn dataspace named 'GameInstance' { + spawn named 'game-instance-control' { + during GameOver() assert Outbound(GameOver()); + on message Inbound(Reset()) { + ^ $QuitDataspace; + } + } + + spawn named 'score' { + let ui = new UI.Anchor(); + field this.score = 0; + + assert Score(this.score); + + on start react { + assert Outbound(ui.html('#board-area',

{this.score}

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

{this.score}
GAME OVER

)); + } + } + + on message IncreaseScore() { + this.score++; + } + } + + spawn named 'flappy' { + let ui = new UI.Anchor(); + field this.xpos = 0; + field this.ypos = 312; + field this.yvel = 0; + + assert Position(this.xpos, this.ypos); + + assert Outbound(ui.html('#board-area',
)); + + on (this.ypos > BOARD_HEIGHT - FLAPPY_HEIGHT) { + this.ypos = BOARD_HEIGHT - FLAPPY_HEIGHT; + react { + assert GameOver(); + } + } + + on start react { + stop on asserted GameOver(); + + on message Inbound(UI.WindowEvent('+keypress', $e)) { + this.yvel = -10; + } + + const ms_per_tick = 1000.0 / 60; + on message Inbound(PeriodicTick(ms_per_tick)) { + this.xpos += 0.15 * ms_per_tick; + this.ypos = (this.ypos + this.yvel); + this.yvel += ms_per_tick * 0.05; + } + } + } + + spawn named 'border-scroll' { + let ui = new UI.Anchor(); + field this.pos = 0; + on asserted Position($xpos, _) this.pos = xpos % 23; + assert Outbound(ui.html( + '#board-area', +
, 0)); + } + + spawn named 'pipe-factory' { + field this.nextPipe = 0; + on asserted Score(this.nextPipe) { + spawnPipe(this.nextPipe++); + } + } + + function spawnPipe(i) { + spawn named ['pipe', i] { + let ui = new UI.Anchor(); + + const xlocation = (i + 1) * 324; + + 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)); + + on start react stop on (this.xpos <= 0) { + ^ IncreaseScore(); + } + + field this.xpos = xlocation; + on asserted Position($xpos, _) this.xpos = xlocation - xpos; + + on asserted Position($xpos, $ypos) { + if (touchingPillar(xpos, ypos)) { + react { + assert GameOver(); + } + } + } + + assert Outbound(ui.html( + '#board-area', +
+
+
+
)); + + function touchingPillar(xpos, ypos) { + 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); + } + } + } + } +}