JavaFX طريقة إنشاء لعبة من سيربح المليون

في هذا الدرس ستتعلم طريقة إنشاء لعبة من سيربح المليون ( Who will win the million ) إحترافية بإستخدام إطار JavaFX.

سورس كود لعبة من سيربح المليون


مميزات اللعبة

  • تلائم حجم أي شاشة كمبيوتر يتم تشغيلها عليه لأنها مبنية بطريقة ( Responsive ).
  • فيها أشكال هندسية مخصصة و مصممة بطريقة تجذب المستخدم, و عدة أصوات و مؤثرات بصرية يتم تشغيلها عندما يتفاعل المستخدم مع اللعبة.
  • تحتوي على 100 سؤال و 400 إجابة يتم عرضهم بشكل عشوائي.
  • فيها نفس وسائل المساعدة الموجودة في لعبة من سيربح المليون.
  • يمكنك تطوير اللعبة و تغيير الأسئلة و الإجابات بسهولة إذا أردت إنشاء نسختك الخاصة من اللعبة.


بناء اللعبة

  • ملفات الجافا وضعناها مباشرةً في المشروع.
  • إستخدمنا خط خاص وضعناه في مجلد إسمه fonts.
  • الصور وضعناه بداخل مجلد إسمه images.
  • الأصوات وضعناه بداخل مجلد إسمه sounds.

سورس كود لعبة من سيربح المليون



خيارات التحميل

⇓ تحميل اللعبة ⇓ تحميل المشروع كاملاً



معلومات عامة عن الكود

  • الكلاس AboutButtonShape قمنا ببنائه خصيصاً لنحصل على شكل الزر الذي أظهرناه في صفحة حول التطبيق
  • الكلاس AboutPane قمنا ببنائه خصيصاً لنحصل على الحاوية الأساسية التي سنعرضها في صفحة حول التطبيق مع الإشارة إلى أننا وضعنا فيه كل محتوى الصفحة.
  • الكلاس GameAnswerButton قمنا ببنائه خصيصاً لنحصل على شكل الأزرار التي يمكن النقر عليها لاختيار الإجابة في صفحة اللعب
  • الكلاس GamePane قمنا ببنائه خصيصاً لتمثيل صفحة اللعب
  • الكلاس GameQuestionShape قمنا ببنائه خصيصاً لنحصل على شكل الحاوية التي ستوضع فيها الأسئلة في صفحة اللعب
  • الكلاس Main قمنا ببناء نافذة اللعبة كل الصفحات الموجودة فيها بالإضافة إلى أنه يعتبر نقطة البداية في هذا المشروع.
  • الكلاس MenuItemShape قمنا ببنائه خصيصاً لبناء شكل الأزرار التي وضعناها في صفحة القائمة الرئيسية
  • الكلاس MenuPane قمنا ببنائه خصيصاً لتمثيل صفحة القائمة الرئيسية
  • الكلاس Questions وضعنا فيه جميع أسئلة اللعبة مع الإجابات الخاصة بها.
  • الكلاس ResultPane قمنا ببنائه خصيصاً لتمثيل صفحة النتيجة النهائية
  • الكلاس Sounds قمنا ببنائه خصيصاً لتجهيز دوال يمكن إستخدامها لتشغيل أصوات في اللعبة.
  • الإنترفيس ScreenBounds وضعنا فيه المعلومات الأساسية و المشتركة التي يجب أن تتوفر في كل حاوية تمثل صفحة في اللعبة.


كود اللعبة

AboutButtonShape.java
import javafx.beans.binding.Bindings;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import javafx.scene.shape.Rectangle;

// و جعله قابل للنقر (Width + Height) هو لتمكيننا من إعطائه حجم Rectangle يرث من الكلاس AboutButtonShape سبب جعل الكلاس
public class AboutButtonShape extends Rectangle {

	// AboutButtonShape لأننا سنعتمد عليه لنرسم شكل الزر الذي نريد الحصول عليه عند إنشاء كائن من الكلاس Polygon هنا قمنا بتعريف كائن نوعه
    Polygon polygon;

	// هنا قمنا بتجهيز هذا الكونستركتور حتى نستطيع تحديد حجم الزر مباشرةً عند إنشاء كائن من هذا الكلاس
    public AboutButtonShape(int width, int height) {

		// عند إنشاء كائن من الكلاس height و width لاحظ أن شكل الزر الذي سيتم رسمه يعتمد بشكل أساسي على القيم التي سنمررها للباراميترين
        polygon = new Polygon(
                0, height/2,
                20, 0,
                width-20, 0,
                width, height/2,
                width-20, height,
                20, height,
                0, height/2
        );
        
		// لأننا سندمجه معه AboutButtonShape و الذي بدوره سيتم تطبيقه على الكائن الذي ننشئه من الكلاس polygon هنا قمنا بإضافة لون أبيض باهت حول الكائن
        polygon.setStroke(Color.color(1, 1, 1, 0.75));

		// الطبيعي هو غامق بنسبة 25 بالمئة و سيصبح أغمق بنسبة 50 بالمئة حين ننقر فوقه بالفأرة polygon هنا حددنا أن لون خلفية الكائن
        polygon.fillProperty().bind(Bindings.when(pressedProperty())
                .then(Color.color(0, 0, 0, 0.50))
                .otherwise(Color.color(0, 0, 0, 0.25))
        );
        
		// AboutButtonShape عند إنشاء كائن من الكلاس height و width حددنا أن حجم الشكل الذي سنحصل عليه سيكون مطابقاً للقيم التي نمررها مكان البارميترين
		// AboutButtonShape يساوي حجم الكائن الذي سنحصل عليه عند دمجه مع الكائن الذي ننشئه من الكلاس polygon بهذه الطريقة يكون حجم الكائن
        this.setWidth(width);
        this.setHeight(height);
		
		// هو أزرق AboutButtonShape هنا حددنا أن لون خلفية الكائن الذي سنحصل عليه عند إنشاء كائن من الكلاس
		// كما أنه عند تمرير الفأرة فوقه سيتحول شكل السهم إلى شكل إصبع, مما يجعل المستخدم يدرك أن هذا الشكل قابل للنقر
        this.setFill(Color.BLUE);
        this.setStyle("-fx-cursor: hand;");

		// AboutButtonShape على الكائن الذي ننشئه من الكلاس polygon هنا قمنا بدمج و تطبيق خصائص الكائن
        this.setClip(polygon);

    }

}
		

AboutPane.java
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.TextAlignment;

// حتى يظهر محتواه في وسط النافذة StackPane يرث من الكلاس AboutPane هنا جعلنا الكلاس
// حتى يكون حجمه مطابق لحجم شاشة المستخدم ScreenBounds و جعلناه يطبق الإنترفيس
public class AboutPane extends StackPane implements ScreenBounds {

	// حتى نستطيع إستدعاء دوال تشغيل الأصوات التي جهزناها فيه Sounds هنا قمنا بإنشاء كائن من الكلاس
    Sounds mySounds = new Sounds();

	// لأننا سنعرض النص عليه Label هنا قمنا بإنشاء كائن من الكلاس
    Label label = new Label("تم تصميم هذه اللعبة لتشجيع الطلاب على التعلم و لمساعدتهم في إختبار قدراتهم على الحفظ\n"
            + "اللعبة من إعداد المبرمج محمد هرموش و هي مجانية بالكامل");
	
	// حتى نحصل على شكل زر خاص لونه لون خلفيته أزرق, مع تحديد حجمه AboutButtonShape هنا قمنا بإنشاء كائن من الكلاس
    AboutButtonShape buttonShape = new AboutButtonShape(220, 40);
	
	// buttonShape بهدف وضعه كنص للزر الذي يمثله الكائن Label هنا قمنا بإنشاء كائن من الكلاس
    Label buttonLabel = new Label("رجوع");
	
	// label لأننا ننوي إنشاء حاوية عامودية حتى نعرض بواسطتها نص الكائن VBox هنا قمنا بإنشاء كائن من الكلاس
	// buttonLabel نص الزر الذي يمثله الكائن + buttonShape و تحته الزر الذي يمثله الكائن 
    VBox vBox = new VBox(30);

	// AboutPane هنا قمنا بتجهيز هذا الكونستركتور لتحديد ما سيحدث عند إنشاء كائن من الكلاس
    public AboutPane() {

		// AboutPane كخلفية للحاوية التي سنحصل عليها عند إنشاء كائن من الكلاس GetBGImage() هنا قمنا بوضع الصورة التي ترجعها الدالة
        this.setBackground(Main.GetBGImage());
        
		// ( لون النص, نوع الخط, حجم الخط و مكان ظهوره ) label هنا قمنا بتحديد خصائص ظهور الكائن
        label.setTextFill(Color.WHITE);
        label.setFont(Font.loadFont(Main.class.getResource("res/fonts/droidnaskh-regular-webfon.ttf").toExternalForm(), 18));
        label.setTextAlignment(TextAlignment.CENTER);

		// ( حجمه, مكان ظهوره, لون النص, نوع الخط, حجم الخط و حجم الفراغ حوله ) buttonLabel هنا قمنا بتحديد خصائص ظهور الكائن
        buttonLabel.setPrefSize(220, 40);
        buttonLabel.setAlignment(Pos.CENTER);
        buttonLabel.setTextFill(Color.WHITE);
        buttonLabel.setFont(Font.loadFont(Main.class.getResource("res/fonts/droidnaskh-regular-webfon.ttf").toExternalForm(), 14));
        buttonLabel.setPadding(new Insets(-5, 0, 0, 0));
		
	    // buttonShape يظهر فوق شكل الزر الذي يمثله الكائن buttonLabel خصيصاً لنجعل نص الكائن StackPane قمنا بإنشاء كائن من الكلاس
		// buttonPane و أصبحنا نستطيع تحريكهما معاً بواسطة الكائن buttonShape بالكائن buttonLabel أي كأننا ألصقنا الكائن
        StackPane buttonPane = new StackPane();
        buttonPane.setPrefSize(220, 40);
        buttonPane.getChildren().addAll(buttonLabel, buttonShape);

		// buttonPane و تحته الزر الذي تمثله الحاوية label هكذا سيظهر في الصفحة نص الكائن .vBox في الكائن buttonPane و من ثم الكائن label هنا قمنا بإضافة الكائن
        vBox.getChildren().addAll(label, buttonPane);

		// AboutPane يظهر في وسطها و من ثم أضفناها إلى الحاوية التي سنحصل عليها عند إنشاء كائن من الكلاس vBox هنا جعلنا محتوى الحاوية
        vBox.setAlignment(Pos.CENTER);
        this.getChildren().add(vBox);
		
		// buttonShape هنا قمنا بتحديد ما سيحدث عند النقر على الزر الذي يمثله الكائن
        buttonShape.setOnMouseClicked((MouseEvent t) -> {
			// Scene لتشغيل صوت نقرة. بعدها سيتم تبديل الحاوية الأساسية في الـ clickSound() سيتم إستدعاء الدالة
			// و بالتالي سيظهر للمستخدم كأنه عاد لصفحة القائمة الأساسية في البرنامج .PANE_MENU بالحاوية
            mySounds.clickSound();
            Main.STAGE.getScene().setRoot(Main.PANE_MENU);
        });

    }

}
		

