Система диалогов.
This commit is contained in:
parent
3c1619ee9f
commit
2a2399dc2c
8 changed files with 264 additions and 88 deletions
23
scripts/ChatLogContainer.cs
Normal file
23
scripts/ChatLogContainer.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using Godot;
|
||||
using System;
|
||||
|
||||
public partial class ChatLogContainer : VBoxContainer
|
||||
{
|
||||
private const float MaxChatLogContainerSize = 220;
|
||||
|
||||
private Vector2 _initialPosition;
|
||||
// Called when the node enters the scene tree for the first time.
|
||||
public override void _Ready()
|
||||
{
|
||||
_initialPosition = Position;
|
||||
}
|
||||
|
||||
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
if (Size.Y > MaxChatLogContainerSize)
|
||||
{
|
||||
Position = _initialPosition + new Vector2(Size.X, MaxChatLogContainerSize) - Size;
|
||||
}
|
||||
}
|
||||
}
|
34
scripts/Dialog.cs
Normal file
34
scripts/Dialog.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
using Godot;
|
||||
using System;
|
||||
|
||||
[Tool]
|
||||
public partial class Dialog : PanelContainer
|
||||
{
|
||||
[Export] public string Text = "Placeholder text";
|
||||
[Export] public string Author = "NPC name";
|
||||
|
||||
private Label _textBox;
|
||||
private Label _authorBox;
|
||||
|
||||
// Called when the node enters the scene tree for the first time.
|
||||
public override void _Ready()
|
||||
{
|
||||
_textBox = (Label)FindChild("TextBox");
|
||||
_authorBox = (Label)FindChild("AuthorBox");
|
||||
if (!Engine.IsEditorHint())
|
||||
{
|
||||
_textBox.Text = Text;
|
||||
_authorBox.Text = Author;
|
||||
}
|
||||
}
|
||||
|
||||
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (Engine.IsEditorHint())
|
||||
{
|
||||
if (_textBox.Text != Text) _textBox.Text = Text;
|
||||
if (_authorBox.Text != Author) _authorBox.Text = Author;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,15 +7,31 @@ public partial class NPC : Node2D
|
|||
{
|
||||
[Export] public string NPCName;
|
||||
[Export] public SpriteFrames Frames;
|
||||
[Export] public string DefaultDialogLine;
|
||||
[Export] public Array<string> DialogLines = new Array<string>();
|
||||
|
||||
public bool Flip
|
||||
{
|
||||
get => _sprite.FlipH;
|
||||
set => _sprite.FlipH = value;
|
||||
}
|
||||
|
||||
private AnimatedSprite2D _sprite;
|
||||
|
||||
private int _currentDialogLine;
|
||||
|
||||
//Диалог закончен, если больше нет строк диалога.
|
||||
public bool IsDialogEnded => _currentDialogLine == DialogLines.Count;
|
||||
|
||||
//Возвращаем строку диалога и увеличиваем счетчик текущей строки если диалог законче, и возвращаем строку по-умолчанию, если диалог законен.
|
||||
public string Message => IsDialogEnded ? DefaultDialogLine : DialogLines[_currentDialogLine++];
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_sprite = (AnimatedSprite2D)FindChild("AnimatedSprite2D");
|
||||
if (Frames is not null) _sprite.SpriteFrames = Frames;
|
||||
_sprite.Play("default");
|
||||
_currentDialogLine = 0;
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
|
@ -30,18 +46,6 @@ public partial class NPC : Node2D
|
|||
}
|
||||
}
|
||||
|
||||
public void test()
|
||||
{
|
||||
if (_sprite.Animation == "walk")
|
||||
{
|
||||
_sprite.Play("default");
|
||||
}
|
||||
else
|
||||
{
|
||||
_sprite.Play("walk");
|
||||
}
|
||||
}
|
||||
|
||||
private void _on_interactable_player_near_by(Player player)
|
||||
{
|
||||
player.InteractableObjects.Add(this);
|
||||
|
|
|
@ -6,17 +6,20 @@ public partial class Player : CharacterBody2D
|
|||
{
|
||||
private const double TransitionTime = 0.5;
|
||||
private const double CameraTransitionTime = 0.25;
|
||||
|
||||
public enum State
|
||||
{
|
||||
Normal,
|
||||
Wait,
|
||||
Transition,
|
||||
ReadChat
|
||||
ReadChat,
|
||||
ChatWithNPC
|
||||
}
|
||||
|
||||
private State _state;
|
||||
|
||||
[Export] public State CurrentState
|
||||
|
||||
[Export]
|
||||
public State CurrentState
|
||||
{
|
||||
get => _state;
|
||||
private set
|
||||
|
@ -24,29 +27,33 @@ public partial class Player : CharacterBody2D
|
|||
switch (value)
|
||||
{
|
||||
case State.Normal:
|
||||
if (_state == State.Transition) DoorSounds.Play();
|
||||
if (_state == State.Transition) _doorSounds.Play();
|
||||
Visible = true;
|
||||
break;
|
||||
case State.Transition:
|
||||
Visible = false;
|
||||
break;
|
||||
case State.ReadChat:
|
||||
// ChatLog.Visible = !ChatLog.Visible;
|
||||
_nextLabel.Visible = false;
|
||||
break;
|
||||
case State.Wait:
|
||||
break;
|
||||
case State.ChatWithNPC:
|
||||
_nextLabel.Visible = true;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
_state = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Export] public float Speed = 300.0f;
|
||||
|
||||
// Get the gravity from the project settings to be synced with RigidBody nodes.
|
||||
public float Gravity = ProjectSettings.GetSetting("physics/2d/default_gravity").AsSingle();
|
||||
|
||||
|
||||
public List<Node2D> InteractableObjects = new List<Node2D>();
|
||||
|
||||
public Node2D InteractableObject
|
||||
|
@ -69,27 +76,34 @@ public partial class Player : CharacterBody2D
|
|||
return nearObj;
|
||||
}
|
||||
}
|
||||
|
||||
protected AnimatedSprite2D Sprite;
|
||||
protected PanelContainer ChatLog;
|
||||
protected Camera2D Camera;
|
||||
protected AudioCollection Footsteps;
|
||||
protected AudioCollection DoorSounds;
|
||||
|
||||
|
||||
private AnimatedSprite2D _sprite;
|
||||
private PanelContainer _chatLog;
|
||||
private PanelContainer _nextLabel;
|
||||
private VBoxContainer _chatLogContainer;
|
||||
private Camera2D _camera;
|
||||
private AudioCollection _footsteps;
|
||||
private AudioCollection _doorSounds;
|
||||
|
||||
private Vector2 _newPosition;
|
||||
private double _currentTransitionTime = 0;
|
||||
private double _currentCameraTransitionTime = 0;
|
||||
private Vector2 _previousPosition;
|
||||
private Vector2 _nextPosition;
|
||||
private Vector2 _cameraDefaultPosition = new(0, -20);
|
||||
private Vector2 _cameraChatLogPosition = new(116, -20);
|
||||
private Vector2 _cameraChatLogPosition = new(96, -20);
|
||||
|
||||
private PackedScene _dialogBox = GD.Load<PackedScene>("res://prefabs/Dialog.tscn");
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
Sprite = (AnimatedSprite2D)FindChild("AnimatedSprite2D");
|
||||
ChatLog = (PanelContainer)FindChild("ChatLog");
|
||||
Camera = (Camera2D)FindChild("Camera2D");
|
||||
Footsteps = (AudioCollection)FindChild("Footsteps");
|
||||
DoorSounds = (AudioCollection)FindChild("DoorSounds");
|
||||
_sprite = (AnimatedSprite2D)FindChild("AnimatedSprite2D");
|
||||
_chatLog = (PanelContainer)FindChild("ChatLog");
|
||||
_nextLabel = (PanelContainer)FindChild("NextLabel");
|
||||
_chatLogContainer = (VBoxContainer)FindChild("ChatLogContainer");
|
||||
_camera = (Camera2D)FindChild("Camera2D");
|
||||
_footsteps = (AudioCollection)FindChild("Footsteps");
|
||||
_doorSounds = (AudioCollection)FindChild("DoorSounds");
|
||||
}
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
|
@ -97,12 +111,13 @@ public partial class Player : CharacterBody2D
|
|||
switch (CurrentState)
|
||||
{
|
||||
case State.Normal:
|
||||
|
||||
if (Camera.Offset != _cameraDefaultPosition)
|
||||
|
||||
if (_camera.Offset != _cameraDefaultPosition)
|
||||
{
|
||||
if (_currentCameraTransitionTime < CameraTransitionTime)
|
||||
{
|
||||
Camera.Offset = _cameraChatLogPosition.Lerp(_cameraDefaultPosition, (float)(_currentCameraTransitionTime * 1/CameraTransitionTime));
|
||||
_camera.Offset = _cameraChatLogPosition.Lerp(_cameraDefaultPosition,
|
||||
(float)(_currentCameraTransitionTime * 1 / CameraTransitionTime));
|
||||
_currentCameraTransitionTime += delta;
|
||||
}
|
||||
else
|
||||
|
@ -110,51 +125,37 @@ public partial class Player : CharacterBody2D
|
|||
_currentCameraTransitionTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vector2 velocity = Velocity;
|
||||
|
||||
// if (!IsOnFloor())
|
||||
// {
|
||||
// velocity += GetGravity() * (float)delta;
|
||||
// }
|
||||
//
|
||||
// if (IsOnFloor() && !Visible)
|
||||
// {
|
||||
// Visible = true;
|
||||
// }
|
||||
|
||||
Vector2 direction = Input.GetVector("move_left", "move_right", "move_up", "move_down");
|
||||
if (direction != Vector2.Zero)
|
||||
{
|
||||
Footsteps.Play();
|
||||
// if (!Footsteps.IsPlaying())
|
||||
// {
|
||||
// // Footsteps.PitchScale = (float)GD.RandRange(0.5, 1.0);
|
||||
// Footsteps.Play();
|
||||
// }
|
||||
_footsteps.Play();
|
||||
velocity.X = direction.X * Speed;
|
||||
Sprite.Play("walk");
|
||||
Sprite.FlipH = direction.X switch
|
||||
_sprite.Play("walk");
|
||||
_sprite.FlipH = direction.X switch
|
||||
{
|
||||
> 0 => false,
|
||||
< 0 => true,
|
||||
_ => Sprite.FlipH
|
||||
_ => _sprite.FlipH
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
// Footsteps.Stop();
|
||||
velocity.X = Mathf.MoveToward(Velocity.X, 0, Speed);
|
||||
Sprite.Play("default");
|
||||
_sprite.Play("default");
|
||||
}
|
||||
|
||||
|
||||
Velocity = velocity;
|
||||
MoveAndSlide();
|
||||
break;
|
||||
case State.Transition:
|
||||
if (_currentTransitionTime < TransitionTime)
|
||||
{
|
||||
GlobalPosition = _previousPosition.Lerp(_nextPosition, (float)(_currentTransitionTime * 1/TransitionTime));
|
||||
GlobalPosition = _previousPosition.Lerp(_nextPosition,
|
||||
(float)(_currentTransitionTime * 1 / TransitionTime));
|
||||
_currentTransitionTime += delta;
|
||||
}
|
||||
else
|
||||
|
@ -165,25 +166,33 @@ public partial class Player : CharacterBody2D
|
|||
|
||||
break;
|
||||
case State.ReadChat:
|
||||
if (Camera.Offset != _cameraChatLogPosition)
|
||||
{
|
||||
if (_currentCameraTransitionTime < CameraTransitionTime)
|
||||
{
|
||||
Camera.Offset = _cameraDefaultPosition.Lerp(_cameraChatLogPosition, (float)(_currentCameraTransitionTime * 1/CameraTransitionTime));
|
||||
_currentCameraTransitionTime += delta;
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentCameraTransitionTime = 0;
|
||||
}
|
||||
}
|
||||
ShowChatLog(delta);
|
||||
break;
|
||||
case State.ChatWithNPC:
|
||||
ShowChatLog(delta);
|
||||
break;
|
||||
case State.Wait:
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void ShowChatLog(double delta)
|
||||
{
|
||||
if (_camera.Offset != _cameraChatLogPosition)
|
||||
{
|
||||
if (_currentCameraTransitionTime < CameraTransitionTime)
|
||||
{
|
||||
_camera.Offset = _cameraDefaultPosition.Lerp(_cameraChatLogPosition,
|
||||
(float)(_currentCameraTransitionTime * 1 / CameraTransitionTime));
|
||||
_currentCameraTransitionTime += delta;
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentCameraTransitionTime = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void _Input(InputEvent @event)
|
||||
|
@ -192,12 +201,41 @@ public partial class Player : CharacterBody2D
|
|||
{
|
||||
if (InteractableObject is NPC npc)
|
||||
{
|
||||
npc.test();
|
||||
void AddMessage()
|
||||
{
|
||||
var msg = _dialogBox.Instantiate<Dialog>();
|
||||
msg.Text = npc.Message;
|
||||
msg.Author = npc.NPCName;
|
||||
_chatLogContainer.AddChild(msg);
|
||||
if (npc.IsDialogEnded) CurrentState = State.ReadChat;
|
||||
}
|
||||
|
||||
switch (CurrentState)
|
||||
{
|
||||
case State.Normal:
|
||||
|
||||
if (GlobalPosition.X - npc.GlobalPosition.X > 0)
|
||||
{
|
||||
npc.Flip = false;
|
||||
_sprite.FlipH = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.Flip = true;
|
||||
_sprite.FlipH = false;
|
||||
}
|
||||
CurrentState = State.ChatWithNPC;
|
||||
AddMessage();
|
||||
break;
|
||||
case State.ChatWithNPC:
|
||||
AddMessage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (InteractableObject is Door door)
|
||||
{
|
||||
DoorSounds.Play();
|
||||
_doorSounds.Play();
|
||||
_previousPosition = GlobalPosition;
|
||||
_nextPosition = door.Exit.GlobalPosition;
|
||||
CurrentState = State.Wait;
|
||||
|
@ -225,4 +263,5 @@ public partial class Player : CharacterBody2D
|
|||
CurrentState = State.Transition;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue