Add new cool light beam for the flashlight

Co-authored-by: Евгений Титаренко <frundle@teasanctuary.ru>
This commit is contained in:
Иван Кузьменко 2023-08-16 00:13:37 +03:00
parent 3832a05c1b
commit f307a7ef00
20 changed files with 230 additions and 68 deletions

9
scripts/Constants.cs Normal file
View file

@ -0,0 +1,9 @@
using Godot;
public static class Constants
{
public static readonly Vector2 ScreenSize = new(256, 192);
public static readonly Vector2 HalfScreenSize = ScreenSize / 2;
public const float MaxFlashlightRadius = 32;
}

48
scripts/Flashlight.cs Normal file
View file

@ -0,0 +1,48 @@
using Godot;
public partial class Flashlight : Node
{
[Export] public Player Player;
[Export] public GameCamera Camera;
[Export] public Node2D Circle;
[Export] public Node2D PlayerCircle;
[Export] public Polygon2D Polygon;
private float FlashlightRadius = Constants.MaxFlashlightRadius;
public override void _Process(double delta)
{
var playerScreenCenterPosition = Player.Position - Camera.Position;
var flashlightScreenCenterPosition = Camera.FlashlightPosition - Camera.Position;
var playerScreenPosition = playerScreenCenterPosition + Constants.HalfScreenSize;
PlayerCircle.Position = playerScreenPosition;
var flashlightScreenPosition = flashlightScreenCenterPosition + Constants.HalfScreenSize;
var flashlightScale = FlashlightRadius / Constants.MaxFlashlightRadius;
Circle.Position = flashlightScreenPosition;
Circle.Scale = new Vector2(flashlightScale, flashlightScale);
var d = Camera.FlashlightPosition.DistanceTo(Player.Position);
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));
Polygon.Polygon = new[]
{ playerScreenPosition, playerScreenPosition + xy3, playerScreenPosition + xy4 };
}
}
}

19
scripts/GameCamera.cs Normal file
View file

@ -0,0 +1,19 @@
using Godot;
public partial class GameCamera : Camera2D
{
/// <summary>
/// World position of the flashlight
/// </summary>
public Vector2 FlashlightPosition;
public override void _Input(InputEvent @event)
{
base._Input(@event);
if (@event is InputEventMouseMotion eventMouseMotion)
{
FlashlightPosition = eventMouseMotion.Position - Constants.HalfScreenSize + Position;
}
}
}

View file

@ -1,52 +1,37 @@
using Godot;
using System;
public partial class Player : CharacterBody2D
{
[Export] public Node2D FlashlightUI;
[Export] public Node2D FlashlightWorld;
[Export] public const float Speed = 50.0f;
[Export] public const float Speed = 50.0f;
protected AnimatedSprite2D Sprite;
protected AnimatedSprite2D Sprite;
public override void _Ready()
{
base._Ready();
public override void _Ready()
{
base._Ready();
Sprite = (AnimatedSprite2D)FindChild("AnimatedSprite2D");
}
Sprite = (AnimatedSprite2D)FindChild("AnimatedSprite2D");
}
public override void _PhysicsProcess(double delta)
{
Vector2 velocity = Velocity;
public override void _PhysicsProcess(double delta)
{
Vector2 velocity = Velocity;
// Get the input direction and handle the movement/deceleration.
// As good practice, you should replace UI actions with custom gameplay actions.
Vector2 direction = Input.GetVector("ui_left", "ui_right", "ui_up", "ui_down");
if (direction != Vector2.Zero)
{
velocity.X = direction.X * Speed;
velocity.Y = direction.Y * Speed;
}
else
{
velocity.X = Mathf.MoveToward(Velocity.X, 0, Speed);
velocity.Y = Mathf.MoveToward(Velocity.Y, 0, Speed);
}
// Get the input direction and handle the movement/deceleration.
// As good practice, you should replace UI actions with custom gameplay actions.
Vector2 direction = Input.GetVector("ui_left", "ui_right", "ui_up", "ui_down");
if (direction != Vector2.Zero)
{
velocity.X = direction.X * Speed;
velocity.Y = direction.Y * Speed;
}
else
{
velocity.X = Mathf.MoveToward(Velocity.X, 0, Speed);
velocity.Y = Mathf.MoveToward(Velocity.Y, 0, Speed);
}
Velocity = velocity;
MoveAndSlide();
}
public override void _Input(InputEvent @event)
{
base._Input(@event);
if (@event is InputEventMouseMotion eventMouseMotion)
{
FlashlightUI.Position = eventMouseMotion.Position;
FlashlightWorld.Position = eventMouseMotion.Position - new Vector2(128F, 96F);
}
}
}
Velocity = velocity;
MoveAndSlide();
}
}

View file

@ -0,0 +1,16 @@
using Godot;
using System;
[Tool]
public partial class PointLight2DWorkaround : PointLight2D
{
[Export] public Viewport LightViewport;
public override void _Process(double delta)
{
base._Process(delta);
Texture = null;
Texture = LightViewport.GetTexture();
}
}