diff --git a/package.json b/package.json
index f9fc341..28e808b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "vcs-game-maker",
- "version": "0.22.0",
+ "version": "0.23.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
diff --git a/src/blocks/event.js b/src/blocks/event.js
index 96add74..d1ff09d 100644
--- a/src/blocks/event.js
+++ b/src/blocks/event.js
@@ -1,12 +1,23 @@
import * as Blockly from 'blockly/core';
-import {START_ICON, SYSTEM_ICON} from './icon';
+import {GAMEOVER_ICON, GAME_ICON, START_ICON, SYSTEM_ICON, TITLE_ICON, UPDATE_ICON} from './icon';
const EVENT_OPTIONS = [
[`${SYSTEM_ICON} ${START_ICON} System start`, `system_start`],
+ [`${TITLE_ICON} ${START_ICON} Title screen start`, `title_start`],
+ [`${TITLE_ICON} ${UPDATE_ICON} Title screen update`, `title_update`],
+ [`${GAME_ICON} ${START_ICON} Gameplay start`, `gameplay_start`],
+ [`${GAMEOVER_ICON} ${START_ICON} Gameover start`, `gameover_start`],
+ [`${GAMEOVER_ICON} ${UPDATE_ICON} Gameover update`, `gameover_update`],
+];
+
+const STATE_OPTIONS = [
+ [`${TITLE_ICON} Title screen`, 'title'],
+ [`${GAME_ICON} Gameplay`, 'gameplay'],
+ [`${GAMEOVER_ICON} Gameover`, 'gameover'],
];
Blockly.defineBlocksWithJsonArray([
- // Block for startup code
+ // Block for events
{
'type': 'event_block',
'message0': 'On %1',
@@ -25,6 +36,22 @@ Blockly.defineBlocksWithJsonArray([
'previousStatement': null,
'nextStatement': null,
'colour': 'rgb(39, 176, 176)',
- 'tooltip': 'Will be executed exactly one time when the ROM boots up',
+ 'tooltip': 'Will be executed when a given event happens',
+ },
+ // Block for changing game state
+ {
+ 'type': 'event_change_state',
+ 'message0': 'Change state to %1',
+ 'args0': [
+ {
+ 'type': 'field_dropdown',
+ 'name': 'STATE',
+ 'options': STATE_OPTIONS,
+ },
+ ],
+ 'previousStatement': null,
+ 'nextStatement': null,
+ 'colour': 'rgb(39, 176, 176)',
+ 'tooltip': 'Change game state to a given one',
},
]);
diff --git a/src/blocks/icon.js b/src/blocks/icon.js
index 2ddad93..bd49c8c 100644
--- a/src/blocks/icon.js
+++ b/src/blocks/icon.js
@@ -13,3 +13,7 @@ export const SOUND_ICON = String.fromCodePoint(0x1F509);
export const ANIMATION_ICON = String.fromCodePoint(0x1F3AC);
export const SYSTEM_ICON = String.fromCodePoint(0x1F3AB);
export const START_ICON = String.fromCodePoint(0x25B6) + String.fromCodePoint(0xFE0F);
+export const TITLE_ICON = String.fromCodePoint(0x1F4FA);
+export const UPDATE_ICON = String.fromCodePoint(0x1F3C3);
+export const GAME_ICON = String.fromCodePoint(0x1F47E);
+export const GAMEOVER_ICON = String.fromCodePoint(0x2620) + String.fromCodePoint(0xFE0F);
diff --git a/src/components/blockly-toolbox.xml.hbs b/src/components/blockly-toolbox.xml.hbs
index 978201d..88fbf82 100644
--- a/src/components/blockly-toolbox.xml.hbs
+++ b/src/components/blockly-toolbox.xml.hbs
@@ -181,7 +181,29 @@
+
+
+ gameover
+
+
+
+ title_update
+
+
+
+
+ joy0fire
+
+
+
+
+ gameplay
+
+
+
+
+
diff --git a/src/generators/bbasic.bb.hbs b/src/generators/bbasic.bb.hbs
index 3afa4ad..a04f88a 100644
--- a/src/generators/bbasic.bb.hbs
+++ b/src/generators/bbasic.bb.hbs
@@ -64,33 +64,22 @@ end
{{{ systemStartEvent }}}
+fullgameloop
+
+{{{ titleStartEvent }}}
+
+{{{ titleUpdateEvent }}}
+
+{{{ gamePlayStartEvent }}}
+
rem **************************************************************************
rem Main loop:
- rem - set colors and record last coordinates of player sprites
rem **************************************************************************
main
- rem **************************************************************************
- rem Draw loop:
- rem - Draws the screen and handles user input. Moves the sprites and
- rem - the ball's position and handles collisions
- rem **************************************************************************
-draw
- COLUP1 = player1realcolor
- COLUP0 = player0realcolor
- NUSIZ0 = player0size
- NUSIZ1 = player1size
+ gosub commongamelogic
drawscreen
- rem **************************************************************************
- rem Backgrounds generated by vcs-game-maker.
- rem **************************************************************************
-
- if newbackground = 0 then goto backgroundchangeend
-{{{ generatedBackgrounds }}}
-backgroundchangeend
- newbackground = 0
-
rem **************************************************************************
rem Code generated by vcs-game-maker.
rem **************************************************************************
@@ -100,7 +89,20 @@ backgroundchangeend
rem **************************************************************************
rem End of generated code.
rem **************************************************************************
+
+ goto main
+{{{ gameOverStartEvent }}}
+
+{{{ gameOverUpdateEvent }}}
+
+ goto fullgameloop
+
+ rem **************************************************************************
+ rem Common game logic subroutine.
+ rem **************************************************************************
+
+commongamelogic
rem **************************************************************************
rem Sound handling.
rem **************************************************************************
@@ -111,7 +113,29 @@ backgroundchangeend
if channnel1duration = 1 then AUDV1 = 0
if channnel1duration <> 0 then channnel1duration = channnel1duration - 1
- goto main
-
- rem if 0 then a = a
-
\ No newline at end of file
+
+ rem **************************************************************************
+ rem - Draws the screen and handles user input. Moves the sprites and
+ rem - the ball's position and handles collisions
+ rem **************************************************************************
+ COLUP1 = player1realcolor
+ COLUP0 = player0realcolor
+ NUSIZ0 = player0size
+ NUSIZ1 = player1size
+
+ rem **************************************************************************
+ rem Backgrounds generated by vcs-game-maker.
+ rem **************************************************************************
+
+ if newbackground = 0 then goto backgroundchangeend
+{{{ generatedBackgrounds }}}
+backgroundchangeend
+ newbackground = 0
+
+ rem **************************************************************************
+ rem Animations generated by vcs-game-maker.
+ rem **************************************************************************
+
+ {{{ generatedAnimations }}}
+
+ return
diff --git a/src/generators/bbasic.js b/src/generators/bbasic.js
index 4a38fee..5276447 100644
--- a/src/generators/bbasic.js
+++ b/src/generators/bbasic.js
@@ -192,14 +192,22 @@ Blockly.BBasic.finish = function(code) {
code = Blockly.BBasic.normalizeIndents(code);
const generatedBackgrounds = Blockly.BBasic.generateBackgrounds();
- const animation = Blockly.BBasic.generateAnimations();
+ const generatedAnimations = Blockly.BBasic.generateAnimations();
+
const systemStartEvent = this.generateGameEvent('system_start');
+ const titleStartEvent = this.generateGameEvent('title_start');
+ const titleUpdateEvent = this.generateGameLoopEvent('title_update');
+ const gamePlayStartEvent = this.generateGameEvent('gameplay_start');
+ const gameOverStartEvent = this.generateGameEvent('gameover_start');
+ const gameOverUpdateEvent = this.generateGameEvent('gameover_update');
this.isInitialized = false;
this.nameDB_.reset();
- const generatedBody = definitions.join('\n\n') + '\n\n\n' + animation + '\n\n\n' + code;
- return handlebarsTemplate({generatedBody, generatedBackgrounds, systemStartEvent});
+ const generatedBody = definitions.join('\n\n') + '\n\n\n' + code;
+ return handlebarsTemplate({generatedBody, generatedBackgrounds, generatedAnimations,
+ systemStartEvent, titleStartEvent, titleUpdateEvent, gamePlayStartEvent,
+ gameOverStartEvent, gameOverUpdateEvent});
};
Blockly.BBasic.normalizeIndents = function(code) {
@@ -365,16 +373,32 @@ Blockly.BBasic.addGameEvent = function(eventName, code) {
this.getGameEvent(eventName).push(code);
};
-Blockly.BBasic.generateGameEvent = function(eventName) {
- const eventCode = this.getGameEvent(eventName).join('\n\n');
+Blockly.BBasic.generateGameEvent = function(eventName,
+ codeGenerator = (eventName, eventCode) => eventCode.join('\n\n')) {
+ const eventCode = codeGenerator(eventName, this.getGameEvent(eventName));
return this.normalizeIndents([
'rem **************************************************************************',
`rem Event: ${eventName}.`,
'rem **************************************************************************',
+ `@${eventName}_begin`,
eventCode,
+ `@${eventName}_end`,
].join('\n'));
};
+Blockly.BBasic.generateGameLoopEvent = function(eventName) {
+ return this.generateGameEvent(eventName, (eventName, eventCode) => {
+ const innerCode = eventCode.join('\n\n');
+ if (!innerCode.trim()) return '';
+ return [
+ 'gosub commongamelogic',
+ 'drawscreen',
+ innerCode,
+ `goto ${eventName}_begin`,
+ ].join('\n');
+ });
+};
+
Blockly.BBasic.generateBackgrounds = function() {
const backgroundsStorage = useBackgroundsStorage();
diff --git a/src/generators/bbasic/event.js b/src/generators/bbasic/event.js
index 5f74583..29f7448 100644
--- a/src/generators/bbasic/event.js
+++ b/src/generators/bbasic/event.js
@@ -8,4 +8,11 @@ export default (Blockly) => {
Blockly.BBasic.addGameEvent(eventName, code);
return '';
};
+
+ Blockly.BBasic['event_change_state'] = function(block) {
+ // Change game state
+ const stateName = Blockly.BBasic.nameDB_.getName(block.getFieldValue('STATE'),
+ Blockly.VARIABLE_CATEGORY_NAME);
+ return `goto ${stateName}_start_begin`;
+ };
};