From e9e01c47f5a48ec4f481e625adfcbf7d8b02f53e Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Tue, 2 Nov 2021 21:50:23 +0200 Subject: [PATCH] [Major] Finished product development - Stage III --- Game/project.godot | 5 + .../player_handlers/player_body_handler.gd | 121 +++++++++++++++++- .../scripts/player_handlers/player_bullet.gd | 54 ++++++++ .../network_processors/network_setup.gd | 11 +- .../scripts/ui_element_handlers/game_UI.gd | 16 +++ .../scripts/ui_element_handlers/winner.gd | 9 ++ Game/source/assets/sprites/bullet/bullet.png | Bin 0 -> 659 bytes .../assets/sprites/bullet/bullet.png.import | 34 +++++ .../source/entities/bullet/player_bullet.tscn | 27 ++++ Game/source/entities/player/player_node.tscn | 25 +++- .../trinity_site/trinity_site_level.tscn | 46 ++++++- Game/source/scenes/GUI/main_menu.tscn | 10 +- 12 files changed, 346 insertions(+), 12 deletions(-) create mode 100644 Game/source/assets/scripts/player_handlers/player_bullet.gd create mode 100644 Game/source/assets/scripts/ui_element_handlers/game_UI.gd create mode 100644 Game/source/assets/scripts/ui_element_handlers/winner.gd create mode 100644 Game/source/assets/sprites/bullet/bullet.png create mode 100644 Game/source/assets/sprites/bullet/bullet.png.import create mode 100644 Game/source/entities/bullet/player_bullet.tscn diff --git a/Game/project.godot b/Game/project.godot index 7c0930a..1fb2854 100644 --- a/Game/project.godot +++ b/Game/project.godot @@ -70,6 +70,11 @@ input_shift={ "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777237,"unicode":0,"echo":false,"script":null) ] } +input_shoot={ +"deadzone": 0.5, +"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"pressed":false,"doubleclick":false,"script":null) + ] +} [physics] diff --git a/Game/source/assets/scripts/player_handlers/player_body_handler.gd b/Game/source/assets/scripts/player_handlers/player_body_handler.gd index 292ea89..f92da2d 100644 --- a/Game/source/assets/scripts/player_handlers/player_body_handler.gd +++ b/Game/source/assets/scripts/player_handlers/player_body_handler.gd @@ -1,14 +1,26 @@ extends KinematicBody2D +var hp = 100 setget set_hp + +var player_bullet = load("res://source/entities/bullet/player_bullet.tscn") var username_text = load("res://source/scenes/OVERLAY/elements/username_text.tscn") var username setget username_set var username_text_instance = null +var can_shoot = true +var is_reloading = false + +puppet var puppet_hp = 100 setget puppet_hp_set puppet var puppet_position = Vector2(0, 0) setget puppet_position_set puppet var puppet_velocity = Vector2() +puppet var puppet_rotation = 0 puppet var puppet_username = "" setget puppet_username_set onready var tween = $Tween +onready var sprite = $player_sprite +onready var reload_timer = $reload_timer +onready var shoot_point = $shoot_point +onready var hit_timer = $hit_timer # Instance of data pre_processors @@ -42,6 +54,13 @@ func _ready(): get_tree().connect("network_peer_connected", self, "_network_peer_connected") username_text_instance = Global.instance_node_at_location(username_text, PersistentNodes, global_position) username_text_instance.player_following = self + update_shoot_mode(false) + Global.alive_players.append(self) + + yield(get_tree(), "idle_frame") + if get_tree().has_network_peer(): + if is_network_master(): + Global.player_master = self # Allow update process override. set_process(true) @@ -87,7 +106,12 @@ func process_rotation(): func _process(delta: float) -> void: if username_text_instance != null: username_text_instance.name = "username" + name - + + if hp <= 0: + if get_tree().is_network_server(): + rpc("destroy") + + user_input = UIN_preset_pre_processor_instance.update() user_state = get_user_state() dimensions = get_dimensions() @@ -116,7 +140,8 @@ func _process(delta: float) -> void: func _physics_process(delta) -> void: if get_tree().has_network_peer(): - if is_network_master(): + if is_network_master() and visible: + look_at(get_global_mouse_position()) if "0" in VDIR: if VDIR["1"]["0"]["ray"]["length"] - dimensions["collider"]["radius"] > 2 and jumpState == false: gravityVector = (VDIR["1"]["0"]["ray"]["position"] - user_state["global_position"]).normalized() @@ -163,7 +188,16 @@ func _physics_process(delta) -> void: else: timedOut = true move_and_slide(gravityVector * jumpSpeed + movementVector.rotated(rotation).normalized() * movementSpeed) - + + if Input.is_action_pressed("input_shoot") and can_shoot and not is_reloading: + rpc("instance_bullet", get_tree().get_network_unique_id()) + is_reloading = true + reload_timer.start() + else: + rotation = lerp_angle(rotation, puppet_rotation, delta * 8) + + if not tween.is_active(): + move_and_slide(puppet_velocity * movementSpeed) func _draw(): for vector_type in VDIR: @@ -174,12 +208,36 @@ func _draw(): draw_line(VDIR[v_t][v]["start"] - user_state["global_position"],(VDIR[v_t][v]["ray"]["position"] - user_state["global_position"]).rotated(-rotation),Color(255,255,255,1),1) +func lerp_angle(from, to, weight): + return from + short_angle_dist(from, to) * weight + + +func short_angle_dist(from, to): + var max_angle = PI * 2 + var difference = fmod(to - from, max_angle) + return fmod(2 * difference, max_angle) - difference + + func puppet_position_set(new_value) -> void: puppet_position = new_value tween.interpolate_property(self, "global_position", global_position, puppet_position, 0.1) tween.start() +func set_hp(new_value): + hp = new_value + if get_tree().has_network_peer(): + if is_network_master(): + rset("puppet_hp", hp) + + +func puppet_hp_set(new_value): + puppet_hp = new_value + if get_tree().has_network_peer(): + if not is_network_master(): + hp = puppet_hp + + func username_set(new_value) -> void: username = new_value if is_network_master() and username_text_instance != null: @@ -202,7 +260,16 @@ func _on_network_tick_rate_timeout(): if is_network_master(): rset_unreliable("puppet_position", global_position) #rset_unreliable("puppet_velocity", movementVector) - rset_unreliable("puppet_rotation", rotation_degrees) + rset_unreliable("puppet_rotation", rotation) + + +sync func instance_bullet(id): + var player_bullet_instance = Global.instance_node_at_location(player_bullet, PersistentNodes, shoot_point.global_position) + player_bullet_instance.name = "Bullet" + name + str(Network.networked_object_name_index) + player_bullet_instance.set_network_master(id) + player_bullet_instance.player_rotation = rotation + player_bullet_instance.player_owner = id + Network.networked_object_name_index += 1 sync func update_position(pos): @@ -210,10 +277,53 @@ sync func update_position(pos): puppet_position = pos +func update_shoot_mode(shoot_mode): + can_shoot = shoot_mode + + +func _on_reload_timer_timeout(): + is_reloading = false + + +func _on_hit_timer_timeout(): + modulate = Color(1, 1, 1, 1) + + +func _on_Hitbox_area_entered(area): + if get_tree().is_network_server(): + if area.is_in_group("Player_damager") and area.get_parent().player_owner != int(name): + rpc("hit_by_damager", area.get_parent().damage) + area.get_parent().rpc("destroy") + + +sync func hit_by_damager(damage): + hp -= damage + modulate = Color(5, 5, 5, 1) + hit_timer.start() + + +sync func enable() -> void: + hp = 100 + can_shoot = false + update_shoot_mode(false) + username_text_instance.visible = true + visible = true + $CollisionShape2D.disabled = false + $Hitbox/CollisionShape2D.disabled = false + + if get_tree().has_network_peer(): + if is_network_master(): + Global.player_master = self + + if not Global.alive_players.has(self): + Global.alive_players.append(self) + + sync func destroy() -> void: username_text_instance.visible = false visible = false $player_collider.disabled = true + $hitbox/CollisionShape2D.disabled = true Global.alive_players.erase(self) if get_tree().has_network_peer(): @@ -226,3 +336,6 @@ func _exit_tree() -> void: if get_tree().has_network_peer(): if is_network_master(): Global.player_master = null + + + diff --git a/Game/source/assets/scripts/player_handlers/player_bullet.gd b/Game/source/assets/scripts/player_handlers/player_bullet.gd new file mode 100644 index 0000000..873355d --- /dev/null +++ b/Game/source/assets/scripts/player_handlers/player_bullet.gd @@ -0,0 +1,54 @@ +extends Sprite + +var velocity = Vector2(1, 0) +var player_rotation + +export(int) var speed = 1400 +export(int) var damage = 25 + +puppet var puppet_position setget puppet_position_set +puppet var puppet_velocity = Vector2(0, 0) +puppet var puppet_rotation = 0 + +onready var initial_position = global_position + +var player_owner = 0 + + +func _ready() -> void: + visible = false + yield(get_tree(), "idle_frame") + + if get_tree().has_network_peer(): + if is_network_master(): + velocity = velocity.rotated(player_rotation) + rotation = player_rotation + rset("puppet_velocity", velocity) + rset("puppet_rotation", rotation) + rset("puppet_position", global_position) + + visible = true + + +func _process(delta: float) -> void: + if get_tree().has_network_peer(): + if is_network_master(): + global_position += velocity * speed * delta + else: + rotation = puppet_rotation + global_position += puppet_velocity * speed * delta + + +func puppet_position_set(new_value) -> void: + puppet_position = new_value + global_position = puppet_position + + +sync func destroy() -> void: + queue_free() + + +func _on_Destroy_timer_timeout(): + if get_tree().has_network_peer(): + if get_tree().is_network_server(): + rpc("destroy") diff --git a/Game/source/assets/scripts/server_handlers/network_processors/network_setup.gd b/Game/source/assets/scripts/server_handlers/network_processors/network_setup.gd index a0faf77..414b3fd 100644 --- a/Game/source/assets/scripts/server_handlers/network_processors/network_setup.gd +++ b/Game/source/assets/scripts/server_handlers/network_processors/network_setup.gd @@ -2,6 +2,7 @@ extends Control var player = load("res://source/entities/player/player_node.tscn") +var min_players = 2 var current_spawn_location_instance_number = 1 var current_player_for_spawn_location_number = null @@ -9,6 +10,7 @@ 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 +onready var floor_ = $floor func _ready(): @@ -32,14 +34,17 @@ func _ready(): current_player_for_spawn_location_number = player else: start_game.hide() + floor_.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(): + if get_tree().get_network_connected_peers().size() >= (min_players - 1) and get_tree().is_network_server(): start_game.show() + floor_.show() else: start_game.hide() + floor_.hide() func _player_connected(id) -> void: @@ -87,4 +92,8 @@ func _on_start_game_pressed(): sync func switch_to_game() -> void: + for child in PersistentNodes.get_children(): + if child.is_in_group("Player"): + child.update_shoot_mode(true) + get_tree().change_scene("res://source/levels/trinity_site/trinity_site_level.tscn") diff --git a/Game/source/assets/scripts/ui_element_handlers/game_UI.gd b/Game/source/assets/scripts/ui_element_handlers/game_UI.gd new file mode 100644 index 0000000..4445058 --- /dev/null +++ b/Game/source/assets/scripts/ui_element_handlers/game_UI.gd @@ -0,0 +1,16 @@ +extends CanvasLayer + +onready var win_timer = $Control/winner/win_timer +onready var winner = $Control/winner + +func _ready() -> void: + winner.hide() + + +func _process(delta: float) -> void: + if Global.alive_players.size() <= 1 and get_tree().has_network_peer(): + if Global.alive_players[0].name == str(get_tree().get_network_unique_id()): + winner.show() + + if win_timer.time_left <= 0: + win_timer.start() diff --git a/Game/source/assets/scripts/ui_element_handlers/winner.gd b/Game/source/assets/scripts/ui_element_handlers/winner.gd new file mode 100644 index 0000000..8470d75 --- /dev/null +++ b/Game/source/assets/scripts/ui_element_handlers/winner.gd @@ -0,0 +1,9 @@ +extends Label + +sync func return_to_lobby(): + get_tree().change_scene("res://source/scenes/GUI/main_menu.tscn") + + +func _on_win_timer_timeout(): + if get_tree().is_network_server(): + rpc("return_to_lobby") diff --git a/Game/source/assets/sprites/bullet/bullet.png b/Game/source/assets/sprites/bullet/bullet.png new file mode 100644 index 0000000000000000000000000000000000000000..da98e56c1e61c40a1ba74bb7de7b7b224827c2e6 GIT binary patch literal 659 zcmV;E0&M+>P)EX>4Tx04R}tkv&MmKpe$iQ>CI61v`j1WT;LSL`5963Pq?8YK2xEOfLO`CJjl7 zi=*ILaPVWX>fqw6tAnc`2!4RLxj8AiNQwVT3N2zhIPS;0dyl(!fKV?p&FUBjG~G5+ ziMW`_u8N^o^guvAVt~vnV@{Hi@Eu?G2=MhT#R+LrZbK)_RE=c^yb;aX1&IOkRo*6OIsd?fEu~=whrHxt9)QG2uqpGG;zL4=) z<-EmND_2?bp8SR3oW8Qmb(+ISU=d4@AVNVEC6r-PUnS_ISV+-++{ZuU`XzEH(v&^mat9cEGGtSBr65fqp9kL0=$o>@z%9_d=JnRx$LRx*rmm7Vz`-Ff zTA=K8pLch)_xA6ZW`92=#&U??p82@|000SaNLh0L01FcU01FcV0GgZ_00007bV*G` z2jvR_5da|u2>=oR000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}0001f zNklHWnWakCGAtZZ;v9SiqHyy%{3q)4q*k8b$YKYe@jVP z{sJ;t;J+nbKd2EEqu1dpf8A3ZAUqgvGELF2#!@UrUJK(002ovPDHLkV1jST9rFMH literal 0 HcmV?d00001 diff --git a/Game/source/assets/sprites/bullet/bullet.png.import b/Game/source/assets/sprites/bullet/bullet.png.import new file mode 100644 index 0000000..a048b61 --- /dev/null +++ b/Game/source/assets/sprites/bullet/bullet.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/bullet.png-18282ec6da1a4943b48ba52afa2f37b8.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://source/assets/sprites/bullet/bullet.png" +dest_files=[ "res://.import/bullet.png-18282ec6da1a4943b48ba52afa2f37b8.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/Game/source/entities/bullet/player_bullet.tscn b/Game/source/entities/bullet/player_bullet.tscn new file mode 100644 index 0000000..d3813c1 --- /dev/null +++ b/Game/source/entities/bullet/player_bullet.tscn @@ -0,0 +1,27 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://source/assets/sprites/bullet/bullet.png" type="Texture" id=1] +[ext_resource path="res://source/assets/scripts/player_handlers/player_bullet.gd" type="Script" id=2] + +[sub_resource type="RectangleShape2D" id=1] +extents = Vector2( 22.0883, 10 ) + +[node name="player_bullet" type="Sprite" groups=[ +"Net", +]] +texture = ExtResource( 1 ) +script = ExtResource( 2 ) + +[node name="hitbox" type="Area2D" parent="." groups=[ +"Player_damager", +]] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="hitbox"] +visible = false +shape = SubResource( 1 ) + +[node name="destroy_timer" type="Timer" parent="."] +one_shot = true +autostart = true + +[connection signal="timeout" from="destroy_timer" to="." method="_on_destroy_timer_timeout"] diff --git a/Game/source/entities/player/player_node.tscn b/Game/source/entities/player/player_node.tscn index 599acd2..5d5405b 100644 --- a/Game/source/entities/player/player_node.tscn +++ b/Game/source/entities/player/player_node.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=18 format=2] +[gd_scene load_steps=19 format=2] [ext_resource path="res://source/assets/sprites/character/player/animation/idle/player_main_body_default_sprite_idle_animation – 4.png" type="Texture" id=1] [ext_resource path="res://source/assets/scripts/player_handlers/player_collider_handler.gd" type="Script" id=2] @@ -26,6 +26,9 @@ animations = [ { "speed": 65.0 } ] +[sub_resource type="RectangleShape2D" id=3] +extents = Vector2( 47.3339, 50.0489 ) + [node name="player" type="KinematicBody2D" groups=[ "Net", "Player", @@ -52,4 +55,24 @@ texture = ExtResource( 5 ) wait_time = 0.03 autostart = true +[node name="reload_timer" type="Timer" parent="."] +wait_time = 0.15 +one_shot = true + +[node name="hit_timer" type="Timer" parent="."] +wait_time = 0.1 +one_shot = true + +[node name="shoot_point" type="Position2D" parent="."] +position = Vector2( 55.9245, -31.8558 ) + +[node name="hitbox" type="Area2D" parent="."] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="hitbox"] +position = Vector2( -3.49359, 3.44745 ) +shape = SubResource( 3 ) + [connection signal="timeout" from="network_tick_rate" to="." method="_on_network_tick_rate_timeout"] +[connection signal="timeout" from="reload_timer" to="." method="_on_reload_timer_timeout"] +[connection signal="timeout" from="hit_timer" to="." method="_on_hit_timer_timeout"] +[connection signal="area_entered" from="hitbox" to="." method="_on_hitbox_area_entered"] diff --git a/Game/source/levels/trinity_site/trinity_site_level.tscn b/Game/source/levels/trinity_site/trinity_site_level.tscn index 2d075d2..ece1ead 100644 --- a/Game/source/levels/trinity_site/trinity_site_level.tscn +++ b/Game/source/levels/trinity_site/trinity_site_level.tscn @@ -1,8 +1,19 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=8 format=2] [ext_resource path="res://source/assets/scripts/server_handlers/trinity_site_level.gd" type="Script" id=1] [ext_resource path="res://source/assets/scripts/ui_element_handlers/UI.gd" type="Script" id=2] [ext_resource path="res://source/levels/trinity_site/images/trinity_site_level_layout-monochrome.png" type="Texture" id=3] +[ext_resource path="res://source/fonts/roboto/Roboto-Regular.ttf" type="DynamicFontData" id=4] +[ext_resource path="res://source/assets/scripts/ui_element_handlers/winner.gd" type="Script" id=5] +[ext_resource path="res://source/assets/scripts/ui_element_handlers/game_UI.gd" type="Script" id=6] + +[sub_resource type="DynamicFont" id=1] +size = 120 +outline_size = 7 +outline_color = Color( 0, 0, 0, 1 ) +use_mipmaps = true +use_filter = true +font_data = ExtResource( 4 ) [node name="trinity-site" type="Node2D"] script = ExtResource( 1 ) @@ -40,3 +51,36 @@ position = Vector2( 969.307, 315.931 ) [node name="UI" type="CanvasLayer" parent="."] script = ExtResource( 2 ) + +[node name="game_UI" type="CanvasLayer" parent="."] +script = ExtResource( 6 ) + +[node name="Control" type="Control" parent="game_UI"] +anchor_right = 1.0 +anchor_bottom = 1.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="winner" type="Label" parent="game_UI/Control"] +anchor_top = 0.5 +anchor_right = 1.0 +anchor_bottom = 0.5 +margin_top = -35.5 +margin_bottom = 57.5 +custom_fonts/font = SubResource( 1 ) +custom_colors/font_color_shadow = Color( 0, 0, 0, 1 ) +custom_constants/shadow_offset_x = 6 +custom_constants/shadow_offset_y = 6 +text = "You are the winner" +align = 1 +valign = 1 +script = ExtResource( 5 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="win_timer" type="Timer" parent="game_UI/Control/winner"] +wait_time = 4.0 + +[connection signal="timeout" from="game_UI/Control/winner/win_timer" to="game_UI/Control/winner" method="_on_win_timer_timeout"] diff --git a/Game/source/scenes/GUI/main_menu.tscn b/Game/source/scenes/GUI/main_menu.tscn index 58d13f8..177aa48 100644 --- a/Game/source/scenes/GUI/main_menu.tscn +++ b/Game/source/scenes/GUI/main_menu.tscn @@ -49,10 +49,10 @@ 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 +margin_left = -266.52 +margin_top = 28.0 +margin_right = 268.48 +margin_bottom = 204.0 custom_fonts/font = ExtResource( 1 ) text = "Join server" __meta__ = { @@ -100,7 +100,7 @@ __meta__ = { } [node name="floor" parent="." instance=ExtResource( 4 )] -position = Vector2( 960, 1104 ) +position = Vector2( 960, 1056 ) scale = Vector2( 2, 1 ) [connection signal="pressed" from="multiplayer_configure/create_server" to="." method="_on_create_server_pressed"]