القائمة الرئيسية

الصفحات

كيفية برمجة لعبة نصية على Android Studio باستخدام Java

How to code a text game in Android Studio using Java، How to code text game in Android Studio Java، إنشاء مشروع، Android Java Main Menu، لعبة نصية Java شاشة رئيسية،Text Adventure Start Screen، About Page Android Java، Sound Effects Android Java، MediaPlayer Button Click، مؤثرات صوتية لعبة اندرويد، Game Inventory Android Java، Game Score Tracking Java،Android SharedPreferences Points، Android Java Dark Theme، Dark Mode Toggle Java App، الوضع الليلي في Android Studio، SharedPreferences Android، حفظ حالة اللعبة Android، استعادة حالة اللعبة Android، بيانات مستمرة Android، Android Activity، Intent Android، SharedPreferences Android، قائمة الإعدادات Android، TextView Android، SeekBar Android، حفظ الإعدادات Android، استعادة الإعدادات Android، Java Android، MainActivity، TextView Java، Button Java، View.OnClickListener، منطق اللعبة، إدارة حالة اللعبة، عرض النص ديناميكيًا، التعامل مع تفاعلات المستخدم، تطوير ألعاب نصية Android، برمجة ألعاب تفاعلية Android Java، ألعاب اختيار القصة Android، ألعاب مغامرات نصية Android، واجهة مستخدم ألعاب نصية Android، حفظ تقدم اللعبة Android، إعدادات ألعاب Android، Android Studio، تخطيط XML Android، واجهة مستخدم Android، TextView Android، Button Android، ScrollView Android، LinearLayout Android، برمجة ألعاب نصية على Android Studio، برمجة ألعاب نصية تفاعلية على Android Studio، باستخدام Java: دليل شامل، كيفية برمجة لعبة نصية على Android Studio باستخدام Java، قائمة الإعدادات Android، TextView، برمجة ألعاب، تطوير ألعاب، واجهة مستخدم، XML،





كيفية برمجة لعبة نصية على Android Studio باستخدام Java



انطلق في رحلة تطوير ألعاب نصية آسرة وممتعة مباشرة على Android Studio
 باستخدام لغة Java القوية ومكونات واجهة المستخدم القياسية. 
يهدف هذا الدليل الشامل إلى تزويدك بالمعرفة والخطوات التفصيلية لإنشاء 
لعبة نصية تفاعلية بالكامل، بدءًا من تصميم واجهة المستخدم البسيطة وصولًا إلى إضافة 
الإعدادات وآلية حفظ التقدم، استعد لإطلاق العنان لخيالك وتحويل قصصك إلى تجارب تفاعلية شيقة للاعبي Android.


خطوات برمجة لعبة نصية على Android Studio



الخطوة الأولى: إنشاء مشروع Android جديد وإعداد الواجهة الأساسية

في هذه الخطوة، سنقوم بإنشاء مشروع Android جديد في Android Studio
 وتصميم التخطيط الأساسي الذي سيعرض قصة اللعبة وخيارات اللاعب.
إنشاء مشروع Android جديد:
- افتح Android Studio وابدأ مشروعًا جديدًا، اختر قالب "Empty Activity".
- قم بتسمية مشروعك (مثل TextAdventureGame)، اختر لغة البرمجة Java.
- حدد الحد الأدنى لإصدار SDK وانقر على "Finish".

* تعديل ملف تخطيط XML (activity_main.xml):

انتقل إلى مجلد app -> res -> layout وافتح ملف activity_main.xml.
استبدل الكود الموجود بالتالي لتصميم واجهة بسيطة:
XML




<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

        <TextView
            android:id="@+id/storyTextView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="18sp"
            android:text="تبدأ مغامرتك هنا..." />

    </ScrollView>

    <LinearLayout
        android:id="@+id/choicesLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:gravity="center_horizontal"
        android:layout_marginTop="16dp">

        </LinearLayout>

</LinearLayout>


--

