Simple game
main.cpp@0:c0ff9a7daaac, 2016-04-13 (annotated)
- Committer:
- AnnaBridge
- Date:
- Wed Apr 13 16:20:53 2016 +0000
- Revision:
- 0:c0ff9a7daaac
First version
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AnnaBridge | 0:c0ff9a7daaac | 1 | /* |
AnnaBridge | 0:c0ff9a7daaac | 2 | The MIT License (MIT) |
AnnaBridge | 0:c0ff9a7daaac | 3 | Copyright (c) 2016 British Broadcasting Corporation. |
AnnaBridge | 0:c0ff9a7daaac | 4 | This software is provided by Lancaster University by arrangement with the BBC. |
AnnaBridge | 0:c0ff9a7daaac | 5 | Permission is hereby granted, free of charge, to any person obtaining a |
AnnaBridge | 0:c0ff9a7daaac | 6 | copy of this software and associated documentation files (the "Software"), |
AnnaBridge | 0:c0ff9a7daaac | 7 | to deal in the Software without restriction, including without limitation |
AnnaBridge | 0:c0ff9a7daaac | 8 | the rights to use, copy, modify, merge, publish, distribute, sublicense, |
AnnaBridge | 0:c0ff9a7daaac | 9 | and/or sell copies of the Software, and to permit persons to whom the |
AnnaBridge | 0:c0ff9a7daaac | 10 | Software is furnished to do so, subject to the following conditions: |
AnnaBridge | 0:c0ff9a7daaac | 11 | The above copyright notice and this permission notice shall be included in |
AnnaBridge | 0:c0ff9a7daaac | 12 | all copies or substantial portions of the Software. |
AnnaBridge | 0:c0ff9a7daaac | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
AnnaBridge | 0:c0ff9a7daaac | 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
AnnaBridge | 0:c0ff9a7daaac | 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
AnnaBridge | 0:c0ff9a7daaac | 16 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
AnnaBridge | 0:c0ff9a7daaac | 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
AnnaBridge | 0:c0ff9a7daaac | 18 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
AnnaBridge | 0:c0ff9a7daaac | 19 | DEALINGS IN THE SOFTWARE. |
AnnaBridge | 0:c0ff9a7daaac | 20 | */ |
AnnaBridge | 0:c0ff9a7daaac | 21 | |
AnnaBridge | 0:c0ff9a7daaac | 22 | /* The letter game.... |
AnnaBridge | 0:c0ff9a7daaac | 23 | |
AnnaBridge | 0:c0ff9a7daaac | 24 | This simple game demonstrates the use of: |
AnnaBridge | 0:c0ff9a7daaac | 25 | 1) The random function |
AnnaBridge | 0:c0ff9a7daaac | 26 | 2) Events on the message bus to handle button presses |
AnnaBridge | 0:c0ff9a7daaac | 27 | 3) Driving the display for both characters, numbers and animations. |
AnnaBridge | 0:c0ff9a7daaac | 28 | 4) The system timer |
AnnaBridge | 0:c0ff9a7daaac | 29 | |
AnnaBridge | 0:c0ff9a7daaac | 30 | The start of the game will be preceeded by the following message: |
AnnaBridge | 0:c0ff9a7daaac | 31 | "Get Ready.." |
AnnaBridge | 0:c0ff9a7daaac | 32 | and then a small animation showing shrinking boxes. |
AnnaBridge | 0:c0ff9a7daaac | 33 | Once the game starts a random letter from A-Z will be displayed on the screen. |
AnnaBridge | 0:c0ff9a7daaac | 34 | If it is a consonant then you press the right button. |
AnnaBridge | 0:c0ff9a7daaac | 35 | If it is a vowel then you press the left button. |
AnnaBridge | 0:c0ff9a7daaac | 36 | You must press the corresponding button within the time period for the current level. |
AnnaBridge | 0:c0ff9a7daaac | 37 | Each time you level up, the time to respond decreases. When you level up the shrinking |
AnnaBridge | 0:c0ff9a7daaac | 38 | box animation will be displayed again. |
AnnaBridge | 0:c0ff9a7daaac | 39 | |
AnnaBridge | 0:c0ff9a7daaac | 40 | The initial allowed time is defined as INITIAL_LIMIT. |
AnnaBridge | 0:c0ff9a7daaac | 41 | The amount by which the time allowed decreases at each level is defined by SPEEDUP. |
AnnaBridge | 0:c0ff9a7daaac | 42 | The point at which a level up occurs is defined as LEVEL_UP. |
AnnaBridge | 0:c0ff9a7daaac | 43 | |
AnnaBridge | 0:c0ff9a7daaac | 44 | */ |
AnnaBridge | 0:c0ff9a7daaac | 45 | |
AnnaBridge | 0:c0ff9a7daaac | 46 | #include "MicroBit.h" |
AnnaBridge | 0:c0ff9a7daaac | 47 | #include <stdio.h> |
AnnaBridge | 0:c0ff9a7daaac | 48 | |
AnnaBridge | 0:c0ff9a7daaac | 49 | void level_up(); |
AnnaBridge | 0:c0ff9a7daaac | 50 | void start(); |
AnnaBridge | 0:c0ff9a7daaac | 51 | void game_over(); |
AnnaBridge | 0:c0ff9a7daaac | 52 | void display_letter(); |
AnnaBridge | 0:c0ff9a7daaac | 53 | void check_press(unsigned long delay); |
AnnaBridge | 0:c0ff9a7daaac | 54 | void onButtonA(MicroBitEvent e); |
AnnaBridge | 0:c0ff9a7daaac | 55 | void onButtonB(MicroBitEvent e); |
AnnaBridge | 0:c0ff9a7daaac | 56 | |
AnnaBridge | 0:c0ff9a7daaac | 57 | |
AnnaBridge | 0:c0ff9a7daaac | 58 | MicroBit uBit; |
AnnaBridge | 0:c0ff9a7daaac | 59 | |
AnnaBridge | 0:c0ff9a7daaac | 60 | #define INITIAL_LIMIT 2000 //ms |
AnnaBridge | 0:c0ff9a7daaac | 61 | #define SPEEDUP 200 //ms |
AnnaBridge | 0:c0ff9a7daaac | 62 | #define LEVEL_UP 20 // level/speed up each time score accumulates by this amount |
AnnaBridge | 0:c0ff9a7daaac | 63 | |
AnnaBridge | 0:c0ff9a7daaac | 64 | typedef enum |
AnnaBridge | 0:c0ff9a7daaac | 65 | { |
AnnaBridge | 0:c0ff9a7daaac | 66 | NONE, |
AnnaBridge | 0:c0ff9a7daaac | 67 | VOWEL, |
AnnaBridge | 0:c0ff9a7daaac | 68 | CONSONANT, |
AnnaBridge | 0:c0ff9a7daaac | 69 | LATE_PRESS |
AnnaBridge | 0:c0ff9a7daaac | 70 | } Letter_type; |
AnnaBridge | 0:c0ff9a7daaac | 71 | |
AnnaBridge | 0:c0ff9a7daaac | 72 | Letter_type buttonPress = NONE; |
AnnaBridge | 0:c0ff9a7daaac | 73 | Letter_type type = NONE; |
AnnaBridge | 0:c0ff9a7daaac | 74 | unsigned long time_val; |
AnnaBridge | 0:c0ff9a7daaac | 75 | unsigned long limit; |
AnnaBridge | 0:c0ff9a7daaac | 76 | unsigned score = 0; |
AnnaBridge | 0:c0ff9a7daaac | 77 | |
AnnaBridge | 0:c0ff9a7daaac | 78 | void level_up() |
AnnaBridge | 0:c0ff9a7daaac | 79 | { |
AnnaBridge | 0:c0ff9a7daaac | 80 | 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"); |
AnnaBridge | 0:c0ff9a7daaac | 81 | uBit.display.print(outer, 0, 0); |
AnnaBridge | 0:c0ff9a7daaac | 82 | uBit.sleep(200); |
AnnaBridge | 0:c0ff9a7daaac | 83 | 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"); |
AnnaBridge | 0:c0ff9a7daaac | 84 | uBit.display.print(middle, 0, 0); |
AnnaBridge | 0:c0ff9a7daaac | 85 | uBit.sleep(200); |
AnnaBridge | 0:c0ff9a7daaac | 86 | 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"); |
AnnaBridge | 0:c0ff9a7daaac | 87 | uBit.display.print(inner, 0, 0); |
AnnaBridge | 0:c0ff9a7daaac | 88 | uBit.sleep(200); |
AnnaBridge | 0:c0ff9a7daaac | 89 | uBit.display.print(middle, 0, 0); |
AnnaBridge | 0:c0ff9a7daaac | 90 | uBit.sleep(200); |
AnnaBridge | 0:c0ff9a7daaac | 91 | uBit.display.print(outer, 0, 0); |
AnnaBridge | 0:c0ff9a7daaac | 92 | uBit.sleep(200); |
AnnaBridge | 0:c0ff9a7daaac | 93 | uBit.display.clear(); |
AnnaBridge | 0:c0ff9a7daaac | 94 | uBit.sleep(300); |
AnnaBridge | 0:c0ff9a7daaac | 95 | } |
AnnaBridge | 0:c0ff9a7daaac | 96 | |
AnnaBridge | 0:c0ff9a7daaac | 97 | void start() |
AnnaBridge | 0:c0ff9a7daaac | 98 | { |
AnnaBridge | 0:c0ff9a7daaac | 99 | score = 0; |
AnnaBridge | 0:c0ff9a7daaac | 100 | limit = INITIAL_LIMIT; |
AnnaBridge | 0:c0ff9a7daaac | 101 | uBit.display.clear(); |
AnnaBridge | 0:c0ff9a7daaac | 102 | uBit.display.scroll("GET READY...", 100); |
AnnaBridge | 0:c0ff9a7daaac | 103 | uBit.sleep(500); |
AnnaBridge | 0:c0ff9a7daaac | 104 | level_up(); |
AnnaBridge | 0:c0ff9a7daaac | 105 | uBit.sleep(500); |
AnnaBridge | 0:c0ff9a7daaac | 106 | display_letter(); |
AnnaBridge | 0:c0ff9a7daaac | 107 | } |
AnnaBridge | 0:c0ff9a7daaac | 108 | |
AnnaBridge | 0:c0ff9a7daaac | 109 | void game_over() |
AnnaBridge | 0:c0ff9a7daaac | 110 | { |
AnnaBridge | 0:c0ff9a7daaac | 111 | char val[5]; |
AnnaBridge | 0:c0ff9a7daaac | 112 | uBit.display.clear(); |
AnnaBridge | 0:c0ff9a7daaac | 113 | uBit.display.scroll("GAME OVER!", 100); |
AnnaBridge | 0:c0ff9a7daaac | 114 | uBit.display.scroll("SCORE = "); |
AnnaBridge | 0:c0ff9a7daaac | 115 | sprintf(val,"%u", score); |
AnnaBridge | 0:c0ff9a7daaac | 116 | uBit.display.scroll(val, 100); |
AnnaBridge | 0:c0ff9a7daaac | 117 | } |
AnnaBridge | 0:c0ff9a7daaac | 118 | |
AnnaBridge | 0:c0ff9a7daaac | 119 | |
AnnaBridge | 0:c0ff9a7daaac | 120 | void display_letter() |
AnnaBridge | 0:c0ff9a7daaac | 121 | { |
AnnaBridge | 0:c0ff9a7daaac | 122 | // random number from 65 - 90 ie ASCII A-Z |
AnnaBridge | 0:c0ff9a7daaac | 123 | char letter = uBit.random(26) + 65; |
AnnaBridge | 0:c0ff9a7daaac | 124 | |
AnnaBridge | 0:c0ff9a7daaac | 125 | switch(letter) |
AnnaBridge | 0:c0ff9a7daaac | 126 | { |
AnnaBridge | 0:c0ff9a7daaac | 127 | case 'A': |
AnnaBridge | 0:c0ff9a7daaac | 128 | case 'E': |
AnnaBridge | 0:c0ff9a7daaac | 129 | case 'I': |
AnnaBridge | 0:c0ff9a7daaac | 130 | case 'O': |
AnnaBridge | 0:c0ff9a7daaac | 131 | case 'U': |
AnnaBridge | 0:c0ff9a7daaac | 132 | type = VOWEL; |
AnnaBridge | 0:c0ff9a7daaac | 133 | break; |
AnnaBridge | 0:c0ff9a7daaac | 134 | |
AnnaBridge | 0:c0ff9a7daaac | 135 | default: |
AnnaBridge | 0:c0ff9a7daaac | 136 | type = CONSONANT; |
AnnaBridge | 0:c0ff9a7daaac | 137 | } |
AnnaBridge | 0:c0ff9a7daaac | 138 | |
AnnaBridge | 0:c0ff9a7daaac | 139 | uBit.display.printChar(letter,500); |
AnnaBridge | 0:c0ff9a7daaac | 140 | //uBit.sleep(limit); |
AnnaBridge | 0:c0ff9a7daaac | 141 | uBit.display.clear(); |
AnnaBridge | 0:c0ff9a7daaac | 142 | time_val = uBit.systemTime(); |
AnnaBridge | 0:c0ff9a7daaac | 143 | } |
AnnaBridge | 0:c0ff9a7daaac | 144 | |
AnnaBridge | 0:c0ff9a7daaac | 145 | void check_press(unsigned long delay) |
AnnaBridge | 0:c0ff9a7daaac | 146 | { |
AnnaBridge | 0:c0ff9a7daaac | 147 | if (buttonPress == type && delay <= limit) |
AnnaBridge | 0:c0ff9a7daaac | 148 | { |
AnnaBridge | 0:c0ff9a7daaac | 149 | score++; |
AnnaBridge | 0:c0ff9a7daaac | 150 | if ((score % LEVEL_UP) == 0 && limit > SPEEDUP) |
AnnaBridge | 0:c0ff9a7daaac | 151 | { |
AnnaBridge | 0:c0ff9a7daaac | 152 | // Increase speed |
AnnaBridge | 0:c0ff9a7daaac | 153 | limit -= SPEEDUP; |
AnnaBridge | 0:c0ff9a7daaac | 154 | level_up(); |
AnnaBridge | 0:c0ff9a7daaac | 155 | } |
AnnaBridge | 0:c0ff9a7daaac | 156 | buttonPress = NONE; |
AnnaBridge | 0:c0ff9a7daaac | 157 | display_letter(); |
AnnaBridge | 0:c0ff9a7daaac | 158 | } |
AnnaBridge | 0:c0ff9a7daaac | 159 | else |
AnnaBridge | 0:c0ff9a7daaac | 160 | { |
AnnaBridge | 0:c0ff9a7daaac | 161 | game_over(); |
AnnaBridge | 0:c0ff9a7daaac | 162 | uBit.sleep(1000); |
AnnaBridge | 0:c0ff9a7daaac | 163 | start(); |
AnnaBridge | 0:c0ff9a7daaac | 164 | } |
AnnaBridge | 0:c0ff9a7daaac | 165 | |
AnnaBridge | 0:c0ff9a7daaac | 166 | } |
AnnaBridge | 0:c0ff9a7daaac | 167 | |
AnnaBridge | 0:c0ff9a7daaac | 168 | void onButtonA(MicroBitEvent e) |
AnnaBridge | 0:c0ff9a7daaac | 169 | { |
AnnaBridge | 0:c0ff9a7daaac | 170 | if (e.value == MICROBIT_BUTTON_EVT_CLICK) |
AnnaBridge | 0:c0ff9a7daaac | 171 | { |
AnnaBridge | 0:c0ff9a7daaac | 172 | unsigned long delay = uBit.systemTime() - time_val; |
AnnaBridge | 0:c0ff9a7daaac | 173 | buttonPress = VOWEL; |
AnnaBridge | 0:c0ff9a7daaac | 174 | check_press(delay); |
AnnaBridge | 0:c0ff9a7daaac | 175 | } |
AnnaBridge | 0:c0ff9a7daaac | 176 | } |
AnnaBridge | 0:c0ff9a7daaac | 177 | |
AnnaBridge | 0:c0ff9a7daaac | 178 | void onButtonB(MicroBitEvent e) |
AnnaBridge | 0:c0ff9a7daaac | 179 | { |
AnnaBridge | 0:c0ff9a7daaac | 180 | if (e.value == MICROBIT_BUTTON_EVT_CLICK) |
AnnaBridge | 0:c0ff9a7daaac | 181 | { |
AnnaBridge | 0:c0ff9a7daaac | 182 | unsigned long delay = uBit.systemTime() - time_val; |
AnnaBridge | 0:c0ff9a7daaac | 183 | buttonPress = CONSONANT; |
AnnaBridge | 0:c0ff9a7daaac | 184 | check_press(delay); |
AnnaBridge | 0:c0ff9a7daaac | 185 | } |
AnnaBridge | 0:c0ff9a7daaac | 186 | |
AnnaBridge | 0:c0ff9a7daaac | 187 | } |
AnnaBridge | 0:c0ff9a7daaac | 188 | |
AnnaBridge | 0:c0ff9a7daaac | 189 | |
AnnaBridge | 0:c0ff9a7daaac | 190 | int main() |
AnnaBridge | 0:c0ff9a7daaac | 191 | { |
AnnaBridge | 0:c0ff9a7daaac | 192 | |
AnnaBridge | 0:c0ff9a7daaac | 193 | // Initialise the micro:bit runtime. |
AnnaBridge | 0:c0ff9a7daaac | 194 | uBit.init(); |
AnnaBridge | 0:c0ff9a7daaac | 195 | |
AnnaBridge | 0:c0ff9a7daaac | 196 | // Set up button event handlers |
AnnaBridge | 0:c0ff9a7daaac | 197 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_EVT_ANY, onButtonB); |
AnnaBridge | 0:c0ff9a7daaac | 198 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_EVT_ANY, onButtonA); |
AnnaBridge | 0:c0ff9a7daaac | 199 | |
AnnaBridge | 0:c0ff9a7daaac | 200 | start(); |
AnnaBridge | 0:c0ff9a7daaac | 201 | while(1) |
AnnaBridge | 0:c0ff9a7daaac | 202 | { |
AnnaBridge | 0:c0ff9a7daaac | 203 | uBit.sleep(100); |
AnnaBridge | 0:c0ff9a7daaac | 204 | } |
AnnaBridge | 0:c0ff9a7daaac | 205 | |
AnnaBridge | 0:c0ff9a7daaac | 206 | // If main exits, there may still be other fibers running or registered event handlers etc. |
AnnaBridge | 0:c0ff9a7daaac | 207 | // Simply release this fiber, which will mean we enter the scheduler. Worse case, we then |
AnnaBridge | 0:c0ff9a7daaac | 208 | // sit in the idle task forever, in a power efficient sleep. |
AnnaBridge | 0:c0ff9a7daaac | 209 | release_fiber(); |
AnnaBridge | 0:c0ff9a7daaac | 210 | } |