[Major] Finished product development - Stage I

The activation of finished product development in a combined development environment.
This commit is contained in:
Alan Alexander Cerna 2021-11-02 13:54:16 +02:00
parent b8c3c30a3b
commit bde1f29107
21 changed files with 801 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

View File

@ -0,0 +1,104 @@
extends Node
const DEFAULT_PORT = 28960
const MAX_CLIENTS = 4
var server = null
var client = null
var ip_address = ""
var current_player_username = ""
var client_connected_to_server = false
var networked_object_name_index = 0 setget networked_object_name_index_set
puppet var puppet_networked_object_name_index = 0 setget puppet_networked_object_name_index_set
onready var client_connection_timeout_timer = Timer.new()
func _ready() -> void:
if OS.get_name() == "Windows":
ip_address = IP.get_local_addresses()[3]
elif OS.get_name() == "Android":
ip_address = IP.get_local_addresses()[0]
else:
ip_address = IP.get_local_addresses()[3]
for ip in IP.get_local_addresses():
if ip.begins_with("192.168.") and not ip.ends_with(".1"):
ip_address = ip
get_tree().connect("connected_to_server", self, "_connected_to_server")
get_tree().connect("server_disconnected", self, "_server_disconnected")
func create_server() -> void:
server = NetworkedMultiplayerENet.new()
server.create_server(DEFAULT_PORT, MAX_CLIENTS)
get_tree().set_network_peer(server)
Global.instance_node(load("res://scenes/server_advertiser.tscn"), get_tree().current_scene)
func join_server() -> void:
client = NetworkedMultiplayerENet.new()
client.create_client(ip_address, DEFAULT_PORT)
get_tree().set_network_peer(client)
func reset_network_connection() -> void:
if get_tree().has_network_peer():
get_tree().network_peer = null
func reset_network_connections():
if get_tree().has_network_peer():
get_tree().network_peer = null
func _connected_to_server() -> void:
print("Successfully connected to the server")
func _server_disconnected() -> void:
print("Disconnected from the server")
for child in PersistentNodes.get_children():
if child.is_in_group("Net"):
child.queue_free()
reset_network_connections()
if Global.ui != null:
var prompt = Global.instance_node(load("res://scenes/simple_prompt.tscn"), Global.ui)
prompt.set_text("Disconnected from server")
func _client_connection_timeout():
if client_connected_to_server == false:
print("Client has been timed out")
reset_network_connection()
var connection_timeout_prompt = Global.instance_node(load("res://scenes/simple_prompt.tscn"), get_tree().current_scene)
connection_timeout_prompt.set_text("Connection timed out")
func _connection_failed():
for child in PersistentNodes.get_children():
if child.is_in_group("Net"):
child.queue_free()
reset_network_connection()
if Global.ui != null:
var prompt = Global.instance_node(load("res://scenes/simple_prompt.tscn"), Global.ui)
prompt.set_text("Connection failed")
func puppet_networked_object_name_index_set(new_value):
networked_object_name_index = new_value
func networked_object_name_index_set(new_value):
networked_object_name_index = new_value
if get_tree().is_network_server():
rset("puppet_networked_object_name_index", networked_object_name_index)

View File