- LinearLayout رئيسي: لتنظيم العناصر عموديًا.
- ScrollView: لعرض نص القصة الطويل مع إمكانية التمرير.
- TextView (storyTextView): لعرض نص القصة الحالي.
- LinearLayout (choicesLayout): سيتم إضافة أزرار خيارات اللاعب إليه ديناميكيًا.

الخطوة الثانية: كتابة منطق اللعبة الأساسي في MainActivity.java

في هذه الخطوة، سنقوم بكتابة كود Java في ملف MainActivity.java 
لإدارة تدفق اللعبة، وعرض القصة، والتعامل مع اختيارات اللاعب.

* فتح ملف MainActivity.java:

انتقل إلى مجلد app -> java -> اسم حزمة التطبيق وافتح ملف MainActivity.java.
إضافة المتغيرات والإشارة إلى عناصر الواجهة:






package your_package_name; // استبدل باسم حزمتك

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private TextView storyTextView;
    private LinearLayout choicesLayout;
    private int currentState = 0; // لتتبع موقع اللاعب في القصة

    // هيكل بسيط لتخزين جزء من القصة وخياراتها
    private static class StoryState {
        String text;
        List<String> choices;
        List<Integer> nextStates;

        public StoryState(String text, List<String> choices, List<Integer> nextStates) {
            this.text = text;
            this.choices = choices;
            this.nextStates = nextStates;
        }
    }

    private List<StoryState> gameStates;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        storyTextView = findViewById(R.id.storyTextView);
        choicesLayout = findViewById(R.id.choicesLayout);

        // تهيئة قصة اللعبة
        initGameStory();

        // بدء اللعبة
        updateStory(currentState);
    }

    private void initGameStory() {
        gameStates = new ArrayList<>();

        // الحالة 0: البداية
        gameStates.add(new StoryState(
                "تستيقظ في غرفة مظلمة. ترى بابين أمامك.",
                List.of("افتح الباب الأيسر", "افتح الباب الأيمن"),
                List.of(1, 2)
        ));

        // الحالة 1: الباب الأيسر
        gameStates.add(new StoryState(
                "دخلت غرفة مليئة بالذهب! ماذا تفعل؟",
                List.of("اجمع الذهب", "اخرج من الغرفة"),
                List.of(3, 0)
        ));

        // الحالة 2: الباب الأيمن
        gameStates.add(new StoryState(
                "دخلت غرفة بها تنين غاضب! لقد خسرت.",
                List.of("ابدأ من جديد"),
                List.of(0)
        ));

        // الحالة 3: جمع الذهب
        gameStates.add(new StoryState(
                "لقد جمعت الكثير من الذهب! تهانينا، لقد فزت!",
                List.of("ابدأ من جديد"),
                List.of(0)
        ));
    }

    private void updateStory(int stateIndex) {
        if (stateIndex >= 0 && stateIndex < gameStates.size()) {
            StoryState current = gameStates.get(stateIndex);
            storyTextView.setText(current.text);
            choicesLayout.removeAllViews(); // إزالة الأزرار القديمة

            for (int i = 0; i < current.choices.size(); i++) {
                Button choiceButton = new Button(this);
                choiceButton.setText(current.choices.get(i));
                int nextState = current.nextStates.get(i);
                choiceButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        currentState = nextState;
                        updateStory(currentState);
                    }
                });
                choicesLayout.addView(choiceButton);
            }
        } else {
            storyTextView.setText("لقد حدث خطأ ما في القصة!");
            choicesLayout.removeAllViews();
        }
    }
}


--

- storyTextView و choicesLayout: مراجع لعناصر الواجهة.
- currentState: لتتبع موقع اللاعب الحالي في القصة.
- StoryState: كلاس بسيط لتخزين نص جزء من القصة وخياراته والحالات التالية لكل خيار.
- gameStates: قائمة لتخزين جميع حالات القصة.
- initGameStory(): تقوم بتهيئة قصة اللعبة وتعبئة قائمة gameStates.
 يمكنك توسيع هذه الدالة لإضافة المزيد من الحالات والخيارات.