GameAnswerButton.java
import javafx.beans.binding.Bindings;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.TextAlignment;

// و جعله قابل للنقر (Width + Height) هو لتمكيننا من إعطائه حجم Rectangle يرث من الكلاس GameAnswerButton سبب جعل الكلاس
public class GameAnswerButton extends Rectangle {

	// GameAnswerButton لأننا سنعتمد عليه لنرسم شكل الزر الذي نريد الحصول عليه عند إنشاء كائن من الكلاس Polygon قمنا بتعريف كائن من الكلاس
	// GameAnswerButton لأننا سنعتمد عليه لعرض النص الذي نريد وضعه على الزر الذي سيملثه الكائن الذي ننشئه من الكلاس Label و قمنا بتعريف كائن من الكلاس
    Polygon clip;
    Label label = new Label();
	
    // clip يظهر فوق شكل الزر الذي يمثله الكائن label خصيصاً لنجعل نص الكائن Pane قمنا بإنشاء كائن من الكلاس
    Pane pane = new Pane();

	// هنا قمنا بتجهيز هذا الكونستركتور حتى نستطيع تحديد حجم الزر + مكان ظهوره مباشرةً عند إنشاء كائن من هذا الكلاس
    public GameAnswerButton(int width, int height, int x, int y) {

		// عند إنشاء كائن من الكلاس height و width لاحظ أن شكل الزر الذي سيتم رسمه يعتمد بشكل أساسي على القيم التي سنمررها للباراميترين
        clip = new Polygon(
                0, height / 2,
                20, height / 2,
                40, 0,
                width - 40, 0,
                width - 20, height / 2,
                width, height / 2,
                width - 20, height / 2,
                width - 40, height,
                40, height,
                20, height / 2
        );

		// لأننا سندمجه معه GameAnswerButton و الذي بدوره سيتم تطبيقه على الكائن الذي ننشئه من الكلاس polygon هنا قمنا بإضافة لون أبيض باهت حول الكائن
        clip.setStroke(Color.color(1, 1, 1, 0.75));

        // الطبيعي هو غامق بنسبة 25 بالمئة و سيصبح أغمق بنسبة 50 بالمئة حين ننقر فوقه بالفأرة polygon هنا حددنا أن لون خلفية الكائن
		clip.fillProperty().bind(Bindings.when(pressedProperty())
                .then(Color.color(0, 0, 0, 0.50))
                .otherwise(Color.color(0, 0, 0, 0.25))
        );

        // GameAnswerButton عند إنشاء كائن من الكلاس height و width حددنا أن حجم الشكل الذي سنحصل عليه سيكون مطابقاً للقيم التي نمررها مكان البارميترين
		// GameAnswerButton يساوي حجم الكائن الذي سنحصل عليه عند دمجه مع الكائن الذي ننشئه من الكلاس polygon بهذه الطريقة يكون حجم الكائن
        this.setWidth(width);
        this.setHeight(height);

		// هو أزرق GameAnswerButton هنا حددنا أن لون خلفية الكائن الذي سنحصل عليه عند إنشاء كائن من الكلاس
		// كما أنه عند تمرير الفأرة فوقه سيتحول شكل السهم إلى شكل إصبع, مما يجعل المستخدم يدرك أن هذا الشكل قابل للنقر        
		this.setDefaultBg();
        this.setStyle("-fx-cursor: hand;");
		
		// GameAnswerButton على الكائن الذي ننشئه من الكلاس polygon هنا قمنا بدمج و تطبيق خصائص الكائن
        this.setClip(clip);

		// ( حجمه, مكان ظهوره, لون النص, نوع الخط, حجم الخط و حجم الفراغ حوله ) label هنا قمنا بتحديد خصائص ظهور الكائن
        label.setFont(new Font(16));
        label.setTextFill(Color.WHITE);
        label.setTextAlignment(TextAlignment.CENTER);
        label.setPrefSize(width, height);
        label.setTextFill(Color.WHITE);
        label.setAlignment(Pos.CENTER_RIGHT);
        label.setPadding(new Insets(-5, 45, 0, 45));
		
		// pane في الكائن GameAnswerButton ثم الكائن الأساسي الذي ننشئه من الكلاس label هنا قمنا بوضع الكائن
        // pane و أصبحنا نستطيع تحريكهما معاً بواسطة الكائن GameAnswerButton بالكائن الذي يتم إنشاؤه من الكلاس label أي كأننا ألصقنا الكائن
        pane.getChildren().addAll(label, this);

		// GameAnswerButton و حجمها و جعلناها مطابقة لحجم الكائن الذي ننشئه من الكلاس pane هنا قمنا بتحديد مكان ظهور الحاوية 
        pane.setTranslateX(x);
        pane.setTranslateY(y);
        pane.setPrefSize(width, height);
    }

	// أخضر, و نستدعيها في حال نقر المستخدم على الإجابة الصحيحة GameAnswerButton هذه الدالة تجعل لون خلفية الزر الذي يمثله الكائن الذي ننشئه من الكلاس
    public void setWinBg() {
        this.setFill(Color.GREEN);
    }

	// برتقالي, و نستدعيها في حال نقر المستخدم على إجابة خطائة GameAnswerButton هذه الدالة تجعل لون خلفية الزر الذي يمثله الكائن الذي ننشئه من الكلاس
    public void setLooseBg() {
        this.setFill(Color.ORANGE);
    }

	// أزرق, و نستدعيها لوضع اللون الإفتراضي للزر GameAnswerButton هذه الدالة تجعل لون خلفية الزر الذي يمثله الكائن الذي ننشئه من الكلاس
    public void setDefaultBg() {
        this.setFill(Color.BLUE);
    }

	// GameAnswerButton هذه الدالة نمرر لها النص الذي نريد وضعه كنس للزر الذي يمثله الكائن الذي ننشئه من الكلاس
    public void setText(String s) {
        this.label.setText(s);
    }

	// GameAnswerButton هذه الدالة ترجع النص الظاهر على الزر الذي يمثله الكائن الذي ننشئه من الكلاس
    public String getText() {
        return this.label.getText();
    }

	// و النص الموضوع فوقه GameAnswerButton هذه الدالة ترجع الحاوية التي تحتوي على الزر الذي يمثله الكائن الذي ننشئه من الكلاس
    public Pane getPane() {
        return pane;
    }

	// و النص الموضوع فوقه GameAnswerButton هذه الدالة تستخدم لإخفاء الزر الذي يمثله الكائن الذي ننشئه من الكلاس
    public void hide() {
        this.setVisible(false);
        label.setVisible(false);
    }

	// و النص الموضوع فوقه GameAnswerButton هذه الدالة تستخدم لعرض الزر الذي يمثله الكائن الذي ننشئه من الكلاس
    public void show() {
        this.setVisible(true);
        label.setVisible(true);
    }

}
		

GamePane.java
import java.util.ArrayList;
import java.util.Collections;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.util.Duration;

public class GamePane extends Pane implements ScreenBounds {

	// حتى نستطيع إستدعاء دوال تشغيل الأصوات التي جهزناها فيه Sounds هنا قمنا بإنشاء كائن من الكلاس
    Sounds mySounds = new Sounds();

	// هنا قمنا بإنشاء كل العناصر الظاهرة في النافذة
    Button btnExit = new Button("", new ImageView(new Image(getClass().getResourceAsStream("/res/images/Close-icon.png"))));
    Button btnBack = new Button("", new ImageView(new Image(getClass().getResourceAsStream("/res/images/Go-back-icon.png"))));
    Button btnCallFriend = new Button("", new ImageView(new Image(getClass().getResourceAsStream("/res/images/Phone-icon.png"))));
    Button btnAskAudience = new Button("", new ImageView(new Image(getClass().getResourceAsStream("/res/images/User-Group-icon.png"))));
    Button btnDeleteTwoAnswers = new Button("", new ImageView(new Image(getClass().getResourceAsStream("/res/images/Number-2-icon.png"))));
    Button btnPlayGame = new Button("إبدأ الآن");
    Label timerLabel = new Label();                  // هذا الكائن سنعرض عليه التوقيت الباقي للإجابة عن الأسئلة و الذي يظهر عندما تبدأ اللعبة
    StackPane playButtonPane = new StackPane();      // هذه الحاوية الأساسية التي وضعنا فيها كل شيء, و التي بدورها ستظهره في وسط النافذة
    ArrayList<Label> moneyLabels = new ArrayList();  // ArrayList موجود في هذا الـ Label حاوية المال التي تظهر في يمين النافذة, كل مربع فيها عبارة

	// هذا الكائن يمثل الحاوية التي يظهر فيها السؤال
    GameQuestionShape questionShape = new GameQuestionShape(640, 60);

    // هذه الكائنات تمثل الأزرار التي تظهر عليها الإجابات المحتلمة لكل سؤال
    GameAnswerButton answer1 = new GameAnswerButton(320, 40, 320, 10);
    GameAnswerButton answer2 = new GameAnswerButton(320, 40, 0, 10);
    GameAnswerButton answer3 = new GameAnswerButton(320, 40, 320, 60);
    GameAnswerButton answer4 = new GameAnswerButton(320, 40, 0, 60);

    // محتوى نافذة اللعب سيتم تقسيمه فعلياً على الخمس حاوية التالية
    HBox hBox = new HBox();
    VBox vBox = new VBox();
    Pane answersPane = new Pane();
    HBox topMenuBox = new HBox(10);
    VBox moneyBox = new VBox(4);

    // سنخزن فيه جميع الأسئلة و الإجابات التي قمنا بإعدادها للعبة questions الكائن
    Questions questions;
	
	// سنخزن فيه في كل مرة سؤال جديد مع الإجابات الخاصة بهذا السؤال question الكائن
    Question question;

	// سنستخدم جميع المتغيرات التالية لإظهار المؤثرات بأوقات محددة بالإضافة إلى حفظ نشاط اللاعب بشكل مؤقت
    boolean isGameOver;
    int InitialSeconds;
    Integer RemainingSeconds;
    boolean anAnswerButtonIsClicked;
    boolean isAnswerCorrect;
    String whichButtonIsClicked;
    int correctAnswersCounter;
    int totalEarning;

	// هذا الكائن سنستخدمه عند إعطاء المستخدم مهلة 30 ثانية للإجابة بالإضافة إلى المؤثرات التي سنعرضها خلال فترات مختلفة
    Timeline timeline;
	
    // هذا المتغير سنستخدمه لتخزين عدد الإجابات التي يمكن للمستخدم أن أن ينقر عليها و فعلياً ستتغير قيمته فقط عندما يقوم بحذف إجابتين
    int hiddenButtonsCounter;

