Simple game
Diff: main.cpp
- Revision:
- 0:c0ff9a7daaac
diff -r 000000000000 -r c0ff9a7daaac main.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Wed Apr 13 16:20:53 2016 +0000
@@ -0,0 +1,210 @@
+/*
+The MIT License (MIT)
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/* The letter game....
+
+ This simple game demonstrates the use of:
+ 1) The random function
+ 2) Events on the message bus to handle button presses
+ 3) Driving the display for both characters, numbers and animations.
+ 4) The system timer
+
+ The start of the game will be preceeded by the following message:
+ "Get Ready.."
+ and then a small animation showing shrinking boxes.
+ Once the game starts a random letter from A-Z will be displayed on the screen.
+ If it is a consonant then you press the right button.
+ If it is a vowel then you press the left button.
+ You must press the corresponding button within the time period for the current level.
+ Each time you level up, the time to respond decreases. When you level up the shrinking
+ box animation will be displayed again.
+
+ The initial allowed time is defined as INITIAL_LIMIT.
+ The amount by which the time allowed decreases at each level is defined by SPEEDUP.
+ The point at which a level up occurs is defined as LEVEL_UP.
+
+*/
+
+#include "MicroBit.h"
+#include <stdio.h>
+
+void level_up();
+void start();
+void game_over();
+void display_letter();
+void check_press(unsigned long delay);
+void onButtonA(MicroBitEvent e);
+void onButtonB(MicroBitEvent e);
+
+
+MicroBit uBit;
+
+#define INITIAL_LIMIT 2000 //ms
+#define SPEEDUP 200 //ms
+#define LEVEL_UP 20 // level/speed up each time score accumulates by this amount
+
+typedef enum
+{
+ NONE,
+ VOWEL,
+ CONSONANT,
+ LATE_PRESS
+} Letter_type;
+
+Letter_type buttonPress = NONE;
+Letter_type type = NONE;
+unsigned long time_val;
+unsigned long limit;
+unsigned score = 0;
+
+void level_up()
+{
+ MicroBitImage outer("255,255,255,255,255\n255,0,0,0,255\n255,0,0,0,255\n255,0,0,0,255\n255,255,255,255,255\n");
+ uBit.display.print(outer, 0, 0);
+ uBit.sleep(200);
+ MicroBitImage middle("0,0,0,0,0\n0,255,255,255,0\n0,255,0,255,0\n0,255,0,255,0\n0,0,0,0,0\n");
+ uBit.display.print(middle, 0, 0);
+ uBit.sleep(200);
+ MicroBitImage inner("0,0,0,0,0\n0,0,0,0,0\n0,0,255,0,0\n0,0,0,0,0\n0,0,0,0,0\n");
+ uBit.display.print(inner, 0, 0);
+ uBit.sleep(200);
+ uBit.display.print(middle, 0, 0);
+ uBit.sleep(200);
+ uBit.display.print(outer, 0, 0);
+ uBit.sleep(200);
+ uBit.display.clear();
+ uBit.sleep(300);
+}
+
+void start()
+{
+ score = 0;
+ limit = INITIAL_LIMIT;
+ uBit.display.clear();
+ uBit.display.scroll("GET READY...", 100);
+ uBit.sleep(500);
+ level_up();
+ uBit.sleep(500);
+ display_letter();
+}
+
+void game_over()
+{
+ char val[5];
+ uBit.display.clear();
+ uBit.display.scroll("GAME OVER!", 100);
+ uBit.display.scroll("SCORE = ");
+ sprintf(val,"%u", score);
+ uBit.display.scroll(val, 100);
+}
+
+
+void display_letter()
+{
+ // random number from 65 - 90 ie ASCII A-Z
+ char letter = uBit.random(26) + 65;
+
+ switch(letter)
+ {
+ case 'A':
+ case 'E':
+ case 'I':
+ case 'O':
+ case 'U':
+ type = VOWEL;
+ break;
+
+ default:
+ type = CONSONANT;
+ }
+
+ uBit.display.printChar(letter,500);
+ //uBit.sleep(limit);
+ uBit.display.clear();
+ time_val = uBit.systemTime();
+}
+
+void check_press(unsigned long delay)
+{
+ if (buttonPress == type && delay <= limit)
+ {
+ score++;
+ if ((score % LEVEL_UP) == 0 && limit > SPEEDUP)
+ {
+ // Increase speed
+ limit -= SPEEDUP;
+ level_up();
+ }
+ buttonPress = NONE;
+ display_letter();
+ }
+ else
+ {
+ game_over();
+ uBit.sleep(1000);
+ start();
+ }
+
+}
+
+void onButtonA(MicroBitEvent e)
+{
+ if (e.value == MICROBIT_BUTTON_EVT_CLICK)
+ {
+ unsigned long delay = uBit.systemTime() - time_val;
+ buttonPress = VOWEL;
+ check_press(delay);
+ }
+}
+
+void onButtonB(MicroBitEvent e)
+{
+ if (e.value == MICROBIT_BUTTON_EVT_CLICK)
+ {
+ unsigned long delay = uBit.systemTime() - time_val;
+ buttonPress = CONSONANT;
+ check_press(delay);
+ }
+
+}
+
+
+int main()
+{
+
+ // Initialise the micro:bit runtime.
+ uBit.init();
+
+ // Set up button event handlers
+ uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_EVT_ANY, onButtonB);
+ uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_EVT_ANY, onButtonA);
+
+ start();
+ while(1)
+ {
+ uBit.sleep(100);
+ }
+
+ // If main exits, there may still be other fibers running or registered event handlers etc.
+ // Simply release this fiber, which will mean we enter the scheduler. Worse case, we then
+ // sit in the idle task forever, in a power efficient sleep.
+ release_fiber();
+}
\ No newline at end of file