Освой Arduino играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

M5Stack. Пинг-понг

На русскоязычном форуме есть урок создания игры в пинг-понг. Урок предназначен для M5Stack Fire и использует светодиодную панель и неудобный способ подключения переменного резистора к порту Grove. Я взял исходники игры с Гитхаба и убрал код для светодиодной панели и загрузки картинки. В качестве переменного резистора использовал большой потенциометр.

Potentiometer

Сигнальный вывод потенциометра подключил к порту 36, остальные два вывода подключил к портам GND и 5V.

M5Stack Ping Pong

Получившийся код.


#include <M5Stack.h>

int screen_width = 320;
int screen_height = 240;
int raket_position;
long interval;
int ball_x;
int ball_y;
int ball_r;
int accel_x;
int accel_y;
int score;

void start() {
  M5.Lcd.fillScreen(0x0000);
  interval = 60;
  ball_x = 160;
  ball_y = 120;
  ball_r = 6;
  accel_x = 4;
  accel_y = 4;
  score = 0;
  M5.Lcd.setTextSize(2);
  long previousMillis = 0;
  long interval = 500;
  int color = 0x0000;
  while (true)
  {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis > interval) {
      previousMillis = currentMillis;
      color = (color == 0x7bef) ? 0xffff : 0x7bef;
      M5.Lcd.setCursor(35, 200);
      M5.Lcd.setTextColor(color);
      M5.Lcd.print("press any key to play");
    }
    M5.update();
    if (M5.BtnA.wasPressed() || M5.BtnB.wasPressed() || M5.BtnC.wasPressed()) break;
  }
  M5.Lcd.fillScreen(0x0000);
  M5.Speaker.tone(800);
  delay(100);
  M5.Speaker.tone(1200);
  delay(100);
  M5.Speaker.mute();
  delay(500);
  M5.Lcd.fillScreen(0xffff);
}

void game() {
  M5.Lcd.fillCircle(ball_x, ball_y, ball_r, 0x7bef);
  long previousMillis = 0;
  while (true)
  {
    int voltage = analogRead(36) * 3400 / 4096;
    int percentage = voltage * 100 / 3400;
    raket_position = map(percentage, 0, 100, 0, 10);
    int raket_width = 20;
    int raket_height = 40;
    int raket_margin = 10;
    int x, y, color, raket_x, raket_y;
    for (int i = 0; i < 10; i++)
    {
      if (i < 5)
      {
        x = 0;
        y = i * (raket_height + raket_margin);
      }
      else
      {
        x = screen_width - raket_width;
        y = (9 - i) * (raket_height + raket_margin);
      }
      color = (i == raket_position) ? RED : WHITE;
      M5.Lcd.fillRect(x, y, raket_width, raket_height, color);

      if (i == raket_position)
      {
        raket_x = x;
        raket_y = y;
      }
    }
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis > interval) {
      previousMillis = currentMillis;
      M5.Lcd.fillCircle(ball_x, ball_y, ball_r, WHITE);
      ball_x += accel_x;
      ball_y += accel_y;
      M5.Lcd.fillCircle(ball_x, ball_y, ball_r, 0x7bef);
      if (ball_y <= 0)
        accel_y *= -1;
      if (ball_y >= 240)
        accel_y *= -1;
      if (raket_position > 4)
      {
        if ((ball_x + ball_r >= raket_x) && (ball_y + ball_r >= raket_y) && (ball_y - ball_r <= raket_y + raket_height))
        {
          accel_x *= -1;
          accel_y *= 1;
          repulse();
        }
      }
      else
      {
        if ((ball_x - ball_r <= raket_x + raket_width) && (ball_y + ball_r >= raket_y) && (ball_y - ball_r <= raket_y + raket_height))
        {
          accel_x *= -1;
          accel_y *= 1;
          repulse();
        }
      }
      if ((ball_x < 0) || (ball_x > screen_width) || (ball_y < 0) || (ball_y > screen_height))
      {
        gameover();
        return;
      }
    }
  }
}

void repulse() {
  M5.Speaker.tone(1800);
  delay(50);
  M5.Speaker.mute();
  score++;
  interval -= (interval >= 25) ? 5 : 0;
}

void gameover() {
  M5.Lcd.fillScreen(0x0000);
  M5.Speaker.tone(1200);
  delay(100);
  M5.Speaker.tone(1000);
  delay(100);
  M5.Speaker.tone(800);
  delay(100);
  M5.Speaker.tone(1100);
  delay(100);
  M5.Speaker.mute();
  M5.Lcd.setCursor(100, 100);
  M5.Lcd.setTextColor(0xffff);
  M5.Lcd.print("GAME OVER");
  delay(1000);

  for (int i = 0; i < score; i++)
  {
    M5.Lcd.setCursor(100, 120);
    M5.Lcd.setTextColor(0xffff);
    M5.Lcd.print("SCORE: ");
    M5.Lcd.setTextColor(0x0000);
    M5.Lcd.print((i < 1) ? 0 : i);
    M5.Lcd.setCursor(100, 120);
    M5.Lcd.setTextColor(0xffff);
    M5.Lcd.print("SCORE: ");
    M5.Lcd.print(i + 1);
    M5.Speaker.tone(1200);
    delay(100);
    M5.Speaker.mute();
  }
  delay(2000);
}

void setup() {
  M5.begin();
  pinMode(36, INPUT);
}

void loop() {
  start();
  game();
}

Дополнительные материалы

Реклама