إعلان
دورة تطوير التطبيقات باستخدام لغة JavaScript في هذه الدورة ستتعلم لغة جافا سكريبت, استخدام مكتبة React.js, بناء API الموقع بواسطة Node.js, تطوير تطبيق جوال باستخدام React Native, و في نهاية الدورة ستتعلم تطوير تطبيق محادثة شبيه بتطبيق WhatsApp. تعلم الآن
دورة تطوير واجهات المستخدم في هذه الدورة ستتعلم لغة HTML و لغة CSS و لغة JavaScript. من ناحية التطبيق العملي ستتعلم طريقة بناء واجهة متجر إلكتروني مكون من ست صفحات, تحويل خمسة تصاميم PSD إلى صفحات ويب, بناء واجهة مستخدم تشبه موقع يوتيوب, بناء لوحة تحكم إحترافية. تعلم الآن
تطوير تطبيقات باستخدام لغة بايثون في هذه الدورة ستتعلم أساسيات البرمجة بلغة بايثون وصولاً إلى التعامل مع أشهر أطر العمل (Flask و Django) و ستتعلم كيف تبني متجر إلكتروني يمكن للمستخدمين البيع و الشراء من خلاله. تعلم الآن
دورة تطوير تطبيقات الويب باستخدام لغة PHP في هذه الدورة ستتعلم لغة PHP من الصفر, استخدام إطار العمل Laravel بشرح مفصّل و عملي, كيفية تطوير شبكة اجتماعية تشبه Instagram, بناء API لتطبيق جوال وفق أسلوب RESTful, تطوير موقع إعلانات مبوبة, تطوير نظام إدارة محتوى CMS كامل. تعلم الآن
دورة تطوير تطبيقات الويب باستخدام لغة Ruby في هذه الدورة ستتعلم البرمجة بلغة Ruby إنطلاقاً من أبسط المفاهيم وحتى بناء تطبيق حقيقي, إستخدام إطار العمل Ruby on Rails بشرح مفصّل و عملي, بناء تطبيق حقيقي عبارة عن شبكة اجتماعية تشبه تويتر, تطوير مجتمع الكتروني يشبه حسوب I/O. تعلم الآن
دورة علوم الحاسوب هذه الدورة معدة لتكون مدخل لعلوم الحاسوب و لغات البرمجة حيث ستتعرف فيها على أنظمة التشغيل و ستتعمق في نظام لينكس و في كيفية التعامل معه من خلال موجه الأوامر, بالإضافة إلى قواعد البيانات و أساسيات الشبكات و الخوادم و مبادئ الحماية والأمان في الويب. تعلم الآن

    JavaFX طريقة إنشاء لعبة الأفعى Snake 2D

    في هذا الدرس ستتعلم طريقة إنشاء لعبة ( Snake 2D ) إحترافية بإستخدام JavaFX.

    javafx 2d snake game source code تحميل كود لعبة الأفعى في جافا


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

    • أعلى مجموع يصل إليه اللاعب يبقى مخزناً حتى إذا تم إغلاق اللعبة.
    • يمكن إيقاف و متابعة اللعبة بالنقر على زر المسافة الفارغة Space.
    • إذا لمست الأفعى الحائط لا يخسر اللاعب, لأن الأفعى ستظهر من الجهة المقابلة.
    • يمكن تعديل كود اللعبة بكل سهولة لأنه غير معقد.


    بناء اللعبة

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


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

    ⇓ تحميل اللعبة ⇓ تحميل المشروع كاملاً ⇓ تحميل مجلد الصور فقط



    كود اللعبة

    Position.java
    // قمنا بإنشاء هذا الكلاس لجعل أي كائن منه يمثل موقع دائرة من الدوائر الموجودة في الأفعى
    public class Position {
     
        // إذاً كل دائرة في الأفعى ستكون موجودة في نفس الوقت على خط طول و خط عرض محددين
        int x, y;
     
        // قمنا بتجهيز هذا الكونستركتور لتحديد مكان وجود أي دائرة في الأفعى لحظة إنشاء الكائن منه
        public Position(int x, int y) {
            this.x = x;
            this.y = y;
        }
     
    }
    		

    Main.java
    import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.util.LinkedList;
    import java.util.Random;
    import javafx.animation.KeyFrame;
    import javafx.animation.Timeline;
    import javafx.application.Application;
    import javafx.event.ActionEvent;
    import javafx.scene.Scene;
    import javafx.scene.canvas.Canvas;
    import javafx.scene.canvas.GraphicsContext;
    import javafx.scene.image.Image;
    import javafx.scene.input.KeyEvent;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.scene.text.Font;
    import javafx.scene.text.FontWeight;
    import javafx.scene.text.Text;
    import javafx.stage.Stage;
    import javafx.util.Duration;
    
    public class Main extends Application {
    
        // قمنا بإنشاء هاتين المصفوفتين لتخزين مكان وجود كل دائرة من الأفعى كل لحظة, أي لتحديد المكان المحجوز لعرض دوائر الأفعى
        // ( بما أن عدد الدوائر الأقصى بالطول هو 22 و بالعرض هو أيضاً 22, فهذا يعني أنه يمكن تخزين 22×22 دائرة ( أي 484
        final int[] boardX = new int[484];
        final int[] boardY = new int[484];
    
        // سنستخدم هذه الكائن لتخزين مكان وجود كل دائرة في الأفعى حتى نعرف الموقع الذي لا يجب أن نظهر فيه الدائرة الحمراء
        // ملاحظة: سبب إستخدام هذا الكائن هو لتخزين موقع كل دائرة في الأفعى من جديد هو فقط لجعل اللعبة لا تعلق, أي لتحسين أداء اللعبة
        LinkedList<Position> snake = new LinkedList();
    
        // سنستخدم هذه المتغيرات لتحديد الإتجاه الذي ستتجه إليه الأفعى
        boolean left = false;
        boolean right = false;
        boolean up = false;
        boolean down = false;
    
        // سنستخدم هذه الكائنات لرسم إتجاه وجه الأفعى
        Image lookToRightImage = new Image(getClass().getResourceAsStream("/images/face-look-right.jpg"));
        Image lookToLeftImage = new Image(getClass().getResourceAsStream("/images/face-look-left.jpg"));
        Image lookToUpImage = new Image(getClass().getResourceAsStream("/images/face-look-up.jpg"));
        Image lookToDownImage = new Image(getClass().getResourceAsStream("/images/face-look-down.jpg"));
    
        // سنستخدم هذا الكائن في كل مرة لرسم جسد الأفعى
        Image snakeBodyImage = new Image(getClass().getResourceAsStream("/images/body.png"));
    
        // سنستخدم هذا الكائن في كل مرة لرسم طعام الأفعى
        Image fruitImage = new Image(getClass().getResourceAsStream("/images/fruit.png"));
    
        // سنستخدم هذا المتغير لتخزين عدد الدوائر التي تشكل الأفعى, أي طول الأفعي
        int lengthOfSnake = 3;
    
        // سنستخدم هاتين المصفوفتين لتحديد الأماكن التي يمكن أن يظهر فيها الطعام
        int[] fruitXPos = {20, 40, 60, 80, 100, 120, 140, 160, 200, 220, 240, 260, 280, 300, 320, 340, 360, 380, 400, 420, 440, 460};
        int[] fruitYPos = {20, 40, 60, 80, 100, 120, 140, 160, 200, 220, 240, 260, 280, 300, 320, 340, 360, 380, 400, 420, 440, 460};
    
        // سنستخدم هذا الكائن لجعل محتوى النافذة يعاد رسمه .Thread و الذي يشبه الـ Timeline هنا قمنا بإنشاء كائن من الكلاس
    	// من جديد كل 0.1 ثانية مما يجعلنا قادرين على رسم الأفعى من جديد كلما تغير موقعها بالإضافة إلى رسم مجموع المستخدم
        Timeline timeline = new Timeline();
    
        // سنستخدم هذا المتغير لمعرفة إذا كانت الأفعى تتحرك أم لا
        int moves = 0;
    
        // سنستخدم هذه المتغيرات لتحديد المجموع الذي يحققه اللاعب أثناء اللعب
        int totalScore = 0;
        int fruitEaten = 0;
        int scoreReverseCounter = 99;
    
        // في حال كان اللاعب قد حقق مجموع عالي من قبل, سيتم إظهاره كأفضل مجموع وصل إليه
    	// readBestScorefromTheFile() ملاحظة: أعلى مجموع يصل إليه اللاعب, نحصل عليه من الدالة
        int bestScore = readBestScorefromTheFile();
    
        // لتوليد أماكن ظهور طعام الأفعى بشكل عشوائي random سنستخدم الكائن
        Random random = new Random();
    
        // هنا قمنا بتحديد مكان أول طعام سيظهر في اللعبة قبل أن يبدأ المستخدم باللعب, و جعلناه يظهر تحت الأفعى
        int xPos = random.nextInt(22);
        int yPos = 5 + random.nextInt(17);
    
        // سنستخدم هذا المتغير لمعرفة ما إذا كان المستخدم قد خسر أم لا
        boolean isGameOver = false;
    
        // هذه الدالة تحفظ أعلى مجموع وصل إليه اللاعب في ملف خارجي بجانب ملف اللعبة
        private void writeBestScoreInTheFile() {
            if (totalScore >= bestScore) {
                try {
                    FileOutputStream fos = new FileOutputStream("./snake-game-best-score.txt");
                    OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
                    osw.write(bestScore + "");
                    osw.flush();
                    osw.close();
                } catch (IOException e) {
                }
            }
        }
    
        // هذه الدالة تقرأ أعلى مجموع وصل إليه اللاعب من الملف الخارجي الموجود بجانب ملف اللعبة مع الإشارة إلى أنه في حال كان
        // لا يوجد ملف خارجي ستقوم بإنشائه و وضع القيمة 0 فيه كقيمة أولية و هذا ما سيحدث عندما يقوم اللاعب بتشغيل اللعبة أول مرة
        private int readBestScorefromTheFile() {
            try {
                InputStreamReader isr = new InputStreamReader(new FileInputStream("./snake-game-best-score.txt"), "UTF-8");
                BufferedReader br = new BufferedReader(isr);
    
                String str = "";
                int c;
                while ((c = br.read()) != -1) {
                    if (Character.isDigit(c)) {
                        str += (char) c;
                    }
                }
                if (str.equals("")) {
                    str = "0";
                }
    
                br.close();
                return Integer.parseInt(str);
            } catch (IOException e) {
            }
            return 0;
        }
    
        // بهدف تحديد كيف سيتم رسم و تلوين كل شيء يظهر في اللعبة drawShapes() هنا قمنا بتعريف الدالة
        // قلنا أنه سيتم إستدعاء هذه الدالة كل 0.1 ثانية start() ملاحظة: في الدالة
        private void drawShapes(GraphicsContext gc) {
            // هنا قمنا بتحديد مكان وجود الأفعى في كل مرة يقوم المستخدم ببدأ اللعبة من جديد
            if (moves == 0) {
                boardX[2] = 40;
                boardX[1] = 60;
                boardX[0] = 80;
    
                boardY[2] = 100;
                boardY[1] = 100;
                boardY[0] = 100;
    
                scoreReverseCounter = 99;
                timeline.play();
            }
    
            // هنا قمنا بجعل المجموع الحالي الذي وصل إليه المستخدم يظهر كأعلى مجموع وصل إليه في حال تخطى المجموع القديم
            if (totalScore > bestScore) {
                bestScore = totalScore;
            }
    
            // هنا قمن بإنشاء مربع أسود يمثل لون خلفية اللعبة
            gc.setFill(Color.BLACK);
            gc.fillRect(0, 0, 750, 500);
    
            // هنا قمنا برسم المربعات التي تشكل الحدود التي لا تستطيع الأفعى عبورها باللون الرمادي
            // حجم كل مربع 13 بيكسل و المسافة بينهما 5 بيكسل
            gc.setFill(Color.color(0.2, 0.2, 0.2));
            for (int i = 6; i <= 482; i += 17) {
                for (int j = 6; j <= 482; j += 17) {
                    gc.fillRect(i, j, 13, 13);
                }
            }
    
            // هنا فمنا بإنشاء مربع أسود كبير فوق المربعات التي تشكل حدود اللعبة لتظهر و كأنها فارغة من الداخل
            gc.setFill(Color.BLACK);
            gc.fillRect(20, 20, 460, 460);
    
            // هنا قمنا بكتابة إسم اللعبة و تلوينه بالأزرق
            gc.setFill(Color.CYAN);
            gc.setFont(Font.font("Arial", FontWeight.BOLD, 26));
            gc.fillText("Snake 2D", 565, 35);
    
            // باللون الأزرق الفاتح Total Score التي ستظهر بجانب قيمة الـ Bonus هنا قمنا برسم النص قيمة الـ
            gc.setFont(Font.font("Arial", FontWeight.NORMAL, 13));
            gc.fillText("+ " + scoreReverseCounter, 510, 222);
    
            // هنا جعلنا أي شيء سنقوم بكتابته يظهر باللون الرمادي
            gc.setFill(Color.LIGHTGRAY);
    
            // هنا قمنا بطباعة أنه تم تطوير اللعبة بواسطة موقعنا
            gc.setFont(Font.font("Arial", FontWeight.NORMAL, 15));
            gc.fillText("Developed by harmash.com", 530, 60);
    
            // هنا جعلنا أي شيء سنقوم بكتابته يظهر بنوع و حجم هذا الخط
            gc.setFont(Font.font("Arial", FontWeight.NORMAL, 18));
    
            // و المربع الذي تحته و الرقم الذي بداخله Best Score هنا قمنا برسم النص
            gc.fillText("Best Score", 576, 110);
            gc.fillRect(550, 120, 140, 30);
            gc.setFill(Color.BLACK);
            gc.fillRect(551, 121, 138, 28);
            gc.setFill(Color.LIGHTGRAY);
            gc.fillText(bestScore + "", 550 + (142 - new Text(bestScore + "").getLayoutBounds().getWidth()) / 2, 142);
    
            // و المربع الذي تحته و الرقم الذي بداخله Total Score هنا قمنا برسم النص
            gc.fillText("Total Score", 573, 190);
            gc.fillRect(550, 200, 140, 30);
            gc.setFill(Color.BLACK);
            gc.fillRect(551, 201, 138, 28);
            gc.setFill(Color.LIGHTGRAY);
            gc.fillText(totalScore + "", 550 + (142 - new Text(totalScore + "").getLayoutBounds().getWidth()) / 2, 222);
    
            // و المربع الذي تحته و الرقم الذي بداخله Fruit Eaten هنا قمنا برسم النص
            gc.fillText("Fruit Eaten", 575, 270);
            gc.fillRect(550, 280, 140, 30);
            gc.setFill(Color.BLACK);
            gc.fillRect(551, 281, 138, 28);
            gc.setFill(Color.LIGHTGRAY);
            gc.fillText(fruitEaten + "", 550 + (142 - new Text(fruitEaten + "").getLayoutBounds().getWidth()) / 2, 302);
    
            // Controls هنا قمنا برسم النص
            gc.setFont(Font.font("Arial", FontWeight.BOLD, 16));
            gc.fillText("Controls", 550, 360);
    
            // Controls هنا قمنا برسم نصوص الإرشاد الظاهرة تحت النص
            gc.setFont(Font.font("Arial", FontWeight.NORMAL, 14));
            gc.fillText("Pause / Start : Space", 550, 385);
            gc.fillText("Move Up : Arrow Up", 550, 410);
            gc.fillText("Move Down : Arrow Down", 550, 435);
            gc.fillText("Move Left : Arrow Left", 550, 460);
            gc.fillText("Move Right : Arrow Right", 550, 485);
    
            // هنا جعلنا الأفعى تنظر ناحية اليمين قبل أن يبدأ اللاعب بتحريكها
            gc.drawImage(lookToRightImage, boardX[0], boardY[0]);
    
            // هنا قمنا بمسح مكان وجود الأفعى السابق لأننا سنقوم بتخزين المكان الجديد كلما تحركت
            snake.clear();
    
            // هنا قمنا بإنشاء حلقة ترسم كامل الدوائر التي تشكل الأفعى كل 0.1 ثانية
            for (int i = 0; i < lengthOfSnake; i++) {
                if (i == 0 && left) {
                    gc.drawImage(lookToLeftImage, boardX[i], boardY[i]);
                } else if (i == 0 && right) {
                    gc.drawImage(lookToRightImage, boardX[i], boardY[i]);
                } else if (i == 0 && up) {
                    gc.drawImage(lookToUpImage, boardX[i], boardY[i]);
                } else if (i == 0 && down) {
                    gc.drawImage(lookToDownImage, boardX[i], boardY[i]);
                } else if (i != 0) {
                    gc.drawImage(snakeBodyImage, boardX[i], boardY[i]);
                }
    
                // snake هنا قمنا بتخزين الموقع الحالي لكل دائرة في الأفعى في الكائن
                snake.add(new Position(boardX[i], boardY[i]));
            }
    
            // تقل بشكل تدريجي و أدنى قيمة ممكن أن تصل إليها هي 10 scoreReverseCounter هنا جعلنا قيمة العداد
            if (scoreReverseCounter != 10) {
                scoreReverseCounter--;
            }
    
            // هنا قمنا بإنشاء هذه الحلقة للتأكد إذا كان رأس الأفعى قد لامس أي جزء من جسدها
            for (int i = 1; i < lengthOfSnake; i++) {
                // إذاً عندما يلمس رأس الأفعى جسدها سيتم جعل أول دائرة موجودة خلف الرأس تمثل رأس الأفعى حتى لا يظهر رأسها فوق جسدها
                if (boardX[i] == boardX[0] && boardY[i] == boardY[0])
    			{
                    if (right)
                        gc.drawImage(lookToRightImage, boardX[1], boardY[1]);
                    
    				else if (left)
                        gc.drawImage(lookToLeftImage, boardX[1], boardY[1]);
    				
                    else if (up)
                        gc.drawImage(lookToUpImage, boardX[1], boardY[1]);
                    
    				else if (down)
                        gc.drawImage(lookToDownImage, boardX[1], boardY[1]);
    
                    // للإشارة إلى أن اللاعب قد خسر true تساوي isGameOver بعدها سيتم جعل قيمة الـ
                    // Space و بالتالي يمكنه أن يبدأ من جديد بالنقر على زر المسافة الفارغة
                    isGameOver = true;
    
                    // يتوقف و بالتالي ستتوقف الأفعى تماماً عن الحركة speedTimeline بعدها سيتم جعل الـ
                    timeline.stop();
    
                    // Game Over بعدها سيتم إظهار النص
                    gc.setFill(Color.WHITE);
                    gc.setFont(Font.font("Arial", FontWeight.BOLD, 50));
                    gc.fillText("Game Over", 110, 220);
    
                    // تحته Press Space To Restart و سيتم إظهار النص
                    gc.setFont(Font.font("Arial", FontWeight.BOLD, 20));
                    gc.fillText("Press Space To Restart", 130, 260);
    
                    // في الأخير سيتم إستدعاء هذه الدالة لحفظ أكبر مجموع وصل إليه اللاعب
                    writeBestScoreInTheFile();
                }
            }
    
            // إذا لمس رأس الأفعى الطعام سيتم إخفاء الطعام و زيادة مجموع اللاعب
            if ((fruitXPos[xPos] == boardX[0]) && fruitYPos[yPos] == boardY[0]) {
                totalScore += scoreReverseCounter;
                scoreReverseCounter = 99;
                fruitEaten++;
                lengthOfSnake++;
            }
    
            // هنا في كل مرة سيتم ضمان أن لا يظهر الطعام فوق الأفعى
            for (int i = 0; i < snake.size(); i++) {
                // في حال ظهر الطعام فوق جسد الأفعى سيتم خلق مكان عشوائي آخر لوضعها فيه
                if (snake.get(i).x == fruitXPos[xPos] && snake.get(i).y == fruitYPos[yPos]) {
                    xPos = random.nextInt(22);
                    yPos = random.nextInt(22);
                }
            }
    
            // في الأخير سيتم عرض الطعام بعيداً عن جسد الأفعى
            gc.drawImage(fruitImage, fruitXPos[xPos], fruitYPos[yPos]);
    
            if (right)
    		{
                for (int i = lengthOfSnake - 1; i >= 0; i--)
                    boardY[i + 1] = boardY[i];
    
                for (int i = lengthOfSnake; i >= 0; i--)
    			{
                    if (i == 0)
                        boardX[i] = boardX[i] + 20;
                    else
                        boardX[i] = boardX[i - 1];
                    
    
                    if (boardX[i] > 460) 
                        boardX[i] = 20;
                }
            } 
    		else if (left) {
                for (int i = lengthOfSnake - 1; i >= 0; i--)
                    boardY[i + 1] = boardY[i];
    
                for (int i = lengthOfSnake; i >= 0; i--)
    			{
                    if (i == 0)
                        boardX[i] = boardX[i] - 20;
                    
    				else
                        boardX[i] = boardX[i - 1];
    
                    if (boardX[i] < 20)
                        boardX[i] = 460;
                }
            }
    		else if (up)
    		{
                for (int i = lengthOfSnake - 1; i >= 0; i--)
                    boardX[i + 1] = boardX[i];
    
                for (int i = lengthOfSnake; i >= 0; i--)
    			{
                    if (i == 0)
                        boardY[i] = boardY[i] - 20;
                    else
                        boardY[i] = boardY[i - 1];
    
                    if (boardY[i] < 20)
                        boardY[i] = 460;
                }
            } 
    		else if (down)
    		{
                for (int i = lengthOfSnake - 1; i >= 0; i--)
                    boardX[i + 1] = boardX[i];
    
                for (int i = lengthOfSnake; i >= 0; i--)
    			{
                    if (i == 0)
                        boardY[i] = boardY[i] + 20;
                    else
                        boardY[i] = boardY[i - 1];
    
                    if (boardY[i] > 460)
                        boardY[i] = 20;
                }
            }
    		
        }
    
    	
        @Override
        public void start(Stage stage) {
    
    	    // لأنه يمثل حاوية يمكن الرسم عليها بسهولة Canvas هنا قمنا بإنشاء كائن من الكلاس
            Canvas canvas = new Canvas(750, 500);
    		
    		// canvas لأننا سنستخدمه للرسم على الكائن canvas مبني على الكائن GraphicsContext هنا قمنا بإنشاء كائن من الكلاس
    		// gc سيكون بواسطة دوال جاهزة موجودة في الكائن canvas فعلياً أي شيء سنرسمه على الكائن
            GraphicsContext gc = canvas.getGraphicsContext2D();
    
            // في النافذة لأننا ننوي ترتيب العناصر فيه بشكل عامودي Root Node و الذي ننوي جعله الـ VBox هنا قمنا بإنشاء كائن من الكلاس
            Pane root = new Pane();
            root.setStyle("-fx-background-color: black;");
    
            root.getChildren().add(canvas);
    
            // فيها و تحديد حجمها Node كأول root هنا قمنا بإنشاء محتوى النافذة مع تعيين الكائن
            Scene scene = new Scene(root);
    
            // هنا وضعنا عنوان للنافذة
            stage.setTitle("Snake 2D");
    
            // أي وضعنا محتوى النافذة الذي قمنا بإنشائه للنافذة .stage في كائن الـ scene هنا وضعنا كائن الـ
            stage.setScene(scene);
    
            // هنا قمنا بإظهار النافذة
            stage.show();
    
    		// timeline لترسم محتوى النافذة كل 0.1 ثانية بشكل تلقائي عندما يتم تشغيل الكائن drawShapes() هنا قمنا باستدعاء الدالة
            timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(0.1), (ActionEvent event) -> {
                drawShapes(gc);
            }));
    
    		// يستمر بالعمل بلا توقف حين يتم تشغيله timeline لها لجعل الكائن INDEFINITE و تمرير الثابت setCycleCount() هنا قمنا باستدعاء الدالة
            timeline.setCycleCount(Timeline.INDEFINITE);
    
    		// timeline لتشغيل الكائن play() هنا قمنا باستدعاء الدالة
            timeline.play();
    
            // لتحديد الإتجاه الذي ستتحرك فيه النافذة keyPressed() للدالة Override هنا فعلنا
            scene.addEventFilter(KeyEvent.KEY_PRESSED, (KeyEvent e) -> {
    
                if (null != e.getCode())
    			{
                    switch (e.getCode())
    				{
                        // هنا قمنا بتحديد ما سيحدث إذا قام اللاعب بالنقر على زر المسافة
                        case SPACE:
                            // سيتم إيقاف اللعبة بشكل مؤقت إذا كانت اللعبة شغالة
                            if (timeline.getStatus() == Timeline.Status.RUNNING && isGameOver == false)
    						{
                                timeline.stop();
                            }
    						// سيتم إعادة اللعبة للعمل إذا كان قد تم إيقافها سابقاً
                            else if (timeline.getStatus() != Timeline.Status.RUNNING && isGameOver == false)
    						{
                                timeline.play();
                            }
    						// سيتم بدأ اللعبة من جديد في حال كان قد تم إيقاف اللعبة لأن اللاعب قد خسر
                            else if (timeline.getStatus() != Timeline.Status.RUNNING && isGameOver == true)
    						{
                                isGameOver = false;
                                timeline.play();
                                moves = 0;
                                totalScore = 0;
                                fruitEaten = 0;
                                lengthOfSnake = 3;
                                right = true;
                                left = false;
                                xPos = random.nextInt(22);
                                yPos = 5 + random.nextInt(17);
                            }
                            break;
    
                        // هنا قمنا بتحديد ما سيحدث إذا قام اللاعب بالنقر على زر السهم الأيمن
                        case RIGHT:
                            // إذا لم تكن الأفعى تسير في الإتجاه الأيسر سيتم توجيهها نحو الإتجاه الأيمن
                            moves++;
                            right = true;
                            if (!left) {
                                right = true;
                            }
    						else
    						{
                                right = false;
                                left = true;
                            }
                            up = false;
                            down = false;
                            break;
    
                        // هنا قمنا بتحديد ما سيحدث إذا قام اللاعب بالنقر على زر السهم الأيسر
                        case LEFT:
                            // إذا لم تكن الأفعى تسير في الإتجاه الأيمن سيتم توجيهها نحو الإتجاه الأيسر
                            moves++;
                            left = true;
                            if (!right)
    						{
                                left = true;
                            }
    						else
    						{
                                left = false;
                                right = true;
                            }
                            up = false;
                            down = false;
                            break;
    
                        // هنا قمنا بتحديد ما سيحدث إذا قام اللاعب بالنقر على زر السهم المتجه للأعلى
                        case UP:
                            // إذا لم تكن الأفعى تسير في اتجاه الأسفل سيتم توجيهها نحو الأعلى
                            moves++;
                            up = true;
                            if (!down)
    						{
                                up = true;
                            }
    						else {
                                up = false;
                                down = true;
                            }
                            left = false;
                            right = false;
                            break;
    
                        // هنا قمنا بتحديد ما سيحدث إذا قام اللاعب بالنقر على زر السهم المتجه للأسفل
                        case DOWN:
                            // إذا لم تكن الأفعى تسير في اتجاه الأعلى سيتم توجيهها نحو الأسفل
                            moves++;
                            down = true;
                            if (!up)
    						{
                                down = true;
                            }
    						else {
                                up = true;
                                down = false;
                            }
                            left = false;
                            right = false;
                            break;
                    }
                }
            });
        }
    
        // هنا قمنا بتشغيل التطبيق
        public static void main(String[] args) {
            launch(args);
        }
    
    }
    		
    إعلان

    Eqla3Tech.com

    شروحات مكتوبة حول لغات البرمجة و تقنية المعلومات باللغة العربية مقدمة من إقلاع تك.

    لغة جافا لغة ++C قواعد البيانات نظام ويندوز نظام لينكس الشبكات تقنية المعلومات الأمن السيبراني

    الدورات

    أدوات مساعدة

    الأقسام

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