//Copyright (C) 16.03.2024, Kirill ZHivotkov
/*
Эта программа - Demo-версия гоночной игры на дисплее 8x32 LED Dot Matrix MAX7219.
Для запуска необходимо нажать центральную кнопку джойстика.
Далее использовать направления джойстика для обхода
движущихся препятствий. Игра заканчивается при
столкновении с одним из препятствий. Игра снабжена
звуковым модулем.
*/
#include "MD_MAXPanel.h"
#include "pitches.h"
//Maximum number of a gamefield tiles (4 matrix segments 8 x 8)
const uint8_t MAX_SEG = 4;
//Maximum number of a gamefield tiles (4 matrix segments 8 x 8)
//One gamefield tile size (8 x 8)
const uint8_t SIZE = 8;
//One gamefield tile size (8 x 8)
//Player size
const uint8_t CAR_ROWS = 3;
const uint8_t CAR_COLS = 4;
//Player size
//Player speed
const uint8_t CAR_SPEED = 50;
//Player speed
//Number of blinks after collision
const uint8_t CAR_BLINK = 3;
//Number of blinks after collision
//Obstacle size
const uint8_t OBSTACLE_ROWS = 2;
const uint8_t OBSTACLE_COLS = 1;
//Obstacle size
//Number of enemies (LEVEL 1 - DEMO)
const uint8_t LEVEL_1_QTY = 10;
//Number of enemies (LEVEL 1 - DEMO)
//Buzzer pin (sound)
const uint8_t BUZZER_PIN = 8;
//Buzzer pin (sound)
//Create a class instance (32 x 8 gamefield)
const MD_MAX72XX::moduleType_t HARDWARE_TYPE = MD_MAX72XX::PAROLA_HW;
const uint8_t X_DEVICES = 4;
const uint8_t Y_DEVICES = 1;
const uint8_t CLK_PIN = 12; // or SCK
const uint8_t DATA_PIN = 11; // or MOSI
const uint8_t CS_PIN = 10; // or SS
MD_MAXPanel mx = MD_MAXPanel(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, X_DEVICES, Y_DEVICES);
//Create a class instance (32 x 8 gamefield)
//Implement class "Sound" (for a game)
class Sound {
private:
//Private class members
int frequency;
int duration;
//Private class members
//Game start melody
int gameStartMelodyNotes[4 * SIZE - 1] = { NOTE_B4, NOTE_B5, NOTE_FS5, NOTE_DS5, NOTE_B5, NOTE_FS5, NOTE_DS5, NOTE_C5, NOTE_C6, NOTE_G6, NOTE_E6, NOTE_C6, NOTE_G6, NOTE_E6, NOTE_B4, NOTE_B5, NOTE_FS5, NOTE_DS5, NOTE_B5, NOTE_FS5, NOTE_DS5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_B5 };
int gameStartMelodyNotesDurations[4 * SIZE - 1] = { 4, 4, 4, 4, 8, 6, 2, 4, 4, 4, 4, 8, 8, 2, 4, 4, 4, 4, 8, 8, 2, 8, 8, 8, 8, 8, 8, 8, 8, 4, 2 };
//Game start melody
public:
//Setters
void setSoundFrequency(int frequency) {
this->frequency = frequency;
}
void setSoundDuration(int duration) {
this->duration = duration;
}
//Setters
//Getters
int getSoundFrequency() {
return this->frequency;
}
int getSoundDuration() {
return this->duration;
}
//Getters
//Declare methods prototypes for this class
void carObstacleCollisionSound();
void carMovementSound();
void playGameStartPushSound();
void playGameStartMelody();
//Declare methods prototypes for this class
//Default constructor
Sound() {};
//Default constructor
//Destructor
~Sound() {};
//Destructor
};
//Implement class "Sound" (for a game)
Sound* snd = new Sound();
//Play a sound when the car collides
void Sound::carObstacleCollisionSound() {
this->setSoundFrequency(100);
this->setSoundDuration(2000);
tone(BUZZER_PIN, this->getSoundFrequency(), this->getSoundDuration());
}
//Play a sound when the car collides
//Play a sound when the car moves
void Sound::carMovementSound() {
this->setSoundFrequency(50);
this->setSoundDuration(50);
tone(BUZZER_PIN, this->getSoundFrequency(), this->getSoundDuration());
}
//Play a sound when the car moves
//Play a sound when the game starts
void Sound::playGameStartPushSound() {
this->setSoundFrequency(250);
this->setSoundDuration(100);
tone(BUZZER_PIN, this->getSoundFrequency(), this->getSoundDuration());
}
//Play a sound when the game starts
//Play game start melody
void Sound::playGameStartMelody() {
for (int note = 0; note < 4 * SIZE - 1; note++) {
int noteDuration = 1000 / this->gameStartMelodyNotesDurations[note];
tone(BUZZER_PIN, this->gameStartMelodyNotes[note], noteDuration);
int pauseBetweenNotes = noteDuration * 1.4;
delay(pauseBetweenNotes);
//Exit from splash screen melody
if (analogRead(A2) == 0) {
noTone(BUZZER_PIN);
break;
}
//Exit from splash screen melody
}
}
//Play game start melody
//Implement class "ScreenText" (to output text on the screen)
class ScreenText {
private:
//Private class members
//Private class members
public:
//Setters
//Setters
//Getters
//Getters
//Declare methods prototypes for this class
void showGameSplashScreen();
void hideGameSplashScreen();
//Declare methods prototypes for this class
//Default constructor
ScreenText() {};
//Default constructor
//Destructor
~ScreenText() {};
//Destructor
};
//Implement class "ScreenText" (to output text on the screen)
ScreenText* scrn = new ScreenText();
void ScreenText::showGameSplashScreen() {
//Frame
for (uint8_t i = 1; i < SIZE; i++) {
mx.setPoint(0, i, 1);
}
for (uint8_t i = 1; i < SIZE; i++) {
mx.setPoint(SIZE * 4 - 1, i, 1);
}
for (uint8_t i = 0; i < 4 * SIZE; i++) {
mx.setPoint(i, 0, 1);
}
//Frame
//L
mx.setPoint(2, 6, 1);
mx.setPoint(2, 5, 1);
mx.setPoint(2, 4, 1);
mx.setPoint(2, 3, 1);
mx.setPoint(2, 2, 1);
mx.setPoint(3, 2, 1);
mx.setPoint(4, 2, 1);
mx.setPoint(4, 3, 1);
//L
//E
mx.setPoint(6, 6, 1);
mx.setPoint(6, 5, 1);
mx.setPoint(6, 4, 1);
mx.setPoint(6, 3, 1);
mx.setPoint(6, 2, 1);
mx.setPoint(7, 6, 1);
mx.setPoint(8, 6, 1);
mx.setPoint(7, 4, 1);
mx.setPoint(8, 4, 1);
mx.setPoint(7, 2, 1);
mx.setPoint(8, 2, 1);
//E
//D
mx.setPoint(10, 6, 1);
mx.setPoint(10, 5, 1);
mx.setPoint(10, 4, 1);
mx.setPoint(10, 3, 1);
mx.setPoint(10, 2, 1);
mx.setPoint(11, 6, 1);
mx.setPoint(11, 2, 1);
mx.setPoint(12, 5, 1);
mx.setPoint(12, 4, 1);
mx.setPoint(12, 3, 1);
//D
//R
mx.setPoint(15, 6, 1);
mx.setPoint(15, 5, 1);
mx.setPoint(15, 4, 1);
mx.setPoint(15, 3, 1);
mx.setPoint(15, 2, 1);
mx.setPoint(16, 6, 1);
mx.setPoint(17, 5, 1);
mx.setPoint(17, 4, 1);
mx.setPoint(17, 2, 1);
mx.setPoint(16, 3, 1);
//R
//A
mx.setPoint(19, 5, 1);
mx.setPoint(19, 4, 1);
mx.setPoint(19, 3, 1);
mx.setPoint(19, 2, 1);
mx.setPoint(21, 5, 1);
mx.setPoint(21, 4, 1);
mx.setPoint(21, 3, 1);
mx.setPoint(21, 2, 1);
mx.setPoint(20, 6, 1);
mx.setPoint(20, 4, 1);
//A
//C
mx.setPoint(23, 5, 1);
mx.setPoint(23, 4, 1);
mx.setPoint(23, 3, 1);
mx.setPoint(24, 6, 1);
mx.setPoint(25, 6, 1);
mx.setPoint(24, 2, 1);
mx.setPoint(25, 2, 1);
//C
//E
mx.setPoint(27, 6, 1);
mx.setPoint(27, 5, 1);
mx.setPoint(27, 4, 1);
mx.setPoint(27, 3, 1);
mx.setPoint(27, 2, 1);
mx.setPoint(28, 6, 1);
mx.setPoint(29, 6, 1);
mx.setPoint(28, 4, 1);
mx.setPoint(29, 4, 1);
mx.setPoint(28, 2, 1);
mx.setPoint(29, 2, 1);
//E
}
void ScreenText::hideGameSplashScreen() {
mx.clear();
}
//Implement class "Obstacle" (enemy)
class Obstacle {
private:
//Private class members
uint8_t x = 0;
uint8_t y = 0;
float speed = 0.0;
//Obstacle skeleton
uint8_t obstacle[OBSTACLE_ROWS][OBSTACLE_COLS] = {{1},
{1}};
//Obstacle skeleton
//Obstacle vars
Obstacle* obs;
float timeIntervalSpeed;
float timeIntervalCreate;
uint8_t maximumDistance;
uint8_t coveredDistance;
uint8_t randomPosition;
uint8_t maximumVisible;
int extraTime;
bool attackEnd;
//Obstacle vars
//Private class members
public:
//Setters
void setPosX(uint8_t x) {
this->x = x;
}
void setPosY(uint8_t y) {
this->y = y;
}
void setTimeIntervalSpeed(float timeIntervalSpeed) {
this->timeIntervalSpeed = timeIntervalSpeed;
}
void setTimeIntervalCreate(float timeIntervalCreate) {
this->timeIntervalCreate = timeIntervalCreate;
}
void setMaximumDistance(uint8_t maximumDistance) {
this->maximumDistance = maximumDistance;
}
void setCoveredDistance(uint8_t coveredDistance) {
this->coveredDistance = coveredDistance;
}
void setRandomPosition(uint8_t randomPosition) {
this->randomPosition = randomPosition;
}
void setObstacleArray(Obstacle* obs) {
this->obs = obs;
}
//Setters
//Getters
uint8_t getPosX() {
return this->x;
}
uint8_t getPosY() {
return this->y;
}
float getTimeIntervalSpeed() {
return this->timeIntervalSpeed;
}
float getTimeIntervalCreate() {
return this->timeIntervalCreate;
}
uint8_t getMaximumDistance() {
return this->maximumDistance;
}
uint8_t getCoveredDistance() {
return this->coveredDistance;
}
uint8_t getRandomPosition() {
return this->randomPosition;
}
Obstacle* getObstacleArray() {
return this->obs;
}
//Getters
//Declare methods prototypes for this class
void obstacleInit(uint8_t, uint8_t);
void obstacleRandomAttack(Obstacle*, int, int);
void obstacleClear(uint8_t, uint8_t);
void obstacleClear();
void obstacleConfig(Obstacle*);
uint8_t obstacleRandomPosition(uint8_t, uint8_t);
//Declare methods prototypes for this class
//Default constructor
Obstacle() {
this->maximumVisible = 1;
this->extraTime = 0;
this->attackEnd = false;
};
//Default constructor
//Destructor
~Obstacle() {};
//Destructor
};
//Implement class "Obstacle" (enemy)
//Create an instance of Obstacle class (enemy)
Obstacle* obs = new Obstacle[LEVEL_1_QTY];
//Create an instance of Obstacle class (enemy)
//Implement class "Player" (car)
class Player {
private:
//Private class members
uint8_t x;
uint8_t y;
float speed;
bool gameStart;
String carStatus;
//Player skeleton
uint8_t player[CAR_ROWS][CAR_COLS] = {{1, 0, 1, 0},
{1, 1, 1, 1},
{1, 0, 1, 0}};
//Player skeleton
//Private class members
public:
//Setters
void setPosX(uint8_t x) {
this->x = x;
}
void setPosY(uint8_t y) {
this->y = y;
}
void setCarSpeed(uint8_t speed) {
this->speed = speed;
}
void setCarSpeedNormalized(float speed) {
this->speed = sqrt(pow(speed, 2) + pow(speed, 2)) - speed;
}
void setCarDiagonalSpeed() {
if (this->getPosY() != 0 && this->getPosY() != SIZE - 3) {
this->setCarSpeedNormalized(CAR_SPEED);
} else {
this->setCarSpeed(CAR_SPEED);
}
}
void setCarStatus(String carStatus) {
this->carStatus = carStatus;
}
void setCarGameStart(bool gameStart) {
this->gameStart = gameStart;
}
//Setters
//Getters
uint8_t getPosX() {
return this->x;
}
uint8_t getPosY() {
return this->y;
}
float getCarSpeed() {
return this->speed;
}
String getCarStatus() {
return this->carStatus;
}
bool getCarGameStart() {
return this->gameStart;
}
//Getters
//Declare methods prototypes for this class
void carStartGame();
void carInit(uint8_t, uint8_t);
void carClear();
void carMove(uint8_t);
void carJoystick();
void carMoveControl();
void carMoveLeft();
void carMoveRight();
void carMoveDown();
void carMoveUp();
void carDetectCollision(Obstacle*, uint8_t, uint8_t, uint8_t, uint8_t);
void carBlinkAfterCollision(uint8_t, uint8_t);
//Declare methods prototypes for this class
//Default constructor
Player() {
this->x = 1;
this->y = 1;
this->speed = 0.0;
this->gameStart = false;
this->carStatus = "";
};
//Default constructor
//Destructor
~Player() {};
//Destructor
};
//Implement class "Player" (car)
//Create an instance of Player class (car)
Player* player = new Player();
//Create an instance of Player class (car)
//Set obstacles config (LEVEL 1 - DEMO)
void Obstacle::obstacleConfig(Obstacle* obs) {
mx.clear();
for (uint8_t i = 0; i < LEVEL_1_QTY; i++) {
obs[i].obstacleClear();
obs[i].setTimeIntervalSpeed(millis());
obs[i].setTimeIntervalCreate(millis());
obs[i].setCoveredDistance(0);
obs[i].setMaximumDistance(SIZE * MAX_SEG);
obs[i].setRandomPosition(obs[i].obstacleRandomPosition(0, SIZE - 1));
}
}
//Set obstacles config (LEVEL 1 - DEMO)
//Obstacle init (random spawn)
void Obstacle::obstacleInit(uint8_t x, uint8_t y) {
for (uint8_t i = 0; i < OBSTACLE_ROWS; i++) {
for (uint8_t j = 0; j < OBSTACLE_COLS; j++) {
if (obstacle[i][j] == 1) {
mx.setPoint(j + x, i + y, 1);
this->setPosX(x);
this->setPosY(y);
}
}
}
}
//Obstacle init (random spawn)
//Obstacle random position generation
uint8_t Obstacle::obstacleRandomPosition(uint8_t low, uint8_t high) {
static uint8_t r = random(low, high);
uint8_t rand = random(low, high - 1);
if (rand >= r) {
rand++;
}
r = rand;
return r;
}
//Obstacle random position generation
//Clear obstacle with coordinate arguments
void Obstacle::obstacleClear(uint8_t x, uint8_t y) {
for (uint8_t i = 0; i < OBSTACLE_ROWS; i++) {
for (uint8_t j = 0; j < OBSTACLE_COLS; j++) {
mx.setPoint(j + x, i + y, 0);
}
}
}
//Clear obstacle with coordinate arguments
//Clear obstacle without coordinate arguments
void Obstacle::obstacleClear() {
for (uint8_t i = 0; i < OBSTACLE_ROWS; i++) {
for (uint8_t j = 0; j < OBSTACLE_COLS; j++) {
mx.setPoint(j + this->getPosX(), i + this->getPosY(), 0);
}
}
}
//Clear obstacle without coordinate arguments
//Obstacles attack method (LEVEL 1 - DEMO)
void Obstacle::obstacleRandomAttack(Obstacle* obs, int speed, int frequency) {
if (player->getCarGameStart() == true) {
for (uint8_t j = 0; j < this->maximumVisible; j++) {
if (obs[j].getMaximumDistance() - obs[j].getCoveredDistance() >= 0) {
if (millis() - obs[j].getTimeIntervalSpeed() >= speed) {
obs[j].obstacleClear(obs[j].getPosX(), obs[j].getPosY());
obs[j].obstacleInit(obs[j].getMaximumDistance() - obs[j].getCoveredDistance(), obs[j].getRandomPosition());
obs[j].setCoveredDistance(obs[j].getCoveredDistance() + 1);
obs[j].setTimeIntervalSpeed(millis());
//Process player collision with an obstacle
obs->setObstacleArray(obs);
if (player->getCarStatus() == "COLLIDED") {
player->setCarStatus("");
//obs[j].obstacleClear(obs[j].getPosX(), obs[j].getPosY());
//Set obstacles config (LEVEL 1 - DEMO)
obs->obstacleConfig(obs);
//Set obstacles config (LEVEL 1 - DEMO)
this->maximumVisible = 1;
break;
}
//Process player collision with an obstacle
}
//Detect collision
Obstacle* tmp = obs->getObstacleArray();
player->carDetectCollision(tmp, player->getPosX(), tmp[j].getPosX(), player->getPosY(), tmp[j].getPosY());
//Detect collision
} else {
obs[j].obstacleClear(obs[j].getPosX(), obs[j].getPosY());
}
finish: if (millis() - obs[j].getTimeIntervalCreate() >= (frequency + this->extraTime)) {
//Serial.println(this->maximumVisible);
extraTime = 0;
if (this->maximumVisible == LEVEL_1_QTY) {
if (this->attackEnd == false) {
this->extraTime = 5000;
this->attackEnd = true;
goto finish;
} else {
//Set obstacles config (LEVEL 1 - DEMO)
obs->obstacleConfig(obs);
//Set obstacles config (LEVEL 1 - DEMO)
this->maximumVisible = 1;
break;
}
}
this->maximumVisible++;
for (uint8_t i = 0; i < this->maximumVisible; i++) {
obs[i].setTimeIntervalCreate(millis());
}
this->extraTime = 0;
this->attackEnd = false;
}
}
}
}
//Obstacles attack method (LEVEL 1 - DEMO)
//Hide player for each coord
void Player::carClear() {
for (uint8_t i = 0; i < CAR_ROWS; i++) {
for (uint8_t j = 0; j < CAR_COLS; j++) {
mx.setPoint(j + this->getPosX(), i + this->getPosY(), 0);
}
}
}
//Hide player for each coord
//Player initial position
void Player::carInit(uint8_t x, uint8_t y) {
for (uint8_t i = 0; i < CAR_ROWS; i++) {
for (uint8_t j = 0; j < CAR_COLS; j++) {
if (player[i][j] == 1) {
mx.setPoint(j + x, i + y, 1);
}
}
}
}
//Player initial position
//Player blink after collision
void Player::carBlinkAfterCollision(uint8_t x, uint8_t y) {
for (uint8_t k = 1; k <= CAR_BLINK; k++) {
//One blink after collision
for (uint8_t i = 0; i < CAR_ROWS; i++) {
for (uint8_t j = 0; j < CAR_COLS; j++) {
if (player[i][j] == 1) {
mx.setPoint(j + x, i + y, 0);
}
}
}
delay(500);
for (uint8_t i = 0; i < CAR_ROWS; i++) {
for (uint8_t j = 0; j < CAR_COLS; j++) {
if (player[i][j] == 1) {
mx.setPoint(j + x, i + y, 1);
}
}
}
delay(500);
//One blink after collision
}
}
//Player blink after collision
//Car move control method
void Player::carMove(uint8_t speed) {
//Show player
this->carInit(this->getPosX(), this->getPosY());
//Show player
//Delay between movements
delay(this->getCarSpeed());
//Delay between movements
}
//Car move control method
//Move to the left
void Player::carMoveLeft() {
if (this->getPosX() >= 1) {
this->carClear();
this->setPosX(this->getPosX() - 1);
snd->carMovementSound();
}
}
//Move to the left
//Move to the right
void Player::carMoveRight() {
if (this->getPosX() < MAX_SEG * SIZE - CAR_COLS) {
this->carClear();
this->setPosX(this->getPosX() + 1);
snd->carMovementSound();
}
}
//Move to the right
//Move upwards
void Player::carMoveUp() {
if (this->getPosY() >= 1) {
this->carClear();
this->setPosY(this->getPosY() - 1);
snd->carMovementSound();
}
}
//Move upwards
//Move downwards
void Player::carMoveDown() {
if (this->getPosY() < SIZE - CAR_ROWS) {
this->carClear();
this->setPosY(this->getPosY() + 1);
snd->carMovementSound();
}
}
//Move downwards
//Joystick method (player control)
void Player::carJoystick() {
int a = analogRead(A1);
int b = analogRead(A0);
//Set game start condition
if (analogRead(A2) == 0) {
snd->playGameStartPushSound();
scrn->hideGameSplashScreen();
this->setCarGameStart(true);
}
//Set game start condition
if (a >= 500 && a <= 600 && b >= 0 && b <= 100) { //right
this->setCarSpeed(CAR_SPEED);
this->carMoveRight();
}
if (a >= 500 && a <= 600 && b >= 600 && b <= 1023) { //left
this->setCarSpeed(CAR_SPEED);
this->carMoveLeft();
}
if (b >= 500 && b <= 600 && a >= 0 && a <= 100) { //up
this->setCarSpeed(CAR_SPEED);
this->carMoveUp();
}
if (b >= 500 && b <= 600 && a >= 600 && a <= 1023) { //down
this->setCarSpeed(CAR_SPEED);
this->carMoveDown();
}
if (a >= 0 && a <= 100 && b >= 0 && b <= 100) { //up and right
this->setCarDiagonalSpeed();
this->carMoveUp();
this->carMoveRight();
}
if (b >= 0 && b <= 100 && a >= 600 && a <= 1023) { //down and right
this->setCarDiagonalSpeed();
this->carMoveDown();
this->carMoveRight();
}
if (a >= 0 && a <= 100 && b >= 600 && b <= 1023) { //up and left
this->setCarDiagonalSpeed();
this->carMoveUp();
this->carMoveLeft();
}
if (a >= 600 && a <= 1023 && b >= 600 && b <= 1023) { //down and left
this->setCarDiagonalSpeed();
this->carMoveDown();
this->carMoveLeft();
}
}
//Joystick method (player control)
//Player control method
void Player::carMoveControl() {
//this->carJoystick();
this->setCarSpeed(CAR_SPEED);
this->carMove(this->getCarSpeed());
}
//Player control method
//Check if the player collides with an obstacle
void Player::carDetectCollision(Obstacle* obs, uint8_t x1, uint8_t x2, uint8_t y1, uint8_t y2) {
bool carHasCollision = false;
for (uint8_t i1 = 0; i1 < CAR_ROWS; i1++) {
for (uint8_t j1 = 0; j1 < CAR_COLS; j1++) {
for (uint8_t i2 = 0; i2 < OBSTACLE_ROWS; i2++) {
for (uint8_t j2 = 0; j2 < OBSTACLE_COLS; j2++) {
if (j1 + x1 == j2 + x2 && i1 + y1 == i2 + y2 && this->player[i1][j1] == 1) {
obs->setPosX(-1);
obs->obstacleClear(x2, y2);
snd->carObstacleCollisionSound();
this->setCarStatus("COLLIDED");
this->carBlinkAfterCollision(x1, y1);
carHasCollision = true;
Serial.println("Game Over");
break;
}
}
if (carHasCollision == true) {
break;
}
}
if (carHasCollision== true) {
break;
}
}
if (carHasCollision == true) {
break;
}
}
}
//Check if the player collides an obstacle
//Implement class "GameManager" (to manage game options)
class GameManager {
private:
//Private class members
//Private class members
public:
//Setters
//Setters
//Getters
//Getters
//Declare methods prototypes for this class
void startGame();
//Declare methods prototypes for this class
//Default constructor
GameManager() {};
//Default constructor
//Destructor
~GameManager() {};
//Destructor
};
//Implement class "GameManager" (to manage game options)
//Create an instance of GameManager class
GameManager* gm = new GameManager();
//Create an instance of GameManager class
void GameManager::startGame() {
//Wait for select push to start the game
player->carJoystick();
//Wait for select push to start the game
//Splash screen melody
if (player->getCarGameStart() == false) {
scrn->showGameSplashScreen();
snd->playGameStartMelody();
obs->obstacleConfig(obs);
}
//Splash screen melody
//Game start
if (player->getCarGameStart() == true) {
player->carMoveControl();
obs->obstacleRandomAttack(obs, 150, 2000);
}
//Game start
}
//Application config
void setup() {
//Link joystick (player control)
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(A2, INPUT);
//Link joystick (player control)
//Link buzzer (sound)
pinMode(BUZZER_PIN, OUTPUT);
//Link buzzer (sound)
//Enable gamefield (32 x 8 matrix)
for (uint8_t index = 0; index < MAX_SEG; index++) {
mx.begin();
mx.setIntensity(0);
}
//Enable gamefield (32 x 8 matrix)
//Serial monitor
Serial.begin(2000000);
//Serial monitor
}
//Application config
//Game loop
void loop () {
gm->startGame();
}
//Game loop