// مشروع لعبة الثعبان باستخدام شاشة أوليد وجويستيك مع الأردوينو
// إعداد المهندس/ أحمد درويش
// تضمين المكتبات الأساسية للتحكم في شاشة OLED
#include <Wire.h> // مكتبة التواصل عبر I2C
#include <Adafruit_GFX.h> // مكتبة الرسومات العامة
#include <Adafruit_SSD1306.h> // مكتبة شاشة OLED من نوع SSD1306
// تحديد أبعاد شاشة OLED
#define SCREEN_WIDTH 128 // عرض الشاشة
#define SCREEN_HEIGHT 64 // ارتفاع الشاشة
// تحديد منافذ التوصيل للأزرار والجهاز الطنان (Buzzer)
#define JOYSTICK_BUTTON 2 // زر الجويستيك متصل بالمنفذ الرقمي 2
#define BUZZER 3 // الجرس متصل بالمنفذ الرقمي 3
// إنشاء كائن لشاشة OLED باستخدام مكتبة Adafruit
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// متغيرات تخزين مواقع الثعبان والتفاحة والنقاط
int snakeX = SCREEN_WIDTH / 2; // موقع الثعبان الأفقي (وسط الشاشة)
int snakeY = SCREEN_HEIGHT / 2; // موقع الثعبان الرأسي (وسط الشاشة)
int appleX = random(0, SCREEN_WIDTH); // موقع التفاحة العشوائي أفقيًا
int appleY = random(0, SCREEN_HEIGHT); // موقع التفاحة العشوائي رأسيًا
int snakeLength = 1; // طول الثعبان الأولي
int score = 0; // النقاط الأولية
// هيكل لتخزين مواقع قطع الثعبان
typedef struct {
int x;
int y;
} SnakeSegment;
// مصفوفة لتخزين مواقع الثعبان حتى 100 قطعة
SnakeSegment snake[100];
// متغيرات تحديد اتجاه الحركة الأولية
int directionX = 1; // التحرك لليمين افتراضياً
int directionY = 0;
// دالة عرض شاشة الترحيب عند بدء اللعبة
void showWelcomeScreen() {
display.clearDisplay(); // مسح الشاشة
display.setTextSize(2); // حجم النص كبير
display.setTextColor(SSD1306_WHITE); // لون النص أبيض
// عرض نص ترحيبي
display.setCursor(10, 20);
display.print("The Snake");
display.display();
delay(3000);
// عرض اسم المهندس المصمم
display.clearDisplay();
display.setCursor(10, 10);
display.print("Eng.");
display.setCursor(10, 30);
display.print("Ahmed");
display.setCursor(10, 50);
display.print("Darwish");
display.display();
delay(3000);
}
// دالة الإعدادات الأولية - تعمل مرة واحدة عند تشغيل الأردوينو
void setup() {
pinMode(JOYSTICK_BUTTON, INPUT_PULLUP); // إعداد زر الجويستيك كمدخل مع مقاومة رفع داخلية
pinMode(BUZZER, OUTPUT); // إعداد منفذ الجرس كخرج
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // بدء تشغيل الشاشة على العنوان 0x3C عبر I2C
display.clearDisplay(); // مسح الشاشة
display.display();
showWelcomeScreen(); // عرض شاشة الترحيب قبل بدء اللعبة
}
// الحلقة الرئيسية - تعمل بشكل مستمر لعرض اللعبة وتشغيلها
void loop() {
// قراءة قيم الجويستيك من المحورين الأفقي والرأسي
int xValue = analogRead(A0); // قراءة المحور الأفقي
int yValue = analogRead(A1); // قراءة المحور الرأسي
// التحكم في اتجاه حركة الثعبان حسب اتجاه الجويستيك
if (xValue < 300) { // تحريك الثعبان لليمين
directionX = 1;
directionY = 0;
} else if (xValue > 700) { // تحريك الثعبان لليسار
directionX = -1;
directionY = 0;
}
if (yValue < 300) { // تحريك الثعبان للأسفل
directionX = 0;
directionY = 1;
} else if (yValue > 700) { // تحريك الثعبان للأعلى
directionX = 0;
directionY = -1;
}
// تحريك الثعبان وتحديث الموقع
snakeX += directionX;
snakeY += directionY;
// تجاوز الحواف بإعادة الدخول من الجهة المقابلة
if (snakeX < 0) snakeX = SCREEN_WIDTH - 1;
if (snakeX >= SCREEN_WIDTH) snakeX = 0;
if (snakeY < 0) snakeY = SCREEN_HEIGHT - 1;
if (snakeY >= SCREEN_HEIGHT) snakeY = 0;
// تحريك جميع أجزاء الثعبان
for (int i = snakeLength; i > 0; i--) {
snake[i] = snake[i - 1];
}
snake[0].x = snakeX;
snake[0].y = snakeY;
// التحقق من التقاط التفاحة
if (abs(snakeX - appleX) < 3 && abs(snakeY - appleY) < 3) {
digitalWrite(BUZZER, HIGH); // إصدار صوت عند التقاط التفاحة
delay(100);
digitalWrite(BUZZER, LOW);
appleX = random(0, SCREEN_WIDTH); // إعادة تحديد موقع جديد للتفاحة
appleY = random(0, SCREEN_HEIGHT);
snakeLength++; // زيادة طول الثعبان
score++; // زيادة النقاط
}
drawSnake(); // عرض الثعبان والتفاحة
displayScore(); // عرض النقاط
// حساب زمن التأخير لجعل اللعبة أسرع كلما زادت النقاط
int delayTime = max(50, 200 - (score * 10));
delay(delayTime);
}
// دالة رسم الثعبان والتفاحة على الشاشة
void drawSnake() {
display.clearDisplay();
// رسم جميع أجزاء الثعبان كمربعات صغيرة
for (int i = 0; i < snakeLength; i++) {
display.fillRect(snake[i].x, snake[i].y, 3, 3, SSD1306_WHITE);
}
// رسم التفاحة كمربع صغير
display.fillRect(appleX, appleY, 3, 3, SSD1306_WHITE);
display.display();
}
// دالة عرض النقاط على الشاشة
void displayScore() {
display.setCursor(0, 0);
display.setTextSize(1); // حجم النص صغير للنقاط
display.setTextColor(SSD1306_WHITE); // لون النص أبيض
display.print("Score: ");
display.print(score);
display.display();
}
Loading
ssd1306
ssd1306