@ -0,0 +1,91 @@
extends Control
var player = load("res://scenes/player.tscn")
var current_spawn_location_instance_number = 1
var current_player_for_spawn_location_number = null
onready var multiplayer_config_ui = $multiplayer_configure
onready var username_text_edit = $multiplayer_configure/username_text_edit
onready var device_ip_address = $UI/device_ip_address
onready var start_game = $UI/start_game
func _ready():
get_tree().connect("network_peer_connected", self, "_player_connected")
get_tree().connect("network_peer_disconnected", self, "_player_disconnected")
get_tree().connect("connected_to_server", self, "_connected_to_server")
device_ip_address.text = Network.ip_address
if get_tree().network_peer != null:
multiplayer_config_ui.hide()
current_spawn_location_instance_number = 1
for player in PersistentNodes.get_children():
if player.is_in_group("Player"):
for spawn_location in $Spawn_locations.get_children():
if int(spawn_location.name) == current_spawn_location_instance_number and current_player_for_spawn_location_number != player:
player.rpc("update_position", spawn_location.global_position)
player.rpc("enable")
current_spawn_location_instance_number += 1
current_player_for_spawn_location_number = player
else:
start_game.hide()
func _process(delta: float) -> void:
if get_tree().network_peer != null:
if get_tree().get_network_connected_peers().size() >= 0 and get_tree().is_network_server():
start_game.show()
else:
start_game.hide()
func _player_connected(id) -> void:
print("Player " + str(id) + " has connected")
instance_player(id)
func _player_disconnected(id) -> void:
print("Player " + str(id) + " has disconnected")
if PersistentNodes.has_node(str(id)):
PersistentNodes.get_node(str(id)).username_text_instance.queue_free()
PersistentNodes.get_node(str(id)).queue_free()
func _on_create_server_pressed():
if username_text_edit.text != "":
Network.current_player_username = username_text_edit.text
multiplayer_config_ui.hide()
Network.create_server()
instance_player(get_tree().get_network_unique_id())
func _on_join_server_pressed():
if username_text_edit.text != "":
multiplayer_config_ui.hide()
username_text_edit.hide()
Global.instance_node(load("res://scenes/server_browser.tscn"), self)
func _connected_to_server() -> void:
yield(get_tree().create_timer(0.1), "timeout")
instance_player(get_tree().get_network_unique_id())
func instance_player(id) -> void:
var player_instance = Global.instance_node_at_location(player, PersistentNodes, Vector2(rand_range(0, 1920), rand_range(0, 1080)))
player_instance.name = str(id)
player_instance.set_network_master(id)
player_instance.username = username_text_edit.text
current_spawn_location_instance_number += 1
func _on_start_game_pressed():
rpc("switch_to_game")
sync func switch_to_game() -> void:
get_tree().change_scene("res://scenes/game.tscn")

View File

@ -0,0 +1,35 @@
extends Node
export (float) var broadcast_interval = 1.0
var server_info = {"name": "LAN Game"}
var socket_udp
var broadcast_timer = Timer.new()
var broadcast_port = Network.DEFAULT_PORT
func _enter_tree():
broadcast_timer.wait_time = broadcast_interval
broadcast_timer.one_shot = false
broadcast_timer.autostart = true
if get_tree().is_network_server():
add_child(broadcast_timer)
broadcast_timer.connect("timeout", self, "broadcast")
socket_udp = PacketPeerUDP.new()
socket_udp.set_broadcast_enabled(true)
socket_udp.set_dest_address('255.255.255.255', broadcast_port)
func broadcast():
server_info.name = Network.current_player_username
var packet_message = to_json(server_info)
var packet = packet_message.to_ascii()
socket_udp.put_packet(packet)
func _exit_tree():
broadcast_timer.stop()
if socket_udp != null:
socket_udp.close()

View File

@ -0,0 +1,47 @@
extends Control
onready var server_listener = $server_listener
onready var server_ip_text_edit = $background_panel/server_ip_text_edit
onready var server_container = $background_panel/VBoxContainer
onready var manual_setup_button = $background_panel/manual_setup
func _ready() -> void:
server_ip_text_edit.hide()
func _on_server_listener_new_server(serverInfo):
var server_node = Global.instance_node(load("res://scenes/server_display.tscn"), server_container)
server_node.text = "%s - %s" % [serverInfo.ip, serverInfo.name]
server_node.ip_address = str(serverInfo.ip)
func _on_server_listener_remove_server(serverIp):
for serverNode in server_container.get_children():
if serverNode.is_in_group("server_display"):
if serverNode.ip_address == serverIp:
serverNode.queue_free()
break
func _on_manual_setup_pressed():
if manual_setup_button.text != "Exit setup":
server_ip_text_edit.show()
manual_setup_button.text = "Exit setup"
server_container.hide()
server_ip_text_edit.call_deferred("grab_focus")
else:
server_ip_text_edit.text = ""
server_ip_text_edit.hide()
server_container.show()
func _on_join_server_pressed():
if server_ip_text_edit.text != "":
Network.ip_address = server_ip_text_edit.text
hide()
Network.join_server()
func _on_go_back_pressed():
get_tree().reload_current_scene()

