From 434493578c254cfc23fdd00fcf117567617c758a Mon Sep 17 00:00:00 2001 From: Ivan Kuzmenko <6745157+rndtrash@users.noreply.github.com> Date: Wed, 16 Aug 2023 02:04:30 +0300 Subject: [PATCH] Flashlight collider, enable YSort, bug: character is shaking while moving --- prefabs/light_sense.tscn | 5 ++ prefabs/player.tscn | 1 + project.godot | 2 + scenes/main_scene.tscn | 57 +++++++++++++++++----- scripts/Flashlight.cs | 100 +++++++++++++++++++++++---------------- 5 files changed, 114 insertions(+), 51 deletions(-) create mode 100644 prefabs/light_sense.tscn diff --git a/prefabs/light_sense.tscn b/prefabs/light_sense.tscn new file mode 100644 index 0000000..fb834de --- /dev/null +++ b/prefabs/light_sense.tscn @@ -0,0 +1,5 @@ +[gd_scene format=3 uid="uid://cf0wpahgwygxx"] + +[node name="LightSense" type="Area2D"] +collision_layer = 2 +collision_mask = 2 diff --git a/prefabs/player.tscn b/prefabs/player.tscn index c714aef..781d9a3 100644 --- a/prefabs/player.tscn +++ b/prefabs/player.tscn @@ -7,6 +7,7 @@ size = Vector2(15, 15) [node name="Player" type="CharacterBody2D"] +y_sort_enabled = true script = ExtResource("1_1vpun") [node name="CollisionShape2D" type="CollisionShape2D" parent="."] diff --git a/project.godot b/project.godot index 1e7c2d7..bd4754a 100644 --- a/project.godot +++ b/project.godot @@ -66,6 +66,8 @@ character_right={ 2d_render/layer_1="Dark World" 2d_render/layer_2="Light World" 2d_render/layer_3="UI" +2d_physics/layer_1="World" +2d_physics/layer_2="Light" [rendering] diff --git a/scenes/main_scene.tscn b/scenes/main_scene.tscn index b60b4f7..b9c6577 100644 --- a/scenes/main_scene.tscn +++ b/scenes/main_scene.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=11 format=3 uid="uid://dhn7yt46fyac8"] +[gd_scene load_steps=14 format=3 uid="uid://dhn7yt46fyac8"] [ext_resource type="PackedScene" uid="uid://bhulqhxesd5gc" path="res://prefabs/player.tscn" id="1_65a7v"] [ext_resource type="Texture2D" uid="uid://py6qiu3rm7cu" path="res://sprites/brickwall.png" id="2_edqdh"] @@ -11,6 +11,14 @@ [sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_wg1ao"] light_mode = 2 +[sub_resource type="ViewportTexture" id="ViewportTexture_dwy4p"] +viewport_path = NodePath("FlashlightViewport") + +[sub_resource type="CircleShape2D" id="CircleShape2D_prnh4"] +radius = 16.0 + +[sub_resource type="CircleShape2D" id="CircleShape2D_qcayn"] + [sub_resource type="ViewportTexture" id="ViewportTexture_nnmvo"] viewport_path = NodePath("FlashlightViewport") @@ -18,15 +26,34 @@ viewport_path = NodePath("FlashlightViewport") light_mode = 2 [node name="Root" type="Node2D"] +y_sort_enabled = true + +[node name="Player" parent="." instance=ExtResource("1_65a7v")] +position = Vector2(19, 4) + +[node name="Controller" type="Node" parent="." node_paths=PackedStringArray("Player", "Camera", "Circle", "PlayerCircle", "Polygon", "CollisionCircle", "CollisionPlayerCircle", "CollisionPolygon")] +script = ExtResource("3_cylxo") +Player = NodePath("../Player") +Camera = NodePath("../PlayerCamera") +Circle = NodePath("../FlashlightViewport/Circle") +PlayerCircle = NodePath("../FlashlightViewport/PlayerCircle") +Polygon = NodePath("../FlashlightViewport/Triangle") +CollisionCircle = NodePath("../PlayerCamera/Area2D/Circle") +CollisionPlayerCircle = NodePath("../PlayerCamera/Area2D/PlayerCircle") +CollisionPolygon = NodePath("../PlayerCamera/Area2D/CollisionPolygon2D") [node name="TestWall" type="Sprite2D" parent="."] light_mask = 2 +y_sort_enabled = true material = SubResource("CanvasItemMaterial_wg1ao") position = Vector2(58, 37) texture = ExtResource("2_edqdh") -[node name="Player" parent="." instance=ExtResource("1_65a7v")] -position = Vector2(19, 4) +[node name="TestWall2" type="Sprite2D" parent="."] +light_mask = 2 +y_sort_enabled = true +position = Vector2(85, 71) +texture = ExtResource("2_edqdh") [node name="FlashlightViewport" type="SubViewport" parent="."] transparent_bg = true @@ -47,14 +74,6 @@ texture = ExtResource("3_8o315") [node name="Triangle" type="Polygon2D" parent="FlashlightViewport"] polygon = PackedVector2Array(-21, -25, 31, 29, -42, 31) -[node name="Controller" type="Node" parent="FlashlightViewport" node_paths=PackedStringArray("Player", "Camera", "Circle", "PlayerCircle", "Polygon")] -script = ExtResource("3_cylxo") -Player = NodePath("../../Player") -Camera = NodePath("../../PlayerCamera") -Circle = NodePath("../Circle") -PlayerCircle = NodePath("../PlayerCircle") -Polygon = NodePath("../Triangle") - [node name="PlayerCamera" type="Camera2D" parent="." node_paths=PackedStringArray("Player")] script = ExtResource("6_quua3") Player = NodePath("../Player") @@ -63,9 +82,24 @@ CameraBounds = Vector2(30, 20) [node name="PointLight2D" type="PointLight2D" parent="PlayerCamera" node_paths=PackedStringArray("LightViewport")] blend_mode = 2 range_item_cull_mask = 2 +texture = SubResource("ViewportTexture_dwy4p") script = ExtResource("6_slohe") LightViewport = NodePath("../../FlashlightViewport") +[node name="Area2D" type="Area2D" parent="PlayerCamera"] +position = Vector2(-128, -96) +collision_layer = 2 +collision_mask = 2 + +[node name="PlayerCircle" type="CollisionShape2D" parent="PlayerCamera/Area2D"] +shape = SubResource("CircleShape2D_prnh4") + +[node name="Circle" type="CollisionShape2D" parent="PlayerCamera/Area2D"] +shape = SubResource("CircleShape2D_qcayn") + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="PlayerCamera/Area2D"] +polygon = PackedVector2Array(0, 0, 0, 0, 0, 0) + [node name="CanvasLayer" type="CanvasLayer" parent="."] [node name="FlashlightUI" type="TextureRect" parent="CanvasLayer"] @@ -88,6 +122,7 @@ grow_vertical = 2 [node name="Sprite2D" type="Sprite2D" parent="."] light_mask = 2 +y_sort_enabled = true material = SubResource("CanvasItemMaterial_au1d0") position = Vector2(-83, 43) texture = ExtResource("3_8o315") diff --git a/scripts/Flashlight.cs b/scripts/Flashlight.cs index 5bd202f..e36f3f2 100644 --- a/scripts/Flashlight.cs +++ b/scripts/Flashlight.cs @@ -1,52 +1,72 @@ +using System; using Godot; public partial class Flashlight : Node { - [Export] public Player Player; - [Export] public GameCamera Camera; + [Export] public Player Player; + [Export] public GameCamera Camera; - [Export] public Node2D Circle; - [Export] public Node2D PlayerCircle; - [Export] public Polygon2D Polygon; + [Export] public Node2D Circle; + [Export] public Node2D PlayerCircle; + [Export] public Polygon2D Polygon; - private float FlashlightRadius = Constants.MaxFlashlightRadius; + [Export] public CollisionShape2D CollisionCircle; + [Export] public CollisionShape2D CollisionPlayerCircle; + [Export] public CollisionPolygon2D CollisionPolygon; - public override void _Process(double delta) - { - var playerScreenCenterPosition = Player.Position - Camera.Position; - var flashlightScreenCenterPosition = Camera.FlashlightPosition - Camera.Position; + private float FlashlightRadius = Constants.MaxFlashlightRadius; - var playerScreenPosition = playerScreenCenterPosition + Constants.HalfScreenSize; - PlayerCircle.Position = playerScreenPosition; + public override void _Ready() + { + base._Ready(); - var d = Camera.FlashlightPosition.DistanceTo(Player.Position); - FlashlightRadius = Mathf.Lerp(Constants.MinFlashlightRadius, Constants.MaxFlashlightRadius, - Mathf.Clamp(d - Constants.MinFlashlightDistance, 0, - Constants.MaxFlashlightDistance - Constants.MinFlashlightDistance) / Constants.MaxFlashlightDistance); - - var flashlightScreenPosition = flashlightScreenCenterPosition + Constants.HalfScreenSize; - var flashlightScale = FlashlightRadius / Constants.MaxFlashlightRadius; - Circle.Position = flashlightScreenPosition; - Circle.Scale = new Vector2(flashlightScale, flashlightScale); + if (CollisionCircle.Shape is not CircleShape2D) + throw new Exception("Invalid collision shape on the circle"); + if (CollisionPlayerCircle.Shape is not CircleShape2D) + throw new Exception("Invalid collision shape on the player circle"); + } - if (d <= FlashlightRadius) - Polygon.Visible = false; - else - { - Polygon.Visible = true; + public override void _Process(double delta) + { + var playerScreenCenterPosition = Player.Position - Camera.Position; + var flashlightScreenCenterPosition = Camera.FlashlightPosition - Camera.Position; - var a = Mathf.Sqrt(d * d - FlashlightRadius * FlashlightRadius); - var xy2 = Camera.FlashlightPosition - Player.Position; - var angle = xy2.Angle(); + var playerScreenPosition = playerScreenCenterPosition + Constants.HalfScreenSize; + PlayerCircle.Position = playerScreenPosition; + CollisionPlayerCircle.Position = playerScreenPosition; - var arcsinRd = Mathf.Asin(FlashlightRadius / d); - var dslkhjdsflkhjsdfhlkjdfsjlk = angle + arcsinRd; - var xy3 = a * new Vector2(Mathf.Cos(dslkhjdsflkhjsdfhlkjdfsjlk), Mathf.Sin(dslkhjdsflkhjsdfhlkjdfsjlk)); - var dslkhjdsflkhjsdfhlkjdfsjlk2 = angle - arcsinRd; - var xy4 = a * new Vector2(Mathf.Cos(dslkhjdsflkhjsdfhlkjdfsjlk2), Mathf.Sin(dslkhjdsflkhjsdfhlkjdfsjlk2)); - - Polygon.Polygon = new[] - { playerScreenPosition, playerScreenPosition + xy3, playerScreenPosition + xy4 }; - } - } -} \ No newline at end of file + var d = Camera.FlashlightPosition.DistanceTo(Player.Position); + FlashlightRadius = Mathf.Lerp(Constants.MinFlashlightRadius, Constants.MaxFlashlightRadius, + Mathf.Clamp(d - Constants.MinFlashlightDistance, 0, + Constants.MaxFlashlightDistance - Constants.MinFlashlightDistance) / Constants.MaxFlashlightDistance); + + var flashlightScreenPosition = flashlightScreenCenterPosition + Constants.HalfScreenSize; + var flashlightScale = FlashlightRadius / Constants.MaxFlashlightRadius; + Circle.Position = flashlightScreenPosition; + Circle.Scale = new Vector2(flashlightScale, flashlightScale); + CollisionCircle.Position = flashlightScreenPosition; + ((CircleShape2D)CollisionCircle.Shape).Radius = FlashlightRadius; + + if (d <= FlashlightRadius) + Polygon.Visible = false; + else + { + Polygon.Visible = true; + + var a = Mathf.Sqrt(d * d - FlashlightRadius * FlashlightRadius); + var xy2 = Camera.FlashlightPosition - Player.Position; + var angle = xy2.Angle(); + + var arcsinRd = Mathf.Asin(FlashlightRadius / d); + var dslkhjdsflkhjsdfhlkjdfsjlk = angle + arcsinRd; + var xy3 = a * new Vector2(Mathf.Cos(dslkhjdsflkhjsdfhlkjdfsjlk), Mathf.Sin(dslkhjdsflkhjsdfhlkjdfsjlk)); + var dslkhjdsflkhjsdfhlkjdfsjlk2 = angle - arcsinRd; + var xy4 = a * new Vector2(Mathf.Cos(dslkhjdsflkhjsdfhlkjdfsjlk2), Mathf.Sin(dslkhjdsflkhjsdfhlkjdfsjlk2)); + + var polygon = new[] + { playerScreenPosition, playerScreenPosition + xy3, playerScreenPosition + xy4 }; + Polygon.Polygon = polygon; + CollisionPolygon.Polygon = polygon; + } + } +}