    // هذا المتغير سنستخدمه كمؤشر لمعرفة ما إن كان المستخدم قد إستخدم وسيلة الإتصال بصديق أم لا
    boolean aFriendIsCalled;

    // هذا المتغير سنستخدمه كمؤشر لمعرفة ما إن كان المستخدم قد إستخدم وسيلة سؤال الجمهور أم لا
    boolean userIsAskingAudience;

	// لكل شيء Reset هذه الدالة يجب استدعاءها في كل مرة سيتم فيها البدء باللعب بهدف أن تقوم بتصفير اللعبة أو تفعل ما نسميه
    public void initialValues() {
        questions = new Questions();
        isGameOver = false;
        timeline = new Timeline();
        InitialSeconds = 30;
        RemainingSeconds = InitialSeconds;
        anAnswerButtonIsClicked = false;
        isAnswerCorrect = false;
        whichButtonIsClicked = "";
        correctAnswersCounter = 0;
        totalEarning = 0;
        hiddenButtonsCounter = 0;
        aFriendIsCalled = false;
        userIsAskingAudience = false;
    }

	// هذه الدالة يجب استدعاءها عندما يتم بدأ اللعبة و هي بدورها ستقوم فقط باستدعاء الدوال الموضوعة فيها بالترتيب
    public void playGame() {
        initialValues();
        mySounds.clickSound();
        displayNewQestion();
        checkAnswer();
    }

	// هذه الدالة يجب استدعاءها عندما يقوم المستخدم باختيار إجابة صحيحة بهدف أن تحدد له كم ربح حتى الآن, فعلياً ستجعل المرحلة التي وصل إليها تظهر بلون متميز
    public void markLastPassedLevel() {
        for (Label label : moneyLabels) {
            label.setTextFill(Color.YELLOW);
            label.setBackground(new Background(new BackgroundFill(Color.BLACK, new CornerRadii(5), Insets.EMPTY)));
        }
        moneyLabels.get(correctAnswersCounter).setTextFill(Color.WHITE);
        moneyLabels.get(correctAnswersCounter).setBackground(new Background(new BackgroundFill(Color.BLUE, new CornerRadii(5), Insets.EMPTY)));
        totalEarning = Integer.parseInt(moneyLabels.get(correctAnswersCounter).getText());
    }

	// و من ثم عرضه في واجهة المستخدم questions هذه الدالة تستخدم لجلب سؤال جديد بشكل عشوائي من الكائن
	// نلاحظ أنه قبل جلب أي سؤال جديد يجب التأكد من عدة أمور, فمثلاً إذا كان المستخدم
	// قد أجاب عن 15 سؤال بشكل صحيح, يجب إعلامه بأنه قد ربح بدل عرض سؤال جديد أمامه
    public void displayNewQestion() {		
        if (userIsAskingAudience == true) {
            userIsAskingAudience = false;
        }
		
        if (aFriendIsCalled == true) {
            aFriendIsCalled = false;
        }

        if (correctAnswersCounter >= 15) {
            timeline.stop();
            ResultPane.setResult(correctAnswersCounter, totalEarning);
            Main.STAGE.getScene().setRoot(Main.PANE_RESULT);
        }
		else {
            if (hiddenButtonsCounter != 0) {
                hiddenButtonsCounter = 0;
                answer1.show();
                answer2.show();
                answer3.show();
                answer4.show();
            }

            question = questions.getQuestion();
            Collections.shuffle(question.answers);

            answer1.setDefaultBg();
            answer2.setDefaultBg();
            answer3.setDefaultBg();
            answer4.setDefaultBg();

            questionShape.setText(question.getPhrase());
            answer1.setText(question.getAnswer(0).getText());
            answer2.setText(question.getAnswer(1).getText());
            answer3.setText(question.getAnswer(2).getText());
            answer4.setText(question.getAnswer(3).getText());
        }
    }

	// هذه الدالة تستخدم لنقل اللاعب إلى الحاوية التي تعرض له نتيجته
    public void displayResult() {
        timeline.stop();
        ResultPane.setResult(correctAnswersCounter, totalEarning);
        Main.STAGE.getScene().setRoot(Main.PANE_RESULT);
    }