View File

@ -0,0 +1,9 @@
extends Label
var ip_address = ""
func _on_join_button_pressed():
Network.ip_address = ip_address
Network.join_server()
get_parent().get_parent().queue_free()

View File

@ -0,0 +1,66 @@
extends Node
signal new_server
signal remove_server
var cleanup_timer = Timer.new()
var socket_udp = PacketPeerUDP.new()
var listen_port = Network.DEFAULT_PORT
var known_servers = {}
export (int) var server_cleanup_threshold = 3
func _init():
cleanup_timer.wait_time = server_cleanup_threshold
cleanup_timer.one_shot = false
cleanup_timer.autostart = true
cleanup_timer.connect("timeout", self, 'clean_up')
add_child(cleanup_timer)
func ready():
known_servers.clear()
if socket_udp.listen(listen_port) != OK:
print("GameServer LAN service: Error listening port: " + str(listen_port))
else:
print("GameServer LAN service: Llistening port: " + str(listen_port))
func _process(delta):
if socket_udp.get_available_packet_count() > 0:
var server_ip = socket_udp.get_packet_ip()
var server_port = socket_udp.get_packet_port()
var array_bytes = socket_udp.get_packet()
if server_ip != "" and server_port > 0:
if not known_servers.has(server_ip):
var serverMessage = array_bytes.get_string_from_ascii()
var gameInfo = parse_json(serverMessage)
gameInfo.ip = server_ip
gameInfo.lastSeen = OS.get_unix_time()
known_servers[server_ip] = gameInfo
emit_signal("new_server", gameInfo)
print(socket_udp.get_packet_ip())
else:
var gameInfo = known_servers[server_ip]
gameInfo.lastSeen = OS.get_unix_time()
func cleanup():
var now = OS.get_unix_time()
for server_ip in known_servers:
var serverInfo = known_servers[server_ip]
if (now - serverInfo.lastSeen) > server_cleanup_threshold:
known_servers.erase(server_ip)
print("Remove old server: %s" % server_ip)
emit_signal("remove_server", server_ip)
func _exit_tree():
socket_udp.close()

View File

@ -0,0 +1,9 @@
extends CanvasLayer
func _ready() -> void:
Global.ui = self
func _exit_tree() -> void:
Global.ui = null

View File

@ -0,0 +1,10 @@
extends Control
func _on_ok_pressed():
get_tree().change_scene("res://scenes/main_menu.tscn")
func set_text(text) -> void:
$Label.text = text

View File

@ -0,0 +1,15 @@
extends Node2D
var player_following = null
var text = "" setget text_set
onready var label = $Label
func _process(delta: float) -> void:
if player_following != null:
global_position = player_following.global_position
func text_set(new_text) -> void:
text = new_text
label.text = text

Binary file not shown.

View File

@ -0,0 +1,9 @@
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://font/Roboto-Regular.ttf" type="DynamicFontData" id=1]
[resource]
size = 64
use_mipmaps = true
use_filter = true
font_data = ExtResource( 1 )

View File

@ -0,0 +1,29 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://scenes/floor.tscn" type="PackedScene" id=1]
[ext_resource path="res://code/game.gd" type="Script" id=2]
[ext_resource path="res://code/UI.gd" type="Script" id=3]
[node name="game" type="Node2D"]
script = ExtResource( 2 )
[node name="floor" parent="." instance=ExtResource( 1 )]
position = Vector2( 960, 1056 )
scale = Vector2( 2, 1 )
[node name="spawn_locations" type="Node" parent="."]
[node name="1" type="Position2D" parent="spawn_locations"]
position = Vector2( 512, 810 )
[node name="2" type="Position2D" parent="spawn_locations"]
position = Vector2( 1408, 810 )
[node name="3" type="Position2D" parent="spawn_locations"]
position = Vector2( 512, 270 )
[node name="4" type="Position2D" parent="spawn_locations"]
position = Vector2( 1408, 270 )
[node name="UI" type="CanvasLayer" parent="."]
script = ExtResource( 3 )

View File

