A simple Pong game with STM32F407VET6 black board (Seeed Arch Max) and ILI9341 320x240 TFT display.
Dependencies: mbed ILI9341_STM32F4
A simple Pong game with STM32F407VET6 black board (compatible with Seed Arch Max) and ILI9341 320x240 TFT display.
Connect the SPI interface of an ILI9341 320x240 TFT display to the STM32F407VET6 board (Seeed Arch Max) as follows:
ILI9341 TFT | SPI interface | STM32F407VET6 |
---|---|---|
VCC | +5V | |
GND | GND | |
CS | PB_7 | |
RESET | PB_8 | |
D/C | PB_6 | |
SDI(MOSI) | PB_5 | |
SCK | PB_3 | |
LED | over a 56 ohm resistor | +5V |
SDO(MISO) | PB_4 |
Revision 1:971e721f6ef2, committed 2019-04-15
- Comitter:
- hudakz
- Date:
- Mon Apr 15 06:02:55 2019 +0000
- Parent:
- 0:887dd664eca0
- Commit message:
- Simple pong game updated.
Changed in this revision
diff -r 887dd664eca0 -r 971e721f6ef2 Ball.cpp --- a/Ball.cpp Thu Apr 11 20:18:15 2019 +0000 +++ b/Ball.cpp Mon Apr 15 06:02:55 2019 +0000 @@ -8,9 +8,31 @@ * @retval */ Ball::Ball(int s /*= 8*/, float v /*= 8*/, uint16_t clr /*= TFT_WHITE*/ ) : - size(s), velocity(v), gameOver(true), color(clr), xPos(320 / 2), yPos(240 / 2), xDir(-1), yDir(1) + size(s), + velocity(v), + color(clr), + xPos(320 / 2), + yPos(240 / 2), + xPosOld(320 / 2), + yPosOld(240 / 2), + xDir(-1), + yDir(1) +{ } + +/** + * @brief + * @note + * @param + * @retval + */ +void Ball::home() { - timeout.attach(callback(this, &Ball::newGame), 2); + xPos = 320 / 2; + yPos = 240 / 2; + xPosOld = xPos; + yPosOld = yPos; + xDir = -1; + yDir = 1; } /** @@ -21,9 +43,8 @@ */ bool Ball::move(Racket* rkt) { - if (gameOver) - return true; - + xPosOld = xPos; + yPosOld = yPos; xPos += xDir * velocity; yPos += yDir * velocity; @@ -45,9 +66,7 @@ yPos = 240 / 2; xDir = -1; yDir = 1; - gameOver = true; - tft_text(320/2 - 35, 240 / 2, "GAME OVER", TFT_WHITE, TFT_BLACK); - timeout.attach(callback(this, &Ball::newGame), 2); + return true; } // hit left wall? @@ -71,10 +90,7 @@ // make sure that length of dir stays at 1 vec2_norm(xDir, yDir); - // paint - //tft_boxfill(xPos - size / 2, yPos - size / 2, xPos - size / 2 + size, yPos - size / 2 + size, TFT_WHITE); - - return gameOver; + return false; } /** @@ -83,21 +99,10 @@ * @param * @retval */ -void Ball::newGame() +void Ball::paint() { - gameOver = false; - tft_text(320/2 - 35, 240 / 2, "GAME OVER", TFT_BLACK, TFT_BLACK); // hide the text -} - -/** - * @brief - * @note - * @param - * @retval - */ -void Ball::paint(uint16_t clr) -{ - tft_boxfill(xPos - size / 2, yPos - size / 2, xPos + size / 2, yPos + size / 2, clr); + tft_boxfill(xPosOld - size / 2, yPosOld - size / 2, xPosOld + size / 2, yPosOld + size / 2, TFT_BLACK); // hide ball at old position + tft_boxfill(xPos - size / 2, yPos - size / 2, xPos + size / 2, yPos + size / 2, TFT_WHITE); // draw ball at new position } /** @@ -108,7 +113,7 @@ */ void Ball::vec2_norm(float& x, float& y) { - // sets a vectors length to 1 (which means that x + y == 1) + // sets vector's length to 1 (which means that x + y = 1) float length = sqrt((x * x) + (y * y)); if (length != 0.0f) { length = 1.0f / length;
diff -r 887dd664eca0 -r 971e721f6ef2 Ball.h --- a/Ball.h Thu Apr 11 20:18:15 2019 +0000 +++ b/Ball.h Mon Apr 15 06:02:55 2019 +0000 @@ -10,18 +10,18 @@ { int size; float velocity; - bool gameOver; uint16_t color; - Timeout timeout; public: - Ball(int s = 8, float v = 8, uint16_t clr = TFT_WHITE ); + Ball(int s = 8, float v = 4, uint16_t clr = TFT_WHITE ); + void home(); bool move(Racket* rkt); - void newGame(); - void paint(uint16_t clr); + void paint(); void vec2_norm(float& x, float &y); int xPos; - int yPos; + int yPos; + int xPosOld; + int yPosOld; float xDir; float yDir;
diff -r 887dd664eca0 -r 971e721f6ef2 Racket.cpp --- a/Racket.cpp Thu Apr 11 20:18:15 2019 +0000 +++ b/Racket.cpp Mon Apr 15 06:02:55 2019 +0000 @@ -7,7 +7,15 @@ * @retval */ Racket::Racket(int w /*= 20*/, int h /*= 40*/, uint16_t clr /*= TFT_WHITE*/ ) : - width(w), height(h), xPos(320), yPos(240 / 2), velocity(10), xDir(0), yDir(0), color(clr) + width(w), + height(h), + xPos(320), + yPos(240 / 2), + yPosOld(240 / 2), + velocity(4), + xDir(0), + yDir(0), + color(clr) { } /** @@ -16,13 +24,29 @@ * @param * @retval */ +void Racket::home() +{ + xPos = 320; + yPos = 240 / 2; + yPosOld = yPos; + xDir = 0; + yDir = 0; +} + +/** + * @brief + * @note + * @param + * @retval + */ void Racket::move(DigitalIn* btnUp, DigitalIn* btnDown) { yDir = 0; if (*btnUp == 0) - yDir = -1; // move up + yDir = -1; // move up if (*btnDown == 0) - yDir = 1; // move down + yDir = 1; // move down + yPosOld = yPos; yPos += yDir * velocity; if (yPos < height / 2) yPos = height / 2; @@ -36,7 +60,14 @@ * @param * @retval */ -void Racket::paint(uint16_t clr /*= TFT_WHITE*/ ) +void Racket::paint() { - tft_boxfill(xPos - width / 2, yPos - height / 2, xPos, yPos + height / 2, clr); + if (yDir == 1) { + tft_boxfill(xPos - width / 2, yPosOld - height / 2, xPos, yPos - height / 2, TFT_BLACK); // hide racket at old position + tft_boxfill(xPos - width / 2, yPos - height / 2, xPos, yPos + height / 2, TFT_WHITE); // draw racket at new position + } + else { + tft_boxfill(xPos - width / 2, yPos + height / 2, xPos, yPosOld + height / 2, TFT_BLACK); // hide racket at old position + tft_boxfill(xPos - width / 2, yPos - height / 2, xPos, yPos + height / 2, TFT_WHITE); // draw racket at new position + } }
diff -r 887dd664eca0 -r 971e721f6ef2 Racket.h --- a/Racket.h Thu Apr 11 20:18:15 2019 +0000 +++ b/Racket.h Mon Apr 15 06:02:55 2019 +0000 @@ -7,19 +7,20 @@ class Racket { public: - Racket(int w = 20, int h = 40, uint16_t clr = TFT_WHITE); - void move(DigitalIn* btnUp, DigitalIn* btnDown); - void paint(uint16_t clr = TFT_WHITE); - - int width; - int height; - int xPos; - int yPos; - float velocity; - int xDir; - int yDir; - bool moved; - uint16_t color; + Racket(int w = 20, int h = 40, uint16_t clr = TFT_WHITE); + void home(); + void move(DigitalIn* btnUp, DigitalIn* btnDown); + void paint(); + + int width; + int height; + int xPos; + int yPos; + int yPosOld; + float velocity; + int xDir; + int yDir; + bool moved; + uint16_t color; }; - #endif // RACKET_H
diff -r 887dd664eca0 -r 971e721f6ef2 main.cpp --- a/main.cpp Thu Apr 11 20:18:15 2019 +0000 +++ b/main.cpp Mon Apr 15 06:02:55 2019 +0000 @@ -1,5 +1,5 @@ -// A simple Pong game with the STM32F407VET6 black board (Seeed Arch Max) and ILI9341 320x240 TFT display. -// More info on STM32F407VET6 black board at https://os.mbed.com/users/hudakz/code/STM32F407VET6_Hello/ +// A simple Pong game with STM32F407VET6 black board (Seeed Arch Max) and ILI9341 320x240 TFT display. +// See more info on the STM32F407VET6 black board at https://os.mbed.com/users/hudakz/code/STM32F407VET6_Hello/ // #include "mbed.h" #include "tft.h" @@ -7,7 +7,8 @@ #include "Ball.h" // Connect the SPI interface of an ILI9341 320x240 TFT display to the STM32F407VET6 board (Seeed Arch Max) as follows: -// ILI9341 STM32F103C8T6 + +// ILI9341 STM32F407VET6 // VCC +5V // GND GND // CS PB_7 @@ -18,12 +19,41 @@ // LED over a 56 ohm resistor +5V // SDO(MISO) PB_4 // -Ticker ticker; -DigitalIn racketUp(PE_4, PullUp); // K0 button -DigitalIn racketDown(PE_3, PullUp); // K1 button -Ball ball; -Racket racket; -bool gameOver; +Ticker ticker; +DigitalIn racketUp(PE_4, PullUp); // K0 button +DigitalIn racketDown(PE_3, PullUp); // K1 button +Ball ball; +Racket racket; +volatile bool gameOn; +volatile bool missed; +Timeout timeout; + +/** + * @brief + * @note + * @param + * @retval + */ +void newGame() +{ + tft_clear(TFT_BLACK); + racket.home(); + ball.home(); + gameOn = true; +} + +/** + * @brief + * @note + * @param + * @retval + */ +void gameOver() +{ + gameOn = false; + tft_text(320 / 2 - 35, 240 / 2, "GAME OVER", TFT_WHITE, TFT_BLACK); + timeout.attach(callback(newGame), 2); +} /** * @brief @@ -33,14 +63,15 @@ */ void updateField() { - racket.paint(TFT_BLACK); // hide racket at old position - racket.move(&racketUp, &racketDown); // move racket - racket.paint(TFT_WHITE); // draw racket at new position - if (!gameOver) - ball.paint(TFT_BLACK); // hide ball at old position - gameOver = ball.move(&racket); // move ball and check for collisions + game over - if (!gameOver) - ball.paint(TFT_WHITE); // draw ball at new position + if (gameOn) { + racket.move(&racketUp, &racketDown); // move racket + racket.paint(); // paint racket + missed = ball.move(&racket); // move ball and check for collisions + if (missed) + gameOver(); + else + ball.paint(); // paint ball + } } /** @@ -52,7 +83,7 @@ int main() { tft_init(); - tft_clear(TFT_BLACK); - ticker.attach_us(updateField, 40 * 1000); // update period = 40 ms + newGame(); + ticker.attach_us(updateField, 20 * 1000); // update period = 20 ms while (true) { } }