Flashlight collider, enable YSort, bug: character is shaking while moving

This commit is contained in:
Иван Кузьменко 2023-08-16 02:04:30 +03:00
parent a610cd0561
commit 434493578c
5 changed files with 114 additions and 51 deletions

5
prefabs/light_sense.tscn Normal file
View file

@ -0,0 +1,5 @@
[gd_scene format=3 uid="uid://cf0wpahgwygxx"]
[node name="LightSense" type="Area2D"]
collision_layer = 2
collision_mask = 2

View file

@ -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="."]

View file

@ -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]

View file

@ -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")

View file

@ -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 };
}
}
}
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;
}
}
}