I need help to switch betweem two games i made with help

So i made the game "SNAKE" HEre is the Code: #include <Adafruit_SSD1306.h>

#include <Adafruit_GFX.h>
#include <Wire.h>

// OLED display settings
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// Define buttons and snake block size
const int LEFT_BUTTON = 5;
const int UP_BUTTON = 3;
const int DOWN_BUTTON = 4;
const int RIGHT_BUTTON = 2;
const int SNAKE_BLOCK_SIZE = 4;


// Define game variables
int deaths = 0;
int score = 0;
int highscore = 0;
int snake_x = 0;
int snake_y = 0;
int snake_dir_x = 1;
int snake_dir_y = 0;
int food_x = 0;
int food_y = 0;
boolean is_food_eaten = true;
const int MAX_SEGMENTS = 100;
int segment_x[MAX_SEGMENTS];
int segment_y[MAX_SEGMENTS];
int num_segments = 3; // Starting with head and 2 additional segments
float speed_multiplier = 1.0;
const float SPEED_INCREMENT = 0.2;
const int BASE_DELAY_TIME = 100;
const int SCREEN_LEFT_EDGE = 0;
const int SCREEN_RIGHT_EDGE = SCREEN_WIDTH - SNAKE_BLOCK_SIZE;
const int SCREEN_TOP_EDGE = 0;
const int SCREEN_BOTTOM_EDGE = SCREEN_HEIGHT - SNAKE_BLOCK_SIZE;



// Define OLED display object
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  // Initialize OLED display
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();

  // Set up button inputs
  pinMode(LEFT_BUTTON, INPUT_PULLUP);
  pinMode(UP_BUTTON, INPUT_PULLUP);
  pinMode(DOWN_BUTTON, INPUT_PULLUP);
  pinMode(RIGHT_BUTTON, INPUT_PULLUP);

  // Set initial snake position and add to segment arrays
  segment_x[0] = snake_x;
  segment_y[0] = snake_y;
  segment_x[1] = snake_x - SNAKE_BLOCK_SIZE;
  segment_y[1] = snake_y;
  segment_x[2] = snake_x - 2*SNAKE_BLOCK_SIZE;
  segment_y[2] = snake_y;

  // Print initial screen with title and prompt
  display.setCursor(0, 10);
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.println("SNAKE");
  display.setCursor(0, SCREEN_HEIGHT-25);
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.println("Press any button to");
  display.setCursor(0, SCREEN_HEIGHT-15);
  display.println("Play");
  display.display();

  // Draw snake graphic
  display.fillRect(100, 8, 8, 4, WHITE);
  display.fillRect(96, 12, 8, 4, WHITE);
  display.fillRect(92, 16, 8, 4, WHITE);
  display.fillRect(88, 20, 8, 4, WHITE);
  display.display();


  // Wait for any button to be pressed
  while (digitalRead(LEFT_BUTTON) == HIGH && digitalRead(UP_BUTTON) == HIGH && digitalRead(DOWN_BUTTON) == HIGH && digitalRead(RIGHT_BUTTON) == HIGH) {
    delay(100);
  }

}

void reset_game() {
  // Reset snake position and direction
  snake_x = SCREEN_WIDTH / 2;
  snake_y = SCREEN_HEIGHT / 2;
  snake_dir_x = 0;
  snake_dir_y = -1;

  // Reset speed and score
  speed_multiplier = 1.0;
  score = 0;

  // Reset snake segments
  num_segments = 3;
  segment_x[0] = snake_x;
  segment_y[0] = snake_y;
  segment_x[1] = snake_x - SNAKE_BLOCK_SIZE;
  segment_y[1] = snake_y;
  segment_x[2] = snake_x - 2*SNAKE_BLOCK_SIZE;
  segment_y[2] = snake_y;

  // Reset food position
  food_x = random(SCREEN_WIDTH / SNAKE_BLOCK_SIZE) * SNAKE_BLOCK_SIZE;
  food_y = random(SCREEN_HEIGHT / SNAKE_BLOCK_SIZE) * SNAKE_BLOCK_SIZE;
  is_food_eaten = false;
}