	// هذه الدالة تستخدم للتأكد من إجابة المستخدم, مع الإشارة إلى أنها أكثر دالة معقدة في كل هذا البرنامج
	// حيث أنها تحلل كل ما يقوم به المستخدم, لعرض كل الأشياء التي يجب أن تظهر له في التوقيت المناسب
    public void checkAnswer() {
        timeline.setCycleCount(Timeline.INDEFINITE);
        timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(1), (ActionEvent event) -> {

            if (RemainingSeconds == 0) {
                timerLabel.setText("إنتهى الوقت");
				// سيتم استدعاءها بعد ثانيتين displayResult() قمنا بإضافة الأسطر الثلاثة التالية فقك لضمان أن الدالة
                RemainingSeconds = -5;
                isAnswerCorrect = false;
                anAnswerButtonIsClicked = true;
            }
			else {
				// إذا لم يقم المستخدم بالنقر على أي إجابة, سيتم عرض الوقت المتبقي له للإجابة فقط
                if (anAnswerButtonIsClicked == false) {
					// في حال قام بالنقر على زر الإتصال بصديق, سيتم طباعة الجمل التالية مع عرض كل جملة مدة ثانيتين تقريباً
					// و في النهاية سيتم عرض الجواب الصحيح أمامه
                    if (aFriendIsCalled == true) {
                        if (RemainingSeconds == 40) {
                            timerLabel.setText("يتم الآن الإتصال بصديقك");
                        } else if (RemainingSeconds == 37) {
                            timerLabel.setText("مرحباً بك أيها الصديق");
                        } else if (RemainingSeconds == 34) {
                            timerLabel.setText("معك 30 ثانية للإجابة على السؤال التالي");
                        } else if (RemainingSeconds == 30) {
                            timerLabel.setText(question.getPhrase());
                        } else if (RemainingSeconds == 22) {
                            timerLabel.setText("أعتقد أن الجواب الصحيح هو");
                        } else if (RemainingSeconds == 18) {
                            if (question.getAnswer(0).isCorrect == true) {
                                timerLabel.setText(question.getAnswer(0).getText());
                            } else if (question.getAnswer(1).isCorrect == true) {
                                timerLabel.setText(question.getAnswer(1).getText());
                            } else if (question.getAnswer(2).isCorrect == true) {
                                timerLabel.setText(question.getAnswer(2).getText());
                            } else if (question.getAnswer(3).isCorrect == true) {
                                timerLabel.setText(question.getAnswer(3).getText());
                            }
                        } else if (RemainingSeconds == 1) {
                            aFriendIsCalled = false;
                            RemainingSeconds = InitialSeconds;
                        }
                    }
					/////////////////////////////////////////////////////////////
					// في حال قام بالنقر على زر طلب المساعدة من الجمهور, سيتم طباعة الجمل التالية مع عرض كل جملة مدة خمس ثواني
					// و في النهاية سيتم عرض الجواب الصحيح أمامه
                    else if (userIsAskingAudience == true) {
                        if (RemainingSeconds == 40) {
                            timerLabel.setText("سيساعدك الآن الجمهور باختيار الإجابة الصحيحة");
                        } else if (RemainingSeconds == 35) {
                            timerLabel.setText("النسبة الأكبر من الأصوات إختارت الإجابة");
                        } else if (RemainingSeconds == 30) {
                            if (question.getAnswer(0).isCorrect == true) {
                                timerLabel.setText(question.getAnswer(0).getText());
                            } else if (question.getAnswer(1).isCorrect == true) {
                                timerLabel.setText(question.getAnswer(1).getText());
                            } else if (question.getAnswer(2).isCorrect == true) {
                                timerLabel.setText(question.getAnswer(2).getText());
                            } else if (question.getAnswer(3).isCorrect == true) {
                                timerLabel.setText(question.getAnswer(3).getText());
                            }
                        } else if (RemainingSeconds == 20) {
                            userIsAskingAudience = false;
                            RemainingSeconds = InitialSeconds;
                        }
                    }
					// هذا الأمر, يعني أنه سيتم عرض الوقت المتبقي للإجابة في حال كان المستخدم لا يطلب حالياً مساعدة صديق أو مساعدة جمهور
					else {
                        timerLabel.setText(RemainingSeconds.toString());
                    }
                    RemainingSeconds--;
                }
				// إذا تم النقر على أي إجابة, سيتم التأكد من ما إذا كانت الإجابة صحيحة أم لا و على أساس ذلك سيتم عرض جمل معينة أمامه
                else if (anAnswerButtonIsClicked == true) {

					// أكبر من 0, سيتم عرض جملة جديدة كل ثانيتين RemainingSeconds إذا كانت قيمة المتغير 
                    if (RemainingSeconds > 0) {
                        RemainingSeconds = 0;
                    }

                    // RemainingSeconds بعدها سيتم إنقاص ثانية واحدة من المتغير
                    RemainingSeconds--;

                    // هنا قمنا بتحديد الجملة الأولى التي سيتم طباعتها
                    if (RemainingSeconds <= -2 && RemainingSeconds >= -5) {
                        if (isAnswerCorrect == true) {
                            timerLabel.setText("الإجابة صحيحة");
                        } else {
                            timerLabel.setText("الإجابة غير صحيحة");
							// إذا كان المستخدم قد قام باختيار إجابة خاطئة, سيتم جعل لون خلفية الزر الذي نقر عليه برتقالي
                            switch (whichButtonIsClicked) {
                                case "answer1":
                                    answer1.setLooseBg();
                                    break;
                                case "answer2":
                                    answer2.setLooseBg();
                                    break;
                                case "answer3":
                                    answer3.setLooseBg();
                                    break;
                                case "answer4":
                                    answer4.setLooseBg();
                                    break;
                            }
                            if (RemainingSeconds == -3) {
								// بعد أن يقوم المستخدم باختيار أي إجابة, سيتم تلوين خلفية الإجابة الصحيحة باللون الأخضر
                                if (question.getAnswer(0).isCorrect == true) {
                                    answer1.setWinBg();
                                } else if (question.getAnswer(1).isCorrect == true) {
                                    answer2.setWinBg();
                                } else if (question.getAnswer(2).isCorrect == true) {
                                    answer3.setWinBg();
                                } else if (question.getAnswer(3).isCorrect == true) {
                                    answer4.setWinBg();
                                }
                            }
                        }
                    }
                    // هنا قمنا بتحديد الجملة الثانية التي سيتم طباعتها
                    else if (RemainingSeconds <= -6 && RemainingSeconds >= -9) {
                        if (isAnswerCorrect == true) {
                            if (RemainingSeconds == -6) {
                                timerLabel.setText("أصبح رصيدك " + moneyLabels.get(correctAnswersCounter).getText());
                                markLastPassedLevel();
                                correctAnswersCounter++;
                            }

                            // حتى يتم نقله لصفحة النتيجة displayResult() إذا تم إنهاء جميع الأسئلة بنجاح سيتم إستدعاء الدالة
                            if (correctAnswersCounter == 16 && RemainingSeconds == -9) {
                                displayResult();
                            }
                        } 
						else {
                            if (RemainingSeconds == -9) {
                                displayResult();
                            }
                        }
                    }
                    // هنا قمنا بتحديد الجملة الثالثة التي سيتم طباعتها
                    else if (RemainingSeconds <= -10 && RemainingSeconds >= -13) {
                        timerLabel.setText("إستعد للسؤال التالي");
                    } 
                    // هنا قمنا بوضع السؤال التالي للمستخدم
                    else if (RemainingSeconds <= -14 && RemainingSeconds >= -16) {
                        if (RemainingSeconds == -16) {
                            anAnswerButtonIsClicked = false;
                            RemainingSeconds = InitialSeconds;
                            displayNewQestion();
                        }
                    }
                }
            }

			// إذا كان المستخدم يملك 10 ثواني أو أقل للإجابة سيتم تشغيل صوت يشبه دقة الثانية في كل ثانية
            if (RemainingSeconds >= 0
                    && RemainingSeconds < 10
                    && aFriendIsCalled == false
                    && userIsAskingAudience == false) {
                mySounds.clockTickSound();
            }
        }
        ));
		// كما كان قبل تشغيله. أي كأنها تقوم بتصفيره timeline حتى تعيد الكائن playFromStart() الدالة 
        timeline.playFromStart();
    }

	// هذا كونستركتور الكلاس
    public GamePane() {

        answer1.setOnMousePressed((MouseEvent t) -> {
            if (anAnswerButtonIsClicked == false) {
                answer1.setWinBg();
                if (question.getAnswer(0).isCorrect == true) {
                    mySounds.ClickOnCorrectAnswerSound();
                    isAnswerCorrect = true;
                } else {
                    mySounds.ClickOnWrongAnswerSound();
                    isAnswerCorrect = false;
                }
                anAnswerButtonIsClicked = true;
                whichButtonIsClicked = "answer1";
            }
        });

        answer2.setOnMousePressed((MouseEvent t) -> {
            if (anAnswerButtonIsClicked == false) {
                answer2.setWinBg();
                if (question.getAnswer(1).isCorrect == true) {
                    mySounds.ClickOnCorrectAnswerSound();
                    isAnswerCorrect = true;
                } else {
                    mySounds.ClickOnWrongAnswerSound();
                    isAnswerCorrect = false;
                }
                anAnswerButtonIsClicked = true;
                whichButtonIsClicked = "answer2";
            }
        });

        answer3.setOnMousePressed((MouseEvent t) -> {
            if (anAnswerButtonIsClicked == false) {
                answer3.setWinBg();
                if (question.getAnswer(2).isCorrect == true) {
                    mySounds.ClickOnCorrectAnswerSound();
                    isAnswerCorrect = true;
                } else {
                    mySounds.ClickOnWrongAnswerSound();
                    isAnswerCorrect = false;
                }
                anAnswerButtonIsClicked = true;
                whichButtonIsClicked = "answer3";
            }
        });

        answer4.setOnMousePressed((MouseEvent t) -> {
            if (anAnswerButtonIsClicked == false) {
                answer4.setWinBg();
                if (question.getAnswer(3).isCorrect == true) {
                    mySounds.ClickOnCorrectAnswerSound();
                    isAnswerCorrect = true;
                } else {
                    mySounds.ClickOnWrongAnswerSound();
                    isAnswerCorrect = false;
                }
                anAnswerButtonIsClicked = true;
                whichButtonIsClicked = "answer4";
            }
        });

        this.setPrefSize(WIDTH, HEIGHT);
        setGameImage();

        answersPane.setPrefSize(640, 100);
        moneyBox.setPrefSize(130, 510);

        btnExit.setPrefSize(100, 50);
        btnBack.setPrefSize(100, 50);
        btnCallFriend.setPrefSize(100, 50);
        btnAskAudience.setPrefSize(100, 50);
        btnDeleteTwoAnswers.setPrefSize(100, 50);

        timerLabel.setPrefSize(640, 300);
        timerLabel.setFont(new Font(30));
        timerLabel.setTextFill(Color.WHITE);
        timerLabel.setContentDisplay(ContentDisplay.CENTER);
        timerLabel.setAlignment(Pos.CENTER);

        String btnStyle = "-fx-focus-color: transparent; -fx-border-width:2; -fx-border-color: #87cefa; -fx-border-radius:50; -fx-background-radius:50; -fx-background-color:rgba(30, 30, 30, 0.5); -fx-cursor: hand;";
        btnExit.setStyle(btnStyle);
        btnBack.setStyle(btnStyle);
        btnCallFriend.setStyle(btnStyle);
        btnAskAudience.setStyle(btnStyle);
        btnDeleteTwoAnswers.setStyle(btnStyle);

        btnStyle
                = "-fx-focus-color: transparent; "
                + "-fx-border-width: 2;"
                + "-fx-border-color: #00f;"
                + "-fx-border-radius: 10;"
                + "-fx-text-fill: white;"
                + "-fx-background-color: rgba(30, 30, 30, 0.5);"
                + "-fx-cursor: hand;"
                + "-fx-font-size: 18;"
                + "-fx-padding: 10 0 10 0;"
                + "-fx-pref-width: 220;"
                + "-fx-pref-height: 40;"
                + "-fx-padding: 10 0 10 0;";

        btnPlayGame.setStyle(btnStyle);

        playButtonPane.setPrefSize(640, 300);
        playButtonPane.getChildren().add(btnPlayGame);

        topMenuBox.setPadding(new Insets(0, 0, 0, 50));

        topMenuBox.getChildren().addAll(btnExit, btnBack, btnCallFriend, btnAskAudience, btnDeleteTwoAnswers);
        answersPane.getChildren().addAll(answer1.getPane(), answer2.getPane(), answer3.getPane(), answer4.getPane());
        vBox.getChildren().addAll(topMenuBox, playButtonPane, questionShape, answersPane);
        hBox.getChildren().addAll(vBox, moneyBox);

        hBox.autosize();

        hBox.setTranslateX((WIDTH / 2) - (hBox.getWidth() / 2));
        hBox.setTranslateY((HEIGHT / 2) - (hBox.getHeight() / 2));

        this.getChildren().add(hBox);
        addMoneyBox();

        btnExit.setOnAction(e -> {
            Platform.exit();
        });

        btnBack.setOnAction(e -> {
            questionShape.setText("");
            mySounds.clickSound();
            Main.STAGE.getScene().setRoot(Main.PANE_MENU);
            timeline.stop();
            timeline = null;
            questions = null;
            vBox.getChildren().set(1, playButtonPane);
            answer1.setText("");
            answer1.setDefaultBg();
            answer1.setVisible(true);
            answer2.setText("");
            answer2.setDefaultBg();
            answer2.setVisible(true);
            answer3.setText("");
            answer3.setDefaultBg();
            answer3.setVisible(true);
            answer4.setText("");
            answer4.setDefaultBg();
            answer4.setVisible(true);
            initialValues();
            btnCallFriend.setDisable(false);
            btnAskAudience.setDisable(false);
            btnDeleteTwoAnswers.setDisable(false);
        });

        btnCallFriend.setOnAction(e -> {
            mySounds.clickSound();
            btnCallFriend.setDisable(true);
            RemainingSeconds = 40;
            aFriendIsCalled = true;
        });

        btnAskAudience.setOnAction(e -> {
            mySounds.clickSound();
            btnAskAudience.setDisable(true);
            RemainingSeconds = 40;
            userIsAskingAudience = true;
        });

        btnDeleteTwoAnswers.setOnAction(e -> {
            mySounds.clickSound();
            btnDeleteTwoAnswers.setDisable(true);

            if (question.getAnswer(0).isCorrect == false && hiddenButtonsCounter < 2) {
                answer1.hide();
                hiddenButtonsCounter++;
            }

            if (question.getAnswer(1).isCorrect == false && hiddenButtonsCounter < 2) {
                answer2.hide();
                hiddenButtonsCounter++;
            }

            if (question.getAnswer(2).isCorrect == false && hiddenButtonsCounter < 2) {
                answer3.hide();
                hiddenButtonsCounter++;
            }

            if (question.getAnswer(3).isCorrect == false && hiddenButtonsCounter < 2) {
                answer4.hide();
                hiddenButtonsCounter++;
            }
        });

        btnPlayGame.setOnAction(e -> {
            vBox.getChildren().set(1, timerLabel);
            playGame();
        });

    }

	// هذه الدالة تستخدم لوضع خلفية للعبة, مع الإشارة إلى أننا استدمنا أيضاً نفس الخلفية التي وضعناها في كل الصفحات
	public void setGameImage() {
        this.setBackground(Main.GetBGImage());
    }

	// هذه الدالة تستخدم لإنشاء و إضافة عناصر الحاوية التي يظهر فيها رصيد المستخدم
    public void addMoneyBox() {
        moneyLabels.add(new Label("100"));
        moneyLabels.add(new Label("200"));
        moneyLabels.add(new Label("300"));
        moneyLabels.add(new Label("500"));
        moneyLabels.add(new Label("1000"));
        moneyLabels.add(new Label("2000"));
        moneyLabels.add(new Label("4000"));
        moneyLabels.add(new Label("8000"));
        moneyLabels.add(new Label("16000"));
        moneyLabels.add(new Label("22000"));
        moneyLabels.add(new Label("64000"));
        moneyLabels.add(new Label("125000"));
        moneyLabels.add(new Label("250000"));
        moneyLabels.add(new Label("500000"));
        moneyLabels.add(new Label("1000000"));

        for (int i = moneyLabels.size() - 1; i > -1; i--) {
            moneyLabels.get(i).setAlignment(Pos.CENTER);
            moneyLabels.get(i).setStyle(
                    "-fx-border-color: #aaa;"
                    + "-fx-border-radius: 5;"
                    + "-fx-background-color: black;"
                    + "-fx-text-fill: yellow;"
                    + "-fx-font-family: calibry;"
                    + "-fx-font-size: 17;"
                    + "-fx-text-alignment: center;"
                    + "-fx-pref-width: 120;"
                    + "-fx-pref-height: 30;"
            );
            moneyBox.getChildren().add(moneyLabels.get(i));
        }
        moneyBox.setAlignment(Pos.CENTER_RIGHT);
    }

}
		

GameQuestionShape.java
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polyline;
import javafx.scene.text.Font;

// ( لأننا ننوي جعله يكون عبارة عن حاوية لها شكل معين و فيها نص ( السؤال Pane يرث من الكلاس GameQuestionShape هنا جعلنا الكلاس
public class GameQuestionShape extends Pane {

    // لأننا سنعرض النص عليه Label هنا قمنا بإنشاء كائن من الكلاس
    Label label = new Label();

