Basic game using accelerometer and LCD screen. You can move and dodge asteroids coming from both left and right. There is no scoring at the moment.

Dependencies:   C12832 FXOS8700Q mbed-rtos mbed

Files at this revision

API Documentation at this revision

Comitter:
co838_gtvl2
Date:
Mon Feb 15 18:18:16 2016 +0000
Child:
1:c6734b909bf0
Commit message:
Basic game, you can move using accelerometer and avoid asteroids coming from both left and right.

Changed in this revision

Asteroid.cpp Show annotated file Show diff for this revision Revisions of this file
Asteroid.h Show annotated file Show diff for this revision Revisions of this file
C12832.lib Show annotated file Show diff for this revision Revisions of this file
FXOS8700Q.lib Show annotated file Show diff for this revision Revisions of this file
Game.cpp Show annotated file Show diff for this revision Revisions of this file
Game.h Show annotated file Show diff for this revision Revisions of this file
Player.cpp Show annotated file Show diff for this revision Revisions of this file
Player.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
main.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Asteroid.cpp	Mon Feb 15 18:18:16 2016 +0000
@@ -0,0 +1,47 @@
+#include "Asteroid.h"
+
+Asteroid::Asteroid(const int &nb)
+{
+    this->number = nb;
+    this->a = static_cast<float>(rand()) / (static_cast<float>(RAND_MAX)) - 0.5f;
+    this->b = rand() % DISPLAY_Y;
+    if (rand() % 2 == 1) {
+        this->x = 0;
+        this->inc = 1;
+    } else {
+        this->x = DISPLAY_X;
+        this->inc = -1;
+    }
+}
+
+bool    Asteroid::move(Player *player)
+{
+    this->x += this->inc;
+    if ((this->getX() == player->getX() || this->getX() == player->getX() + 1) && 
+        (this->getY() == player->getY() || this->getY() == player->getY() + 1)) {
+        player->die();   
+    }
+    if (this->inc == 1 && this->x == DISPLAY_X + 1) {
+        return false;
+    } else if (this->inc == -1 && this->x == -1) {
+        return false;
+    } else {
+        return true;
+    }
+}
+
+int     Asteroid::getX() const
+{
+    return x;
+}
+
+int     Asteroid::getY() const
+{
+    return static_cast<int>(this->a * this->x + this->b);
+}
+
+int     Asteroid::getNumber() const
+{
+    return this->number;    
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Asteroid.h	Mon Feb 15 18:18:16 2016 +0000
@@ -0,0 +1,23 @@
+#ifndef _ASTEROID_H_
+# define _ASTEROID_H_
+
+# include "main.h"
+# include "Player.h"
+
+class Asteroid
+{
+public:
+    Asteroid(const int&);
+    int         getX() const;
+    int         getY() const;
+    int         getNumber() const;
+    bool        move(Player*);
+private:
+    int         number;
+    int         inc;    // -1 / +1
+    int         x;      // 127=>0 / 0=>127
+    float       a;      // [A] * x + b
+    int         b;      // a * x + [B]
+};
+
+#endif /* _ASTEROID_H_ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C12832.lib	Mon Feb 15 18:18:16 2016 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/chris/code/C12832/#7de323fa46fe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FXOS8700Q.lib	Mon Feb 15 18:18:16 2016 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/JimCarver/code/FXOS8700Q/#5553a64d0762
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Game.cpp	Mon Feb 15 18:18:16 2016 +0000
@@ -0,0 +1,105 @@
+#include "Game.h"
+
+#if defined _DEBUG
+Serial host(USBTX, USBRX);      // Serial Host
+#endif
+
+Game::Game()
+    : _thread(&Game::threader, this, osPriorityNormal,1024)
+{
+#if defined _DEBUG
+    host.baud(38400);
+#endif
+    this->player = new Player();
+    this->lcd = new C12832(D11, D13, D12, D7, D10);
+    this->lcd->set_auto_up(0);
+
+    this->accel = new FXOS8700Q_acc(PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1);
+    this->accel->enable();
+    this->accel->getY(&this->steadyPosition);
+    this->asteroids = std::list<Asteroid*>();
+    this->_thread.signal_set(START_THREAD);
+}
+
+Game::~Game()
+{
+    this->accel->disable();
+    this->_thread.terminate();
+    this->lcd->rect(this->player->getX() - 2, this->player->getY() - 2, this->player->getX() + 3, this->player->getY() + 3, 1);
+    this->lcd->copy_to_lcd();
+    this->lcd->locate(0, 0);
+    this->lcd->printf("GAME OVER");
+    delete this->player;
+    delete this->accel;
+    delete this->lcd;
+}
+
+void    Game::threader(void const *p)
+{
+    Game *instance = (Game*) p;
+    instance->watchAccel();
+}
+
+void    Game::loop()
+{
+    while (this->player->isAlive()) {
+        this->process();
+        this->display();
+        Thread::wait(DELTA_TIME);
+    }
+}
+
+void    Game::watchAccel()
+{
+    this->_thread.signal_wait(START_THREAD);
+    while (true) {
+        int16_t raX, raY;
+        this->accel->getX(&raX);
+        this->accel->getY(&raY);
+        this->player->move(-raX, raY - this->steadyPosition);
+        Thread::wait(DELTA_TIME);
+    }
+}
+
+void    Game::process()
+{
+    static int delta = 0;
+    static int next = rand() % 6;
+    if (delta >= next) {
+        this->generate();
+        next = rand() % 6;
+        delta = 0;
+    }
+    ++delta;
+    
+    std::list<Asteroid*>::iterator it;
+    
+    for (it = this->asteroids.begin(); it != this->asteroids.end(); it++) {
+        if (!(*it)->move(this->player)) {
+            #if defined _DEBUG
+            host.printf("Erasing Asteroid #%d !\r\n", (*it)->getNumber());
+            #endif 
+            it = this->asteroids.erase(it);
+        }
+    }
+}
+
+void    Game::generate()
+{
+    static int current = 0;
+    this->asteroids.push_back(new Asteroid(++current));
+    #if defined _DEBUG
+        host.printf("New Asteroid #%d !\r\n", current);
+    #endif
+}
+
+void    Game::display()
+{
+    this->lcd->cls();
+    std::list<Asteroid*>::iterator it;
+    for (it = this->asteroids.begin(); it != this->asteroids.end(); it++) {
+        this->lcd->pixel((*it)->getX(), (*it)->getY(), 1);    
+    } 
+    this->lcd->rect(this->player->getX(), this->player->getY(), this->player->getX() + 1, this->player->getY() + 1, 1);
+    this->lcd->copy_to_lcd();
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Game.h	Mon Feb 15 18:18:16 2016 +0000
@@ -0,0 +1,31 @@
+#ifndef _GAME_H_
+# define _GAME_H_
+
+# include "main.h"
+# include "Player.h"
+# include "Asteroid.h"
+
+# include <list>
+# include <iterator>
+
+class Game
+{
+public:
+    Game();
+    ~Game();
+    static void             threader(void const *p);
+    void                    loop();
+    void                    watchAccel();
+    void                    display();
+    void                    process();
+    void                    generate();
+private:
+    Player                  *player;
+    Thread                  _thread;
+    C12832                  *lcd;
+    FXOS8700Q_acc           *accel;
+    int16_t                 steadyPosition;
+    std::list<Asteroid*>    asteroids;
+};
+
+#endif /* _GAME_H_ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Player.cpp	Mon Feb 15 18:18:16 2016 +0000
@@ -0,0 +1,52 @@
+#include "Player.h"
+
+Player::Player()
+{
+    this->x = DISPLAY_X / 2;
+    this->y = DISPLAY_Y / 2;
+    this->alive = true;
+}
+
+bool    Player::move(const int &x, const int &y)
+{
+    bool okMove = true;
+    float newX = this->x + static_cast<float>(x) / DELTA_MOVE;
+    float newY = this->y + static_cast<float>(y) / DELTA_MOVE;
+
+    // TODO, opti this but clearer at the moment
+    if (newX < 0 || newY < 0) {
+        newX = (newX < 0 ? 0 : newX);
+        newY = (newY < 0 ? 0 : newY);
+        okMove = false;
+    }
+
+    if (newX > DISPLAY_X - 1 || newY > DISPLAY_Y - 1) {
+        newX = (newX > DISPLAY_X - 1 ? DISPLAY_X - 1 : newX);
+        newY = (newY > DISPLAY_Y - 1 ? DISPLAY_Y - 1 : newY);
+        okMove = false;
+    }
+
+    this->x = newX;
+    this->y = newY;
+    return okMove;
+}
+
+bool    Player::die()
+{
+    this->alive = false;
+}
+
+bool    Player::isAlive() const
+{
+    return this->alive;   
+}
+
+int     Player::getX() const
+{
+    return static_cast<int>(this->x);
+}
+
+int     Player::getY() const
+{
+    return static_cast<int>(this->y);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Player.h	Mon Feb 15 18:18:16 2016 +0000
@@ -0,0 +1,21 @@
+#ifndef _PLAYER_H_
+# define _PLAYER_H_
+
+# include "main.h"
+
+class Player
+{
+public:
+    Player();
+    bool        move(const int&, const int&);
+    bool        die();
+    int         getX() const;
+    int         getY() const;
+    bool        isAlive() const;
+private:
+    float       x;
+    float       y;
+    bool        alive;
+};
+
+#endif /* _PLAYER_H_ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Feb 15 18:18:16 2016 +0000
@@ -0,0 +1,8 @@
+#include "Game.h"
+
+int main(void)
+{
+    Game *g = new Game();
+    g->loop(); 
+    delete g;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.h	Mon Feb 15 18:18:16 2016 +0000
@@ -0,0 +1,18 @@
+#ifndef _MAIN_H_
+# define _MAIN_H_
+
+# include "mbed.h"
+# include "rtos.h"
+# include "C12832.h"
+# include "FXOS8700Q.h"
+
+# define DISPLAY_X 127
+# define DISPLAY_Y 31
+# define DELTA_MOVE 1000.0f
+# define DELTA_TIME 100
+# define START_THREAD 999
+
+// # define _DEBUG
+# undef _DEBUG
+
+#endif /* _MAIN_H_ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Mon Feb 15 18:18:16 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-rtos/#f62a48e9da94
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Feb 15 18:18:16 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/f141b2784e32
\ No newline at end of file