[Tạo 2D Platformer Game với Godot] Phần 26: Thêm điểm số khi hết game
Trong phần này thì mình sẽ hướng dẫn bạn cách để thêm điểm số vào cái LevelMap để nó có thể cập nhật số sao sau khi hết game.
Điểm số
Cách giải quyết
Về cách xử lý vấn đề của phần này thì mình sẽ giải thích như sau:
+ Đầu tiên mình sẽ cần 1 script và script đó có thể được truy cập vào mọi nơi, script này sẽ chịu trách nhiệm cho việc lưu trữ dữ liệu cụ thể ở đây là điểm số của từng map.
+ Mình sẽ tính điểm số đạt được của 1 map ở trong script của EndLevelMenu, điểm số này nếu muốn tính sẽ cần có: (số đồng xu đã thu thập được / tổng số đồng xu trong map ) * 100.
+ Để lấy được tổng số đồng xu thì mình sẽ thêm cái scene đồng xu vào 1 group gọi là dongxu và mình có hàm get_tree().get_nodes_in_group(“dongxu) sẽ cho phép mình lấy tất cả số đông xu đang có trên scene và hàm này sẽ trả về kiểu array.
+ Rồi ở LevelMap mấy child Level1,2,.. mình sẽ gán biến SoDiem đã làm ở phần trước bằng với điểm số ở trong script chứa dữ liêu.
Autoload script
Đây là 1 tính năng của Godot cho phép bạn biến 1 script nào đó thành script autoload tức là nó luôn luôn chạy cho dù bạn đang ở bất kỳ scene nào và có thể được truy cập ở mọi nơi.
Bạn tao cho mình 1 script mới tên là PlayerData ở Scenes
Rồi vô Project -> project settings -> Autoload
Nhấn vô icon thư mục.
Tìm script vừa tạoNhấn vô add và bạn sẽ thấy nó hiển thị ở ô bên dưới.
Add group scene đồng xu
Qua scene đồng xu
Ở bên phải bên cạnh signals bạn nhán vô group rồi gõ tên group -> nhấn add để thêm node vô group
Map
Ở scene Map1 mình sẽ add thêm 1 Node2D để chứa các node DongXu để nhìn cho nó gọn.
Rồi mình chỉnh sao cho dễ để thu thập
Bạn chỉnh đồng xu bao nhiêu là tuỳ bạn nhé không nhất thiết phải giống mình.
Player
Ở script của Player bạn chỉ cần thêm cho mình 1 biến đó là:
onready var max_dongxu = get_tree().get_nodes_in_group("dongxu")
Biến này mình dùng để xác định tổng số lượng đồng xu có trong map.
PlayerData
Ở Script autoload Playerdata mà mình vừa tạo trên nãy thì mình thêm 1 biến thuộc Dictonary tên là điểm số và nó có trách nhiệm là mang điểm số của từng map.
extends Node var diemso = { "Map1": 0, "Map2":0, "Map3:": 0, }
EndLevelMenu
extends CanvasLayer onready var level = get_parent().get_node("KhuVucDiChuyen") onready var map = get_parent().name onready var player = get_parent().get_node("Player") var diemso func _on_NutLevelKeTiep_pressed(): get_tree().paused = false get_tree().change_scene(level.LevelKeTiep) diemso = int(( float(player.dongxu) /player.max_dongxu) * 100) if diemso > PlayerData.diemso[map]: PlayerData.diemso[map] = diemso pass # Replace with function body. func _on_NutChoiLai_pressed(): get_tree().paused = false get_tree().reload_current_scene() print("choi lai") pass # Replace with function body. func _on_NutVeMenu_pressed(): get_tree().paused = false get_tree().change_scene("res://Scences/Map/LevelMap.tscn") diemso = int(( float(player.dongxu) /player.max_dongxu.size()) * 100) if diemso > PlayerData.diemso[map]: PlayerData.diemso[map] = diemso pass # Replace with function body.
Ở đây, mình khai báo thêm 3 biến là:
+ map: để mình xác định được tên của map mình đang chơi.
+ player: để mình có thể lấy được số lượng đồng xu đã thu thập và tổng số đồng xu trong map.
+ diemso: tính điểm số mà bạn đạt được.
func _on_NutLevelKeTiep_pressed(): get_tree().paused = false get_tree().change_scene(level.LevelKeTiep) diemso = int(( float(player.dongxu) /player.max_dongxu) * 100) if diemso > PlayerData.diemso[map]: PlayerData.diemso[map] = diemso
diemso = int(( float(player.dongxu) /player.max_dongxu) * 100)
: là công thức mình tính điểm số.
if diemso > PlayerData.diemso[map]:
là mình check nếu như diemso của màn này mà lớn hơn điểm số đã có sẵn thì nó sẽ thêm điểm số này vào và ngược lại.
Mình sẽ làm tương tự như bên hàm NutVeMenu vì khi bạn show cái EndLevelMenu là bạn đã hoàn thành nó rồi cho nên thoát ra hay chơi tiếp đều tính và nếu như nhấn chơi lại thì không.
Level Script
Bạn qua cho mình cái scene Level ở LevelMap ấy.
Và ở hàm _process mình thêm 1 dòng để cập nhật điểm số.
SoDiem = PlayerData.diemso[MapName]
Mình sẽ có full code như bên dưới:
extends Control export (String) var MapName export (String,FILE) var Scene export (String) var Level onready var ngoisaovang = preload("res://Assets/LevelMap/3 UI/Star1.png") var SoDiem = 0 func _ready(): $SoLevel.text = Level func _process(delta): SoDiem = PlayerData.diemso[MapName] if SoDiem >= 1 and SoDiem <= 30: $NgoiSao1.texture = ngoisaovang elif SoDiem >= 30 and SoDiem <= 95: $NgoiSao1.texture = ngoisaovang $NgoiSao2.texture = ngoisaovang elif SoDiem >= 95: $NgoiSao1.texture = ngoisaovang $NgoiSao2.texture = ngoisaovang $NgoiSao3.texture = ngoisaovang func _on_HinhTron_pressed(): get_tree().change_scene(Scene) pass # Replace with function body.
Kết quả
Vậy sau khi thu thập hết đồng xu mình thêm vào và quay về Level Mênu mình sẽ được 3 sao.
Lưu ý
Ở cái Menu ấy, bạn chỉnh code chỗ nút Bắt đầu, cái change_scene thành cái scene Level Map nha.
Tổng Kết
Vậy là mình đã hướng dẫn xong bạn cách thêm số sao đạt được rồi, trong phần tiếp mình sẽ hướng dẫn bạn cách để khoá level lại và unlock level kế tiếp.