@ -0,0 +1,96 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://font/roboto.tres" type="DynamicFont" id=1]
[ext_resource path="res://code/server/network_setup.gd" type="Script" id=2]
[ext_resource path="res://code/UI.gd" type="Script" id=3]
[node name="network_setup" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="multiplayer_configure" type="Control" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 2.5199
margin_right = 2.5199
__meta__ = {
"_edit_use_anchors_": false
}
[node name="create_server" type="Button" parent="multiplayer_configure"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -267.5
margin_top = -202.0
margin_right = 267.5
margin_bottom = -26.0
custom_fonts/font = ExtResource( 1 )
text = "Create server"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="join_server" type="Button" parent="multiplayer_configure"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -267.5
margin_top = 24.0
margin_right = 267.5
margin_bottom = 200.0
custom_fonts/font = ExtResource( 1 )
text = "Join server"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="username_text_edit" type="LineEdit" parent="multiplayer_configure"]
anchor_left = 0.5
anchor_right = 0.5
margin_left = -422.5
margin_top = 117.0
margin_right = 422.5
margin_bottom = 221.0
custom_fonts/font = ExtResource( 1 )
align = 1
placeholder_text = "Enter username"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="UI" type="CanvasLayer" parent="."]
script = ExtResource( 3 )
[node name="start_game" type="Button" parent="UI"]
margin_left = 27.0
margin_top = 27.0
margin_right = 391.0
margin_bottom = 158.0
custom_fonts/font = ExtResource( 1 )
text = "Start game"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="device_ip_address" type="Label" parent="UI"]
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_top = -150.0
custom_fonts/font = ExtResource( 1 )
align = 1
valign = 1
__meta__ = {
"_edit_use_anchors_": false
}
[connection signal="pressed" from="multiplayer_configure/create_server" to="." method="_on_create_server_pressed"]
[connection signal="pressed" from="multiplayer_configure/join_server" to="." method="_on_join_server_pressed"]
[connection signal="pressed" from="UI/start_game" to="." method="_on_start_game_pressed"]

View File

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://code/server/server_advertiser.gd" type="Script" id=1]
[node name="server_advertiser" type="Node"]
script = ExtResource( 1 )

View File

@ -0,0 +1,146 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://font/roboto.tres" type="DynamicFont" id=1]
[ext_resource path="res://scenes/server_listener.tscn" type="PackedScene" id=2]
[ext_resource path="res://code/server/server_browser.gd" type="Script" id=3]
[sub_resource type="Animation" id=1]
resource_name = "searching_for_servers"
length = 0.8
loop = true
tracks/0/type = "value"
tracks/0/path = NodePath(".:text")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.2, 0.4, 0.6 ),
"transitions": PoolRealArray( 1, 1, 1, 1 ),
"update": 1,
"values": [ "Searching for servers", "Searching for servers.", "Searching for servers..", "Searching for servers..." ]
}
[node name="server_browser" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 3 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="background_panel" type="Panel" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 96.0
margin_top = 162.0
margin_right = -96.0
margin_bottom = -54.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="manual_setup" type="Button" parent="background_panel"]
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -473.0
margin_top = -175.0
margin_right = -30.0
margin_bottom = -30.0
custom_fonts/font = ExtResource( 1 )
text = "Manual setup"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="go_back" type="Button" parent="background_panel"]
anchor_top = 1.0
anchor_bottom = 1.0
margin_left = 30.0
margin_top = -170.0
margin_right = 473.0
margin_bottom = -25.0
custom_fonts/font = ExtResource( 1 )
text = "Go back"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="server_ip_text_edit" type="LineEdit" parent="background_panel"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -403.0
margin_top = -243.0
margin_right = 403.0
margin_bottom = -138.0
custom_fonts/font = ExtResource( 1 )
align = 1
[node name="type_in_server_ip" type="Label" parent="background_panel/server_ip_text_edit"]
anchor_right = 1.0
margin_top = -105.0
custom_fonts/font = ExtResource( 1 )
text = "Type in server IP"
align = 1
valign = 1
[node name="join_server" type="Button" parent="background_panel/server_ip_text_edit"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -221.5
margin_top = 94.5
margin_right = 221.5
margin_bottom = 239.5
custom_fonts/font = ExtResource( 1 )
text = "Join server"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VBoxContainer" type="VBoxContainer" parent="background_panel"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 70.0
margin_top = 40.0
margin_right = -70.0
margin_bottom = -175.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="searching_for_servers" type="Label" parent="background_panel/VBoxContainer"]
margin_right = 1588.0
margin_bottom = 76.0
rect_min_size = Vector2( 0, 70 )
custom_fonts/font = ExtResource( 1 )
text = "Searching for servers.."
align = 1
valign = 1
[node name="AnimationPlayer" type="AnimationPlayer" parent="background_panel/VBoxContainer/searching_for_servers"]
autoplay = "searching_for_servers"
playback_speed = 0.5
anims/searching_for_servers = SubResource( 1 )
[node name="server_browser_label" type="Label" parent="background_panel"]
anchor_right = 1.0
margin_top = -176.0
custom_fonts/font = ExtResource( 1 )
text = "Server Browser"
align = 1
valign = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="server_listener" parent="." instance=ExtResource( 2 )]
[connection signal="pressed" from="background_panel/manual_setup" to="." method="_on_manual_setup_pressed"]
[connection signal="pressed" from="background_panel/go_back" to="." method="_on_go_back_pressed"]
[connection signal="pressed" from="background_panel/server_ip_text_edit/join_server" to="." method="_on_join_server_pressed"]

