PONG game
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// TFT module connections | |
char TFT_DataPort at PORTJ; | |
sbit TFT_RST at LATD3_bit; | |
sbit TFT_BLED at LATC2_bit; | |
sbit TFT_RS at LATE0_bit; | |
sbit TFT_CS at LATD2_bit; | |
sbit TFT_RD at LATH1_bit; | |
sbit TFT_WR at LATH2_bit; | |
char TFT_DataPort_Direction at TRISJ; | |
sbit TFT_RST_Direction at TRISD3_bit; | |
sbit TFT_BLED_Direction at TRISC2_bit; | |
sbit TFT_RS_Direction at TRISE0_bit; | |
sbit TFT_CS_Direction at TRISD2_bit; | |
sbit TFT_RD_Direction at TRISH1_bit; | |
sbit TFT_WR_Direction at TRISH2_bit; | |
// End TFT module connections | |
// Joysticks | |
sbit J1L_Direction at TRISE3_bit; | |
sbit J1R_Direction at TRISE6_bit; | |
sbit J2L_Direction at TRISE7_bit; | |
sbit J2R_Direction at TRISG2_bit; | |
sbit Start_Direction at TRISG1_bit; | |
void Init_MCU() { | |
PLLEN_bit = 1; | |
Delay_ms(150); | |
WDTCON.B4 = 1; | |
ANCON0 = 0xF0; // All pins to digital | |
ANCON1 = 0xFF; | |
WDTCON.B4 = 0; | |
TFT_Set_Default_Mode(); | |
TP_TFT_Set_Default_Mode(); | |
} | |
int paddleX, paddleY, oldPaddleX, oldPaddleY; | |
int ballDirectionX, ballDirectionY; | |
int ballX, ballY, oldBallX, oldBallY; | |
int paddleWidth; | |
int paddleHeight; | |
unsigned char is_in_paddle; | |
unsigned char count; | |
unsigned char max_count; | |
void Init_Game() { | |
// Dark blue screen | |
TFT_Fill_Screen(CL_NAVY); | |
// Draw the walls | |
TFT_Set_Pen(CL_AQUA, 1); | |
TFT_H_Line(0, 320, 0); | |
TFT_H_Line(0, 319, 1); | |
TFT_H_Line(0, 319, 2); | |
TFT_V_Line(0, 239, 0); | |
TFT_V_Line(0, 239, 1); | |
TFT_V_Line(0, 239, 2); | |
TFT_V_Line(0, 239, 319); | |
TFT_V_Line(0, 239, 318); | |
TFT_V_Line(0, 239, 317); | |
Delay_ms(100); | |
// No borders | |
TFT_Set_Pen(CL_NAVY, 0); | |
Delay_ms(100); | |
// Start with the ball somewhere in the middle | |
ballX = 180; | |
ballY = 50; | |
oldBallX = 180; | |
oldBallY = 180; | |
ballDirectionX = 1; | |
ballDirectionY = -1; | |
// start the paddle also in the midle | |
paddleX = 120; | |
paddleY = 229; | |
oldPaddleX = 120; | |
oldPaddleY = 229; | |
paddleWidth = 79; | |
paddleHeight = 10; | |
count = 0; | |
max_count = 5; | |
//Draw initial paddle | |
TFT_Set_Brush(1, CL_WHITE, 0, LEFT_TO_RIGHT, CL_NAVY, CL_NAVY); | |
TFT_Rectangle(paddleX, paddleY, paddleX + paddleWidth, paddleY + paddleHeight); | |
Delay_ms(500); | |
} | |
// This function checks the position of the ball | |
// to see if it intersects with the paddle | |
// x and y are coordinates of ball center | |
// rectX and rectY are upper left coordinated of paddle | |
// rectWidth and rectHeight are paddle sizes | |
// void TFT_Rectangle(int x_upper_left, int y_upper_left, int x_bottom_right, int y_bottom_right); | |
unsigned char inPaddle(int x, int y, int rectX, int rectY, int rectWidth, int rectHeight) { | |
unsigned char result; | |
result = 0; | |
if ((x >= (rectX-8)) & | |
(x <= (rectX + rectWidth + 8)) & | |
(y >= (rectY - 9)) & | |
(y <= (rectY + rectHeight - 9))) { | |
result = 1; | |
} | |
else { | |
} | |
return result; | |
} | |
// Note the ball radius is 8 | |
// there are three pixels on top, left and right due to lines | |
void moveBall() { | |
if ((ballX > 307) | (ballX < 12)) { | |
ballDirectionX = - ballDirectionX; | |
} | |
if (ballY < 13) { | |
ballDirectionY = - ballDirectionY; | |
} | |
if (ballY > 239){ // game lost | |
TFT_Fill_Screen(CL_BLACK); | |
TFT_Set_Font(TFT_defaultFont, CL_WHITE, FO_HORIZONTAL); | |
TFT_Write_Text("GAME OVER !", 110, 60); | |
TFT_Write_Text("PRESS START TO BEGIN A NEW GAME", 50, 90); | |
while(Button(&PORTG, 1, 1, 1) == 0); | |
Init_Game(); | |
} | |
is_in_paddle= inPaddle(ballX, ballY, paddleX, paddleY, paddleWidth, paddleHeight); | |
if (is_in_paddle == 1) { | |
ballDirectionY = - ballDirectionY; | |
// Let's add some difficulty | |
count++; | |
if (count == max_count){ | |
count = 0; | |
// Clear Paddle | |
TFT_Set_Brush(1, CL_NAVY, 0, LEFT_TO_RIGHT, CL_NAVY, CL_NAVY); | |
TFT_Rectangle(paddleX, paddleY, paddleX + paddleWidth, paddleY + paddleHeight); | |
paddleWidth = paddleWidth - 5; | |
// If we don't take some precautions | |
// The paddle will be smaller than the ball | |
if (paddleWidth < 20){ | |
paddleWidth = 20; | |
} | |
// Redraw paddle | |
TFT_Set_Brush(1, CL_WHITE, 0, LEFT_TO_RIGHT, CL_NAVY, CL_NAVY); | |
TFT_Rectangle(paddleX, paddleY, paddleX + paddleWidth, paddleY + paddleHeight); | |
} | |
} | |
ballX += ballDirectionX; | |
ballY += ballDirectionY; | |
if ((oldBallX != ballX) | (oldBallY != ballY)) { | |
// erase last ball position | |
TFT_Set_Brush(1, CL_NAVY, 0, LEFT_TO_RIGHT, CL_NAVY, CL_NAVY); | |
TFT_Circle(oldBallX, oldBallY, 8); | |
// draw new ball | |
TFT_Set_Brush(1, CL_WHITE, 0, LEFT_TO_RIGHT, CL_NAVY, CL_NAVY); | |
TFT_Circle(ballX, ballY, 8); | |
} | |
oldBallX = ballX; | |
oldBallY = ballY; | |
Delay_us(40); | |
} | |
void MovePaddle(){ | |
// Is one of the buttons pressed? | |
// Buttons are active high | |
// Is left button pressed? | |
if (Button(&PORTE, 3, 1, 1) | Button(&PORTE, 7, 1, 1)){ | |
PaddleX--; | |
// Is the paddle out of the screen? | |
if (PaddleX < 3){ | |
PaddleX = 3; | |
} | |
else{ // move paddle one position to the left | |
// we add one rectangle of width 1 px and height paddleHeight to the left | |
TFT_Set_Brush(1, CL_WHITE, 0, LEFT_TO_RIGHT, CL_NAVY, CL_NAVY); | |
TFT_Rectangle(paddleX, paddleY, oldPaddleX, paddleY + paddleHeight); | |
// we clear one rectangle of width 1 px and height paddleHeight to the right | |
TFT_Set_Brush(1, CL_NAVY, 0, LEFT_TO_RIGHT, CL_NAVY, CL_NAVY); | |
TFT_Rectangle(paddleX + paddleWidth, paddleY, oldPaddleX + paddleWidth, paddleY + paddleHeight); | |
} | |
} | |
// Is right button pressed? | |
if (Button(&PORTE, 6, 1, 1) | Button(&PORTG, 2, 1, 1)){ | |
PaddleX++; | |
// Is the paddle out of the screen? | |
if (PaddleX > (317 - paddleWidth)){ | |
PaddleX = 317 - paddleWidth; | |
} | |
else{ | |
// we add one rectangle of width 1 px and height paddleHeight to the right | |
TFT_Set_Brush(1, CL_WHITE, 0, LEFT_TO_RIGHT, CL_NAVY, CL_NAVY); | |
TFT_Rectangle(oldPaddleX + paddleWidth, paddleY, paddleX + paddleWidth, paddleY + paddleHeight); | |
// we clear one rectangle of width 1 px and height paddleHeight to the left | |
TFT_Set_Brush(1, CL_NAVY, 0, LEFT_TO_RIGHT, CL_NAVY, CL_NAVY); | |
TFT_Rectangle(oldPaddleX, paddleY, paddleX, paddleY + paddleHeight); | |
} | |
} | |
oldPaddleX = PaddleX; | |
oldPaddleY = PaddleY; | |
} | |
void main() { | |
Init_MCU(); | |
// Set joystick buttons as inputs | |
J1L_Direction = 1; | |
J1R_Direction = 1; | |
J2L_Direction = 1; | |
J2R_Direction = 1; | |
Start_Direction = 1; | |
TFT_Init_ILI9341_8bit(320, 240); | |
Delay_ms(100); | |
Init_Game(); | |
// Let the game begin | |
while(1){ | |
MovePaddle(); | |
MoveBall(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Project page | |
# |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment