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 وضعنا فيه المعلومات الأساسية و المشتركة التي يجب أن تتوفر في كل حاوية تمثل صفحة في اللعبة.
كود اللعبة
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);
}
}
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);
}
}
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);
});
}
}
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);
});
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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();
}
}
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();
}
}
// بما أن كل سؤال في اللعبة يجب أن يكون له 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);
}
}
// بما أن كل سؤال في اللعبة يجب أن يكون له 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);
}
}
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 + "$");
}
}
}
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 + "$");
}
}
}
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();
}
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();
}
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();
}
}
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();
}
}