ST7735 Pong by Jonne Valola, derived work from William Johnston\'s mbed Pong for NokiaLCD / PS2 keyboard This pong uses a rotary encoder hooked to pins 21 and 22, ST7735_TFT library by me, RotaryEncoder library by Shinichiro Nakamura. All copyrights of respective owners. Use on your own risk and discretion.

Dependencies:   mbed ST7735_TFT RotaryEncoder TFT_fonts_old

Files at this revision

API Documentation at this revision

Comitter:
smultron1977
Date:
Mon Dec 12 21:35:42 2011 +0000
Commit message:
Original 2 hour hack

Changed in this revision

RotaryEncoder.lib Show annotated file Show diff for this revision Revisions of this file
ST7735_TFT.lib Show annotated file Show diff for this revision Revisions of this file
TFT_fonts.lib Show annotated file Show diff for this revision Revisions of this file
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
main.cpp 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
paddle.cpp Show annotated file Show diff for this revision Revisions of this file
paddle.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RotaryEncoder.lib	Mon Dec 12 21:35:42 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/shintamainjp/code/RotaryEncoder/#8000eddbf4aa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ST7735_TFT.lib	Mon Dec 12 21:35:42 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/smultron1977/code/ST7735_TFT/#967235e6fd48
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TFT_fonts.lib	Mon Dec 12 21:35:42 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/dreschpe/code/TFT_fonts/#31ce4466ecdf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ball.cpp	Mon Dec 12 21:35:42 2011 +0000
@@ -0,0 +1,100 @@
+#include "mbed.h"
+#include "ball.h"
+
+Ball::Ball() {
+  int x=y=width=height=color=xInc=yInc=0;
+}
+
+Ball::Ball(int x, int y, int w, int h, int c, int xi, int yi)
+ : x(x), y(y), width(w), height(h), color(c), xInc(xi), yInc(yi) {}
+ 
+ 
+/* 
+ * Member Function move:
+ * Description: Colors in the previous ball black
+ *  and moves ball to new position.
+ */
+void Ball::move(ST7735_TFT &lcd) {
+  draw(lcd, true);
+  x += xInc; y += yInc;
+}
+
+/* 
+ * Member Function draw:
+ * Description: Draws object on screen
+ *  if isBlack, color in black.
+ */
+void Ball::draw(ST7735_TFT &lcd, bool isBlack) const {
+  lcd.fillrect(x, y, x+width, y+height, (isBlack) ? 0x000000 : color);
+}
+
+int Ball::size() const {
+  return width*height;
+}
+
+int Ball::getX() const {
+  return x;
+}
+
+int Ball::getY() const {
+  return y;
+}
+
+bool Ball::hitX() {
+  return (x+width<=width) || (x+width>=160);
+}
+
+bool Ball::hitY() {
+  return (y<=0) || (y+height>=128);
+}
+
+/* 
+ * Member Function hitP1:
+ * Description: Checks to see if there is
+ *  a collision between paddle1 and the ball.
+ *  Has special functionality for changing
+ *  y-incline based on collision point.
+ */
+bool Ball::hitP1(int _x, int _y, int _height) {
+  bool hit = ((_x>=x) && (xInc<0)) && 
+         (((_y<=y) && (_y+_height>=y+height)) ||
+          ((_y>=y) && (_y<=y+height)) ||
+          ((_y+_height>=y) && (_y+_height<=y+height))
+         );
+  if(hit) {
+    if(_y+_height-y < 4 && yInc>0) yInc = 2;
+    if(y-_y < 4 && yInc<0) yInc = -2;
+    else yInc = (yInc>0) ? 1 : -1;
+  }
+  return hit;
+}
+
+
+/* 
+ * Member Function hitP2:
+ * Description: Checks to see if there is
+ *  a collision between paddle2 and the ball.
+ *  Has special functionality for changing
+ *  y-incline based on collision point.
+ */
+bool Ball::hitP2(int _x, int _y, int _height) {
+  bool hit = ((_x<=x+width) && (xInc>0)) && 
+         (((_y<=y) && (_y+_height>=y+height)) ||
+          ((_y>=y) && (_y<=y+height)) ||
+          ((_y+_height>=y) && (_y+_height<=y+height))
+         );
+  if(hit) {
+    if(_y+_height-y < 4 && yInc>0) yInc = 2;
+    if(y-_y < 4 && yInc<0) yInc = -2;
+    else yInc = (yInc>0) ? 1 : -1;
+  }
+  return hit;
+}
+
+void Ball::reverseX() {
+  xInc *= -1;
+}
+
+void Ball::reverseY() {
+  yInc *= -1;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ball.h	Mon Dec 12 21:35:42 2011 +0000
@@ -0,0 +1,26 @@
+#include "ST7735_TFT.h"
+
+class Ball {
+  /* This class creates a ball object */
+  
+  // Attributes
+  int x,y,width,height,color,xInc,yInc;
+
+public:
+  // Constructors
+  Ball();
+  Ball(int x, int y, int w, int h, int c, int xi, int yi);
+  
+  // Member functions
+  void move(ST7735_TFT &lcd);
+  void draw(ST7735_TFT &lcd, bool isBlack) const;
+  int getX() const;
+  int getY() const;
+  bool hitX();
+  bool hitY();
+  bool hitP1(int _x, int _y, int _height);
+  bool hitP2(int _x, int _y, int _height);
+  int size() const;
+  void reverseX();
+  void reverseY();
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Dec 12 21:35:42 2011 +0000
@@ -0,0 +1,109 @@
+/** ST7735 Pong by Jonne Valola, derived work from William Johnston's mbed Pong for NokiaLCD / PS2 keyboard
+* This pong uses a rotary encoder hooked to pins 21 and 22,
+* ST7735_TFT library by me, RotaryEncoder library by Shinichiro Nakamura
+* All copyrights of respective owners. Use on your own risk and discretion.  
+*/ 
+
+#include "mbed.h"
+#include "ball.h"
+#include "paddle.h"
+#include "ST7735_TFT.h"
+#include "string"
+#include "Arial12x12.h"
+#include "Arial24x23.h"
+#include "RotaryEncoder.h"
+
+RotaryEncoder re(p21, p22, 0, 600, 300);
+
+// State enumerator
+typedef enum {
+  RESET, RUN, PAUSE
+} STATES;
+
+ST7735_TFT lcd(p5, p6, p7, p8, p11, p15,"TFT"); // mosi, miso, sclk, cs, rs, reset
+
+/* 
+ * Subroutine drawScreen:
+ * Description: Draws both paddles
+ *  and the ball.
+ */
+void drawScreen(Paddle paddle1, Paddle paddle2, Ball theBall, bool isBlack) {
+  paddle1.draw(lcd, isBlack);
+  paddle2.draw(lcd ,isBlack);
+  theBall.draw(lcd ,isBlack);
+}
+
+/* 
+ * Subroutine drawScores:
+ * Description: Draws the scoreboard
+ */
+void drawScores(Paddle paddle1, Paddle paddle2) {
+  lcd.locate(60,1);
+  lcd.printf("%d", paddle1.getScore());
+  lcd.locate(90,1);
+  lcd.printf("%d", paddle2.getScore());
+  lcd.fillrect(79,0,81,128,0xFFFFFF);
+}
+
+int main() {
+  lcd.background(0x000000);
+  lcd.cls();
+  lcd.set_orientation(1);
+  lcd.set_font((unsigned char*) Arial12x12);  // select the font
+  Paddle paddle1, paddle2;
+  Ball theBall;
+  int temp, count=0, oldY;
+  drawScreen(paddle1, paddle2, theBall, false);
+  drawScores(paddle1, paddle2);
+  STATES state = RESET; // Initial state is RESET
+  while(1) {  
+    switch(state) {
+      case RESET: // Reset objects, draw the screen, state = PAUSE
+        lcd.cls();
+        paddle1 = Paddle(0,40,5,25,0xFFFFFF,paddle1.getLives(),paddle1.getScore());
+        paddle2 = Paddle(154,40,5,25,0xFFFFFF,paddle2.getLives(),paddle2.getScore());
+        theBall = Ball(80,64,5,5,0xFFFF00,1,1);
+        drawScreen(paddle1, paddle2, theBall, false);
+        drawScores(paddle1, paddle2);
+        oldY = re.getVal();
+        state = RUN;
+        break;
+      case RUN: 
+        if (oldY > re.getVal()) { // Executes if encoder turned
+                if(paddle1.getY()>2)
+                paddle1.move(lcd, -2);
+        }
+         if (oldY < re.getVal()) { // Executes if encoder turned
+              if(paddle1.getY()+paddle1.getHeight()<128)
+                paddle1.move(lcd, 2);
+        }
+        oldY = re.getVal();
+       
+        if(count%2) // Only let CPU move once every 2 times through the loop
+          paddle2.moveCPU(lcd, theBall.getY());
+        if(++count==5) { // Only move the ball once every 5 times through the loop
+          count = 0;
+          if(theBall.hitP1((paddle1.getX()+paddle1.getWidth()), paddle1.getY(), paddle1.getHeight()))
+            theBall.reverseX();
+          if(theBall.hitP2(paddle2.getX(), paddle2.getY(), paddle2.getHeight()))
+            theBall.reverseX();
+          if(theBall.hitX()) { // If the ball hits one of the sides of the screen
+            if(theBall.getX()<7) { // If the ball hit paddle1's side
+                paddle2.addPoint();              
+            }
+            else if(theBall.getX()>153) { // If the ball hit paddle2's side
+                paddle1.addPoint();            
+            }
+            theBall.reverseX();
+            state = RESET; // Reset the objects
+          }
+          if(theBall.hitY()) 
+            theBall.reverseY();
+          theBall.move(lcd);
+        }
+        break;
+    }
+    drawScreen(paddle1, paddle2, theBall, false);
+    drawScores(paddle1, paddle2);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Dec 12 21:35:42 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/029aa53d7323
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/paddle.cpp	Mon Dec 12 21:35:42 2011 +0000
@@ -0,0 +1,80 @@
+#include "mbed.h"
+#include "paddle.h"
+
+Paddle::Paddle() {
+  int x=y=width=height=color=score=0;
+  lives = 3;
+}
+
+Paddle::Paddle(int x, int y, int w, int h, int c, int l, int s)
+ : x(x), y(y), width(w), height(h), color(c), lives(l), score(s) {}
+ 
+/* 
+ * Member Function move:
+ * Description: Colors in the previous paddle black
+ *  and moves paddle to new position.
+ */
+void Paddle::move(ST7735_TFT &lcd, int increment) {
+  draw(lcd, true);
+  y += increment;
+}
+
+
+/* 
+ * Member Function moveCPU:
+ * Description: Colors in the previous paddle black
+ *  and moves paddle to new position.
+ *  inc variable allows paddle to only move every
+ *  other function call.
+ */
+void Paddle::moveCPU(ST7735_TFT &lcd, int _y) {
+  static int inc = 1;
+  draw(lcd, true);
+  if(_y>y+height/2 && y+height<128) y += inc;
+  else if(_y+5<y+height/2 && y>0) y -= inc;
+  inc = (inc) ? 0 : 1;
+}
+
+void Paddle::draw(ST7735_TFT &lcd, bool isBlack) const {
+  lcd.fillrect(x, y, x + width, y + height, (isBlack) ? 0x000000 : color);
+}
+
+bool Paddle::loseLife() {
+  return --lives;
+}
+
+void Paddle::addPoint() {
+  ++score;
+}
+
+int Paddle::size() const {
+  return width*height;
+}
+
+int Paddle::getWidth() const {
+  return width;
+}
+
+int Paddle::getHeight() const {
+  return height;
+}
+
+int Paddle::getX() const {
+  return x;
+}
+
+int Paddle::getY() const {
+  return y;
+}
+
+int Paddle::getLives() const {
+  return lives;
+}
+
+int Paddle::getScore() const {
+  return score;
+}
+
+void Paddle::setLives(int l) {
+  lives = l;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/paddle.h	Mon Dec 12 21:35:42 2011 +0000
@@ -0,0 +1,29 @@
+#include "ST7735_TFT.h"
+
+class Paddle {
+  /* This class creates a paddle object */
+ 
+  // Attributes
+  int x,y,width,height,color,lives,score;
+
+public: 
+  // Constructors
+  Paddle();
+  Paddle(int x, int y, int w, int h, int c, int l, int s);
+  
+  // Member functions
+  void move(ST7735_TFT &lcd, int increment);
+  void moveCPU(ST7735_TFT &lcd, int _y);
+  void draw(ST7735_TFT &lcd, bool isBlack) const;
+  bool loseLife();
+  void addPoint();
+  int size() const;
+  int getWidth() const;
+  int getHeight() const;
+  int getX() const;
+  int getY() const;
+  int getLives() const;
+  int getScore() const;
+  void setLives(int l);
+  
+};
\ No newline at end of file