- updateStory(int stateIndex): تقوم بعرض النص الحالي للقصة 
وإضافة أزرار الخيارات ديناميكيًا بناءً على currentState. عند النقر على زر، 
يتم تحديث currentState واستدعاء updateStory() مرة أخرى للانتقال إلى الجزء التالي من القصة.

الخطوة الثالثة: إضافة قائمة الإعدادات

في هذه الخطوة، سنقوم بإنشاء نشاط إعدادات بسيط يسمح للاعب بتعديل
 بعض الخيارات (مثال: تغيير حجم النص).

* إنشاء تخطيط XML لنشاط الإعدادات (settings_activity.xml):

انتقل إلى app -> res -> layout وانقر بزر الماوس الأيمن -> New -> Layout Resource File.
سمِّ الملف settings_activity.xml وأضف الكود التالي:
XML




<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="الإعدادات"
        android:textSize="24sp"
        android:textStyle="bold"
        android:layout_marginBottom="16dp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center_vertical">

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="حجم النص:"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/textSizeValueTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="18sp"
            android:text="18sp"
            android:layout_marginStart="8dp" />

    </LinearLayout>

    <SeekBar
        android:id="@+id/textSizeSeekBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="30"
        android:progress="18"
        android:layout_marginTop="8dp" />

</LinearLayout>


--

تخطيط بسيط يحتوي على عنوان، ومؤشر شريط التمرير (SeekBar) لتغيير 
حجم النص، و TextView لعرض قيمة حجم النص الحالي.

* إنشاء نشاط Java لصفحة الإعدادات (SettingsActivity.java):

انقر بزر الماوس الأيمن على اسم حزمة التطبيق في مجلد java -> New -> Activity -> Empty Activity.

* سمِّ النشاط SettingsActivity وأضف الكود التالي:





package your_package_name; // استبدل باسم حزمتك

import androidx.appcompat.app.AppCompatActivity;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;

public class SettingsActivity extends AppCompatActivity {

    private SeekBar textSizeSeekBar;
    private TextView textSizeValueTextView;
    private SharedPreferences sharedPreferences;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.settings_activity);

        textSizeSeekBar = findViewById(R.id.textSizeSeekBar);
        textSizeValueTextView = findViewById(R.id.textSizeValueTextView);
        sharedPreferences = getSharedPreferences("game_settings", MODE_PRIVATE);

        // استعادة حجم النص المحفوظ
        int savedTextSize = sharedPreferences.getInt("text_size", 18);
        textSizeSeekBar.setProgress(savedTextSize);
        textSizeValueTextView.setText(savedTextSize + "sp");

        // مستمع لتغييرات شريط التمرير
        textSizeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                textSizeValueTextView.setText(progress + "sp");
                // حفظ حجم النص عند تغييره
                SharedPreferences.Editor editor = sharedPreferences.edit();
                editor.putInt("text_size", progress);
                editor.apply();
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                // لا يلزم فعل شيء هنا
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                // لا يلزم فعل شيء هنا
            }
        });
    }
}


--

- يحصل هذا النشاط على مراجع لعناصر الواجهة.
- يستخدم SharedPreferences لحفظ واستعادة حجم النص تحت المفتاح "text_size".
- يستمع إلى تغييرات SeekBar ويقوم بتحديث TextView وحفظ قيمة حجم النص الجديدة.




* إضافة زر لفتح صفحة الإعدادات في MainActivity:

أضف زرًا إلى تخطيط activity_main.xml:

    <Button
android:id="@+id/settingsButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="الإعدادات"
android:layout_gravity="end"
android:layout_marginTop="8dp" />
--

* أضف مستمعًا لهذا الزر في `MainActivity.java`:

java

// داخل onCreate في MainActivity
Button settingsButton = findViewById(R.id.settingsButton);
settingsButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(MainActivity.this, SettingsActivity.class);
        startActivity(intent);
    }
});

// ... (بقية كود MainActivity)
--

* تطبيق الإعدادات في MainActivity:

في MainActivity.java، قم باستعادة حجم النص المحفوظ في
 onCreate() وقم بتطبيقه على storyTextView:
Java