void loop() {
    boolean is_collision = false;

    // Clear display before drawing new elements
    display.clearDisplay();
    
    // Calculate delay time based on current speed multiplier
    int delay_time = (int)(BASE_DELAY_TIME / speed_multiplier);

    // Check button input and update snake direction
    if (digitalRead(LEFT_BUTTON) == LOW) {
      snake_dir_x = -1;
      snake_dir_y = 0;
    } else if (digitalRead(UP_BUTTON) == LOW) {
      snake_dir_x = 0;
      snake_dir_y = -1;
    } else if (digitalRead(DOWN_BUTTON) == LOW) {
      snake_dir_x = 0;
      snake_dir_y = 1;
    } else if (digitalRead(RIGHT_BUTTON) == LOW) {
      snake_dir_x = 1;
      snake_dir_y = 0;
    }

    // Erase previous snake head position
    display.fillRect(segment_x[num_segments-1], segment_y[num_segments-1], SNAKE_BLOCK_SIZE, SNAKE_BLOCK_SIZE, BLACK);

    // Move snake segments
    for (int i = num_segments - 1; i > 0; i--) {
      segment_x[i] = segment_x[i-1];
      segment_y[i] = segment_y[i-1];
    }

    // Update snake head position
    snake_x += snake_dir_x * SNAKE_BLOCK_SIZE;
    snake_y += snake_dir_y * SNAKE_BLOCK_SIZE;

    // Wrap around to opposite edge if going out of bounds
    if (snake_x < SCREEN_LEFT_EDGE) {
      snake_x = SCREEN_RIGHT_EDGE;
    } else if (snake_x > SCREEN_RIGHT_EDGE) {
      snake_x = SCREEN_LEFT_EDGE;
    }
    if (snake_y < SCREEN_TOP_EDGE) {
      snake_y = SCREEN_BOTTOM_EDGE;
    } else if (snake_y > SCREEN_BOTTOM_EDGE) {
      snake_y = SCREEN_TOP_EDGE;

    }
    // Check for food collision
    if (snake_x == food_x && snake_y == food_y) {
      // Increase speed and reset food position
      speed_multiplier += SPEED_INCREMENT;
      is_food_eaten = true;
      tone(48, 40, 30);
      score++;

      // Update high score if necessary
      if (score > highscore) {
        highscore = score;
      }

      // Add new segment to snake if possible
      if (num_segments < MAX_SEGMENTS) {
        segment_x[num_segments] = segment_x[num_segments-1];
        segment_y[num_segments] = segment_y[num_segments-1];
        num_segments++;
      }
    }

    // Check for self-collision
    for (int i = 1; i < num_segments; i++) {
      if (snake_x == segment_x[i] && snake_y == segment_y[i]) {
        is_collision = true;
        break;
      }
    }

    // Update snake head segment
    segment_x[0] = snake_x;
    segment_y[0] = snake_y;

    // Place food if needed
    if (is_food_eaten) {
      food_x = random(SCREEN_WIDTH / SNAKE_BLOCK_SIZE) * SNAKE_BLOCK_SIZE;
      food_y = random(SCREEN_HEIGHT / SNAKE_BLOCK_SIZE) * SNAKE_BLOCK_SIZE;
      is_food_eaten = false;
    }

    // Draw snake and food
    for (int i = 0; i < num_segments; i++) {
      display.fillRect(segment_x[i], segment_y[i], SNAKE_BLOCK_SIZE, SNAKE_BLOCK_SIZE, WHITE);
    }
    display.fillCircle(food_x + SNAKE_BLOCK_SIZE/2, food_y + SNAKE_BLOCK_SIZE/2, SNAKE_BLOCK_SIZE/2, WHITE);

    

// Display game over message if collision detected
if (is_collision) {
  tone(48, 400, 500);
  display.clearDisplay();
  display.setCursor(0, 10);
  display.setTextColor(WHITE);
  display.setTextSize(2);
  display.print("GAME OVER!");
  display.setTextSize(1);
  display.setCursor(0, SCREEN_HEIGHT-30);
  display.print("Deaths: ");
  display.print(deaths + 1);
  display.setCursor(0, SCREEN_HEIGHT-20);
  display.setTextColor(WHITE);
  display.print("Score: ");
  display.print(score);
  display.setCursor(0, SCREEN_HEIGHT-10);
  display.print("Highscore: ");
  display.print(highscore);
  display.display();
  delay(3000);

  while (digitalRead(LEFT_BUTTON) == HIGH && digitalRead(UP_BUTTON) == HIGH && digitalRead(DOWN_BUTTON) == HIGH && digitalRead(RIGHT_BUTTON) == HIGH) {
    delay(10);
  }
  reset_game();
  deaths++;
}

  // Update display
  display.display();

  // Delay for smooth animation
  delay(delay_time);
}

