So , I'm trying to make a pong-like game using a screen and two buttons , which I have achieved by it self , but when trying to integrate it in a bigger code where there's different modes with a menu you can use to select which mode you want to use every mode works , except for the "pong" mode , it makes the program loop back right from the setup loop . I've done some trouble shooting , and it seems that when i try to change the value of "BallySpeed" , it makes the program hard reset . when removing the part of the code that changes this value , the code works fine except for the fact , the "ball" doesn't bounce back on the walls , obviously .
I'm really sorry if this is a stupid question , i'm a beginner , and i've learned only by trial and error , this is why my code might seem a bit wanky , i'll try to clean it up later and if you have any other suggestions on how I can make it better , I'll be happy to listen to them .
Thanks a lot .
Here's the full code , with the menu and the pong game , which does not work .
// Library for RTC module
#include <TimeLib.h>
#include <Wire.h>
#include <DS1307RTC.h>
// Library for display
#include <U8g2lib.h>
#include <USBAPI.h>
U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R2, /* reset=*/ U8X8_PIN_NONE);
//Variables Button
int currentMode = 0;
const int PIN_UP = 3;
const int PIN_DOWN = 2;
int currentTimeMode = 2 ;
int currentRobotMode = 1;
// Variables position of the eyes
int wEyes = 10;
int hEyes = 0 ;
int wMouth = 42 ;
int hMouth = 4 ;
int EyeSpace = 84;
int xSpace = (128-EyeSpace-(wEyes*2))/2;
int ySpace = (64-hEyes)-xSpace-12;
int EyesClosed = 0 ;
// Strings
int S="z" ;
int W=0 ;
int S1="x";
int W1=0;
int S2="y";
int W2=0;
int HFont = 24 ;
int suffix = "er";
//Calendar
char *monthName[13] = {"","Janvier", "Fevrier", "Mars", "Avril", "Mai", "Juin", "Juillet" , "Aout" , "Septembre" , "Octobre" , "Novembre" , "Decembre"};
char *weekDayName[8] = {"","Dimanche","Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi","Samedi"};
//Time
unsigned long previousMillis = 0;
// Ball size & position
int Balllenght = 4;
int BallxPos = 64 ;
int BallyPos = 32 ;
int BallxSpeed = 4;
int BallySpeed = -2;
// Bar size & position Player
int Barxlenght = 4;
int Barylenght = 12;
int BarxPos = 4 ;
int BaryPos = 32-(Barylenght/2) ;
int BarySpeed = 3;
int PlayerScore = 0;
char SPlayerScore = "Player";
int WPlayerScore = 0;
// Bar size & position Bot
int Botxlenght = 4;
int Botylenght = 12;
int BotxPos = 128-8 ;
int BotyPos = 32-(Barylenght/2) ;
int BotySpeed = 3;
int BotScore = 0;
char SBotScore = "Bot";
int WBotScore = 0;
int FailRate = 0;
// Victory
int SVictory = "0";
int WVictory = 0;
int Victory = "PLAYER";
//String Menu
int StringH = 0;
int DisplayH = 64;
int DisplayW = 128;
int MenuW = 0;
int SRobotW = 0;
int SClockW = 0;
int SPongW = 0;
int SpaceW = 0;
//Selection
int selection = 1;
int ModeSelection = 1;
int RobotSelection = U8G2_BTN_BW1;
int ClockSelection = U8G2_BTN_BW0;
int PongSelection = U8G2_BTN_BW0;
void setup() {
u8g2.begin();
StartupGreeting();
// RTC module setup
Serial.begin(9600);
while (!Serial) ; // wait until Arduino Serial Monitor opens
setSyncProvider(RTC.get); // the function to get the time from the RTC
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
// Mode switch setup
pinMode(PIN_UP, INPUT_PULLUP);
pinMode(PIN_DOWN, INPUT_PULLUP);
DisplayH = u8g2.getDisplayHeight();
DisplayW = u8g2.getDisplayWidth();
}
void StartupGreeting() {
// Startup greating
u8g2.setFont(u8g2_font_logisoso16_tr);
S = "hello.";
W = u8g2.getStrWidth(S);
u8g2.firstPage();
do {
u8g2.drawStr(64-(W/2),32+(HFont/2),S);
} while (u8g2.nextPage());
delay (1500);
}
void ModeTime() {
if (digitalRead(PIN_DOWN) == LOW) {
currentTimeMode++ ;
delay (200) ;
}
if (currentTimeMode > 2) {
currentTimeMode = 1 ;
}
if (currentTimeMode==1) {
HFont = 32 ;
u8g2.setFont(u8g2_font_logisoso32_tn);
sprintf(S, "%02d:%02d" , hour(), minute() );
W = u8g2.getStrWidth(S);
u8g2.firstPage();
do {
u8g2.drawStr(64-(W/2),32+(HFont/2),S);
} while (u8g2.nextPage());
}
if (currentTimeMode==2){
//font settings
HFont = 18 ;
u8g2.setFont(u8g2_font_logisoso16_tr);
// Date
if (day()==1)
{
suffix = "er";
} else { suffix = "";}
{
sprintf(S2, "%d" ,year());
W2 = u8g2.getStrWidth(S2);
sprintf(S, "%s" ,weekDayName[weekday()] );
W = u8g2.getStrWidth(S);
sprintf(S1, "%d%s %s" ,day(),suffix,monthName[month()]);
W1 = u8g2.getStrWidth(S1);
}
u8g2.firstPage();
do {
u8g2.drawStr(64-(W/2),64/3,S);
u8g2.drawStr(64-(W1/2),(64/3*2),S1);
u8g2.drawStr(64-(W2/2),64,S2);
} while (u8g2.nextPage());
}
}
void ModeRobot() {
u8g2.firstPage();
do {
u8g2.drawBox(xSpace,ySpace,wEyes,hEyes);
u8g2.drawBox(EyeSpace+xSpace+wEyes,ySpace,wEyes,hEyes);
u8g2.drawBox(64-(wMouth/2),64-hMouth*2,wMouth,hMouth);
} while (u8g2.nextPage() );
u8g2.sendBuffer();
unsigned long currentMillis = millis();
if (hEyes < 24 && EyesClosed == 0) {
hEyes += 4;
ySpace -=2 ;
}
if (hEyes == 24 && currentMillis - previousMillis >= random(6000,12000)) {
previousMillis = currentMillis;
EyesClosed = 1 ;
}
if (hEyes > 0 && EyesClosed == 1 ){
hEyes -= 4;
ySpace +=2 ;
}
if (hEyes == 0) {
EyesClosed = 0 ;
}
}
void ModePong() {
//String Victory
u8g2.setFont(u8g2_font_bauhaus2015_tn);
sprintf(SBotScore, "%0d" ,BotScore);
sprintf(SPlayerScore, "%0d" ,PlayerScore);
WBotScore = u8g2.getStrWidth(SBotScore);
WPlayerScore = u8g2.getStrWidth(SPlayerScore);
//Draw screen
u8g2.firstPage();
do {
u8g2.drawBox(BallxPos,BallyPos,Balllenght,Balllenght);
u8g2.drawBox(BarxPos,BaryPos,Barxlenght,Barylenght);
u8g2.drawBox(BotxPos,BotyPos,Botxlenght,Botylenght);
u8g2.drawBox(63, 0,2,64);
u8g2.drawStr(64+8,12,SBotScore);
u8g2.drawStr(64-(WPlayerScore+8),12,SPlayerScore);
} while (u8g2.nextPage());
// Ball movement
BallxPos += BallxSpeed;
BallyPos += BallySpeed;
if ((BallyPos > 60 or BallyPos < 0)
or (BallyPos + Balllenght == BaryPos || BallyPos == BaryPos + Barylenght) && BallxPos > BarxPos && BallxPos < BarxPos + Barxlenght) {
BallySpeed = 0;
}
if (BallxPos == (BarxPos + Barxlenght) && BallyPos + Balllenght > BaryPos && BallyPos < BaryPos + Barylenght
or (BallxPos + Balllenght )== BotxPos && BallyPos + Balllenght > BotyPos && BallyPos < BotyPos + Botylenght ){
BallxSpeed *= -1;
FailRate = random(-10,10);
}
//BotScore
if (BallxPos < 0) {
BallxPos = 60;
BallxSpeed *= -1;
BotScore ++;
}
//PlayerScore
if ( BallxPos > 124) {
BallxPos = 60;
BallxSpeed *= -1;
PlayerScore ++;
}
//BotScript
if ((BallyPos+Balllenght/2+FailRate)< (BotyPos+Botylenght/2) && BotyPos>0) {
BotyPos -= 2;
}
if ( (BallyPos+Balllenght/2+FailRate) > (BotyPos+Botylenght/2) && (Botylenght+BotyPos)<64) {
BotyPos += 2 ;
}
//Bar movement
if (digitalRead(PIN_UP) == LOW && BaryPos<64-Barylenght) {
BaryPos += BarySpeed ;
}
if (digitalRead(PIN_DOWN) == LOW && BaryPos>0){
BaryPos -= BarySpeed ;
}
//VICTORY
if (BotScore == 10) {
Victory = "ROBOT";
}
if (PlayerScore == 10) {
Victory = "PLAYER";
}
if (BotScore >=10 or PlayerScore >=10) {
u8g2.setFont(u8g2_font_logisoso16_tr);
sprintf(SVictory, "%s WINS",Victory);
WVictory = u8g2.getStrWidth(SVictory);
u8g2.clearDisplay();
u8g2.firstPage();
do {
u8g2.drawStr(64-(WVictory/2),42,SVictory);
} while (u8g2.nextPage());
BotScore = 0;
PlayerScore = 0;
delay(5000);
selection++ ;
BaryPos = 32-(Barylenght/2);
}
}
void loop(){
if (currentMode == 0) {
if (ModeSelection==1) {
ModeRobot();
}
if (ModeSelection==2){
ModeTime();
}
if (ModeSelection==3) {
ModePong();
}
}
if (digitalRead(PIN_UP) == LOW && digitalRead(PIN_DOWN) == LOW) {
currentMode ++ ;
if (currentMode > 1) { currentMode = 0;}
delay (200) ;
}
if (currentMode == 1) {
if (digitalRead(PIN_UP) == LOW) {
delay (200) ;
currentMode=0;
ModeSelection = selection;
}
if (digitalRead(PIN_DOWN) == LOW) {
selection ++ ;
delay (200) ;
}
if (selection == 1) {
RobotSelection = U8G2_BTN_INV;
}
else {RobotSelection = 0;
}
if (selection == 2) {
ClockSelection = U8G2_BTN_INV;
}
else {ClockSelection = 0;
}
if (selection == 3) {
PongSelection = U8G2_BTN_INV;
}
else {PongSelection = 0;
}
if (selection > 3) {
selection = 1;
}
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_lastapprenticebold_tr);
StringH = u8g2.getAscent();
SRobotW = u8g2.getStrWidth("Robot");
SClockW = u8g2.getStrWidth("Clock");
SPongW = u8g2.getStrWidth("Pong");
MenuW = SRobotW + SClockW + SPongW;
SpaceW = (DisplayW-MenuW)/4;
u8g2.drawButtonUTF8(SpaceW,DisplayH/2+(StringH/2), RobotSelection, 0, 2, 2, "Robot" );
u8g2.drawButtonUTF8(SRobotW+SpaceW*2, DisplayH/2+(StringH/2), ClockSelection, 0, 2, 2, "Clock" );
u8g2.drawButtonUTF8(SRobotW+SClockW+SpaceW*3, DisplayH/2+(StringH/2), PongSelection, 0, 2, 2, "Pong" );
} while (u8g2.nextPage() );
u8g2.sendBuffer();
}
}
Here's the code for the pong game only , which works just fine .
// Library for display
#include <U8g2lib.h>
#include <Arduino.h>
#include <Wire.h>
U8G2_SH1106_128X64_NONAME_2_HW_I2C u8g2(U8G2_R2, /* reset=*/ U8X8_PIN_NONE);
// Ball size & position
int Balllenght = 4;
int BallxPos = 64 ;
int BallyPos = 32 ;
int BallxSpeed = 4;
int BallySpeed = -2;
// Bar size & position Player
int Barxlenght = 4;
int Barylenght = 12;
int BarxPos = 4 ;
int BaryPos = 32-(Barylenght/2) ;
int BarySpeed = 3;
int PlayerScore = 0;
char SPlayerScore = "Player";
int WPlayerScore = 0;
// Bar size & position Bot
int Botxlenght = 4;
int Botylenght = 12;
int BotxPos = 128-8 ;
int BotyPos = 32-(Barylenght/2) ;
int BotySpeed = 3;
int BotScore = 0;
char SBotScore = "Bot";
int WBotScore = 0;
int FailRate = 0;
// Buttons
const int PIN_UP = 3;
const int PIN_DOWN = 2;
// Victory
char SVictory = "0";
int WVictory = 0;
int Victory = "PLAYER";
void setup() {
u8g2.begin();
u8g2.setFont(u8g2_font_bauhaus2015_tr);
pinMode(PIN_UP, INPUT_PULLUP);
pinMode(PIN_DOWN, INPUT_PULLUP);
}
void loop() {
//String Victory
sprintf(SBotScore, "%0d" ,BotScore);
sprintf(SPlayerScore, "%0d" ,PlayerScore);
WBotScore = u8g2.getStrWidth(SBotScore);
WPlayerScore = u8g2.getStrWidth(SPlayerScore);
//Draw screen
u8g2.firstPage();
do {
u8g2.drawBox(BallxPos,BallyPos,Balllenght,Balllenght);
u8g2.drawBox(BarxPos,BaryPos,Barxlenght,Barylenght);
u8g2.drawBox(BotxPos,BotyPos,Botxlenght,Botylenght);
u8g2.drawBox(63, 0,2,64);
u8g2.drawStr(64+8,12,SBotScore);
u8g2.drawStr(64-(WPlayerScore+8),12,SPlayerScore);
} while (u8g2.nextPage());
// Ball movement
BallxPos += BallxSpeed;
BallyPos += BallySpeed;
if ((BallyPos > 60 or BallyPos < 0)
or (BallyPos + Balllenght == BaryPos || BallyPos == BaryPos + Barylenght) && BallxPos > BarxPos && BallxPos < BarxPos + Barxlenght) {
BallySpeed *= -1;
}
if (BallxPos == (BarxPos + Barxlenght) && BallyPos + Balllenght > BaryPos && BallyPos < BaryPos + Barylenght
or (BallxPos + Balllenght )== BotxPos && BallyPos + Balllenght > BotyPos && BallyPos < BotyPos + Botylenght ){
BallxSpeed *= -1;
FailRate = random(-10,10);
}
//BotScore
if (BallxPos < 0) {
BallxPos = 60;
BallxSpeed *= -1;
BotScore ++;
}
//PlayerScore
if ( BallxPos > 124) {
BallxPos = 60;
BallxSpeed *= -1;
PlayerScore ++;
}
//BotScript
if ((BallyPos+Balllenght/2+FailRate)< (BotyPos+Botylenght/2) && BotyPos>0) {
BotyPos -= 2;
}
if ( (BallyPos+Balllenght/2+FailRate) > (BotyPos+Botylenght/2) && (Botylenght+BotyPos)<64) {
BotyPos += 2 ;
}
//Bar movement
if (digitalRead(PIN_UP) == LOW && BaryPos<64-Barylenght) {
BaryPos += BarySpeed ;
}
if (digitalRead(PIN_DOWN) == LOW && BaryPos>0){
BaryPos -= BarySpeed ;
}
//VICTORY
if (BotScore == 10) {
Victory = "BOT";
}
if (PlayerScore == 10) {
Victory = "PLAYER";
}
if (BotScore >=10 or PlayerScore >=10) {
sprintf(SVictory, "%s WINS",Victory);
WVictory = u8g2.getStrWidth(SVictory);
u8g2.clearDisplay();
u8g2.firstPage();
do {
u8g2.drawStr(64-(WVictory/2),44,SVictory);
} while (u8g2.nextPage());
BotScore = 0;
PlayerScore = 0;
delay(5000);
}
}