diff --git a/plugin/demo/scenes/players/PlayerDisplay.gd b/plugin/demo/scenes/players/PlayerDisplay.gd new file mode 100644 index 0000000..ffd387f --- /dev/null +++ b/plugin/demo/scenes/players/PlayerDisplay.gd @@ -0,0 +1,27 @@ +extends Control + +@onready var id_label: Label = %IdLabel +@onready var name_label: Label = %NameLabel +@onready var title_label: Label = %TitleLabel +@onready var status_label: Label = %StatusLabel +@onready var level_label: Label = %LevelLabel +@onready var xp_label: Label = %XpLabel + +@onready var compare_button: Button = %CompareButton + +var player: PlayersClient.Player + +func _ready() -> void: + if player: + _set_up_display() + compare_button.pressed.connect(func(): + PlayersClient.compare_profile(player.player_id) + ) + +func _set_up_display() -> void: + id_label.text = player.player_id + name_label.text = player.display_name + title_label.text = player.title + status_label.text = PlayersClient.PlayerFriendStatus.find_key(player.friend_status) + level_label.text = str(player.level_info.current_level.level_number) + xp_label.text = str(player.level_info.current_xp_total) diff --git a/plugin/demo/scenes/players/PlayerDisplay.tscn b/plugin/demo/scenes/players/PlayerDisplay.tscn new file mode 100644 index 0000000..9bb2316 --- /dev/null +++ b/plugin/demo/scenes/players/PlayerDisplay.tscn @@ -0,0 +1,148 @@ +[gd_scene load_steps=3 format=3 uid="uid://cipu5ch2lo1ne"] + +[ext_resource type="Theme" uid="uid://bmm3mvq11y045" path="res://theme.tres" id="1_uv4o5"] +[ext_resource type="Script" path="res://scenes/players/PlayerDisplay.gd" id="2_87phy"] + +[node name="FriendDisplay" type="PanelContainer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 1 +theme = ExtResource("1_uv4o5") +script = ExtResource("2_87phy") + +[node name="MarginContainer" type="MarginContainer" parent="."] +layout_mode = 2 +theme_override_constants/margin_left = 25 +theme_override_constants/margin_top = 25 +theme_override_constants/margin_right = 25 +theme_override_constants/margin_bottom = 25 + +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"] +layout_mode = 2 +theme_override_constants/separation = 25 + +[node name="Id" type="HBoxContainer" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="Label" type="Label" parent="MarginContainer/VBoxContainer/Id"] +layout_mode = 2 +text = "ID:" + +[node name="IdLabel" type="Label" parent="MarginContainer/VBoxContainer/Id"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +text_overrun_behavior = 3 + +[node name="Name" type="HBoxContainer" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="Label" type="Label" parent="MarginContainer/VBoxContainer/Name"] +layout_mode = 2 +text = "Name:" + +[node name="NameLabel" type="Label" parent="MarginContainer/VBoxContainer/Name"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +text_overrun_behavior = 3 + +[node name="Title" type="HBoxContainer" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="Label" type="Label" parent="MarginContainer/VBoxContainer/Title"] +layout_mode = 2 +text = "Title:" + +[node name="TitleLabel" type="Label" parent="MarginContainer/VBoxContainer/Title"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="Status" type="HBoxContainer" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="Label" type="Label" parent="MarginContainer/VBoxContainer/Status"] +layout_mode = 2 +text = "Status:" + +[node name="StatusLabel" type="Label" parent="MarginContainer/VBoxContainer/Status"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="Level" type="HBoxContainer" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="Label" type="Label" parent="MarginContainer/VBoxContainer/Level"] +layout_mode = 2 +text = "Level:" + +[node name="LevelLabel" type="Label" parent="MarginContainer/VBoxContainer/Level"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="Xp" type="HBoxContainer" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="Label" type="Label" parent="MarginContainer/VBoxContainer/Xp"] +layout_mode = 2 +text = "XP:" + +[node name="XpLabel" type="Label" parent="MarginContainer/VBoxContainer/Xp"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="HSeparator" type="HSeparator" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="Compare" type="VBoxContainer" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 +theme_override_constants/separation = 25 + +[node name="CompareButton" type="Button" parent="MarginContainer/VBoxContainer/Compare"] +unique_name_in_owner = true +layout_mode = 2 +theme = ExtResource("1_uv4o5") +text = "Compare" +text_overrun_behavior = 3 + +[node name="HSeparator2" type="HSeparator" parent="MarginContainer/VBoxContainer"] +visible = false +layout_mode = 2 + +[node name="Variants" type="VBoxContainer" parent="MarginContainer/VBoxContainer"] +visible = false +layout_mode = 2 +theme_override_constants/separation = 25 + +[node name="TimeSpan" type="VBoxContainer" parent="MarginContainer/VBoxContainer/Variants"] +layout_mode = 2 + +[node name="Label" type="Label" parent="MarginContainer/VBoxContainer/Variants/TimeSpan"] +layout_mode = 2 +text = "Time Span" + +[node name="TimeSpan" type="OptionButton" parent="MarginContainer/VBoxContainer/Variants/TimeSpan"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="Collection" type="VBoxContainer" parent="MarginContainer/VBoxContainer/Variants"] +layout_mode = 2 + +[node name="Label" type="Label" parent="MarginContainer/VBoxContainer/Variants/Collection"] +layout_mode = 2 +text = "Collection" + +[node name="Collection" type="OptionButton" parent="MarginContainer/VBoxContainer/Variants/Collection"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="ShowVariant" type="Button" parent="MarginContainer/VBoxContainer/Variants"] +unique_name_in_owner = true +layout_mode = 2 +theme = ExtResource("1_uv4o5") +disabled = true +text = "Show Leaderboard Variant" +text_overrun_behavior = 3 diff --git a/plugin/demo/scenes/players/Players.gd b/plugin/demo/scenes/players/Players.gd index 6678302..b003364 100644 --- a/plugin/demo/scenes/players/Players.gd +++ b/plugin/demo/scenes/players/Players.gd @@ -2,10 +2,13 @@ extends Control @onready var back_button: Button = %Back +@onready var search_button: Button = %SearchButton +@onready var search_display: VBoxContainer = %SearchDisplay + @onready var friends_display: VBoxContainer = %FriendsDisplay var _friends_cache: Array[PlayersClient.Player] = [] -var _friend_display := preload("res://scenes/players/FriendDisplay.tscn") +var _player_display := preload("res://scenes/players/PlayerDisplay.tscn") func _ready() -> void: if _friends_cache.is_empty(): @@ -15,11 +18,21 @@ func _ready() -> void: _friends_cache = friends if not _friends_cache.is_empty() and friends_display.get_child_count() == 0: for friend: PlayersClient.Player in _friends_cache: - var container := _friend_display.instantiate() as Control - container.friend = friend + var container := _player_display.instantiate() as Control + container.player = friend friends_display.add_child(container) ) + PlayersClient.player_searched.connect(func(player: PlayersClient.Player): + for child in search_display.get_children(): + child.queue_free() + var container := _player_display.instantiate() as Control + container.player = player + search_display.add_child(container) + ) back_button.pressed.connect(func(): get_tree().change_scene_to_file("res://scenes/MainMenu.tscn") ) + search_button.pressed.connect(func(): + PlayersClient.search_player() + ) diff --git a/plugin/demo/scenes/players/Players.tscn b/plugin/demo/scenes/players/Players.tscn index a221c3a..b1e4ec8 100644 --- a/plugin/demo/scenes/players/Players.tscn +++ b/plugin/demo/scenes/players/Players.tscn @@ -43,28 +43,40 @@ layout_mode = 2 size_flags_vertical = 3 horizontal_scroll_mode = 0 -[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/VBoxContainer/ScrollContainer"] +[node name="ScrollChild" type="VBoxContainer" parent="MarginContainer/VBoxContainer/ScrollContainer"] layout_mode = 2 size_flags_horizontal = 3 size_flags_vertical = 3 theme_override_constants/separation = 25 -[node name="ShowAchievements" type="Button" parent="MarginContainer/VBoxContainer/ScrollContainer/VBoxContainer"] +[node name="Search" type="VBoxContainer" parent="MarginContainer/VBoxContainer/ScrollContainer/ScrollChild"] +layout_mode = 2 +theme_override_constants/separation = 25 + +[node name="SearchButton" type="Button" parent="MarginContainer/VBoxContainer/ScrollContainer/ScrollChild/Search"] unique_name_in_owner = true -visible = false custom_minimum_size = Vector2(500, 200) layout_mode = 2 theme = ExtResource("1_i7feq") -text = "Show Achievements" +text = "Search Players" -[node name="Label" type="Label" parent="MarginContainer/VBoxContainer/ScrollContainer/VBoxContainer"] +[node name="SearchDisplay" type="VBoxContainer" parent="MarginContainer/VBoxContainer/ScrollContainer/ScrollChild/Search"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="HSeparator" type="HSeparator" parent="MarginContainer/VBoxContainer/ScrollContainer/ScrollChild"] +layout_mode = 2 + +[node name="Friends" type="VBoxContainer" parent="MarginContainer/VBoxContainer/ScrollContainer/ScrollChild"] +layout_mode = 2 +theme_override_constants/separation = 25 + +[node name="Label" type="Label" parent="MarginContainer/VBoxContainer/ScrollContainer/ScrollChild/Friends"] layout_mode = 2 text = "Friends" horizontal_alignment = 1 -[node name="FriendsDisplay" type="VBoxContainer" parent="MarginContainer/VBoxContainer/ScrollContainer/VBoxContainer"] +[node name="FriendsDisplay" type="VBoxContainer" parent="MarginContainer/VBoxContainer/ScrollContainer/ScrollChild/Friends"] unique_name_in_owner = true layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 theme_override_constants/separation = 25 diff --git a/plugin/export_scripts_template/autoloads/players_client.gd b/plugin/export_scripts_template/autoloads/players_client.gd index 44f3256..29aa073 100644 --- a/plugin/export_scripts_template/autoloads/players_client.gd +++ b/plugin/export_scripts_template/autoloads/players_client.gd @@ -10,6 +10,12 @@ extends Node ## The array will be empty if there was an error loading the friends list. signal friends_loaded(friends: Array[Player]) +## Signal emitted after selecting a player in the search window opened by the +## [method search_player] method.[br] +## [br] +## [param player]: The selected player. +signal player_searched(player: Player) + ## Friends list visibility statuses. enum FriendsListVisibilityStatus { FEATURE_UNAVAILABLE = 3, ## The friends list is currently unavailable for the game. @@ -38,6 +44,10 @@ func _connect_signals() -> void: friends_loaded.emit(friends) ) + GodotPlayGameServices.android_plugin.playerSearched.connect(func(friend_json: String): + var safe_dictionary := GodotPlayGameServices.json_marshaller.safe_parse_dictionary(friend_json) + player_searched.emit(Player.new(safe_dictionary)) + ) ## Use this method and subscribe to the emitted signal to receive the list of friends ## for the current player.[br] @@ -92,6 +102,13 @@ func compare_profile_with_alternative_name_hints( current_player_in_game_name ) +## Displays a screen where the user can search for players. If the user selects +## a player, then the [signal player_searched] signal will be emitted, returning +## the selected player. +func search_player() -> void: + if GodotPlayGameServices.android_plugin: + GodotPlayGameServices.android_plugin.searchPlayer() + ## Player information. class Player: var banner_image_landscape_uri: String ## Banner image of the player in landscape. @@ -99,6 +116,7 @@ class Player: var friends_list_visibility_status: FriendsListVisibilityStatus ## Visibility status of this player's friend list. var display_name: String ## The display name of the player. var hi_res_image_uri: String ## The hi-res image of the player. + var icon_image_uri: String ## The icon image of the player. var level_info: PlayerLevelInfo ## Information about the player level. var player_id: String ## The player id. var friend_status: PlayerFriendStatus ## The friend status of this player with the signed in player. @@ -113,6 +131,7 @@ class Player: if dictionary.has("friendsListVisibilityStatus"): friends_list_visibility_status = FriendsListVisibilityStatus.get(dictionary.friendsListVisibilityStatus) if dictionary.has("displayName"): display_name = dictionary.displayName if dictionary.has("hiResImageUri"): hi_res_image_uri = dictionary.hiResImageUri + if dictionary.has("iconImageUri"): icon_image_uri = dictionary.iconImageUri if dictionary.has("levelInfo"): level_info = PlayerLevelInfo.new(dictionary.levelInfo) if dictionary.has("playerId"): player_id = dictionary.playerId if dictionary.has("friendStatus"): friend_status = PlayerFriendStatus.get(dictionary.friendStatus) @@ -129,6 +148,7 @@ class Player: result.append("friends_list_visibility_status: %s" % FriendsListVisibilityStatus.find_key(friends_list_visibility_status)) result.append("display_name: %s" % display_name) result.append("hi_res_image_uri: %s" % hi_res_image_uri) + result.append("icon_image_uri: %s" % icon_image_uri) result.append("level_info: {%s}" % str(level_info)) result.append("player_id: %s" % player_id) result.append("friend_status: %s" % PlayerFriendStatus.find_key(friend_status))