And i want to make a screen where you can switch between these games, where the names are, with D2 (to the right) and with D5 (to the left). ON the left there is SNAKE and on the other PING_PONG. HEre is code for PING_PONG:

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// Pins for buttons
const int UP_BUTTON = 3;
const int DOWN_BUTTON = 4;

// Paddle dimensions
const int PADDLE_WIDTH = 4;
const int PADDLE_HEIGHT = 20;

// Ball dimensions and speed
const int BALL_SIZE = 4;
const int BALL_SPEED = 2;

// Define game variables
int player1_score = 0;
int player2_score = 0;

// Define paddle positions
int player1_paddle_y = SCREEN_HEIGHT / 2;
int player2_paddle_y = SCREEN_HEIGHT / 2;

// Define ball position and direction
int ball_x = SCREEN_WIDTH / 2;
int ball_y = SCREEN_HEIGHT / 2;
int ball_dx = BALL_SPEED;
int ball_dy = BALL_SPEED;

// Define OLED display object
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  // Initialize OLED display
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();

  // Set up button inputs
  pinMode(UP_BUTTON, INPUT_PULLUP);
  pinMode(DOWN_BUTTON, INPUT_PULLUP);

  // Print initial screen with title and prompt
  display.setCursor(0, 10);
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.println("PING PONG");
  display.setCursor(0, SCREEN_HEIGHT-25);
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.println("Press any button to");
  display.setCursor(0, SCREEN_HEIGHT-15);
  display.println("Play");
  display.display();

  // Wait for any button to be pressed
  while (digitalRead(UP_BUTTON) == HIGH && digitalRead(DOWN_BUTTON) == HIGH) {
    delay(100);
  }

  // Draw initial screen with paddles and ball
  display.clearDisplay();
  display.fillRect(0, player1_paddle_y - PADDLE_HEIGHT / 2, PADDLE_WIDTH, PADDLE_HEIGHT, WHITE);
  display.fillRect(SCREEN_WIDTH - PADDLE_WIDTH, player2_paddle_y - PADDLE_HEIGHT / 2, PADDLE_WIDTH, PADDLE_HEIGHT, WHITE);
  display.fillRect(ball_x - BALL_SIZE / 2, ball_y - BALL_SIZE / 2, BALL_SIZE, BALL_SIZE, WHITE);
  update_scoreboard();
  display.display();
}

void loop() {
  // Move paddles based on button inputs
  if (digitalRead(UP_BUTTON) == LOW) {
    player1_paddle_y = max(PADDLE_HEIGHT / 2, player1_paddle_y - 2);
  }
  if (digitalRead(DOWN_BUTTON) == LOW) {
    player1_paddle_y = min(SCREEN_HEIGHT - PADDLE_HEIGHT / 2, player1_paddle_y + 2);
  }

  // Move opponent paddle to follow ball
  if (ball_y < player2_paddle_y) {
    player2_paddle_y = max(PADDLE_HEIGHT / 2, player2_paddle_y - 1);
  }
  if (ball_y > player2_paddle_y) {
    player2_paddle_y = min(SCREEN_HEIGHT - PADDLE_HEIGHT / 2, player2_paddle_y + 1);
  }

  // Move ball
  ball_x += ball_dx;
  ball_y += ball_dy;

  // Check for ball collision with top or bottom walls
  if (ball_y - BALL_SIZE / 2 < 0 || ball_y + BALL_SIZE / 2 > SCREEN_HEIGHT) {
    ball_dy *= -1;
  }

  // Check for ball collision with player 1 paddle
  if (ball_x - BALL_SIZE / 2 <= PADDLE_WIDTH && abs(ball_y - player1_paddle_y) <= PADDLE_HEIGHT / 2) {
    ball_dx *= -1;
  }

  // Check for ball collision with player 2 paddle
  if (ball_x + BALL_SIZE / 2 >= SCREEN_WIDTH - PADDLE_WIDTH && abs(ball_y - player2_paddle_y) <= PADDLE_HEIGHT / 2) {
    ball_dx *= -1;
  }

  // Check for ball going out of bounds
  if (ball_x - BALL_SIZE / 2 < 0) {
    player2_score++;
    reset_ball();
  }
  if (ball_x + BALL_SIZE / 2 > SCREEN_WIDTH) {
    player1_score++;
    reset_ball();
  }

  // Redraw screen with updated positions
  display.clearDisplay();
  display.fillRect(0, player1_paddle_y - PADDLE_HEIGHT / 2, PADDLE_WIDTH, PADDLE_HEIGHT, WHITE);
  display.fillRect(SCREEN_WIDTH- PADDLE_WIDTH, player2_paddle_y - PADDLE_HEIGHT / 2, PADDLE_WIDTH, PADDLE_HEIGHT, WHITE);
  display.fillRect(ball_x - BALL_SIZE / 2, ball_y - BALL_SIZE / 2, BALL_SIZE, BALL_SIZE, WHITE);
  update_scoreboard();
  display.display();
}