    // هنا قمنا بتجهيز هذا الكونستركتور حتى نستطيع تحديد حجم النص مباشرةً عند إنشاء كائن من هذا الكلاس
    public GameQuestionShape(int width, int height) {

		// label سيمثل الشكل الهندسي الذي سيظهر حول السؤال, أي حول نص الكائن polyline الكائن
        Polyline polyline = new Polyline(
                0, 30,
                20, 30,
                40, 0,
                600, 0,
                620, 30,
                640, 30,
                620, 30,
                600, 60,
                40, 60,
                20, 30
        );
        
		// لأننا سندمجه معه GameQuestionShape و الذي بدوره سيتم تطبيقه على الكائن الذي ننشئه من الكلاس polyline هنا قمنا بإضافة لون أبيض باهت حول الكائن
        polyline.setStroke(Color.color(1, 1, 1, 0.75));

		// ( حجمه, مكان ظهوره, لون النص, نوع الخط, حجم الخط و حجم الفراغ حوله ) label هنا قمنا بتحديد خصائص ظهور الكائن
        label.setTranslateX(0);
        label.setTranslateY(0);
        label.setPrefSize(width, height);
        label.setAlignment(Pos.CENTER_RIGHT);
        label.setPadding(new Insets(-10, 40, 0, 40));
        label.setFont(Font.loadFont(Main.class.getResource("res/fonts/droidnaskh-regular-webfon.ttf").toExternalForm(), 16));
        label.setTextFill(Color.WHITE);

        // GameQuestionShape في الحاوية التي يمثلها الكائن الذي ننشئه من الكلاس polyline و label هنا قمنا بوضع الكائن
        // و أصبحنا نستطيع تحريكهما معاً GameQuestionShape بالكائن الذي يتم إنشاؤه من الكلاس polyline و label أي كأننا ألصقنا الكائن
        getChildren().addAll(polyline, label);
    }

	// GameQuestionShape و الذي بدوره سيوضع في الكائن الذي ننشئه من الكلاس label هذه الدالة نمرر لها النص الذي نريد وضعه للكائن
    public void setText(String s) {
        this.label.setText(s);
    }
}
		

Main.java
import java.util.Locale;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundImage;
import javafx.scene.layout.BackgroundPosition;
import javafx.scene.layout.BackgroundRepeat;
import javafx.scene.layout.BackgroundSize;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class Main extends Application implements ScreenBounds {

	// لأننا سنعتبر كل واحد منهم كصفحة في التطبيق Pane لأنه سيمثل نافذة التطبيق, و 4 كائنات من الكلاس STAGE هنا قمنا بإنشاء كائن من الكلاس
	// لتسهيل الوصول إليهم و لعدم الحاجة إلى إنشاء كائن منهم كلما أردنا التنقل بين الصفحات و هذا الأمر يجعل حجم البرنامج أصغر في الذاكرة static و قمنا بتعريفهم كـ
    static Stage STAGE;
    static Pane PANE_MENU = new MenuPane();
    static Pane PANE_ABOUT = new AboutPane();
    static Pane PANE_RESULT = new ResultPane();
    static Pane PANE_GAME = new GamePane();

    @Override
    public void start(Stage stage) {

		// هنا قمنا بإنشاء النافذة و جعلناها تملئ شاشة المستخدم, غير قابلة للتصغير, و وضعنا أيقونة لها, كما أننا وضعنا لها عنوان
        STAGE = stage;
        STAGE.setFullScreen(true);
        STAGE.setResizable(false);
        STAGE.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
        STAGE.getIcons().add(new Image(Main.class.getResourceAsStream("res/images/icon.png")));
        STAGE.setTitle("من سيربح المليون - أسئلة إسلامية");

		// STAGE ثم مررناه للكائن ( PANE_MENU وضعنا فيه الحاوية ) Scene هنا قمنا بإنشاء كائن من الكلاس
		// هي أول حاوية ( أي أول صفحة ) يتم عرضها عند تشغيل اللعبة PANE_MENU هكذا ستكون الحاوية 
        STAGE.setScene(new Scene(PANE_MENU));

		// هنا قمنا بإظهار نافذة اللعبة
        STAGE.show();

    }

	// هذه الدالة قمنا ببنائها لتعيين الصورة التي نريد وضعها كخلفية لأي حاوية ( و نقصد صفحة ) نعرضها في اللعبة, فعلياً ترجع لنا الصورة فقط
    public static Background GetBGImage() {
        BackgroundImage myBI = new BackgroundImage(
                new Image("res/images/black-wallpaper.jpg"),
                BackgroundRepeat.NO_REPEAT,
                BackgroundRepeat.NO_REPEAT,
                BackgroundPosition.DEFAULT,
                BackgroundSize.DEFAULT);

        return new Background(myBI);
    }

    public static void main(String[] args) {
        Locale.setDefault(new Locale("ar"));
        launch(args);
    }

}
		

MenuItemShape.java
import javafx.beans.binding.Bindings;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import javafx.scene.shape.Rectangle;

// و جعله قابل للنقر (Width + Height) هو لتمكيننا من إعطائه حجم Rectangle يرث من الكلاس MenuItemShape سبب جعل الكلاس
public class MenuItemShape extends Rectangle {

	// MenuItemShape لأننا سنعتمد عليه لنرسم شكل الزر الذي نريد الحصول عليه عند إنشاء كائن من الكلاس Polygon قمنا بتعريف كائن من الكلاس
    Polygon polygon;

    // هنا قمنا بتجهيز هذا الكونستركتور حتى نستطيع تحديد حجم الزر مباشرةً عند إنشاء كائن من هذا الكلاس
	public MenuItemShape(int width, int height) {

		// عند إنشاء كائن من الكلاس height و width لاحظ أن شكل الزر الذي سيتم رسمه يعتمد بشكل أساسي على القيم التي سنمررها للباراميترين
        polygon = new Polygon(
                0, height/2,
                20, 0,
                width, 0,
                width, height,
                20, height,
                0, height/2
        );
        
		// لأننا سندمجه معه MenuItemShape و الذي بدوره سيتم تطبيقه على الكائن الذي ننشئه من الكلاس polygon هنا قمنا بإضافة لون أبيض باهت حول الكائن
        polygon.setStroke(Color.color(1, 1, 1, 0.75));

		// الطبيعي هو غامق بنسبة 25 بالمئة و سيصبح أغمق بنسبة 50 بالمئة حين ننقر فوقه بالفأرة polygon هنا حددنا أن لون خلفية الكائن
        polygon.fillProperty().bind(Bindings.when(pressedProperty())
                .then(Color.color(0, 0, 0, 0.50))
                .otherwise(Color.color(0, 0, 0, 0.25))
        );
        
		// MenuItemShape عند إنشاء كائن من الكلاس height و width حددنا أن حجم الشكل الذي سنحصل عليه سيكون مطابقاً للقيم التي نمررها مكان البارميترين
        // MenuItemShape يساوي حجم الكائن الذي سنحصل عليه عند دمجه مع الكائن الذي ننشئه من الكلاس polygon بهذه الطريقة يكون حجم الكائن
        this.setWidth(width);
        this.setHeight(height);
		
		// هو أزرق MenuItemShape هنا حددنا أن لون خلفية الكائن الذي سنحصل عليه عند إنشاء كائن من الكلاس
        // كما أنه عند تمرير الفأرة فوقه سيتحول شكل السهم إلى شكل إصبع, مما يجعل المستخدم يدرك أن هذا الشكل قابل للنقر
        this.setFill(Color.BLUE);
        this.setStyle("-fx-cursor: hand;");

		// MenuItemShape على الكائن الذي ننشئه من الكلاس polygon هنا قمنا بدمج و تطبيق خصائص الكائن
        this.setClip(polygon);

    }
    
}
		

MenuPane.java
import javafx.animation.ScaleTransition;
import javafx.animation.TranslateTransition;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.effect.DropShadow;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.util.Duration;

public class MenuPane extends Pane implements ScreenBounds {

    Text title = new Text("من سيربح المليون");
    VBox vBox = new VBox(5);
    Line line = new Line();
    Sounds mySounds = new Sounds();

	// هذه الدالة تستخدم لرسم العامود الأبيض الذي سيظهر على يمين الأزرار
    private void addLine() {

        double xStart = (WIDTH / 2) + 110;
        double yStart = (HEIGHT / 2) - (vBox.getChildren().size() * 40 / 2);

        double xEnd = xStart;   // جعلنا هاتين النقتطين متساويتين حتى يظهر الخط بشكل عامودي
        double yEnd = (HEIGHT / 2) + (vBox.getChildren().size() * 40 / 2) + (vBox.getChildren().size() * 5) - 5;

        line = new Line(xStart, yStart, xEnd, yEnd);
        line.setStrokeWidth(3);
        line.setStroke(Color.color(0, 0, 1, 0.75));
        line.setEffect(new DropShadow(5, Color.BLACK));
        line.setScaleY(0);

        this.getChildren().add(line);
    }

	// هذه الدالة تستخدم لتشغيل المؤثرات الموضوعة لعناصر الحاوية
    private void startAnimation() {
        ScaleTransition st = new ScaleTransition(Duration.seconds(1));
        st.setNode(title);
        st.setToY(1);
        st.play();

        ScaleTransition st2 = new ScaleTransition(Duration.seconds(1));
        st2.setDelay(Duration.seconds(1));
        st2.setNode(line);
        st2.setToY(1);
        st2.setOnFinished(e -> {

            for (int i = 0; i < vBox.getChildren().size(); i++) {
                Node n = vBox.getChildren().get(i);

                TranslateTransition tt = new TranslateTransition(Duration.seconds(1 + i * 0.15), n);
                tt.setToX(0);
                tt.setOnFinished(e2 -> n.setClip(null));
                tt.play();
            }
        });
        st2.play();
    }

	// هذه الدالة تستخدم لإضافة حاوية الأزرار في حاوية الصفحة الأساسية و لتحديد مكان ظهورها
    private void addVBox() {
        double x = (WIDTH / 2) - (220 / 2);
        double y = (HEIGHT / 2) - (vBox.getChildren().size() * 40 / 2);

        vBox.setTranslateX(x);
        vBox.setTranslateY(y);

        this.getChildren().add(vBox);
    }

	// هذه الدالة تستخدم لإضافة عنوان الصفحة ( و الذي في حالتنا يمثل إسم اللعبة ) و لتحديد حجمه, لونه, نوع خطه و مكان ظهوره
    private void addTitle() {
        title.setFont(Font.loadFont(Main.class.getResource("res/fonts/droidnaskh-regular-webfon.ttf").toExternalForm(), 36));
        title.setFill(Color.WHITE);
        title.setEffect(new DropShadow(30, Color.BLACK));
        
        title.setTranslateX(WIDTH / 2 - title.getLayoutBounds().getWidth() / 2);
        title.setTranslateY(HEIGHT / 3);
        title.setScaleY(0);

        this.getChildren().add(title);
    }

