#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define NOTE_EIGHTH 200
#define NOTE_SIXTEENTH 100
#define NOTE_QUARTER 400
#define NOTE_HALF 800
#define S_WIDTH 128
#define S_HIGHT 64
#define BRICK_W 16
#define BRICK_H 7
#define BRICKS_COLS (S_WIDTH / BRICK_W)
#define BRICKS_ROWS (28 / BRICK_H)
#define PADDLE_W 40
#define PADDLE_H 6
#define BALL_RAD 2
//oled
Adafruit_SSD1306 oled(S_WIDTH, S_HIGHT, &Wire, -1);
bool game_over = false;
//joystick
int joyX = A1;
//piezo
const int piezo = 7;
//brick
const int brick_status_size = (S_WIDTH / BRICK_W) * (28 / BRICK_H);
int bricks_status[brick_status_size];
int bricks_left = brick_status_size;
int ball_x, ball_y, player_x, player_y;
int speedX = 1, speedY = 1, player_speed = 4;
void setup() {
pinMode(joyX, INPUT);
pinMode(piezo, OUTPUT);
//https://randomnerdtutorials.com/guide-for-oled-display-with-arduino/
if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
while (true);
}
for (int i = 0; i < brick_status_size; i++) {
bricks_status[i] = 1;
}
ball_x = S_WIDTH / 2;
ball_y = S_HIGHT / 2;
player_x = (S_WIDTH/2) - (PADDLE_W/2);
player_y = S_HIGHT - PADDLE_H;
oled.clearDisplay();
setup_oled();
}
void loop() {
if(game_over) return;
int val_x = analogRead(joyX);
move_player(val_x);
move_ball();
if((ball_y + BALL_RAD) >= S_HIGHT){
oled.clearDisplay();
oled.setTextSize(2);
oled.setTextColor(WHITE);
oled.setCursor(0, 0);
oled.print("YOU LOSE");
oled.display();
loose_melody();
game_over = true;
return;
}else{
check_colision();
oled.clearDisplay();
draw_player(player_x, player_y);
draw_ball(ball_x, ball_y);
draw_map();
oled.display();
}
if(bricks_left == 0){
oled.clearDisplay();
oled.setTextSize(2);
oled.setTextColor(WHITE);
oled.setCursor(0, 0);
oled.print("YOU WIN");
oled.display();
play_music();
game_over = true;
return;
}
}
void setup_oled() {
oled.setTextSize(1);
oled.setTextColor(WHITE);
oled.setCursor(0, 0);
}
void draw_map() {
int x, y;
for (int i = 0; i < BRICKS_ROWS; i++) {
for (int j = 0; j < BRICKS_COLS; j++) {
if (bricks_status[i * BRICKS_COLS + j]) {
x = j * BRICK_W;
y = i * BRICK_H;
oled.drawRect(x, y, BRICK_W, BRICK_H, WHITE);
}
}
}
}
void draw_player(int x, int y) {
oled.fillRect(x, y, PADDLE_W, PADDLE_H, WHITE);
}
void move_player(int x){
int threshold = 200;
if (x > 512 && player_x > 0)
player_x -= player_speed;
if (x < 512 && player_x + PADDLE_W < S_WIDTH)
player_x += player_speed;
}
void draw_ball(int x, int y) {
oled.drawCircle(x, y, BALL_RAD, WHITE);
}
void move_ball() {
ball_x += speedX;
ball_y += speedY;
if (ball_x <= 0 || ball_x >= S_WIDTH - BALL_RAD) {
speedX = -speedX;
speedY += random(-1, 1);
speedY = constrain(speedY, -2, 2);
}
if (ball_y <= 0) {
speedY = -speedY;
speedX += random(-1, 1);
speedX = constrain(speedX, -2, 2);
}
if (speedX == 0) speedX = 1;
if (speedY == 0) speedY = 1;
}
void check_colision(){
if(ball_x + BALL_RAD >= player_x && ball_x + BALL_RAD <= player_x + PADDLE_W){
if(ball_y + BALL_RAD >= player_y && ball_y - BALL_RAD <= player_y + PADDLE_H){
speedY = - speedY;
int paddle_center = player_x + PADDLE_W / 2;
int offset = ball_x - paddle_center;
speedX = offset / 2;
hit_sound();
}
}
int brick_x, brick_y;
for(int i = 0; i < BRICKS_ROWS; i++){
for(int j = 0; j < BRICKS_COLS; j++){
int index = i * BRICKS_COLS + j;
if(!bricks_status[index]) continue;
brick_x = j * BRICK_W;
brick_y = i * BRICK_H;
if (ball_x + BALL_RAD >= brick_x && ball_x - BALL_RAD <= brick_x + BRICK_W && ball_y + BALL_RAD >= brick_y && ball_y - BALL_RAD <= brick_y + BRICK_H){
bricks_status[index] = 0;
bricks_left--;
hit_sound();
if (ball_x >= brick_x && ball_x <= brick_x + BRICK_W) {
speedY = -speedY;
} else {
speedX = -speedX;
}
return;
}
}
}
}
void hit_sound() {
tone(piezo, random(100,300), 20);
delay(20);
noTone(piezo);
}
void playNote(int note, int duration) {
tone(piezo, note, duration);
delay(duration * 1.1);
noTone(piezo);
}
void play_music(){
// Первая часть мелодии
playNote(554, NOTE_EIGHTH); // C#5
playNote(554, NOTE_EIGHTH); // C#5
playNote(587, NOTE_SIXTEENTH); // D5
playNote(554, NOTE_SIXTEENTH); // C#5
playNote(494, NOTE_SIXTEENTH); // B4
playNote(587, NOTE_SIXTEENTH); // D5
playNote(554, NOTE_EIGHTH); // C#5
playNote(494, NOTE_EIGHTH); // B4
playNote(440, NOTE_EIGHTH); // A4
playNote(494, NOTE_EIGHTH); // B4
playNote(440, NOTE_EIGHTH); // A4
playNote(440, NOTE_EIGHTH); // A4
playNote(494, NOTE_SIXTEENTH); // B4
playNote(440, NOTE_SIXTEENTH); // A4
playNote(415, NOTE_SIXTEENTH); // G#4
playNote(440, NOTE_EIGHTH); // A4
playNote(370, NOTE_QUARTER); // F#4
playNote(277, NOTE_QUARTER);
// Вторая часть (добавленная)
playNote(554, NOTE_EIGHTH); // C#5
playNote(554, NOTE_EIGHTH); // C#5
playNote(587, NOTE_SIXTEENTH); // D5
playNote(554, NOTE_SIXTEENTH); // C#5
playNote(494, NOTE_SIXTEENTH); // B4
playNote(587, NOTE_SIXTEENTH); // D5
playNote(494, NOTE_EIGHTH); // B4
playNote(494, NOTE_EIGHTH); // B4
playNote(554, NOTE_SIXTEENTH); // C#5
playNote(494, NOTE_SIXTEENTH); // B4
playNote(440, NOTE_SIXTEENTH); // A4
playNote(494, NOTE_SIXTEENTH); // B4
playNote(440, NOTE_EIGHTH); // A4
playNote(440, NOTE_EIGHTH); // A4
playNote(494, NOTE_SIXTEENTH); // B4
playNote(440, NOTE_SIXTEENTH); // A4
playNote(415, NOTE_SIXTEENTH); // G#4
playNote(440, NOTE_SIXTEENTH); // A4
playNote(415, NOTE_EIGHTH); // G#4
playNote(415, NOTE_EIGHTH); // G#4
playNote(440, NOTE_EIGHTH); // A4
playNote(494, NOTE_EIGHTH); // B4
playNote(554, NOTE_EIGHTH); // C#5
playNote(554, NOTE_EIGHTH); // C#5
playNote(587, NOTE_SIXTEENTH); // D5
playNote(554, NOTE_SIXTEENTH); // C#5
playNote(494, NOTE_SIXTEENTH); // B4
playNote(587, NOTE_SIXTEENTH); // D5
playNote(554, NOTE_EIGHTH); // C#5
playNote(494, NOTE_EIGHTH); // B4
playNote(440, NOTE_EIGHTH); // A4
playNote(494, NOTE_EIGHTH); // B4
playNote(440, NOTE_EIGHTH); // A4
playNote(440, NOTE_EIGHTH); // A4
playNote(494, NOTE_SIXTEENTH); // B4
playNote(440, NOTE_SIXTEENTH); // A4
playNote(415, NOTE_SIXTEENTH); // G#4
playNote(440, NOTE_EIGHTH); // A4
playNote(370, NOTE_QUARTER); // F#4
}
void loose_melody(){
playNote(261, NOTE_EIGHTH); // C4
playNote(329, NOTE_EIGHTH); // E4
playNote(392, NOTE_EIGHTH); // G4
playNote(349, NOTE_EIGHTH); // F4
playNote(330, NOTE_EIGHTH); // E4
playNote(294, NOTE_EIGHTH); // D4
playNote(262, NOTE_EIGHTH); // C4
delay(NOTE_EIGHTH); // пауза
playNote(196, NOTE_QUARTER); // G3
playNote(262, NOTE_QUARTER); // C4
delay(NOTE_EIGHTH); // пауза
playNote(196, NOTE_QUARTER); // G3
playNote(262, NOTE_QUARTER); // C4
delay(NOTE_EIGHTH); // пауза
playNote(330, NOTE_EIGHTH); // E4
playNote(294, NOTE_EIGHTH); // D4
playNote(262, NOTE_HALF); // C4
}