// Reset ball to center position and randomize direction
void reset_ball() {
  ball_x = SCREEN_WIDTH / 2;
  ball_y = SCREEN_HEIGHT / 2;
  ball_dx = random(2) == 0 ? BALL_SPEED : -BALL_SPEED;
  ball_dy = random(2) == 0 ? BALL_SPEED : -BALL_SPEED;
}

// Update scoreboard with current scores
void update_scoreboard() {
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(SCREEN_WIDTH / 2 - 10, 0);
  display.print(player1_score);
  display.setCursor(SCREEN_WIDTH / 2 + 10, 0);
  display.print(player2_score);
  display.setCursor(SCREEN_WIDTH / 2, 0);
  display.print(":");

}

So i am new to arduino IDE and i was never coding c++ before. I made the projects with help from ai's and tutorials. But i still dont know how to make a screen where you can switch between these two games. Could someone help me and send me the Code? It would be Very very Nice!!!

Greetings, Alex

My standard advice:

Keep asking the robot until he/she/it gives you the correct result you expect.

One answer could probably be 42.

1 Like

@alexgamer2815 - Combining sketches is a matter of putting "wrappers" around your original functions (loop() and setup()) and setting flags to enter the separate sketches. This one had a memory issue, because of large arrays. It still needs work, but you said you wrote it, so you can fix it. : )

// https://forum.arduino.cc/t/i-need-help-to-switch-betweem-two-games-i-made-with-help/1140149

#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <Wire.h>

// OLED display settings
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// Define OLED display object
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// Define buttons and snake block size
const int LEFT_BUTTON = 5;
const int UP_BUTTON = 3;
const int DOWN_BUTTON = 4;
const int RIGHT_BUTTON = 2;

//***************
// SNEK
//***************
bool playsnek = 0;

// Define game variables
int deaths = 0;
int score = 0;
int highscore = 0;
int snake_x = 0;
int snake_y = 0;
int snake_dir_x = 1;
int snake_dir_y = 0;
int food_x = 0;
int food_y = 0;
boolean is_food_eaten = true;
const int MAX_SEGMENTS = 50; // 100 segments might crash memory
int segment_x[MAX_SEGMENTS];
int segment_y[MAX_SEGMENTS];
int num_segments = 3; // Starting with head and 2 additional segments
float speed_multiplier = 1.0;
const int SNAKE_BLOCK_SIZE = 4;
const float SPEED_INCREMENT = 0.2;
const int BASE_DELAY_TIME = 100;
const int SCREEN_LEFT_EDGE = 0;
const int SCREEN_RIGHT_EDGE = SCREEN_WIDTH - SNAKE_BLOCK_SIZE;
const int SCREEN_TOP_EDGE = 0;
const int SCREEN_BOTTOM_EDGE = SCREEN_HEIGHT - SNAKE_BLOCK_SIZE;

//***************
// PING
//***************
bool playping = 0;

// Paddle dimensions
const int PADDLE_WIDTH = 4;
const int PADDLE_HEIGHT = 20;

// Define paddle positions
int player1_paddle_y = SCREEN_HEIGHT / 2;
int player2_paddle_y = SCREEN_HEIGHT / 2;

// Ball dimensions and speed
const int BALL_SIZE = 4;
const int BALL_SPEED = 2;

// Game variables
int player1_score = 0;
int player2_score = 0;

// Ball position and direction
int ball_x = SCREEN_WIDTH / 2;
int ball_y = SCREEN_HEIGHT / 2;
int ball_dx = BALL_SPEED;
int ball_dy = BALL_SPEED;

