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 TFTSPI interfaceSTM32F407VET6
VCC+5V
GNDGND
CSPB_7
RESETPB_8
D/CPB_6
SDI(MOSI)PB_5
SCKPB_3
LEDover a 56 ohm resistor+5V
SDO(MISO)PB_4

Files at this revision

API Documentation at this revision

Comitter:
hudakz
Date:
Mon Apr 15 06:02:55 2019 +0000
Parent:
0:887dd664eca0
Commit message:
Simple pong game updated.

Changed in this revision

Ball.cpp Show annotated file Show diff for this revision Revisions of this file
Ball.h Show annotated file Show diff for this revision Revisions of this file
Racket.cpp Show annotated file Show diff for this revision Revisions of this file
Racket.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
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) { }
 }