اذهب إلى المحتوى

سنتعلم في مقال اليوم كيفية حفظ البيانات المحلية بين جلسات اللعب وتحميل هذه البيانات عند الحاجة لها، هذا الموضوع مهم بشكل خاص عندما نريد الاحتفاظ بتقدم اللاعب أو إعدادات اللعبة عبر عدة جلسات لعب، حتى بعد إغلاق اللعبة وإعادة فتحها.

كيف نحفظ البيانات المحلية في جودو

يعتمد نظام إدخال وإخراج الملفات الخاص بمحرك الألعاب جودو Godot على كائن يسمى FileAccess ويمكنا فتحه من خلال استدعاء التابع open()‎ كما يلي:

var file = FileAccess.open("user://myfile.name", File.READ)

ملاحظة: يجب تخزين بيانات المستخدم فقط في المسار user://‎، ويمكننا استخدام المسار res://‎ عند التشغيل من المحرّر، ولكن يصبح هذا المسار للقراءة فقط عند تصدير مشروعنا.

الوسيط الثاني الموجود بعد مسار الملف هو راية الوضع Mode Flag ويمكن أن يكون لها أحد الخيارات التالية:

  • FileAccess.READ: مفتوح للقراءة
  • FileAccess.WRITE: مفتوح للكتابة، وينشئ الملف إن لم يكن موجودًا مسبقًا ويقتطعه Truncate إذا كان موجودًا مسبقًا
  • FileAccess.READ_WRITE: مفتوح للقراءة والكتابة، ولا يقتطع الملف
  • FileAccess.WRITE_READ: مفتوح للقراءة أو الكتابة، وينشئ الملف إن لم يكن موجودًا مسبقًا ويقتطعه إذا كان موجودًا مسبقًا

تخزين البيانات

يمكننا حفظ البيانات باستخدام نوع البيانات المحدّد مثل store_float()‎ و store_string()‎ وغير ذلك، أو باستخدام الدالة store_var()‎ المعمَّمة، والتي ستستخدم التسلسل Serialization المُدمَج في جودو لتشفير بياناتك بما في ذلك البيانات المعقدة مثل الكائنات التي سنتحدث عنها لاحقًا.

لنبدأ بمثال بسيط لحفظ أعلى نتيجة للاعب، حيث يمكننا كتابة دالة يمكن استدعاؤها كلما احتجنا إلى حفظ النتيجة:

var save_path = "user://score.save"

func save_score():
    var file = FileAccess.open(save_path, FileAccess.WRITE)
    file.store_var(highscore)

نحفظ النتيجة، ولكن يجب تحميلها عند بدء اللعبة كما يلي:

func load_score():
    if FileAccess.file_exists(save_path):
        print("file found")
        var file = FileAccess.open(save_path, FileAccess.READ)
        highscore = file.get_var()
    else:
        print("file not found")
        highscore = 0

علينا أن لا ننسى التحقق من وجود الملف قبل محاولة القراءة منه، إذ قد لا يكون موجودًا، وإن كان غير موجود، فيمكننا استخدام قيمة افتراضية.

كما يمكن استخدام الدالتين store_var()‎ و get_var()‎ عدة مرات حسب حاجتك مع أيّ عدد من القيم.

حفظ الموارد

تعمل الطريقة السابقة بنجاح عندما نريد أن نحفظ عددًا معينًا من القيم، ولكن يمكننا حفظ بياناتنا في مورد Resource في الحالات الأكثر تعقيدًا كما يفعل جودو الذي يحفظ جميع موارد البيانات الخاصة به على أنها ملفات ‎.tres مثل Animations و TileSets و Shaders وما إلى ذلك حيث يمكننا تطبيق ذلك أيضًا. 

يمكن حفظ الموارد وتحميلها باستخدام صنفي جودو ResourceSaver و ResourceLoader.

لنفترض مثلًا تخزين جميع بيانات الإحصائيات الخاصة بشخصية لعبتنا في مورد كما يلي:

extends Resource
class_name PlayerData

var level = 1
var experience = 100

var strength = 5
var intelligence = 3
var charisma = 2

يمكننا بعد ذلك الحفظ والتحميل كما يلي:

func load_character_data():
    if ResourceLoader.exists(save_path):
        return load(save_path)
    return null

func save_character_data(data):
    ResourceSaver.save(data, save_path)

قد تحتوي الموارد على موارد فرعية، لذا يمكن أيضًا تضمين موارد مخزن اللاعب وغير ذلك.

هل يمكن تخزين البيانات في ملف JSON

قد يخطر في البال سؤال عن إمكانية استخدام صيغة JSON لحفظ البيانات، ولكن يُوصَى بعدم استخدام JSON مع ملفات الحفظ الخاصة بنا. يدعم جودو صيغة JSON، ولكن لا يُعَد حفظ بيانات اللعبة هدف استخدام JSON التي هي صيغة لتبادل البيانات، والغرض منها هو السماح للأنظمة التي تستخدم صيغ بيانات ولغات مختلفة بتبادل البيانات، لذا ستسبّب صيغة JSON قيودًا سلبية عندما يتعلق الأمر بحفظ بيانات اللعبة. 

إضافة لذلك لا تدعم JSON العديد من أنواع البيانات، إذ لا يوجد نوع البيانات int مقابل نوع البيانات float مثلًا، لذا يجب إجراء الكثير من عمليات التحويل والتحقق لمحاولة حفظ أو تحميل بياناتنا، ويُعَد ذلك أمرًا مرهقًا ويستغرق وقتًا طويلًا.

لا ننصح بتضيع الوقت في محاولة كهذه، إذ يمكننا تخزين كائنات جودو الأصيلة مثل العقد والموارد والمشاهد دون أي جهد باستخدام التسلسل المُدمَج في جودو، مما يعني أننا ستستخدم شيفرة برمجية أقل مع وجود أخطاء أقل، ولا يستخدم جودو صيغة JSON لحفظ المشاهد والموارد.

الخاتمة

تعلمنا في مقال اليوم أساسيات حفظ واسترجاع البيانات المحلية بين جلسات اللعب، وتجدر الإشارة لأن هذا المقال لا يمثل سوى جزء بسيط ممّا يمكنك إنجازه باستخدام FileAccess، لذا ننصح بالاطلاع على توثيق FileAccess للحصول على القائمة الكاملة لتوابعه.

ترجمة -وبتصرّف- للقسم Saving/loading data من توثيقات Kidscancode.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...