void setup() {
  // OLED display
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.display();

  // Buttons
  pinMode(LEFT_BUTTON, INPUT_PULLUP);
  pinMode(UP_BUTTON, INPUT_PULLUP);
  pinMode(DOWN_BUTTON, INPUT_PULLUP);
  pinMode(RIGHT_BUTTON, INPUT_PULLUP);

  // Select
  display.setCursor(0, 10);
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.println("PRESS LEFT FOR SNEK");
  display.print("\nPRESS RIGHT FOR PING");
  display.display();

  while (digitalRead(LEFT_BUTTON) == HIGH && digitalRead(RIGHT_BUTTON) == HIGH) {
    if (!digitalRead(RIGHT_BUTTON))
      playping = 1;
    if (!digitalRead(LEFT_BUTTON))
      playsnek = 1;
  }
  delay(50); // button debounce
  display.clearDisplay();

  //********************
  // SNEK setup
  //********************
  if (playsnek) {

    // Print initial screen with title and prompt
    title("SNEK");

    // Set initial snake position and add to segment arrays
    resetSnake();

    // Draw snake graphic on welcome screen
    display.fillRect(100, 8, 8, 4, WHITE);
    display.fillRect(96, 12, 8, 4, WHITE);
    display.fillRect(92, 16, 8, 4, WHITE);
    display.fillRect(88, 20, 8, 4, WHITE);
    display.display();

    // Wait for any button to be pressed
    pressanybutton();
  } // SNEK setup END

  //********************
  // PING setup
  //********************
  if (playping) {
    // Print initial screen with title and prompt
    title("PING");

    // Wait for any button to be pressed
    pressanybutton();

    // Draw initial screen with paddles and ball
    display.clearDisplay();
    display.fillRect(0, player1_paddle_y - PADDLE_HEIGHT / 2, PADDLE_WIDTH, PADDLE_HEIGHT, WHITE);
    display.fillRect(SCREEN_WIDTH - PADDLE_WIDTH, player2_paddle_y - PADDLE_HEIGHT / 2, PADDLE_WIDTH, PADDLE_HEIGHT, WHITE);
    display.fillRect(ball_x - BALL_SIZE / 2, ball_y - BALL_SIZE / 2, BALL_SIZE, BALL_SIZE, WHITE);
    update_scoreboard();
    display.display();
  } // PING setup END
}