View File

@ -0,0 +1,32 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://font/roboto.tres" type="DynamicFont" id=1]
[ext_resource path="res://code/server/server_display.gd" type="Script" id=2]
[node name="server_display" type="Label"]
anchor_right = 1.0
margin_right = -220.0
margin_bottom = 130.0
rect_min_size = Vector2( 0, 130 )
custom_fonts/font = ExtResource( 1 )
text = "N/A: 000.000.000"
align = 1
valign = 1
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="join_button" type="Button" parent="." groups=[
"server_display",
]]
anchor_left = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -302.0
margin_top = 13.0
margin_bottom = -13.0
custom_fonts/font = ExtResource( 1 )
text = "Join"
[connection signal="pressed" from="join_button" to="." method="_on_join_button_pressed"]

View File

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://code/server/server_listener.gd" type="Script" id=1]
[node name="server_listener" type="Node"]
script = ExtResource( 1 )

View File

@ -0,0 +1,68 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://font/Roboto-Regular.ttf" type="DynamicFontData" id=1]
[ext_resource path="res://code/simple_prompt.gd" type="Script" id=2]
[sub_resource type="DynamicFont" id=1]
size = 100
use_mipmaps = true
use_filter = true
font_data = ExtResource( 1 )
[sub_resource type="DynamicFont" id=2]
size = 100
use_mipmaps = true
use_filter = true
font_data = ExtResource( 1 )
[node name="simple_prompt" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Panel" type="Panel" parent="."]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -704.0
margin_top = -330.0
margin_right = 704.0
margin_bottom = 330.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="ok" type="Button" parent="Panel"]
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
margin_left = -257.0
margin_top = -310.0
margin_right = 257.0
margin_bottom = -113.0
custom_fonts/font = SubResource( 1 )
text = "OK"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Label" type="Label" parent="."]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -516.0
margin_top = -155.5
margin_right = 516.0
margin_bottom = -68.5
custom_fonts/font = SubResource( 2 )
text = "Simple prompt"
align = 1
valign = 1
[connection signal="pressed" from="Panel/ok" to="." method="_on_ok_pressed"]

View File

@ -0,0 +1,23 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://font/roboto.tres" type="DynamicFont" id=1]
[ext_resource path="res://code/username_text.gd" type="Script" id=2]
[node name="username_text" type="Node2D" groups=[
"Net",
]]
z_index = 10
script = ExtResource( 2 )
[node name="Label" type="Label" parent="."]
margin_left = -197.0
margin_top = -125.0
margin_right = 197.0
margin_bottom = -49.0
custom_fonts/font = ExtResource( 1 )
text = "null"
align = 1
valign = 1
__meta__ = {
"_edit_use_anchors_": false
}