	// vBox هنا قمنا ببناء الأزرار الثلاثة الذين سيظهروا في الصفحة و من ثم إضافتهم على الحاوية
	// MenuItemShape يحتوي على كائن Pane كل زر, عبارة عن كائن
	// الذي جلعنا خلفيته شفافة MenuItemShape موضوع خلف الكائن Label و النص الموضوع على كل زر عبارة كائن
	// إضافة إلى ذلك, قمنا بتحديد النافذة التي نريدها أن تفتح عند النقر على كل زر منهم
    private void addItems() {

        MenuItemShape item1 = new MenuItemShape(220, 40);
        MenuItemShape item2 = new MenuItemShape(220, 40);
        MenuItemShape item3 = new MenuItemShape(220, 40);

        Pane pane1 = new Pane();
        Pane pane2 = new Pane();
        Pane pane3 = new Pane();

        pane1.setPrefSize(220, 40);
        pane2.setPrefSize(220, 40);
        pane3.setPrefSize(220, 40);

        Label label1 = new Label("إبدأ التحدي");
        label1.setPrefSize(220, 40);
        label1.setAlignment(Pos.CENTER_RIGHT);
        label1.setPadding(new Insets(-5, 15, 0, 0));
        label1.setFont(Font.loadFont(Main.class.getResource("res/fonts/droidnaskh-regular-webfon.ttf").toExternalForm(), 14));
        label1.setTextFill(Color.WHITE);

        Label label2 = new Label("حول اللعبة");
        label2.setPrefSize(220, 40);
        label2.setAlignment(Pos.CENTER_RIGHT);
        label2.setPadding(new Insets(-5, 15, 0, 0));
        label2.setFont(Font.loadFont(Main.class.getResource("res/fonts/droidnaskh-regular-webfon.ttf").toExternalForm(), 14));
        label2.setTextFill(Color.WHITE);

        Label label3 = new Label("خروج من اللعبة");
        label3.setPrefSize(220, 40);
        label3.setAlignment(Pos.CENTER_RIGHT);
        label3.setPadding(new Insets(-5, 15, 0, 0));
        label3.setFont(Font.loadFont(Main.class.getResource("res/fonts/droidnaskh-regular-webfon.ttf").toExternalForm(), 14));
        label3.setTextFill(Color.WHITE);

        pane1.getChildren().addAll(label1, item1);
        pane2.getChildren().addAll(label2, item2);
        pane3.getChildren().addAll(label3, item3);

        pane1.setTranslateX(220);
        Rectangle clip1 = new Rectangle(220, 40);
        pane1.setClip(clip1);
        clip1.translateXProperty().bind(pane1.translateXProperty().negate());

        pane2.setTranslateX(220);
        Rectangle clip2 = new Rectangle(220, 40);
        pane2.setClip(clip2);
        clip2.translateXProperty().bind(pane2.translateXProperty().negate());

        pane3.setTranslateX(220);
        Rectangle clip3 = new Rectangle(220, 40);
        pane3.setClip(clip3);
        clip3.translateXProperty().bind(pane3.translateXProperty().negate());

        vBox.getChildren().addAll(pane1, pane2, pane3);

        item1.setOnMouseClicked((MouseEvent t) -> {
            mySounds.clickSound();
            Main.STAGE.getScene().setRoot(Main.PANE_GAME);
        });

        item2.setOnMouseClicked((MouseEvent t) -> {
            mySounds.clickSound();
            Main.STAGE.getScene().setRoot(Main.PANE_ABOUT);
        });

        item3.setOnMouseClicked((MouseEvent t) -> {
            Platform.exit();
        });
    }

	// هذا كونستركتور الكلاس
    public MenuPane() {
        setPrefSize(WIDTH, HEIGHT);
        setBackground(Main.GetBGImage());
        addItems();
        addTitle();
        addLine();
        addVBox();
        startAnimation();
        mySounds.introSound();
    }

}
		

Questions.java
// بما أن كل سؤال في اللعبة يجب أن يكون له 4 أجوبة و منهم إجابة واحدة صحيحة فعلنا التالي
// لأن كل جواب سيكون له نص ( أي نص الإجابة ) بالإضافة إلى مؤشر لنعرف من خلاله ما إن كانت الإجابة صحيحة أم لا Answer قمنا بتمثيل كل جواب بالكلاس
// Answer لأن كل سؤال سيكون له نص ( أي نص السؤال ) مع 4 إجابات, أي مصفوفة فيها 4 كائنات من الكلاس Question قمنا بتمثيل كل جواب بالكلاس
// Answer و الكلاس Question الذي بنيناه على أساس الكلاس Questions قمنا بتمثيل كل الأسئلة و الأجوبة التي نريد وضعها في اللعبة في الكلاس

import java.util.ArrayList;
import java.util.Collections;


// هذا الكلاس يمثل كيف سيتم تخزين كل إجابة في اللعبة سواء كانت صحيحة أو خاطئة
class Answer {

    String text;
    boolean isCorrect;

    public Answer(String text, boolean isCorrect) {
        this.text = text;
        this.isCorrect = isCorrect;
    }

    public Answer(String text) {
        this.text = text;
        this.isCorrect = false;
    }

    public String getText() {
        return this.text;
    }

    public boolean isCorrect() {
        return this.isCorrect;
    }

}


// هذا الكلاس يمثل كيف سيتم تخزين كل سؤال في اللعبة مع الإجابات الأربعة الخاصة فيه
class Question {

    String phrase;
    ArrayList<Answer> answers = new ArrayList();

    public Question(String phrase, Answer[] answers) {
        this.phrase = phrase;
        this.answers.add(answers[0]);
        this.answers.add(answers[1]);
        this.answers.add(answers[2]);
        this.answers.add(answers[3]);
    }

    public String getPhrase() {
        return this.phrase;
    }

    public Answer getAnswer(int answerIndex) {
        return this.answers.get(answerIndex);
    }
	
}


// Question و الكلاس Answer هذا الكلاس يستخدم للحصول على مئة سؤال و هو مبني على أساس الكلاس
public class Questions {

    ArrayList<Question> al = new ArrayList();

    public Questions() {
        createQuestions();
    }

    public Question getQuestion() {
        Question question = al.get(0);
        al.remove(0);
        return question;
    }