void loop() {

  //********************
  // SNEK
  //********************
  if (playsnek) {

    boolean is_collision = false;

    // Clear display before drawing new elements
    display.clearDisplay();

    // Calculate delay time based on current speed multiplier
    int delay_time = (int)(BASE_DELAY_TIME / speed_multiplier);

    // Check button input and update snake direction
    if (digitalRead(LEFT_BUTTON) == LOW) {
      snake_dir_x = -1;
      snake_dir_y = 0;
    } else if (digitalRead(UP_BUTTON) == LOW) {
      snake_dir_x = 0;
      snake_dir_y = -1;
    } else if (digitalRead(DOWN_BUTTON) == LOW) {
      snake_dir_x = 0;
      snake_dir_y = 1;
    } else if (digitalRead(RIGHT_BUTTON) == LOW) {
      snake_dir_x = 1;
      snake_dir_y = 0;
    }

    // Erase previous snake head position
    display.fillRect(segment_x[num_segments - 1], segment_y[num_segments - 1], SNAKE_BLOCK_SIZE, SNAKE_BLOCK_SIZE, BLACK);

    // Move snake segments
    for (int i = num_segments - 1; i > 0; i--) {
      segment_x[i] = segment_x[i - 1];
      segment_y[i] = segment_y[i - 1];
    }

    // Update snake head position
    snake_x += snake_dir_x * SNAKE_BLOCK_SIZE;
    snake_y += snake_dir_y * SNAKE_BLOCK_SIZE;

    // Wrap around to opposite edge if going out of bounds
    if (snake_x < SCREEN_LEFT_EDGE) {
      snake_x = SCREEN_RIGHT_EDGE;
    } else if (snake_x > SCREEN_RIGHT_EDGE) {
      snake_x = SCREEN_LEFT_EDGE;
    }
    if (snake_y < SCREEN_TOP_EDGE) {
      snake_y = SCREEN_BOTTOM_EDGE;
    } else if (snake_y > SCREEN_BOTTOM_EDGE) {
      snake_y = SCREEN_TOP_EDGE;
    }

    // Check for food collision
    if (snake_x == food_x && snake_y == food_y) {
      // Increase speed and reset food position
      speed_multiplier += SPEED_INCREMENT;
      is_food_eaten = true;
      tone(48, 40, 30);
      score++;

      // Update high score if necessary
      if (score > highscore) {
        highscore = score;
      }

      // Add new segment to snake if possible
      if (num_segments < MAX_SEGMENTS) {
        segment_x[num_segments] = segment_x[num_segments - 1];
        segment_y[num_segments] = segment_y[num_segments - 1];
        num_segments++;
      }
    }

    // Check for self-collision
    for (int i = 1; i < num_segments; i++) {
      if (snake_x == segment_x[i] && snake_y == segment_y[i]) {
        is_collision = true;
        break;
      }
    }

    // Update snake head segment
    segment_x[0] = snake_x;
    segment_y[0] = snake_y;

    // Place food if needed
    if (is_food_eaten) {
      food_x = random(SCREEN_WIDTH / SNAKE_BLOCK_SIZE) * SNAKE_BLOCK_SIZE;
      food_y = random(SCREEN_HEIGHT / SNAKE_BLOCK_SIZE) * SNAKE_BLOCK_SIZE;
      is_food_eaten = false;
    }

    // Draw snake and food
    for (int i = 0; i < num_segments; i++) {
      display.fillRect(segment_x[i], segment_y[i], SNAKE_BLOCK_SIZE, SNAKE_BLOCK_SIZE, WHITE);
    }

    display.fillCircle(food_x + SNAKE_BLOCK_SIZE / 2, food_y + SNAKE_BLOCK_SIZE / 2, SNAKE_BLOCK_SIZE / 2, WHITE);

    // Display game over message if collision detected
    if (is_collision)
      game_over();

    // Update display
    display.display();

    // Delay for smooth animation
    delay(delay_time);
  }

  //********************
  // PING
  //********************
  if (playping) {
    // Move paddles based on button inputs
    if (digitalRead(UP_BUTTON) == LOW) {
      player1_paddle_y = max(PADDLE_HEIGHT / 2, player1_paddle_y - 2);
    }
    if (digitalRead(DOWN_BUTTON) == LOW) {
      player1_paddle_y = min(SCREEN_HEIGHT - PADDLE_HEIGHT / 2, player1_paddle_y + 2);
    }

    // Move opponent paddle to follow ball
    if (ball_y < player2_paddle_y) {
      player2_paddle_y = max(PADDLE_HEIGHT / 2, player2_paddle_y - 1);
    }
    if (ball_y > player2_paddle_y) {
      player2_paddle_y = min(SCREEN_HEIGHT - PADDLE_HEIGHT / 2, player2_paddle_y + 1);
    }

    // Move ball
    ball_x += ball_dx;
    ball_y += ball_dy;

    // Check for ball collision with top or bottom walls
    if (ball_y - BALL_SIZE / 2 < 0 || ball_y + BALL_SIZE / 2 > SCREEN_HEIGHT) {
      ball_dy *= -1;
    }

    // Check for ball collision with player 1 paddle
    if (ball_x - BALL_SIZE / 2 <= PADDLE_WIDTH && abs(ball_y - player1_paddle_y) <= PADDLE_HEIGHT / 2) {
      ball_dx *= -1;
    }

    // Check for ball collision with player 2 paddle
    if (ball_x + BALL_SIZE / 2 >= SCREEN_WIDTH - PADDLE_WIDTH && abs(ball_y - player2_paddle_y) <= PADDLE_HEIGHT / 2) {
      ball_dx *= -1;
    }

    // Check for ball going out of bounds
    if (ball_x - BALL_SIZE / 2 < 0) {
      player2_score++;
      reset_ball();
    }
    if (ball_x + BALL_SIZE / 2 > SCREEN_WIDTH) {
      player1_score++;
      reset_ball();
    }

    // redraw screen with updated positions
    display.clearDisplay();
    display.fillRect(0, player1_paddle_y - PADDLE_HEIGHT / 2, PADDLE_WIDTH, PADDLE_HEIGHT, WHITE);
    display.fillRect(SCREEN_WIDTH - PADDLE_WIDTH, player2_paddle_y - PADDLE_HEIGHT / 2, PADDLE_WIDTH, PADDLE_HEIGHT, WHITE);
    display.fillRect(ball_x - BALL_SIZE / 2, ball_y - BALL_SIZE / 2, BALL_SIZE, BALL_SIZE, WHITE);
    update_scoreboard();
    display.display();
  }
}