// داخل onCreate في MainActivity
SharedPreferences sharedPreferences = getSharedPreferences("game_settings", MODE_PRIVATE);
int textSize = sharedPreferences.getInt("text_size", 18);
storyTextView.setTextSize(textSize);

// ... (بقية كود onCreate)
--

تأكد من استعادة الإعدادات أيضًا في دالة onResume() لجعل
 التغييرات تنعكس عند العودة إلى النشاط :
Java

@Override
protected void onResume() {
    super.onResume();
    SharedPreferences sharedPreferences = getSharedPreferences("game_settings", MODE_PRIVATE);
    int textSize = sharedPreferences.getInt("text_size", 18);
    storyTextView.setTextSize(textSize);
}
--

الخطوة الرابعة: إضافة حفظ واستعادة تقدم اللعبة

في هذه الخطوة، سنقوم بتطبيق آلية بسيطة لحفظ واستعادة تقدم اللعبة (الحالة الحالية للقصة).

* حفظ التقدم عند مغادرة النشاط :

- في MainActivity.java، قم بتجاوز دالة onPause() لحفظ currentState:
Java

@Override
protected void onPause() {
    super.onPause();
    SharedPreferences sharedPreferences = getSharedPreferences("game_progress", MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putInt("current_state", currentState);
    editor.apply();
}
--

* استعادة التقدم عند إنشاء النشاط:

في MainActivity.java، قم باستعادة currentState في onCreate():





@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        storyTextView = findViewById(R.id.storyTextView);
        choicesLayout = findViewById(R.id.choicesLayout);

        // استعادة حجم النص المحفوظ
        SharedPreferences settingsPreferences = getSharedPreferences("game_settings", MODE_PRIVATE);
        int textSize = settingsPreferences.getInt("text_size", 18);
        storyTextView.setTextSize(textSize);

        // استعادة تقدم اللعبة
        SharedPreferences progressPreferences = getSharedPreferences("game_progress", MODE_PRIVATE);
        currentState = progressPreferences.getInt("current_state", 0); // 0 هي القيمة الافتراضية

        // تهيئة قصة اللعبة
        initGameStory();

        // بدء اللعبة أو استئنافها بناءً على الحالة المحفوظة
        updateStory(currentState);

        // زر الإعدادات
        Button settingsButton = findViewById(R.id.settingsButton);
        settingsButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, SettingsActivity.class);
                startActivity(intent);
            }
        });
    }

    
--
 
التغييرات المضافة:

- تم استدعاء updateStory(currentState); بعد استعادة قيمة 
currentState من SharedPreferences. هذا يضمن أنه عند
 إعادة تشغيل التطبيق، سيتم عرض القصة في آخر حالة تم حفظها.
الآن، يجب أن يكون لديك مثال أساسي للعبة نصية تفاعلية على Android Studio
 مع واجهة مستخدم بسيطة، وقائمة إعدادات لتغيير حجم النص، وآلية لحفظ واستعادة تقدم اللعبة.
 يمكنك الآن توسيع هذا الأساس بإضافة المزيد من الحالات للقصة، وخيارات أكثر تعقيدًا،
وربما عناصر أخرى مثل المخزون أو نظام النقاط.

* برمجة شاشة رئيسية (Main Menu)

 إنشاء واجهة أولية تحتوي على أزرار لبدء اللعبة، استئناف، الإعدادات، حول اللعبة.

* تخطيط XML (activity_main_menu.xml):
xml




<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    android:padding="24dp">

    <Button
        android:id="@+id/startGameButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="ابدأ اللعبة" />

    <Button
        android:id="@+id/resumeGameButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="استئناف"
        android:layout_marginTop="12dp" />

    <Button
        android:id="@+id/settingsButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="الإعدادات"
        android:layout_marginTop="12dp" />

    <Button
        android:id="@+id/aboutButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="حول اللعبة"
        android:layout_marginTop="12dp" />
</LinearLayout>


--

* كود MainMenuActivity.java:
java




package your_package;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;

