diff --git a/source/main.cpp b/source/main.cpp index 42d8caaa8ff2b1b6b3c64328d50d8f7f3134fbda..14cf50b4aa5e62b7a45e05c07ee8a3427af46337 100755 --- a/source/main.cpp +++ b/source/main.cpp @@ -18,27 +18,117 @@ #include "MicroBit.h" +/** + * @brief Main class responsible for the game loop and logic + */ class Game { public: + /** + * @brief Constructor + * @details takes reference to the micro-bit instance for the sake of not + * using global variables. + */ Game(MicroBit& micro_bit); + /** + * @brief Starts a new run of the game + * @note method blocks until game over. + */ void run(); + /* begin event handler methods */ + + /** + * Handles Button A Press event + */ + void press_button_a(MicroBitEvent e); + + /** + * Handles Button B Press event + */ + void press_button_b(MicroBitEvent e); + + /* end event handler methods */ + private: + /** + * @brief Draws whatever's in the screen buffer to display + */ + void draw(); + + // reference to our MicroBit instance MicroBit& micro_bit; + // internal screen-buffer, which we draw to first before pasting to display + MicroBitImage screen_buffer; }; Game::Game(MicroBit& micro_bit) : micro_bit(micro_bit) - {} + , screen_buffer(5, 5) // our screen buffer mirrors the display dimensions +{} void Game::run() { - this->micro_bit.display.scroll("NEW GAME"); + this->micro_bit.display.scroll("NEW GAME!"); + // init screen display mode, to be sure it is in a known-state + // TODO: consider changing to greyscale to allow "mutli-coloured" blocks + this->micro_bit.display.setDisplayMode(DISPLAY_MODE_BLACK_AND_WHITE); + // register event-handlers + this->micro_bit.messageBus.listen( + MICROBIT_ID_BUTTON_A, + MICROBIT_BUTTON_EVT_CLICK, + this, + &Game::press_button_a + ); + this->micro_bit.messageBus.listen( + MICROBIT_ID_BUTTON_B, + MICROBIT_BUTTON_EVT_CLICK, + this, + &Game::press_button_b + ); + while (true) { // TODO: change to use game-over condition + this->draw(); // render screen buffer + // sleep to conserve CPU cycles and allow other fibers a chance to run + this->micro_bit.sleep(50); // a 50ms sleep gives us a 20Hz tick-rate + } + // TODO: add the rest of the game logic + this->micro_bit.display.scroll("GAME OVER!"); + // TODO: display final score + // TODO: de-register event-handlers + this->micro_bit.messageBus.ignore( + MICROBIT_ID_BUTTON_A, + MICROBIT_BUTTON_EVT_CLICK, + this, + &Game::press_button_a + ); + this->micro_bit.messageBus.ignore( + MICROBIT_ID_BUTTON_B, + MICROBIT_BUTTON_EVT_CLICK, + this, + &Game::press_button_b + ); } +void Game::draw() { + // XXX: debug drawing, fill the screen buffer with black + this->screen_buffer.clear(); + // render our screen buffer + this->micro_bit.display.image.paste(this->screen_buffer); +} + +void Game::press_button_a(MicroBitEvent e) { + // XXX: debug + this->screen_buffer.setPixelValue(0, 2, 255); +} + +void Game::press_button_b(MicroBitEvent e) { + // XXX: debug + this->screen_buffer.setPixelValue(4, 2, 255); +} + + MicroBit micro_bit; -int main(void) { +int main() { // Initialise the micro:bit runtime. micro_bit.init();