void game_over() {
// snek
  tone(48, 400, 500);
  display.clearDisplay();
  display.setCursor(0, 10);
  display.setTextColor(WHITE);
  display.setTextSize(2);
  display.print("GAME OVER!");
  display.setTextSize(1);
  display.setCursor(0, SCREEN_HEIGHT - 30);
  display.print("Deaths: ");
  display.print(deaths + 1);
  display.setCursor(0, SCREEN_HEIGHT - 20);
  display.setTextColor(WHITE);
  display.print("Score: ");
  display.print(score);
  display.setCursor(0, SCREEN_HEIGHT - 10);
  display.print("Highscore: ");
  display.print(highscore);
  display.display();
  delay(3000);
  pressanybutton();
  reset_game();
  deaths++;
  playsnek = 0;
}

void reset_game() {
  // Reset snake position and direction
  snake_x = SCREEN_WIDTH / 2;
  snake_y = SCREEN_HEIGHT / 2;
  snake_dir_x = 0;
  snake_dir_y = -1;

  // Reset speed and score
  speed_multiplier = 1.0;
  score = 0;

  // Reset snake segments
  num_segments = 3;

  // Set initial snake position and add to segment arrays
  resetSnake();

  // Reset food position
  food_x = random(SCREEN_WIDTH / SNAKE_BLOCK_SIZE) * SNAKE_BLOCK_SIZE;
  food_y = random(SCREEN_HEIGHT / SNAKE_BLOCK_SIZE) * SNAKE_BLOCK_SIZE;
  is_food_eaten = false;
}


void resetSnake() {
  // Reset initial snake position and add to segment arrays
  segment_x[0] = snake_x;
  segment_y[0] = snake_y;
  segment_x[1] = snake_x - SNAKE_BLOCK_SIZE;
  segment_y[1] = snake_y;
  segment_x[2] = snake_x - 2 * SNAKE_BLOCK_SIZE;
  segment_y[2] = snake_y;
}

void reset_ball() {
  // ping - reset ball to center position and randomize direction
  ball_x = SCREEN_WIDTH / 2;
  ball_y = SCREEN_HEIGHT / 2;
  ball_dx = random(2) == 0 ? BALL_SPEED : -BALL_SPEED;
  ball_dy = random(2) == 0 ? BALL_SPEED : -BALL_SPEED;
}

void update_scoreboard() {
  // ping - update scoreboard with current scores
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(SCREEN_WIDTH / 2 - 10, 0);
  display.print(player1_score);
  display.setCursor(SCREEN_WIDTH / 2 + 10, 0);
  display.print(player2_score);
  display.setCursor(SCREEN_WIDTH / 2, 0);
  display.print(":");
}

void title(char gamename[]) {
  // ping and snek
  display.setCursor(0, 10);
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.println(gamename);
  display.setCursor(0, SCREEN_HEIGHT - 25);
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.println("Press any button to");
  display.setCursor(0, SCREEN_HEIGHT - 15);
  display.println("Play");
  display.display();
}

void pressanybutton() {
  // ping and snek
  while (
    digitalRead(LEFT_BUTTON) == HIGH &&
    digitalRead(UP_BUTTON) == HIGH &&
    digitalRead(DOWN_BUTTON) == HIGH &&
    digitalRead(RIGHT_BUTTON) == HIGH
  )
    delay(50); // button debounce
}

I have a solution for this as now I use it to switch between 5 function on my oled. Use a menu function and loop wrapper individual program.

As for the snake game, anyone know how to make it work only with 2 button instead on 4? To toggle left/right only

What you could do is make each game a class then call the corresponding setup and loop functions from each instance respectfully. This way you can have as many games as you want, provided you have the memory to hold them all.

Why no up/down? A vertical scroller?

Maybe one more game?

Sketch uses 18828 bytes (61%) of program storage space. Maximum is 30720 bytes.
Global variables use 721 bytes (35%) of dynamic memory, leaving 1327 bytes for local variables. Maximum is 2048 bytes.

Wallball perhaps? One less object to keep track of. OP could learn inheritance too in the process.

Sure, any direction as long only 2 button involve.

Replying your quote about the memory, expand the nano memory by editing the storage,

I do this yesterday and its working. I add 5 program into my nano, 2 of it is dino game and flappy bird game.

You say you do this, but can not find the six lines of code to ignore the up/down buttons? What have you tried?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.