    public void createQuestions() {

        al.add(new Question("كان من خلق النبي صلى الله عليه وسلم؟",
                new Answer[]{
                    new Answer("الصدق", true),
                    new Answer("الغضب"),
                    new Answer("عدم التواضع"),
                    new Answer("عدم الصدق"),})
        );

        al.add(new Question("ما اسم والد النبي صلى الله عليه وسلم؟",
                new Answer[]{
                    new Answer("عبدالله", true),
                    new Answer("محمد"),
                    new Answer("إبراهيم"),
                    new Answer("عبد مناف"),})
        );

        al.add(new Question("ما اسم والدة النبي صلى الله عليه وسلم؟",
                new Answer[]{
                    new Answer("آمنة بنت وهب", true),
                    new Answer("حليمة السعدية"),
                    new Answer("فاطمة بنت حبيش"),
                    new Answer("خديجة بنت خويلد"),})
        );

        al.add(new Question("في أي يوم ولد النبي صلى الله عليه وسلم؟",
                new Answer[]{
                    new Answer("في الثاني عشر من ربيع الأول", true),
                    new Answer("في الأول من صفر"),
                    new Answer("في الثاني من محرم"),
                    new Answer("في السابع من شوال"),})
        );

        al.add(new Question("كم كان عمر النبي عندما توفي والده؟",
                new Answer[]{
                    new Answer("كان جنينا في بطن أمه", true),
                    new Answer("كان رضيعا"),
                    new Answer("كان طفلا"),
                    new Answer("كان شابا"),})
        );

        al.add(new Question("ما اسم عمه الذي كفله وحماه من المشركين؟",
                new Answer[]{
                    new Answer("أبو طالب", true),
                    new Answer("أبو لهب"),
                    new Answer("أبو جهل"),
                    new Answer("أبو عبيدة"),})
        );

        al.add(new Question("ما اسم زوجة النبي صلى الله عليه وسلم؟",
                new Answer[]{
                    new Answer("خديجة بنت خويلد", true),
                    new Answer("فاطمة بنت قبيس"),
                    new Answer("مريم بنت الزبير"),
                    new Answer("الخنساء"),})
        );

        al.add(new Question("ما اسم الغار الذي كان النبي يعبد ربه فيه؟",
                new Answer[]{
                    new Answer("غار حراء", true),
                    new Answer("غار ثور"),
                    new Answer("غار علقمة"),
                    new Answer("غار تميم"),})
        );

        al.add(new Question("كم كان عمر النبي عندما نزل عليه الوحي؟",
                new Answer[]{
                    new Answer("41 سنة", true),
                    new Answer("50 سنة"),
                    new Answer("60 سنة"),
                    new Answer("44 سنة"),})
        );

        al.add(new Question("ما اسم ملك الوحي الذي نزل على النبي في الغار؟",
                new Answer[]{
                    new Answer("جبريل", true),
                    new Answer("ميكائيل"),
                    new Answer("إسرافيل"),
                    new Answer("ملك الجبال"),})
        );

        al.add(new Question("من أول من أسلم من النساء؟",
                new Answer[]{
                    new Answer("خديجة بنت خويلد", true),
                    new Answer("فاطمة بنت قبيس"),
                    new Answer("عائشة بنت أبي بكر"),
                    new Answer("زينب أم المساكين"),})
        );

        al.add(new Question("من أول من أسلم من الصبيان؟",
                new Answer[]{
                    new Answer("علي بن أبي طالب", true),
                    new Answer("زيد بن حارثة"),
                    new Answer("عبدالله بن عمر"),
                    new Answer("عبدالله بن عباس"),})
        );

        al.add(new Question("من أول من أسلم من الرجال؟",
                new Answer[]{
                    new Answer("أبو بكر الصديق", true),
                    new Answer("عثمان بن عفان"),
                    new Answer("عبدالله بن مسعود"),
                    new Answer("عمر بن الخطاب"),})
        );

        al.add(new Question("ما اسم القبيلة التي حاربت النبي صلى الله عليه وسلم؟",
                new Answer[]{
                    new Answer("قريش", true),
                    new Answer("بنو تميم"),
                    new Answer("ثقيف"),
                    new Answer("بنو قيس"),})
        );

        al.add(new Question("أين كان يعيش النبي صلى الله عليه وسلم؟",
                new Answer[]{
                    new Answer("مكة المكرمة", true),
                    new Answer("العراق"),
                    new Answer("الشام"),
                    new Answer("اليمن"),})
        );

        al.add(new Question("ما اسم عمَ النبي الذي لقب بأسد الله؟",
                new Answer[]{
                    new Answer("حمزة بن عبد المطلب", true),
                    new Answer("أبو لهب"),
                    new Answer("أبو طالب"),
                    new Answer("العباس"),})
        );

        al.add(new Question("إلى أي بلاد هاجر المسلمون أول مرة؟",
                new Answer[]{
                    new Answer("الحبشة", true),
                    new Answer("اليمن "),
                    new Answer("الشام"),
                    new Answer("نجد"),})
        );

        al.add(new Question("ما اسم الصحابي الذي قاد المسلمين إلى الحبشة؟",
                new Answer[]{
                    new Answer("جعفر بن أبي طالب", true),
                    new Answer("حذيفة بن اليمان"),
                    new Answer("أبو عبيدة بن الجراح"),
                    new Answer("سعد بن معاذ"),})
        );

        al.add(new Question("ماذا كان اسم ملك الحبشة؟",
                new Answer[]{
                    new Answer("النجاشي", true),
                    new Answer("كسرى"),
                    new Answer("قيصر"),
                    new Answer("النمرود"),})
        );

        al.add(new Question("ماذا كان اسم ملك الحبشة؟",
                new Answer[]{
                    new Answer("النجاشي", true),
                    new Answer("كسرى"),
                    new Answer("قيصر"),
                    new Answer("النمرود"),})
        );

        al.add(new Question("تقع الكعبة المشرفة في ...",
                new Answer[]{
                    new Answer("مكة المكرمة", true),
                    new Answer("خيبر"),
                    new Answer("الشام"),
                    new Answer("يثرب"),})
        );

        al.add(new Question("يقع المسجد الأقصى في ...",
                new Answer[]{
                    new Answer("القدس", true),
                    new Answer("الطائف "),
                    new Answer("يثرب"),
                    new Answer("اليمن"),})
        );

        al.add(new Question("القدس عاصمة أي من الدول الآتية؟",
                new Answer[]{
                    new Answer("فلسطين", true),
                    new Answer("العراق"),
                    new Answer("اليمن"),
                    new Answer("لبنان"),})
        );

        al.add(new Question("ما هما الرحلتان العظيمتان اللتان قام بهما الرسول؟",
                new Answer[]{
                    new Answer("الاسراء والمعراج", true),
                    new Answer("حطين"),
                    new Answer("عين جالوت"),
                    new Answer("أحد"),})
        );

        al.add(new Question("ماذا فرض الله تعالى في ليلة الاسراء والمعراج؟",
                new Answer[]{
                    new Answer("الصلوات الخمس", true),
                    new Answer("صوم رمضان"),
                    new Answer("حج البيت"),
                    new Answer("الزكاة"),})
        );

        al.add(new Question("ما اسم أول بيعة للأنصار في الإسلام؟",
                new Answer[]{
                    new Answer("بيعة العقبة", true),
                    new Answer("بيعة نجد"),
                    new Answer("بيعة ثقيف"),
                    new Answer("بيعة الخزرج"),})
        );

        al.add(new Question("إلى أين هاجر المسلمون بعد الحبشة؟",
                new Answer[]{
                    new Answer("المدينة المنورة", true),
                    new Answer("مكة"),
                    new Answer("اليمن"),
                    new Answer("الشام"),})
        );

        al.add(new Question("ماذا كان لقب المسلمين من أهل المدينة؟",
                new Answer[]{
                    new Answer("الأنصار", true),
                    new Answer("المهاجرين"),
                    new Answer("الفقراء"),
                    new Answer("المسافرين"),})
        );

        al.add(new Question("ماذا كان لقب المسلمين القادمين من مكة؟",
                new Answer[]{
                    new Answer("المهاجرين", true),
                    new Answer("الانصار"),
                    new Answer("المقاتلين"),
                    new Answer("الاغنياء"),})
        );

        al.add(new Question("من الصحابي الذي هاجر مع النبي إلى المدينة المنورة؟",
                new Answer[]{
                    new Answer("أبو بكر الصديق", true),
                    new Answer("عمر بن الخطاب"),
                    new Answer("علي بن أبي طالب"),
                    new Answer("عثمان بن عفان"),})
        );

        al.add(new Question("ما اسم الغار الذي ارتاح فيه النبي قبل الوصول الى المدينة؟",
                new Answer[]{
                    new Answer("غار ثور", true),
                    new Answer("غار حراء"),
                    new Answer("غار شعلان"),
                    new Answer("غار آدم"),})
        );

        al.add(new Question("ماذا قال النبي لأبي بكر وهما في الغار؟",
                new Answer[]{
                    new Answer("لا تحزن إن الله معنا", true),
                    new Answer("لا تحزن سنموت سويا"),
                    new Answer("لا تحزن لن نقتل"),
                    new Answer("لا تحزن سنهزمهم"),})
        );

        al.add(new Question("ما هو أول أمر فعله النبي عندما وصل إلى المدينة؟",
                new Answer[]{
                    new Answer("بنى مسجدا", true),
                    new Answer("أعطاهم مالا"),
                    new Answer("أخذ تمرا"),
                    new Answer("اشترى منزلا"),})
        );

        al.add(new Question("في بيت من أقام النبي عندما وصل إلى المدينة؟",
                new Answer[]{
                    new Answer("أبو أيوب الأنصاري", true),
                    new Answer("سعد بن معاذ"),
                    new Answer("عبادة بن الصامت"),
                    new Answer("معاذ بن جبل"),})
        );

        al.add(new Question("ماذا فعل النبي بعد بناء المسجد؟",
                new Answer[]{
                    new Answer("آخى بين المهاجرين والأنصار", true),
                    new Answer("حاسب الظالمين"),
                    new Answer("بناء القصور"),
                    new Answer("الراحة بعد السفر"),})
        );

        al.add(new Question("من كان يسكن في المدينة بجانب المسلمين؟",
                new Answer[]{
                    new Answer("اليهود", true),
                    new Answer("الروم"),
                    new Answer("الفرس"),
                    new Answer("النصارى"),})
        );

        al.add(new Question("ماذا فعل النبي بعد المؤخاة بين المسلمين؟",
                new Answer[]{
                    new Answer("أقام معاهدة مع اليهود", true),
                    new Answer("حارب اليهود"),
                    new Answer("دعى الناس للطعام"),
                    new Answer("نصب نفسه ملكا"),})
        );

        al.add(new Question("في أي سنة بعد الهجرة فرض الله صيام رمضان؟",
                new Answer[]{
                    new Answer("السنة الثانية", true),
                    new Answer("السنة الأولى"),
                    new Answer("السنة الخامسة"),
                    new Answer("السنة الرابعة"),})
        );

        al.add(new Question("أول سرية في الاسلام كانت بقيادة من ...",
                new Answer[]{
                    new Answer("عبدالله بن جحش", true),
                    new Answer("ابن مسعود"),
                    new Answer("ابو عبيدة"),
                    new Answer("خالد بن الوليد"),})
        );

        al.add(new Question("ماذا كان اسم رأس المنافقين في المدينة؟",
                new Answer[]{
                    new Answer("عبدالله بن أبي سلول", true),
                    new Answer("عبدالله بن سلام"),
                    new Answer("ولعان الأعمى"),
                    new Answer("سعيد المصلوب"),})
        );

        al.add(new Question("ماذا كان اسم ـول معركة بين المسلمين والمشركين؟",
                new Answer[]{
                    new Answer("معركة بدر", true),
                    new Answer("معركة ذات السلاسل"),
                    new Answer("معركة القادسية"),
                    new Answer("معركة أحد"),})
        );

        al.add(new Question("في أي سنة كانت معركة بدر الكبرى؟",
                new Answer[]{
                    new Answer("السنة الثانية", true),
                    new Answer("السنة الثالثة"),
                    new Answer("السنة السابعة"),
                    new Answer("السنة الرابعة"),})
        );

        al.add(new Question("كم كان عدد المسلمين في معركة بدر؟",
                new Answer[]{
                    new Answer("313 رجلا", true),
                    new Answer("500 رجل"),
                    new Answer("1000 رجل"),
                    new Answer("800 رجل"),})
        );

        al.add(new Question("كم كان عدد المشركين في معركة بدر؟",
                new Answer[]{
                    new Answer("1000 رجل", true),
                    new Answer("2000 رجل"),
                    new Answer("1500 رجل"),
                    new Answer("900 رجل"),})
        );

        al.add(new Question("ما اسم الصحابي الذي اقترح مكان المعركة في بدر؟",
                new Answer[]{
                    new Answer("الحباب بن المنذر", true),
                    new Answer("عمر بن الخطاب"),
                    new Answer("أبو عبيدة بن الجراح"),
                    new Answer("خالد بن الوليد"),})
        );

        al.add(new Question("من انتصر في معركة بدر؟",
                new Answer[]{
                    new Answer("المسلمون", true),
                    new Answer("المشركون"),
                    new Answer("الشيطان"),
                    new Answer("الباطل"),})
        );

        al.add(new Question("كم عدد أركان الإسلام؟",
                new Answer[]{
                    new Answer("خمسة أركان", true),
                    new Answer("ركنان"),
                    new Answer("ثلاثة أركان"),
                    new Answer("ركن واحد"),})
        );

        al.add(new Question("كان من خلق النبي صلى الله عليه وسلم؟",
                new Answer[]{
                    new Answer("الأمانة ", true),
                    new Answer("الخيانة"),
                    new Answer("الغش"),
                    new Answer("التكبر"),})
        );

        al.add(new Question("من هو الصحابي الذي لقب بالصديق؟",
                new Answer[]{
                    new Answer("أبو بكر", true),
                    new Answer("عثمان بن عفان"),
                    new Answer("أبو عبيدة بن الجراح"),
                    new Answer("أبو هريرة"),})
        );

        al.add(new Question("من هو الصحابي الذي لقب بالفاروق؟",
                new Answer[]{
                    new Answer("عمر بن الخطاب", true),
                    new Answer("سعد بن معاذ"),
                    new Answer("عبدالله بن الزبير"),
                    new Answer("خالد بن الوليد"),})
        );

        al.add(new Question("من هو الصحابي الذي لقب بذي النورين؟",
                new Answer[]{
                    new Answer("عثمان بن عفان", true),
                    new Answer("الزبير بن العوام"),
                    new Answer("حذيفة بن اليمان"),
                    new Answer("أبو صخر"),})
        );

        al.add(new Question("من هو الصحابي الذي لقب بأمين الأمة؟",
                new Answer[]{
                    new Answer("أبو عبيدة بن الجراح", true),
                    new Answer("عامر بن عبدالله"),
                    new Answer("أبو موسى الأشعري"),
                    new Answer("عيينة بن حصين"),})
        );

        al.add(new Question("من هو الصحابي الذي لقب بسيف الله المسلول؟",
                new Answer[]{
                    new Answer("خالد بن الوليد", true),
                    new Answer("الزبير بن العوام"),
                    new Answer("الاقرع بن الحابس"),
                    new Answer("عبدالله بن عباس"),})
        );

        al.add(new Question("من هو الصحابي الذي لقب بأمين السر النبوي؟",
                new Answer[]{
                    new Answer("حذيفة بن اليمان", true),
                    new Answer("ابن مسعود"),
                    new Answer("ابن عمر"),
                    new Answer("عمر بن الخطاب"),})
        );

        al.add(new Question("من هو الصحابي الذي لقب بترجمان القرآن؟",
                new Answer[]{
                    new Answer("عبدالله بن عباس", true),
                    new Answer("الحباب بن المنذر"),
                    new Answer("قتادة"),
                    new Answer("بلال بن رباح"),})
        );

        al.add(new Question("من هو مؤذن رسول الله؟",
                new Answer[]{
                    new Answer("بلال بن رباح", true),
                    new Answer("عطاء بن أبي رباح"),
                    new Answer("أبي بن كعب"),
                    new Answer("زيد بن ثابت"),})
        );

        al.add(new Question("ما هو لقب الرسول صلى الله عليه وسلم؟",
                new Answer[]{
                    new Answer("الصادق الأمين", true),
                    new Answer("التاجر الصدوق"),
                    new Answer("البر الأمين"),
                    new Answer("الأمين الأمين"),})
        );

        al.add(new Question("ما هو عمل الرسول في شبابه؟",
                new Answer[]{
                    new Answer("التجارة", true),
                    new Answer("الزراعة"),
                    new Answer("السياسة"),
                    new Answer("الحياكة"),})
        );

        al.add(new Question("إلى من أرسل الرسول صلى الله عليه وسلم؟",
                new Answer[]{
                    new Answer("إلى كافة الناس", true),
                    new Answer("إلى قريش"),
                    new Answer("إلى بني هاشم"),
                    new Answer("إلى الحجاز"),})
        );

        al.add(new Question("ما الذي جاء به الرسول محمد صلى الله عليه وسلم؟",
                new Answer[]{
                    new Answer("بالشريعة الإسلامية", true),
                    new Answer("باليهودية"),
                    new Answer("بالمجوسية"),
                    new Answer("بالنصرانية"),})
        );

        al.add(new Question("ما أكثر طعام الرسول صلى الله عليه وسلم؟",
                new Answer[]{
                    new Answer("التمر والماء", true),
                    new Answer("اللحم والخبز"),
                    new Answer("الدجاج واللبن"),
                    new Answer("الفاكهة والخضار"),})
        );

        al.add(new Question("كم حجة حج النبي صلى الله عليه وسلم؟",
                new Answer[]{
                    new Answer("حجة واحدة", true),
                    new Answer("حجتان"),
                    new Answer("ثلاث حجات"),
                    new Answer("خمس حجات"),})
        );

        al.add(new Question("كم رمضان صام النبي صلى الله عليه وسلم؟",
                new Answer[]{
                    new Answer("تسع مرات", true),
                    new Answer("ثلاث مرات"),
                    new Answer("خمس مرات"),
                    new Answer("مرتان"),})
        );

        al.add(new Question("ما هي كنية الرسول صلى الله عليه وسلم؟",
                new Answer[]{
                    new Answer("أبو القاسم", true),
                    new Answer("أبو ابراهيم"),
                    new Answer("أبو يوسف"),
                    new Answer("أبو اسماعيل"),})
        );

        al.add(new Question("ما آخر غزوة غزاها الرسول؟",
                new Answer[]{
                    new Answer("غزوة تبوك", true),
                    new Answer("غزوة الخندق"),
                    new Answer("غزوة بدر"),
                    new Answer("غزوة ذات السلاسل"),})
        );

        al.add(new Question("ما هي معجزة النبي الخالدة؟",
                new Answer[]{
                    new Answer("القرآن الكريم", true),
                    new Answer("الانجيل"),
                    new Answer("التوراة"),
                    new Answer("الزبور"),})
        );

        al.add(new Question("متى توفي الرسول صلى الله عليه وسلم؟",
                new Answer[]{
                    new Answer("شهر ربيع الاول عام 11 للهجرة", true),
                    new Answer("شهر صفر عام 14 للهجرة"),
                    new Answer("شهر محرم عام 8 للهجرة"),
                    new Answer("شهر شعبان عام 20 للهجرة"),})
        );

        al.add(new Question("كم كان عمره صلى الله عليه وسلم عند وفاته؟",
                new Answer[]{
                    new Answer("63 سنة", true),
                    new Answer("64 سنة"),
                    new Answer("70 سنة"),
                    new Answer("55 سنة"),})
        );

        al.add(new Question("في أي بلد دفن النبي صلى الله عليه وسلم؟",
                new Answer[]{
                    new Answer("المدينة المنورة", true),
                    new Answer("مكة المكرمة"),
                    new Answer("فلسطين"),
                    new Answer("اليمن"),})
        );

        al.add(new Question("ماذا نسمي معرفة حياة الرسول من ولادته حتى مماته؟",
                new Answer[]{
                    new Answer("السيرة النبوية", true),
                    new Answer("قصة"),
                    new Answer("فيلم وثائقي"),
                    new Answer("رواية"),})
        );

        Collections.shuffle(al);
    }

}
		

