A departure from the traditional Pong while still keeping the skill requirement:
For the ProMicro 32U4
/*Binary sketch size: 13,766 bytes (of a 28,672 byte maximum)
This example code is in the public domain.
Based upon:http://arduino.cc/en/Tutorial/TFTPong
Created by Tom Igoe December 2012
Modified 15 April 2013 by Scott Fitzgerald
Modified 15 June 2014 by M. Ray Burnette for ILI9340 TFT & X/Y joystick
Joystick used: http://www.ebay.com/itm/New-JoyStick-Breakout-Module-Shield-PS2-Joystick-Game-Controller-For-Arduino-/200955114766
LCD TFT 2.2": http://www.ebay.com/itm/2-2-inch-2-2-SPI-TFT-LCD-Display-module-240x320-ILI9341-51-AVR-STM32-ARM-PIC-/200939222521
LCD Note: Exact version used is an older version of the above, ILI9340.
Color definitions for TFT SPI 2.2" Display:
ILI9340_BLACK 0x0000
ILI9340_BLUE 0x001F
ILI9340_RED 0xF800
ILI9340_GREEN 0x07E0
ILI9340_CYAN 0x07FF
ILI9340_MAGENTA 0xF81F
ILI9340_YELLOW 0xFFE0
ILI9340_WHITE 0xFFFF
*/
#include "Adafruit_ILI9340.h"
#include "Adafruit_GFX.h"
#include <SPI.h>
// SPI pins Sparkfun Pro Micro 32U4
#define mosi 16
#define miso 14
#define sclk 15
#define cs 10
#define dc 9
#define rst 8
void(* resetFunc) (void) = 0; //declare reset function @ address 0
// Use hardware SPI
Adafruit_ILI9340 TFT = Adafruit_ILI9340(cs, dc, rst);
// variables for the position of the ball and paddle
int paddleX ;
int paddleY ;
int oldPaddleX ;
int oldPaddleY ;
int ballDirectionX = 1;
int ballDirectionY = 1;
int ballSpeed = 10; // lower numbers are faster
int ballX, ballY, oldBallX, oldBallY;
// screen stuff used to be private now global
int myWidth ;
int myHeight ;
boolean OneTime ;
char Arduino = 57 ;
char Player = 57 ;
void setup()
{
pinMode( 2, INPUT) ; digitalWrite( 2, HIGH); // turn on pullup resistor
// initialize the display
TFT.begin();
myWidth = TFT.width() ;
myHeight = TFT.height();
TFT.fillScreen(ILI9340_BLACK); // clear display
TFT.setRotation(3); // landscape
// black background
TFT.setTextColor(0xF9B0, ILI9340_BLACK) ;
TFT.setTextSize(1); // Small 53 char / line
TFT.print("A game by Ray Burnette") ;
TFT.setTextSize(2); // Small 26 char / line
TFT.setCursor(40, 40) ; TFT.print("Blazing Paddle") ;
TFT.setTextColor(ILI9340_YELLOW, ILI9340_BLACK) ;
TFT.setCursor(0, 59); TFT.print("<--FASTER-+-SLOWER-->") ;
TFT.setCursor(0, 174); TFT.print(" Left or Right joystick ") ;
TFT.setCursor(0, 195); TFT.print(" to adjust ball speed. ") ;
TFT.setCursor(0, 220); TFT.print("Press down to continue...") ;
paddleX = oldPaddleX ;
paddleY = oldPaddleY = myHeight / 3 ;
while( UserInput() )
{
// map( value, fromLow, fromHigh, toLow, toHigh)
paddleX = map(analogRead(A0), 0, 1023, 0, myWidth) ;
if ( oldPaddleX != paddleX )
{
TFT.fillRect(oldPaddleX, oldPaddleY, 20, 5, ILI9340_BLACK) ;
}
TFT.fillRect(paddleX, paddleY, 20, 5, ILI9340_WHITE);
oldPaddleX = paddleX;
}
randomSeed(analogRead(0)); // X axis value
TFT.begin();
myWidth = TFT.width() - 85 ; // smaller court for score keeping
// myWidth = TFT.width() ; // full-screen court
myHeight = TFT.height();
TFT.setRotation(3); // landscape
TFT.fillScreen(ILI9340_BLACK); // clear display
ballX = random(20, 220) ;
ballY = random( 5, 235) ;
// partition court for score keeping to right side of screen
// drawLine( x0, y0, x1, y1, uint16_t color);
TFT.drawLine(myWidth + 20, 0, myWidth + 20, myHeight, ILI9340_CYAN ) ;
// drawChar(uint16_t x, uint16_t y, char c, uint16_t color, uint16_t bg, uint8_t size);
TFT.drawChar(myWidth + 30, 55, 'M', ILI9340_CYAN, ILI9340_BLACK, 2) ;
TFT.drawChar(myWidth + 45, 55, 'e', ILI9340_CYAN, ILI9340_BLACK, 2) ;
TFT.drawChar(myWidth + 30, 128, 'Y', ILI9340_YELLOW, ILI9340_BLACK, 2) ;
TFT.drawChar(myWidth + 45, 128, 'o', ILI9340_YELLOW, ILI9340_BLACK, 2) ;
TFT.drawChar(myWidth + 60, 128, 'u', ILI9340_YELLOW, ILI9340_BLACK, 2) ;
}
void loop()
{
// map the paddle's location to the position of the potentiometers
// map( value, fromLow, fromHigh, toLow, toHigh)
paddleX = map(analogRead(A0), 0, 1020, 1, myWidth - 20) ; //- 20/2;
paddleY = map(analogRead(A1), 0, 1020, 5, myHeight - 5) ; //- 5/2;
// set the fill color to black and erase the previous
// position of the paddle if different from present
if ( (oldPaddleX != paddleX) || (oldPaddleY != paddleY) )
{
TFT.fillRect(oldPaddleX, oldPaddleY, 20, 5, ILI9340_BLACK) ;
}
// draw the paddle on screen, save the current position
TFT.fillRect(paddleX, paddleY, 20, 5, ILI9340_WHITE);
oldPaddleX = paddleX;
oldPaddleY = paddleY;
// update the ball's position and draw it on screen
if (millis() % ballSpeed < 2)
{
moveBall();
}
if ( Scoring(Arduino, Player) ) // either score has gone to 0
{
TFT.setTextColor(ILI9340_GREEN, ILI9340_BLACK) ;
TFT.setTextSize(3);
TFT.setCursor(5, 30) ; TFT.print(" END OF GAME") ;
TFT.setCursor(5, 180) ; TFT.print("PRESS JOYSTICK") ;
TFT.setCursor(5, 100) ;
if (Arduino == '0')
{
TFT.print(" YOU WIN !") ;
}
else
{
TFT.print(" I WIN !!!") ;
}
while( UserInput() ) {}
resetFunc(); //call reset function to reboot Arduino code
}
}
void moveBall() // this function determines the ball's position on screen
{
OneTime = true ;
// if the ball goes offscreen, reverse the direction:
if (ballX > myWidth || ballX < 1 )
{
ballDirectionX = -ballDirectionX;
}
if (ballY >= TFT.height() || ballY < 1)
{
ballDirectionY = -ballDirectionY;
if( OneTime ) {
Player-- ; // deduct 1 from player
OneTime = false ;
}
}
// check if the ball and the paddle occupy the same space on screen
if (inPaddle(ballX, ballY, paddleX, paddleY, 20, 5))
{
ballDirectionX = -ballDirectionX;
ballDirectionY = -ballDirectionY;
if (OneTime ) {
Arduino-- ; // deduct 1 from Arduino
OneTime = false ;
}
}
// update the ball's position
ballX += ballDirectionX;
ballY += ballDirectionY;
// erase the ball's previous position
if (oldBallX != ballX || oldBallY != ballY)
{
TFT.fillRect(oldBallX, oldBallY, 7, 7, ILI9340_BLACK) ; // ball orig 5*5 made larger to see on denser TFT
}
// draw the ball's current position
// fillRect( x0, y0, w, h, uint16_t color);
TFT.fillRect(ballX, ballY, 7, 7, ILI9340_GREEN) ;
oldBallX = ballX ;
oldBallY = ballY ;
}
// this function checks the position of the ball to see if it intersects with the paddle
boolean inPaddle(int x, int y, int rectX, int rectY, int rectWidth, int rectHeight)
{
boolean result = false;
if ((x >= rectX && x <= (rectX + rectWidth)) &&
(y >= rectY && y <= (rectY + rectHeight)))
{
result = true;
}
return result;
}
boolean UserInput()
{
// map ( value, fromLow, fromHigh, toLow, toHigh)
ballSpeed = map(analogRead(A0), 0, 1023, 1, 20) ;
return digitalRead(2);
}
boolean Scoring(char Arduino, char Player)
{
boolean endGame = false ;
static char previousArduino, previousPlayer ;
uint16_t x = 270 ;
uint16_t y = 75 ;
uint16_t y1 = 150 ;
if( Arduino == 48 || Player == 48) endGame = true ; // char 48 == int 0
if ( Arduino != previousArduino || Player != previousPlayer )
{
// drawChar(uint16_t x, uint16_t y, char c, uint16_t color, uint16_t bg, uint8_t size);
TFT.drawChar(x, y, Arduino, ILI9340_CYAN, ILI9340_BLACK, 3);
TFT.drawChar(x, y1, Player, ILI9340_YELLOW, ILI9340_BLACK, 3);
previousArduino = Arduino ;
previousPlayer = Player ;
}
return endGame ;
}
Notes/etc:
/*
// These are the pins used for the UNO
UNO LEO // J2 header pin # on GLCD
#define _sclk 13 15 // 7
#define _miso 12 14 // 9
#define _mosi 11 16 // 6
#define _cs 10 10 // 3
#define _dc 9 9 // 5
#define _rst 8 8 // 4
+-\/-+
Reset PC6 1| |28 PC5 (AI 5)
Rx (D 0) PD0 2| |27 PC4 (AI 4)
Tx (D 1) PD1 3| |26 PC3 (AI 3)
(D 2) PD2 4| |25 PC2 (AI 2)
PWM+ (D 3) PD3 5| |24 PC1 (AI 1)
lDebug Low=true (D 4) PD4 6| |23 PC0 (AI 0)
+5 VCC 7| |22 GND GND
GND GND 8| |21 AREF +5 and bypass cap
XTL1 PB6 9| |20 AVCC +5
XTL2 PB7 10| |19 PB5 (D 13) J2#7/SCK -----------> D15 32U4
(D 5) PD5 11| |18 PB4 (D 12) J2#9/MISO -----------> D14 32U4
BAUD (low=4800) PWM+ (D 6) PD6 12| |17 PB3 (D 11) PWM J2#6/MOSI (SDI) -----> D16 32U4
(D 7) PD7 13| |16 PB2 (D 10) PWM J2#3/CS
J2#4/Reset (D 8) PB0 14| |15 PB1 (D 9) PWM J2#5/DC
+----+
/--------------------------------------------------------------------/
/ Color definitions for TFT SPI 2.2" Display /
/ ILI9340_BLACK 0x0000 /
/ ILI9340_BLUE 0x001F /
/ ILI9340_RED 0xF800 /
/ ILI9340_GREEN 0x07E0 /
/ ILI9340_CYAN 0x07FF /
/ ILI9340_MAGENTA 0xF81F /
/ ILI9340_YELLOW 0xFFE0 /
/ ILI9340_WHITE 0xFFFF /
/--------------------------------------------------------------------/
0 1 2 = 26 x 15 = 390 char/display
12345678901234567890123456 = 240 x 320 (landscape) = 76,800 pixels
___display characters_____/ line# character#
12345678901234567890123456 1 1 - 26
12345678901234567890123456 2 27 - 52
12345678901234567890123456 3 53 - 78
12345678901234567890123456 4 79 - 104
12345678901234567890123456 5 105 - 130
12345678901234567890123456 6 131 - 156
12345678901234567890123456 7 157 - 182
12345678901234567890123456 8 183 - 208
12345678901234567890123456 9 209 - 234
12345678901234567890123456 10 235 - 260
12345678901234567890123456 11 261 - 286
12345678901234567890123456 12 287 - 312
12345678901234567890123456 13 313 - 338
12345678901234567890123456 14 339 - 364
12345678901234567890123456 15 365 - 390
--------------------------/
//tft.drawLine( x1, y1, x2, y2, color);
lcd.drawLine( 0, 0, 319, 0, ILI9340_YELLOW);
lcd.drawLine( 0, 15, 319, 15, ILI9340_YELLOW);
lcd.drawLine( 0, 0, 0, 239, ILI9340_YELLOW);
lcd.drawLine( 11, 0, 11, 239, ILI9340_YELLOW);
//lcd.setTextColor(ILI9340_WHITE, ILI9340_BLACK) ;
(character# % 26 ) * 16 == (000,yyy)
***** Graphic text appears to be 12w x 16h font for .setTextSize(2) ***** Landscape == 15 Lines x 26 Characters Wide == 390 Characters per Screen
___________________________________/1st/_______________________________________________________ ___________________________________/26th/_______________________________________________________
_______/_______/_______/_______/_______/_______/_______/_______/_______/_______/_______/_______/ _______/_______/_______/_______/_______/_______/_______/_______/_______/_______/_______/_______/
000,000 001,000 002,000 003,000 004,000 005,000 006,000 007,000 008,000 009,000 010,000 011,000 308,000 309,000 310,000 311,000 312,000 313,000 314,000 315,000 316,000 317,000 318,000 319,000
000,001 001,001 001,002 001,003 001,004 001,005 001,006 001,007 001,008 001,009 001,010 001,011 308,001 309,001
000,002 308,002
000,003 308,003
000,004 308,004
000,005 308,005
000,006 308,006
000,007 308,007
000,008 308,008
000,009 308,009
000,010 308,010
000,011 308,011
000,012 308,012
000,013 308,013
000,014 308,014
000,015 001,015 002,015 003,015 004,015 005,015 006,015 007,015 008,015 009,015 010,015 011,015 308,015 309,015 310,015 311,015 312,015 313,015 314,015 315,015 316,015 317,015 318,015 319,015
000,016 .line 2 000,080 .line 6 000,144 .line 10 000,208 .line 14
000,032 .line 3 000,096 .line 7 000,160 .line 11 000,224 .line 15
000,048 .line 4 000,112 .line 8 000,176 .line 12 000,240 --- > 000,000
000,064 .line 5 000,128 .line 9 000,192 .line 13
___________________________________/365th/_____________________________________________________ ___________________________________/390th/_____________________________________________________
_______/_______/_______/_______/_______/_______/_______/_______/_______/_______/_______/_______/ _______/_______/_______/_______/_______/_______/_______/_______/_______/_______/_______/_______/
000,224 001,224 002,224 003,224 004,224 005,224 006,224 007,224 008,224 009,224 010,224 011,224 308,224 309,224 310,224 311,224 312,224 313,224 314,224 315,224 316,224 317,224 318,224 319,224
000,225 308,225
000,226 308,226
000,227 308,227
000,228 308,228
000,229 308,229
000,230 308,230
000,231 308,231
000,232 308,232
000,233 308,233
000,234 308,234
000,235 308,235
000,236 308,236
000,237 308,237
000,238 308,238
000,239 001,239 002,239 003,239 004,239 005,239 006,239 007,239 008,239 009,239 010,239 011,239 308,239 309,239 310,239 311,239 312,239 313,239 314,239 315,239 316,239 317,239 318,239 319,239
*/