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

Game.cpp

Committer:
co838_gtvl2
Date:
2016-02-17
Revision:
2:9e0c826103d7
Parent:
1:c6734b909bf0

File content as of revision 2:9e0c826103d7:

/**
 *  Basic game using accelerometer. You must avoid Asteroids coming on your ship.
 *  Won't work because C++'s lists memory management sucks.  :(
 **/

#include "Game.h"

#if defined _DEBUG
Serial host(USBTX, USBRX);      // Serial Host
#endif

Game::Game()
    :   thread(&Game::threader, this, osPriorityNormal,1024),
        mutex(),
        boost(D4)
{
#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->score = 0;
    this->next = 0;
    this->delta = 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);
    srand(time(NULL));
}

Game::~Game()
{
    this->thread.terminate();
    this->accel->disable();
    this->display();
    this->lcd->rect(this->player->getX() - 2, this->player->getY() - 2, this->player->getX() + 3, this->player->getY() + 3, 1);
    this->lcd->locate(0, 0);
    this->lcd->printf("GAME OVER\r\nScore: %d\r\n", this->score);
    this->lcd->copy_to_lcd();
    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();
        ++this->score;
        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->mutex.lock(100);
        this->player->move(-raX, raY - this->steadyPosition);
        this->mutex.unlock();
        Thread::wait(this->boost ? DELTA_TIME / 2 : DELTA_TIME);
    }
}

void    Game::process()
{
    this->factory();
#if defined _DEBUG
    // host.printf("Currently %d Asteroid(s).\r\n", this->asteroids.size());
#endif
    this->move();
}

void    Game::factory()
{
    ++this->delta;
#if defined _DEBUG
    // host.printf("=> [%c] next asteroid in %d/%d cycle(s).\r\n", this->delta >= this->next ? '1' : '0', this->delta, this->next);
#endif
    if (this->delta >= this->next && (MAX_ASTEROID_NBS != 0 ? this->asteroids.size() <= MAX_ASTEROID_NBS : true)) {
        this->generate();
        this->next = rand() % GENERATION_CYCLES + 1;
        this->delta = 0;
    }
}

void    Game::generate()
{
    this->asteroids.push_front(new Asteroid());
}

void    Game::move()
{
    this->mutex.lock(100);
    std::list<Asteroid*>::iterator it = this->asteroids.begin();
    while (it != this->asteroids.end()) {
        if (!(*it)->move(this->player)) {
            delete *this->asteroids.end();
            this->asteroids.pop_back();
            break;
        } else {
            ++it;
        }
    }
    this->mutex.unlock();
}

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();
}