ResultPane.java
import javafx.application.Platform;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;

// حتى يظهر محتواه في وسط النافذة StackPane يرث من الكلاس ResultPane هنا جعلنا الكلاس
// حتى يكون حجمه مطابق لحجم شاشة المستخدم ScreenBounds و جعلناه يطبق الإنترفيس
public class ResultPane extends StackPane implements ScreenBounds {
	
	// حتى نستطيع إستدعاء دوال تشغيل الأصوات التي جهزناها فيه Sounds هنا قمنا بإنشاء كائن من الكلاس
    Sounds mySounds = new Sounds();
	
	// ResultPane هنا منا بتعريف جميع الأشياء التي سنعرضها في الحاوية التي سيمثلها الكائن الذي نرجعه من الكلاس
    static Label label = new Label();
    Button buttonClose = new Button("خروج");
    Button buttonRetry = new Button("إلعب من جديد");
    VBox vBox = new VBox(20);

	// هذا كونستركتور الكلاس
    public ResultPane() {

        // ResultPane كخلفية للحاوية التي سنحصل عليها عند إنشاء كائن من الكلاس GetBGImage() هنا قمنا بوضع الصورة التي ترجعها الدالة
        this.setBackground(Main.GetBGImage());

        // Label هنا قمنا بتجهيز التصميم الذي نريد تطبيقه على الكائن
		String labelStyle
                = "-fx-text-fill: white; "
                + "-fx-font-size: 24;"
                + "-fx-padding: 0 0 20 0;"
                + "-fx-alignment: CENTER;";

        // buttonRetry و buttonClose هنا قمنا بتجهيز التصميم الذي نريد تطبيقه على الكائنين
        String btnStyle
                = "-fx-focus-color: transparent; "
                + "-fx-border-width: 2;"
                + "-fx-border-color: #00f;"
                + "-fx-border-radius: 10;"
                + "-fx-text-fill: white;"
                + "-fx-background-color: rgba(30, 30, 30, 0.5);"
                + "-fx-cursor: hand;"
                + "-fx-font-size: 18;"
                + "-fx-padding: 10 0 10 0;"
                + "-fx-pref-width: 220;"
                + "-fx-pref-height: 40;"
                + "-fx-padding: 10 0 10 0;";

		// buttonRetry و buttonClose, label هنا قمنا بتطبيق التصاميم على الكائنات
        label.setStyle(labelStyle);
        buttonClose.setStyle(btnStyle);
        buttonRetry.setStyle(btnStyle);

		// لكي يظهروا عامودياً تحت بعضهم البعض و في وسط الحاويةvBox في الحاوية buttonRetry و buttonClose, label هنا قمنا بإضافة الكائنات
        vBox.getChildren().addAll(label, buttonRetry, buttonClose);
        vBox.setAlignment(Pos.CENTER);
		
		// أي في الحاوية التي تمثل الصفحة نفسها .ResultPane في الكائن الذي ستم إنشاؤه من الكلاس vBox هنا أضفنا الحاوية
        this.getChildren().addAll(vBox);

		// buttonRetry هنا قمنا بتحديد ما سيحدث عند النقر على الزر الذي يمثله الكائن
        buttonRetry.setOnAction(e -> {
            mySounds.clickSound();
            Main.STAGE.getScene().setRoot(new GamePane());
        });

		// buttonClose هنا قمنا بتحديد ما سيحدث عند النقر على الزر الذي يمثله الكائن
        buttonClose.setOnAction(e -> {
            Platform.exit();
        });

    }

    public static void setResult(int answeredQuestions, int totalEarning) {
        if (answeredQuestions == 0) {
            label.setText("لم تعرف إجابة أي سؤال لذلك لم تفز بأي مبلغ !");
        }
        else if (answeredQuestions < 15){
            label.setText("لقد تخطيت السؤال رقم " + answeredQuestions + " و فزت بمبلغ " + totalEarning + "$");
        }
        else if (answeredQuestions == 15) {
            label.setText("لقد تخطيت جميع الأسئلة و فزت بمبلغ "+ totalEarning + "$");            
        }
    }
    
}
		

ScreenBounds.java
import javafx.geometry.Rectangle2D;
import javafx.stage.Screen;

// وضعنا في هذا الإنترفيس, المعلومات الأساسية و المشتركة التي يجب أن تتوفر في كل حاوية تمثل صفحة في اللعبة
public interface ScreenBounds {
    
    Screen SCREEN = Screen.getPrimary();
    Rectangle2D BOUNDS = SCREEN.getVisualBounds();

    double WIDTH = BOUNDS.getMaxX();
    double HEIGHT = BOUNDS.getMaxY();
    
}
		

Sounds.java
import javafx.scene.media.AudioClip;

// وضعنا فيه 5 دوال, كل دالة منهم تعطينا صوت معين عند إستدعاءها Sounds الكلاس
public class Sounds {
    
	// لتمثلها و لنستطيع تشغيلها من خلالها AudioClip الملفات الصوتية الموضوعة في المشروع قمنا بإنشاء كائنات من الكلاس
    AudioClip audio_1 = new AudioClip(getClass().getResource("res/sounds/general-click.wav").toString());
    AudioClip audio_2 = new AudioClip(getClass().getResource("res/sounds/playing-click.wav").toString());
    AudioClip audio_3 = new AudioClip(getClass().getResource("res/sounds/intro.MP3").toString());
    AudioClip audio_4 = new AudioClip(getClass().getResource("res/sounds/clock-tick.wav").toString());
    AudioClip audio_5 = new AudioClip(getClass().getResource("res/sounds/win-sound.mp3").toString());
    
    public void clickSound() {
        audio_1.play();
    }
    
    public void ClickOnWrongAnswerSound() {
        audio_2.play();
    }
    
    public void ClickOnCorrectAnswerSound() {
        audio_5.play();
    }
    
    public void introSound() {
        audio_3.play();
    }
    
    public void clockTickSound() {
        audio_4.play();
    }
    
}
		

الدورات

أدوات مساعدة

أقسام الموقع

دورات
مقالات كتب مشاريع أسئلة