public class MainMenuActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_menu);

        Button startButton = findViewById(R.id.startGameButton);
        Button resumeButton = findViewById(R.id.resumeGameButton);
        Button settingsButton = findViewById(R.id.settingsButton);
        Button aboutButton = findViewById(R.id.aboutButton);

        startButton.setOnClickListener(v -> {
            getSharedPreferences("game_progress", MODE_PRIVATE).edit().putInt("current_state", 0).apply();
            startActivity(new Intent(this, MainActivity.class));
        });

        resumeButton.setOnClickListener(v ->
            startActivity(new Intent(this, MainActivity.class))
        );

        settingsButton.setOnClickListener(v ->
            startActivity(new Intent(this, SettingsActivity.class))
        );

        aboutButton.setOnClickListener(v ->
            startActivity(new Intent(this, AboutActivity.class))
        );
    }
}


--

* شاشة "حول اللعبة" (About)

معلومات حول اللعبة ، Text Game Developer Info




* XML (activity_about.xml):
xml




<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="24dp">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="لعبة مغامرة نصية\n\nالمطور: أحمد المطور\nفكرة اللعبة: تفاعل واختيارات\nالإصدار: 1.0\n\nشكراً لتجربتك!" 
        android:textSize="18sp" />
</ScrollView>


--

* Java (AboutActivity.java):

package your_package;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;

public class AboutActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_about);
    }
}
--

*  إضافة مؤثرات صوتية،  إضافة ملف صوتي:
ضع ملف مثل click.mp3 في مجلد res/raw/.

* تعديل MainActivity.java:

import android.media.MediaPlayer;

// داخل MainActivity
private MediaPlayer mediaPlayer;

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    mediaPlayer = MediaPlayer.create(this, R.raw.click);
}

// في updateStory() داخل onClick:
choiceButton.setOnClickListener(v -> {
    mediaPlayer.start();
    currentState = nextState;
    updateStory(currentState);
});
--

* نظام النقاط أو "المخزون"

* إضافة متغير score في MainActivity:

private int score = 0;
--

* زيادة النقاط بناءً على اختيارات:

if (stateIndex == 3) { // إذا فاز بالذهب مثلاً
    score += 50;
}
--

* حفظ واسترجاع النقاط:
java

@Override
protected void onPause() {
    super.onPause();
    SharedPreferences progressPrefs = getSharedPreferences("game_progress", MODE_PRIVATE);
    SharedPreferences.Editor editor = progressPrefs.edit();
    editor.putInt("current_state", currentState);
    editor.putInt("score", score);
    editor.apply();
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    SharedPreferences prefs = getSharedPreferences("game_progress", MODE_PRIVATE);
    score = prefs.getInt("score", 0);

}
--

* نمط ليلي (Dark Mode)

* تحديث res/values/themes.xml:
xml

<style name="Theme.MyApp.Dark" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
    <!-- تخصيص السمات إن أردت -->
</style>
--

* تبديل الثيم حسب الاختيار:
java

// في SettingsActivity.java أو أي مكان آخر
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); // أو NO
--

* حفظ اختيار المستخدم:
java

SharedPreferences.Editor editor = getSharedPreferences("game_settings", MODE_PRIVATE).edit();
editor.putBoolean("dark_mode", true);
editor.apply();
--

* ثم في onCreate():
java

boolean darkMode = getSharedPreferences("game_settings", MODE_PRIVATE).getBoolean("dark_mode", false);
AppCompatDelegate.setDefaultNightMode(darkMode ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO);
--

الخاتمة 

تهانينا! لقد تعلمت كيف تطور لعبة مغامرة نصية تفاعلية بالكامل باستخدام 
Java وAndroid Studio، مع واجهة رئيسية أنيقة، إعدادات قابلة للتخصيص،
 مؤثرات صوتية، ومكونات مثل نظام النقاط ونمط الليل. بإمكانك الآن توسيع مشروعك
ليتضمن فصول متعددة، نظام معارك، أو حتى التكامل مع قاعدة بيانات Room أو Firebase. 
هذه اللعبة تشكل حجر الأساس لمغامرات أكثر تعقيدًا، فاستمر في التعلم والتجربة!


جدول المحتويات