diff --git a/bullet.gd b/bullet.gd index 3a99923..8f88682 100644 --- a/bullet.gd +++ b/bullet.gd @@ -5,9 +5,12 @@ extends CharacterBody2D func _physics_process(delta): var collision = move_and_collide(velocity * delta) if collision: - if collision.get_position().x > position.x: - velocity.x = -velocity.x + var collider = collision.get_collider() + var pos = collision.get_position() + if abs(pos.y - collider.global_position.y) > collider.get_node("CollisionShape2D").shape.size.y * collider.global_scale.y / 2 - 0.001: + velocity.y *= -1 else: - velocity.y = -velocity.y - collision_mask = 0 + velocity.x = -velocity.x + collision_mask = 0 $Trail.shrinking = true + $Ricochet.play() diff --git a/bullet.tscn b/bullet.tscn index 8b3897e..2c0e1ed 100644 --- a/bullet.tscn +++ b/bullet.tscn @@ -1,19 +1,19 @@ -[gd_scene load_steps=9 format=3 uid="uid://bxyl3aa8j8qc5"] +[gd_scene load_steps=10 format=3 uid="uid://bxyl3aa8j8qc5"] [ext_resource type="Script" path="res://bullet.gd" id="1_eeg3n"] [ext_resource type="Script" path="res://trail.gd" id="2_uq0x2"] -[ext_resource type="Texture2D" uid="uid://dbjqbgu6ru4m1" path="res://white.png" id="3_35obe"] [ext_resource type="Texture2D" uid="uid://bda38sojncx5q" path="res://light.png" id="4_jdr6g"] +[ext_resource type="Texture2D" uid="uid://bcl076hrv3pfy" path="res://circle.png" id="4_tv64x"] +[ext_resource type="AudioStream" uid="uid://dhayng4sypahr" path="res://fire.mp3" id="5_es1i2"] +[ext_resource type="AudioStream" uid="uid://oet1lthsa14c" path="res://ricochet.mp3" id="6_6fq30"] [sub_resource type="CircleShape2D" id="CircleShape2D_1y8mw"] +radius = 2.0 [sub_resource type="Curve" id="Curve_qw0p6"] _data = [Vector2(0, 1), 0.0, -1.0, 0, 1, Vector2(1, 0), -1.0, 0.0, 1, 0] point_count = 2 -[sub_resource type="Gradient" id="Gradient_s173t"] -colors = PackedColorArray(0.967279, 0.105729, 0.103599, 1, 0.980392, 0.541176, 0.160784, 1) - [sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_uqkxw"] properties/0/path = NodePath("../..:position") properties/0/spawn = true @@ -29,10 +29,13 @@ speed = 2000.0 shape = SubResource("CircleShape2D_1y8mw") [node name="Trail" type="Line2D" parent="."] +width = 4.0 width_curve = SubResource("Curve_qw0p6") -gradient = SubResource("Gradient_s173t") +default_color = Color(0.913725, 0.494118, 0.780392, 1) script = ExtResource("2_uq0x2") MAX_LENGTH = 3 +OPACITY_SHRINK_RATE = 15 +SIZE_SHRINK_RATE = 15 [node name="PointLight2D" type="PointLight2D" parent="Trail"] scale = Vector2(0.1, 0.1) @@ -40,9 +43,19 @@ color = Color(0.996078, 0.807843, 0.682353, 1) energy = 2.5 texture = ExtResource("4_jdr6g") -[node name="Sprite2D" type="Sprite2D" parent="."] -visible = false -texture = ExtResource("3_35obe") +[node name="Sprite2D" type="Sprite2D" parent="Trail"] +modulate = Color(0.960784, 0.94902, 0.0431373, 1) +scale = Vector2(0.125, 0.125) +texture = ExtResource("4_tv64x") + +[node name="Fire" type="AudioStreamPlayer" parent="."] +stream = ExtResource("5_es1i2") +volume_db = -5.0 +autoplay = true + +[node name="Ricochet" type="AudioStreamPlayer" parent="."] +stream = ExtResource("6_6fq30") +volume_db = -12.0 [node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."] root_path = NodePath("../Trail/PointLight2D") diff --git a/circle.png b/circle.png new file mode 100644 index 0000000..99bf89f Binary files /dev/null and b/circle.png differ diff --git a/circle.png.import b/circle.png.import new file mode 100644 index 0000000..5486865 --- /dev/null +++ b/circle.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bcl076hrv3pfy" +path="res://.godot/imported/circle.png-10953cad44a8947fbdd4128a631e9e52.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://circle.png" +dest_files=["res://.godot/imported/circle.png-10953cad44a8947fbdd4128a631e9e52.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/fire.mp3 b/fire.mp3 new file mode 100644 index 0000000..40f8bf7 Binary files /dev/null and b/fire.mp3 differ diff --git a/fire.mp3.import b/fire.mp3.import new file mode 100644 index 0000000..6bd03fb --- /dev/null +++ b/fire.mp3.import @@ -0,0 +1,19 @@ +[remap] + +importer="mp3" +type="AudioStreamMP3" +uid="uid://dhayng4sypahr" +path="res://.godot/imported/fire.mp3-667fd5274750730e838dfad45086e33d.mp3str" + +[deps] + +source_file="res://fire.mp3" +dest_files=["res://.godot/imported/fire.mp3-667fd5274750730e838dfad45086e33d.mp3str"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/gun.gd b/gun.gd index f21256a..4923b3c 100644 --- a/gun.gd +++ b/gun.gd @@ -2,19 +2,28 @@ extends Node2D @export var bullet: PackedScene @export var spread = 10.0 +@export var recoil = 600.0 +@export var fire_rate = 20 + +var last_fired = 0.0 # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(_delta): - if Input.is_action_just_pressed("fire"): + if Input.is_action_pressed("fire") and (Time.get_ticks_msec() - last_fired) > fire_rate: + last_fired = Time.get_ticks_msec() fire.rpc() @rpc("any_peer", "call_local") func fire(): - var authority = get_parent().get_node("MultiplayerSynchronizer").get_multiplayer_authority() - if authority != get_multiplayer_authority(): - return; + if get_parent().get_node("MultiplayerSynchronizer").get_multiplayer_authority() != get_parent().multiplayer.get_unique_id(): + return + var color = get_parent().get_node("Sprite2D").modulate var new_bullet = bullet.instantiate() + new_bullet.get_node("Trail/Sprite2D").modulate = color + new_bullet.get_node("Trail").default_color = color + new_bullet.get_node("Trail/PointLight2D").color = color + new_bullet.get_node("Fire").pitch_scale = randf_range(0.95, 1.05) new_bullet.position = global_position new_bullet.velocity = Vector2.from_angle(rotation + deg_to_rad(randf_range(-spread / 2, spread / 2))) * new_bullet.speed; get_tree().root.add_child(new_bullet) - get_parent().x_velocity_offset = -600 * cos(rotation) + get_parent().apply_central_impulse(-recoil * Vector2(cos(rotation), sin(rotation))) diff --git a/main.tscn b/main.tscn index 183406f..9a8fcc8 100644 --- a/main.tscn +++ b/main.tscn @@ -26,24 +26,16 @@ position = Vector2(526, 361) position = Vector2(848, 361) [node name="CollisionShape2D" parent="." instance=ExtResource("3_njyoi")] -position = Vector2(114, 593) +position = Vector2(598, 441) scale = Vector2(9.84444, 4.5) [node name="CollisionShape2D2" parent="." instance=ExtResource("3_njyoi")] -position = Vector2(323, 448) -scale = Vector2(9.40821, 0.413171) +position = Vector2(-48, 597) +scale = Vector2(9.84444, 4.5) [node name="CollisionShape2D5" parent="." instance=ExtResource("3_njyoi")] -position = Vector2(606, 389) -scale = Vector2(9.40821, 0.413171) - -[node name="CollisionShape2D6" parent="." instance=ExtResource("3_njyoi")] -position = Vector2(-50, 393) -scale = Vector2(9.40821, 0.413171) - -[node name="CollisionShape2D7" parent="." instance=ExtResource("3_njyoi")] -position = Vector2(31, 273) -scale = Vector2(9.40821, 0.413171) +position = Vector2(258, 429) +scale = Vector2(3.77016, 0.370991) [node name="CollisionShape2D3" parent="." instance=ExtResource("3_njyoi")] position = Vector2(289, 634) diff --git a/platform.tscn b/platform.tscn index 1a4d526..61ff3d6 100644 --- a/platform.tscn +++ b/platform.tscn @@ -14,7 +14,7 @@ polygon = PackedVector2Array(16, 16, -16, 16, -16, -16, 16, -16) shape = SubResource("RectangleShape2D_6fi6a") [node name="Sprite2D" type="Sprite2D" parent="."] -modulate = Color(0.105882, 0.105882, 0.105882, 1) +modulate = Color(0, 0, 0, 1) texture = ExtResource("1_eu1eh") [node name="LightOccluder2D" type="LightOccluder2D" parent="."] diff --git a/player.gd b/player.gd index 3412f5e..7292268 100644 --- a/player.gd +++ b/player.gd @@ -1,17 +1,14 @@ -extends CharacterBody2D +extends RigidBody2D @export var speed = 300.0 @export var jump_velocity = -400.0 @export var wall_jump_velocity = 600.0 -@export var ungrounded_x_lerp = 10.0 -@export var grounded_drag_lerp = 5.0 -@export var ungrounded_drag_lerp = 5.0 @export var fox_time = 5 @export var limp_gravity_modifier = 2.0 +@export var on_ground_force = 50.0 +@export var in_air_force = 10.0 +@export var stop_force = 10.0 -var x_velocity_offset = 0 -var x_movement = 0 -var desired_x_movement = 0 var last_grounded = 0 # Get the gravity from the project settings to be synced with RigidBody nodes. @@ -29,42 +26,53 @@ func _ready(): $Sprite2D.modulate = Color.from_hsv((username_hash % 255) / 255.0, 0.5, 0.8) gun = $Gun -func _physics_process(delta): +func _physics_process(_delta): if $MultiplayerSynchronizer.get_multiplayer_authority() != multiplayer.get_unique_id(): return # Add the gravity. - if is_on_floor(): + var is_on_floor = len($FloorDetect.get_overlapping_bodies()) > 0 + if is_on_floor: last_grounded = Time.get_ticks_msec() - else: - velocity.y += gravity * delta * (limp_gravity_modifier if Input.is_action_pressed("limp") else 1.0) + gravity_scale = limp_gravity_modifier if Input.is_action_pressed("limp") else 1.0 gun.look_at(get_global_mouse_position()) var grounded = Time.get_ticks_msec() - last_grounded < fox_time + + var on_left_wall = len($WallDetectLeft.get_overlapping_bodies()) > 0 + var on_right_wall = len($WallDetectRight.get_overlapping_bodies()) > 0 + var on_wall = on_left_wall or on_right_wall - x_velocity_offset = lerpf(x_velocity_offset, 0, (grounded_drag_lerp if is_on_floor() else ungrounded_drag_lerp) * delta) - - # Handle Jump. - if Input.is_action_just_pressed("jump"): - if grounded: - velocity.y = jump_velocity - elif len($WallDetect.get_overlapping_bodies()) > 0: - velocity.y = jump_velocity - if $WallDetect.get_overlapping_bodies()[0].position.x > position.x: - x_velocity_offset = -wall_jump_velocity - else: - x_velocity_offset = wall_jump_velocity + #velocity_offset = velocity_offset.lerp(Vector2.ZERO, (grounded_drag_lerp if is_on_floor() else ungrounded_drag_lerp) * delta) # Get the input direction and handle the movement/deceleration. # As good practice, you should replace UI actions with custom gameplay actions. var direction = Input.get_axis("move_left", "move_right") - velocity.x = x_velocity_offset - if direction: - desired_x_movement = direction * speed; - x_movement = lerpf(x_movement, desired_x_movement, 1 if grounded else ungrounded_x_lerp * delta) - velocity.x += x_movement - else: - velocity.x = move_toward(velocity.x, 0, speed) + if grounded: + apply_central_force(Vector2.RIGHT * direction * speed * on_ground_force) + if direction == 0: + if linear_velocity.x > 0.1: + apply_central_force(Vector2.LEFT * stop_force) + elif linear_velocity.x < 0.1: + apply_central_force(Vector2.RIGHT * stop_force) + elif (not on_wall) or (on_left_wall && direction > 0) or (on_right_wall and direction < 0): + apply_central_force(Vector2.RIGHT * direction * speed * in_air_force) + + if linear_velocity.x > speed: + linear_velocity.x = speed + elif linear_velocity.x < -speed: + linear_velocity.x = -speed - move_and_slide() + # Handle Jump. + if Input.is_action_just_pressed("jump"): + if grounded: + apply_central_impulse(Vector2.UP * jump_velocity) + $JumpSound.play() + if not grounded and on_wall: + apply_central_impulse(Vector2.UP * jump_velocity) + if on_right_wall: + apply_central_impulse(Vector2.LEFT * wall_jump_velocity) + else: + apply_central_impulse(Vector2.RIGHT * wall_jump_velocity) + $JumpSound.play() diff --git a/player.tscn b/player.tscn index 9815352..3bef918 100644 --- a/player.tscn +++ b/player.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=9 format=3 uid="uid://b6olswaoek0bw"] +[gd_scene load_steps=12 format=3 uid="uid://b6olswaoek0bw"] [ext_resource type="Script" path="res://player.gd" id="1_0p8o6"] [ext_resource type="Script" path="res://gun.gd" id="2_847gu"] [ext_resource type="PackedScene" uid="uid://bxyl3aa8j8qc5" path="res://bullet.tscn" id="3_ckwue"] [ext_resource type="Texture2D" uid="uid://bda38sojncx5q" path="res://light.png" id="4_q0kom"] +[ext_resource type="AudioStream" uid="uid://c30svhturh63u" path="res://swoosh.mp3" id="5_dg8cc"] [sub_resource type="CompressedTexture2D" id="CompressedTexture2D_2xv6m"] load_path = "res://.godot/imported/white.png-d8533361663a5f8fe5200e5b5262a62d.ctex" @@ -12,7 +13,13 @@ load_path = "res://.godot/imported/white.png-d8533361663a5f8fe5200e5b5262a62d.ct size = Vector2(32, 48) [sub_resource type="RectangleShape2D" id="RectangleShape2D_2cyhj"] -size = Vector2(38, 48) +size = Vector2(3, 48) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_64slp"] +size = Vector2(3, 48) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_j3l6y"] +size = Vector2(12, 2) [sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_38o4e"] properties/0/path = NodePath(".:position") @@ -24,13 +31,16 @@ properties/1/spawn = true properties/1/sync = true properties/1/watch = false -[node name="Player" type="CharacterBody2D"] +[node name="Player" type="RigidBody2D"] collision_layer = 2 +lock_rotation = true script = ExtResource("1_0p8o6") -jump_velocity = -700.0 +speed = 400.0 +jump_velocity = 700.0 wall_jump_velocity = 700.0 fox_time = 100 limp_gravity_modifier = 3.0 +stop_force = 300.0 [node name="Sprite2D" type="Sprite2D" parent="."] light_mask = 0 @@ -41,6 +51,8 @@ texture = SubResource("CompressedTexture2D_2xv6m") z_index = 1 script = ExtResource("2_847gu") bullet = ExtResource("3_ckwue") +recoil = 125.0 +fire_rate = 75 [node name="Sprite2D" type="Sprite2D" parent="Gun"] position = Vector2(19, 0) @@ -53,11 +65,24 @@ position = Vector2(31, 0) [node name="CollisionShape2D" type="CollisionShape2D" parent="."] shape = SubResource("RectangleShape2D_8wbiu") -[node name="WallDetect" type="Area2D" parent="."] +[node name="WallDetectLeft" type="Area2D" parent="."] -[node name="CollisionShape2D" type="CollisionShape2D" parent="WallDetect"] +[node name="CollisionShape2D" type="CollisionShape2D" parent="WallDetectLeft"] +position = Vector2(-17.5, 0) shape = SubResource("RectangleShape2D_2cyhj") +[node name="WallDetectRight" type="Area2D" parent="."] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="WallDetectRight"] +position = Vector2(17.5, 0) +shape = SubResource("RectangleShape2D_64slp") + +[node name="FloorDetect" type="Area2D" parent="."] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="FloorDetect"] +position = Vector2(0, 26) +shape = SubResource("RectangleShape2D_j3l6y") + [node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."] replication_config = SubResource("SceneReplicationConfig_38o4e") @@ -78,5 +103,9 @@ text = "Player" horizontal_alignment = 1 [node name="PointLight2D" type="PointLight2D" parent="."] +position = Vector2(0, 6) shadow_enabled = true texture = ExtResource("4_q0kom") + +[node name="JumpSound" type="AudioStreamPlayer2D" parent="."] +stream = ExtResource("5_dg8cc") diff --git a/ricochet.mp3 b/ricochet.mp3 new file mode 100644 index 0000000..b6b5b11 Binary files /dev/null and b/ricochet.mp3 differ diff --git a/ricochet.mp3.import b/ricochet.mp3.import new file mode 100644 index 0000000..18b1086 --- /dev/null +++ b/ricochet.mp3.import @@ -0,0 +1,19 @@ +[remap] + +importer="mp3" +type="AudioStreamMP3" +uid="uid://oet1lthsa14c" +path="res://.godot/imported/ricochet.mp3-b081ee84c3b23356d6acf066f5078da4.mp3str" + +[deps] + +source_file="res://ricochet.mp3" +dest_files=["res://.godot/imported/ricochet.mp3-b081ee84c3b23356d6acf066f5078da4.mp3str"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/swoosh.mp3 b/swoosh.mp3 new file mode 100644 index 0000000..e32bce8 Binary files /dev/null and b/swoosh.mp3 differ diff --git a/swoosh.mp3.import b/swoosh.mp3.import new file mode 100644 index 0000000..3b1c8e1 --- /dev/null +++ b/swoosh.mp3.import @@ -0,0 +1,19 @@ +[remap] + +importer="mp3" +type="AudioStreamMP3" +uid="uid://c30svhturh63u" +path="res://.godot/imported/swoosh.mp3-1d9db0e492afd5d6e5da34466e55e5d5.mp3str" + +[deps] + +source_file="res://swoosh.mp3" +dest_files=["res://.godot/imported/swoosh.mp3-1d9db0e492afd5d6e5da34466e55e5d5.mp3str"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/trail.gd b/trail.gd index 0328a3e..061d0e3 100644 --- a/trail.gd +++ b/trail.gd @@ -18,3 +18,4 @@ func _process(delta): modulate.a = lerpf(modulate.a, 0, OPACITY_SHRINK_RATE * delta) width = lerpf(width, 0, SIZE_SHRINK_RATE * delta) $PointLight2D.energy = lerpf($PointLight2D.energy, 0, OPACITY_SHRINK_RATE * delta) + $Sprite2D.visible = false