310 lines
11 KiB
GDScript

extends Control
const ApiClientScript := preload("res://scripts/services/api_client.gd")
const AUTO_USERNAME := "13800000001"
const AUTO_PASSWORD := "123456"
const DESIGN_SIZE := Vector2(640.0, 960.0)
const LOADING_BG_PATH := "res://assets/replacement/loading/loading_bg.jpg"
const LOADING_BAR_BG_PATH := "res://assets/replacement/loading/loading_bar_bg.png"
const LOADING_BAR_FILL_PATH := "res://assets/replacement/loading/loading_bar_fill.png"
const LOADING_BAR_SOURCE_SIZE := Vector2(1117.0, 223.0)
const LOADING_BAR_TARGET_WIDTH := 500.0
const LOADING_BAR_SIZE := Vector2(
LOADING_BAR_TARGET_WIDTH,
LOADING_BAR_TARGET_WIDTH * LOADING_BAR_SOURCE_SIZE.y / LOADING_BAR_SOURCE_SIZE.x
)
const LOADING_BAR_POSITION := Vector2((DESIGN_SIZE.x - LOADING_BAR_SIZE.x) * 0.5, 792.0)
const LOADING_BAR_SLOT_REGION := Rect2(190.0, 83.0, 738.0, 68.0)
const LOADING_FILL_SOURCE_REGION := Rect2(57.0, 55.0, 1003.0, 113.0)
const STARTUP_ASSET_PATHS := [
"res://scenes/ui/game_scene.tscn",
"res://assets/egret/common/common.png",
"res://assets/egret/assets/common.png",
"res://assets/egret/assets/game/menu2/menu3.png",
"res://assets/egret/assets/game/friend/friend.png",
"res://assets/egret/assets/game/rank/rank.png",
"res://assets/egret/assets/game/building/building.png",
"res://assets/egret/assets/game/landup/landup.png",
"res://assets/egret/assets/game/sign/sign.png",
"res://assets/egret/assets/game/roleinfo/roleinfo.png",
"res://assets/egret/assets/game/createrole/createrole.png",
"res://assets/egret/assets/common2.png",
"res://assets/egret/assets/game/gift/onLineGift.png",
"res://assets/egret/assets/game/lottery/lottery.png",
"res://assets/egret/assets/game/mofahecheng/mofahecheng.png",
"res://assets/egret/assets/game/battlePet/battle_pet.png",
"res://assets/egret/assets/game/pay/pay_com.png",
"res://assets/egret/assets/game/pay/pay_bg.png",
"res://assets/egret/land/land0.png",
"res://assets/egret/land/land1.png",
"res://assets/egret/land/land-1.png",
"res://assets/egret/assets/icon/land/land2.png",
"res://assets/egret/assets/icon/land/land3.png",
"res://assets/egret/common/land_light_png.tres",
"res://assets/egret/common/bag_bg_png.tres",
"res://assets/egret/common/bag_line_png.tres",
"res://assets/egret/common/log_itembg_png.tres",
"res://assets/egret/common/m_phase_clock_png.tres",
"res://assets/egret/common/m_phase_pro_bar_png.tres",
"res://assets/egret/common/m_phase_pro_bg_png.tres",
"res://assets/egret/menu/menu_p_plant.png",
"res://assets/egret/menu/menu_p_gain.png",
"res://assets/egret/menu/menu_p_uproot.png",
"res://assets/egret/menu/menu_p_manure.png",
"res://assets/egret/assets/game/menu/menu_p_put_water.png",
"res://assets/egret/menu/menu_p_die_bug.png",
"res://assets/egret/menu/menu_p_die_grass.png",
"res://assets/egret/assets/game/menu/menu_p_steal.png",
"res://assets/egret/assets/game/menu/menu_p_put_bug.png",
"res://assets/egret/assets/game/menu/menu_p_put_grass.png",
"res://assets/egret/menu/plant_state1.png",
"res://assets/egret/menu/plant_state2.png",
"res://assets/egret/menu/plant_state3.png",
"res://assets/replacement/menu2/market.png",
"res://assets/replacement/panels/panel_content.png",
"res://assets/replacement/panels/panel_shell.png",
]
@export var main_scene: PackedScene
var _current_scene: Node
var _api_client: ApiClient
var _loading_layer: Control
var _loading_fill_clip: Control
var _loading_percent_label: Label
var _loading_fill_size := Vector2.ZERO
var _preloaded_resources: Array[Resource] = []
func _ready() -> void:
_build_loading_ui()
_set_loading_progress(0.0)
_api_client = ApiClientScript.new()
add_child(_api_client)
await get_tree().process_frame
await _preload_startup_assets()
var player_data := await _auto_login()
if player_data.is_empty():
_set_loading_text("登录失败")
return
_set_loading_progress(1.0)
await get_tree().process_frame
_show_main_scene(player_data)
func _auto_login() -> Dictionary:
_set_loading_progress(0.86)
var login_path := str(ProjectSettings.get_setting("farm_game/api/login_path", "user/login"))
var result := await _api_client.post_json(login_path, {
"username": AUTO_USERNAME,
"password": AUTO_PASSWORD
})
if not result.get("ok", false):
push_error("Auto login failed. HTTP %s, game status %s" % [
result.get("status", 0),
result.get("game_status", "unknown")
])
return {}
_set_loading_progress(0.94)
var body = result.get("body", {})
var player_data: Dictionary = {}
if body is Dictionary and body.get("data", {}) is Dictionary:
player_data = body["data"]
return player_data
func _show_main_scene(player_data: Dictionary) -> void:
if main_scene == null:
push_error("Missing main scene.")
return
var main := main_scene.instantiate()
if main.has_method("setup"):
main.setup(player_data)
_show_scene(main)
_hide_loading_ui()
_preloaded_resources.clear()
func _show_scene(scene: Node) -> void:
if _current_scene != null:
_current_scene.queue_free()
_current_scene = scene
add_child(_current_scene)
func _build_loading_ui() -> void:
if _loading_layer != null and is_instance_valid(_loading_layer):
return
_loading_layer = Control.new()
_loading_layer.name = "LoadingLayer"
_loading_layer.size = DESIGN_SIZE
_loading_layer.mouse_filter = Control.MOUSE_FILTER_STOP
add_child(_loading_layer)
var background := TextureRect.new()
background.name = "Background"
var background_texture := load(LOADING_BG_PATH) as Texture2D
background.texture = background_texture
var background_size := _fit_cover_size(background_texture.get_size(), DESIGN_SIZE)
background.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
background.stretch_mode = TextureRect.STRETCH_SCALE
background.position = (DESIGN_SIZE - background_size) * 0.5
background.size = background_size
background.mouse_filter = Control.MOUSE_FILTER_IGNORE
_loading_layer.add_child(background)
var bar_group := Control.new()
bar_group.name = "ProgressBar"
bar_group.position = LOADING_BAR_POSITION
bar_group.size = LOADING_BAR_SIZE
bar_group.mouse_filter = Control.MOUSE_FILTER_IGNORE
_loading_layer.add_child(bar_group)
var bar_bg := TextureRect.new()
bar_bg.name = "Bg"
bar_bg.texture = load(LOADING_BAR_BG_PATH) as Texture2D
bar_bg.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
bar_bg.stretch_mode = TextureRect.STRETCH_SCALE
bar_bg.size = LOADING_BAR_SIZE
bar_bg.mouse_filter = Control.MOUSE_FILTER_IGNORE
bar_group.add_child(bar_bg)
var fill_texture := load(LOADING_BAR_FILL_PATH) as Texture2D
var fill_rect := _loading_fill_rect()
_loading_fill_size = fill_rect.size
_loading_fill_clip = Control.new()
_loading_fill_clip.name = "FillClip"
_loading_fill_clip.position = fill_rect.position
_loading_fill_clip.size = Vector2(0.0, fill_rect.size.y)
_loading_fill_clip.clip_contents = true
_loading_fill_clip.mouse_filter = Control.MOUSE_FILTER_IGNORE
bar_group.add_child(_loading_fill_clip)
var fill := TextureRect.new()
fill.name = "Fill"
fill.texture = _make_atlas_texture(fill_texture, LOADING_FILL_SOURCE_REGION)
fill.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
fill.stretch_mode = TextureRect.STRETCH_SCALE
fill.size = fill_rect.size
fill.mouse_filter = Control.MOUSE_FILTER_IGNORE
_loading_fill_clip.add_child(fill)
_loading_percent_label = Label.new()
_loading_percent_label.name = "Percent"
_loading_percent_label.position = fill_rect.position
_loading_percent_label.size = fill_rect.size
_loading_percent_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
_loading_percent_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
_loading_percent_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
_loading_percent_label.add_theme_font_size_override("font_size", 24)
_loading_percent_label.add_theme_color_override("font_color", Color.WHITE)
_loading_percent_label.add_theme_color_override("font_outline_color", Color.html("#5b2a0e"))
_loading_percent_label.add_theme_constant_override("outline_size", 3)
bar_group.add_child(_loading_percent_label)
func _fit_cover_size(source_size: Vector2, target_size: Vector2) -> Vector2:
if source_size.x <= 0.0 or source_size.y <= 0.0:
return target_size
var scale := maxf(target_size.x / source_size.x, target_size.y / source_size.y)
return source_size * scale
func _loading_bar_scale() -> float:
return LOADING_BAR_SIZE.x / LOADING_BAR_SOURCE_SIZE.x
func _loading_fill_rect() -> Rect2:
var scale := _loading_bar_scale()
var slot_position := LOADING_BAR_SLOT_REGION.position * scale
var slot_size := LOADING_BAR_SLOT_REGION.size * scale
var fill_size := Vector2(
slot_size.x,
slot_size.x * LOADING_FILL_SOURCE_REGION.size.y / LOADING_FILL_SOURCE_REGION.size.x
)
var fill_position := slot_position + Vector2(0.0, (slot_size.y - fill_size.y) * 0.5)
return Rect2(fill_position, fill_size)
func _make_atlas_texture(texture: Texture2D, region: Rect2) -> Texture2D:
if texture == null:
return null
var atlas := AtlasTexture.new()
atlas.atlas = texture
atlas.region = region
return atlas
func _preload_startup_assets() -> void:
var total := maxi(STARTUP_ASSET_PATHS.size(), 1)
for index in range(STARTUP_ASSET_PATHS.size()):
var path := str(STARTUP_ASSET_PATHS[index])
await _preload_asset(path, index, total)
_set_loading_progress(0.84)
func _preload_asset(path: String, index: int, total: int) -> void:
if not ResourceLoader.exists(path):
push_warning("Startup asset missing: %s" % path)
_set_loading_progress(_asset_progress(index + 1.0, total))
return
var request_error := ResourceLoader.load_threaded_request(path)
if request_error != OK:
var resource := load(path) as Resource
if resource != null:
_preloaded_resources.append(resource)
_set_loading_progress(_asset_progress(index + 1.0, total))
await get_tree().process_frame
return
var progress: Array = []
while true:
progress.clear()
var status := ResourceLoader.load_threaded_get_status(path, progress)
var item_progress := 0.0
if not progress.is_empty():
item_progress = clampf(float(progress[0]), 0.0, 1.0)
_set_loading_progress(_asset_progress(float(index) + item_progress, total))
if status == ResourceLoader.THREAD_LOAD_LOADED:
var loaded_resource := ResourceLoader.load_threaded_get(path)
if loaded_resource is Resource:
_preloaded_resources.append(loaded_resource)
_set_loading_progress(_asset_progress(index + 1.0, total))
return
if status == ResourceLoader.THREAD_LOAD_FAILED or status == ResourceLoader.THREAD_LOAD_INVALID_RESOURCE:
push_warning("Startup asset failed to load: %s" % path)
_set_loading_progress(_asset_progress(index + 1.0, total))
return
await get_tree().process_frame
func _asset_progress(value: float, total: int) -> float:
return 0.05 + clampf(value / maxf(float(total), 1.0), 0.0, 1.0) * 0.79
func _set_loading_progress(progress: float) -> void:
var normalized := clampf(progress, 0.0, 1.0)
if _loading_fill_clip != null and is_instance_valid(_loading_fill_clip):
var fill_size := _loading_fill_size
if fill_size == Vector2.ZERO:
fill_size = _loading_fill_rect().size
_loading_fill_clip.size = Vector2(fill_size.x * normalized, fill_size.y)
if _loading_percent_label != null and is_instance_valid(_loading_percent_label):
_loading_percent_label.text = "%d%%" % roundi(normalized * 100.0)
func _set_loading_text(text: String) -> void:
if _loading_percent_label != null and is_instance_valid(_loading_percent_label):
_loading_percent_label.text = text
func _hide_loading_ui() -> void:
if _loading_layer == null or not is_instance_valid(_loading_layer):
return
_loading_layer.queue_free()
_loading_layer = null
_loading_fill_clip = null
_loading_percent_label = null