[Tạo 2D Platformer Game với Godot] Phần 29: Lưu và load dữ liệu game

Trong phần này, mình sẽ hướng dẫn bạn cách để lưu và load dữ liệu người dùng cho game.

Save and load

Các bước

Về các bước thực hiện mình sẽ mô tả ở bên dưới:

+ Đầu tiên, mình sẽ cần 1 autoload script mới có trọng trách là xử lý vấn đề lưu dữ liệu game và load dữ liệu game. Mình xài autoload cho nó dễ + không lằng nhằng rồi mình tạo 2 hàm đó là luu_game() và load_game() .

+Ở hàm luu_game() mình sẽ lưu dưới type ConfigFile thay vì Json file như mấy kênh Youtube hay làm bởi vì nó gọn không dài dòng như json file.

+ Khi lưu game mình sẽ có thể chọn lưu bình thường và lưu dưới dạng mã hoá. Vậy lưu mã hoá là gì? Đó là khi bạn lưu dưới dạng mã hoá file lưu game của bạn sẽ được mã hoá lại và người dùng không thể mở nó ra rồi edit nhằm việc gian lận.

+ Hàm load_game() thì mình sẽ tạo 1 biến và biến này có 2 trách nhiệm đó là vừa kiểm tra rằng file lưu dữ liệu có tồn tại và load file lưu dữ liệu.

Autoload

[Tạo 2D Platformer Game với Godot] Phần 29: Lưu và load dữ liệu game 5

Mình tạo 1 script mới tên là DuLieu.

[Tạo 2D Platformer Game với Godot] Phần 29: Lưu và load dữ liệu game 6 [Tạo 2D Platformer Game với Godot] Phần 29: Lưu và load dữ liệu game 7

Sau đó vào Autoload và add cái script DuLieu vào.

Lưu game

Mình khai báo 1 biến const chứa địa chỉ lưu file dữ liệu. const SAVE_PATH = "user://file_dulieu.data"

File dữ liệu bạn có thể lưu với các đuôi khác nhau như data,ini,abc,jqk,cfg,file,… Và tuỳ vào bạn.

Về phần hàm:

func luu_game():
    var config = ConfigFile.new()
    config.set_value("player","diemso",PlayerData.diemso)
    config.set_value("player","unlocked_maps",PlayerData.Unlocked_map)
    config.save(SAVE_PATH)

Mình tạo 1 file Confìg mới rồi mình đưa dữ liệu điểm số và unlocked maps vào file đó.

Ở set_value() sẽ có 3 praramters:

+ Cái đâu tiên là Section: Đây là khu dữ liệu,mỗi khu dữ liệu sẽ có các giá trị của nó.

Key: Mình gọi đây là giá trị lưu trong 1 Section, nếu nhìn đoạn code trên thì sẽ thấy key ở đây là diemso,unlockedmap.

value: Đây là giá trị bạn cần gán cho key.

Sau đó, save file lại.

Load Game

func load_game():
    var config = ConfigFile.new()
    var check_file = config.load(SAVE_PATH)
    if check_file != OK: # Neu file khong bi loi hoac khong co
        return  # Huy bo load file
    PlayerData.diemso = config.get_value("player","diemso")
    PlayerData.Unlocked_map = config.get_value("player","unlocked_maps")

Ở load game thì mình khai báo 1 biến là check_file rồi gán nó = confg.load(SAVE_PATH) khi chạy thì config nó sẽ load file + với gán file vào check_file.

Rồi mình check nếu file OK thì tiếp tục và sau đó lấy giá trị từ save file.

Menu

Ở cái Menu mình sẽ thêm 2 dòng.

func _ready():
    DuLieu.load_game()

Mình gọi DuLieu sau đó thì load_game() để khi mới chạy game lên thì mình load dữ liệu luôn.

EndLevelMenu

Ở EndLevelMenu mình sẽ loại bỏ code tính điểm số và thêm nó vào trong KhuVucDiChuyen cho gọn.

extends CanvasLayer


onready var level = get_parent().get_node("KhuVucDiChuyen")
func _on_NutLevelKeTiep_pressed():
    get_tree().paused = false
    get_tree().change_scene(level.LevelKeTiep)
    pass # Replace with function body.

func _on_NutChoiLai_pressed():
    get_tree().paused = false
    get_tree().reload_current_scene()
    pass # Replace with function body.


func _on_NutVeMenu_pressed():
    get_tree().paused = false
    get_tree().change_scene("res://Scences/Map/LevelMap.tscn")

KhuVucDiChuyen

Trong đây, mình sẽ tính toán hết mọi thứ rồi lưu dữ liệu lại.

extends Area2D


export (String,FILE) var LevelKeTiep
onready var endlevelmenu = get_parent().get_node("EndLevelMenu")
var diemso
onready var player = get_parent().get_node("Player")
onready var map = get_parent().name
func _on_KhuVucDiChuyen_body_entered(body):
    if body.name == "Player":
        endlevelmenu.get_node("EndLevelMenu").show()    
        get_tree().paused = true
        PlayerData.Unlocked_map[get_parent().name] = true
        diemso = int( float(player.dongxu /player.max_dongxu.size()) * 100)
        if diemso > PlayerData.diemso[map]: 
            PlayerData.diemso[map] = diemso
        DuLieu.luu_game()

Kết quả

Sau khi chạy game bạn chơi xong 1 ván rồi thoát ra vô lại sẽ thấy nó được lưu và load dữ liệu game.

[Tạo 2D Platformer Game với Godot] Phần 29: Lưu và load dữ liệu game

Bạn có thể thấy file_dulieu đã được tạo ra.

[Tạo 2D Platformer Game với Godot] Phần 29: Lưu và load dữ liệu game 8

Bạn có thể tìm thấy vị trí lưu file ở Project -> Open Projec Data Folder

Tổng Kết

Vậy là Series lập trình game Platformer với Godot Engine đã hoàn thành, nếu như bạn nào khong hiểu thì có thể lên cộng đồng hỏi nhé.

Mình sẽ để project ở bên dưới:

DeathGM/platformer-game-voi-godot-engine

 

 

 

 

 

 

 

Previous Post Next Post