Add VN textbox (needs some more bug fixing)

This commit is contained in:
2025-01-07 22:14:17 -06:00
parent 93c740f1ff
commit 75082e0598
10 changed files with 191 additions and 9 deletions

15
Themes/UI Theme.tres Normal file
View File

@@ -0,0 +1,15 @@
[gd_resource type="Theme" load_steps=2 format=3 uid="uid://dm7ee4aqjr2dl"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_l4fss"]
bg_color = Color(9.14484e-07, 0.446448, 0.577112, 1)
corner_radius_top_left = 8
corner_radius_top_right = 8
corner_radius_bottom_right = 8
corner_radius_bottom_left = 8
[resource]
MarginContainer/constants/margin_bottom = 16
MarginContainer/constants/margin_left = 16
MarginContainer/constants/margin_right = 16
MarginContainer/constants/margin_top = 16
PanelContainer/styles/panel = SubResource("StyleBoxFlat_l4fss")

View File

@@ -1,9 +1,10 @@
[gd_scene load_steps=5 format=3 uid="uid://iibqlagufwhm"]
[gd_scene load_steps=6 format=3 uid="uid://iibqlagufwhm"]
[ext_resource type="Script" path="res://scripts/System/Systems.gd" id="1_uen2c"]
[ext_resource type="Script" path="res://scripts/System/CutsceneSystem.gd" id="2_sf62c"]
[ext_resource type="Script" path="res://scripts/System/ItemSystem.gd" id="3_nwp6i"]
[ext_resource type="Script" path="res://scripts/System/QuestSystem.gd" id="4_d00wi"]
[ext_resource type="Script" path="res://scripts/System/VNSystem.gd" id="5_22p3i"]
[node name="Systems" type="Node3D"]
script = ExtResource("1_uen2c")
@@ -16,3 +17,6 @@ script = ExtResource("3_nwp6i")
[node name="Quest" type="Node3D" parent="."]
script = ExtResource("4_d00wi")
[node name="VN" type="Node3D" parent="."]
script = ExtResource("5_22p3i")

View File

@@ -1,10 +1,12 @@
[gd_scene load_steps=9 format=3 uid="uid://bdrpqtbwvtivd"]
[gd_scene load_steps=11 format=3 uid="uid://bdrpqtbwvtivd"]
[ext_resource type="PackedScene" uid="uid://yhtpoum3eek7" path="res://scenes/Entities/Rosa.tscn" id="1_3u2u0"]
[ext_resource type="PackedScene" uid="uid://iibqlagufwhm" path="res://scenes/Systems.tscn" id="1_3x3uf"]
[ext_resource type="PackedScene" uid="uid://dr4b2pmsknuhc" path="res://scenes/Entities/TestNPC.tscn" id="2_6f3lj"]
[ext_resource type="PackedScene" uid="uid://7wjfo6u4dp3h" path="res://scenes/Maps/test.tscn" id="4_18e1y"]
[ext_resource type="PackedScene" uid="uid://cy4r0tp2htivb" path="res://scenes/MapBounds.tscn" id="4_gv7tl"]
[ext_resource type="Theme" uid="uid://dm7ee4aqjr2dl" path="res://Themes/UI Theme.tres" id="6_d185f"]
[ext_resource type="PackedScene" uid="uid://bkx3l0kckf4a8" path="res://scenes/UI/VNTextbox.tscn" id="7_nofjj"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_1b6it"]
sky_horizon_color = Color(0.59625, 0.6135, 0.6375, 1)
@@ -41,3 +43,16 @@ omni_range = 281.646
[node name="MapBounds" parent="." instance=ExtResource("4_gv7tl")]
transform = Transform3D(22.0363, 0, 0, 0, 7.5201, 0, 0, 0, 19.278, 1.48402, 2.89779, 1.65935)
[node name="UI" type="Control" parent="."]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme = ExtResource("6_d185f")
[node name="VNTextbox" parent="UI" instance=ExtResource("7_nofjj")]
layout_mode = 1
offset_top = -133.0

26
scenes/UI/VNTextbox.tscn Normal file
View File

@@ -0,0 +1,26 @@
[gd_scene load_steps=3 format=3 uid="uid://bkx3l0kckf4a8"]
[ext_resource type="Theme" uid="uid://dm7ee4aqjr2dl" path="res://Themes/UI Theme.tres" id="1_wx4lp"]
[ext_resource type="Script" path="res://scripts/UI/VNTextbox.gd" id="2_uo1gm"]
[node name="VNTextbox" type="PanelContainer"]
anchors_preset = 12
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_top = -134.0
grow_horizontal = 2
grow_vertical = 0
theme = ExtResource("1_wx4lp")
script = ExtResource("2_uo1gm")
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 2
theme = ExtResource("1_wx4lp")
[node name="Label" type="RichTextLabel" parent="MarginContainer"]
layout_mode = 2
theme = ExtResource("1_wx4lp")
text = "test
test
test"

View File

@@ -3,11 +3,14 @@ const TestCutscene = preload("res://scripts/Cutscene/TestCutscene.gd")
func interact(interactor) -> void:
var systems = getSystems();
systems.CUTSCENE.setCurrentCutscene(TestCutscene.new())
#systems.ITEM.addItem(systems.ITEM.ITEM_POTION, 1);
#var itemSystem = (get_node("Systems") as Systems).ITEM;
#itemSystem.addItem(itemSystem.ITEM_POTION, 1);
#pass
# systems.VN.getTextbox().setText("1-2-3\n4-5-6\n\n7-8-9\n10-11-12\n13-14-15\n16-17-18\n19-20-21\n22-23-24\n25-26-27\n28-29-30\n31-32-33\n34-35-36\n37-38-39\n40-41-42\n43-44-45\n46-47-48\n49-50-51\n52-53-54\n55-56-57\n58-59-60\n61-62-63\n64-65-66\n67-68-69\n70-71-72\n73-74-75\n76-77-78\n79-80-81\n82-83-84\n85-86-87\n88-89-90\n91-92-93\n94-95-96\n97-98-99\n100-101-102\n103-104-105\n106-107-108\n109-110-111\n112-113-114\n115-116-117\n118-119-120\n121-122-123\n124-125-126\n127-128-129\n130-131-132\n133-134-135\n136-137-138\n139-140-141\n142-143-144\n145-146-147\n148-149-150\n151-152-153\n154-155-156\n157-158-159\n160-161-162\n163-164-165\n166-167-168\n169-170-171\n172-173-174\n175-176-177\n178-179-180\n181-182-183\n184-185-186\n187-188-189\n190-191-192\n193-194-195\n196-197-198\n199-200-201\n202-203-204\n205-206-207\n208-209-210\n211-212-213\n214-215-216\n217-218-219\n220-221-222\n223-224-225\n226-227-228\n229-230-231\n232-233-234\n235-236-237\n238-239-240\n241-242-243\n244-245-246\n247-248-249\n250-251-252\n253-254-255\n256-257-258");
systems.VN.getTextbox().setText("Hello World\nHow are you?");
# systems.VN.getTextbox().setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras ut convallis nisl. Nulla eleifend erat non odio convallis tempus. Quisque sagittis egestas lacus, eget varius diam ullamcorper vel. Donec lacinia luctus turpis ac sodales. Praesent in quam maximus justo pretium iaculis. Morbi tristique nisi est, imperdiet volutpat velit semper congue. Nam eleifend ornare lorem eu ornare. Donec ac venenatis mauris. Etiam a purus a velit cursus pellentesque sed at neque. Proin viverra turpis ut lorem congue vestibulum. Proin a sapien id odio tempus tincidunt sed at lacus. Curabitur nisi nulla, porta ac magna sit amet, ornare elementum nisi. Proin convallis eget nisi ac vehicula. Mauris at consequat dolor, 1 2 3 4 5 pellentesque est. Nullam dapibus aliquet nisl eu porta. Quisque sagittis sem nec nibh tristique fermentum.
# Mauris eu nunc condimentum est rhoncus suscipit elementum sit amet felis. Morbi ut hendrerit ipsum. Cras vel sollicitudin odio. Maecenas eget finibus orci. Etiam tempus nulla vitae tincidunt aliquet. Nulla consectetur, massa sed rutrum iaculis, leo nulla bibendum erat, commodo rutrum magna lorem sit amet turpis. Morbi vel sollicitudin arcu, sit amet tempus leo. Nunc molestie sed dui eu fringilla. Mauris egestas lectus ac nisi condimentum, sollicitudin rhoncus arcu pellentesque. Vestibulum quis suscipit odio.
# Aenean ac metus nisi. Quisque et posuere ex. Vivamus et laoreet nulla. Nam quis faucibus diam. Aenean blandit dui sed est vehicula, sit amet dignissim mauris ultricies. Vivamus semper nisi vel erat dignissim interdum eu vitae enim. Nunc dignissim ligula imperdiet finibus dapibus. Pellentesque non erat sollicitudin libero convallis convallis. Nulla commodo, dolor aliquet laoreet lacinia, turpis lectus aliquet sem, et porttitor ipsum elit quis quam. Aliquam erat volutpat. Aliquam sit amet quam vel enim scelerisque blandit. Sed congue aliquam sodales.
# Pellentesque nec mauris id felis dignissim ullamcorper. Fusce quis ex accumsan, dictum risus vel, blandit ligula. Vestibulum at dolor ut neque faucibus rhoncus ac rhoncus risus. Nulla id semper dolor. In vel aliquam lectus. Morbi et dignissim augue. Nunc commodo elit at ligula ullamcorper iaculis. Morbi accumsan accumsan lectus, a iaculis magna. Nam auctor ac eros at venenatis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Duis et tincidunt lacus. Aliquam vitae quam et ipsum luctus tincidunt tincidunt eget sem. Morbi vestibulum ante mauris. Vestibulum ac faucibus quam. Vestibulum interdum odio nulla, nec pellentesque mi imperdiet ac.
# Morbi dictum mattis porttitor. Integer eu nulla maximus, vehicula urna at, iaculis odio. Nam feugiat, dui vitae imperdiet mattis, felis dui elementum risus, sed dapibus sem turpis quis mi. Sed lacinia vehicula risus, sed scelerisque enim euismod sed. Sed aliquet efficitur sapien vitae cursus. Phasellus non elit metus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque vitae tellus erat. Curabitur vel elit sagittis, dignissim orci at, vulputate lacus. Nam ut magna velit. Fusce sit amet tristique lacus.");
# systems.QUEST.QUEST_EXAMPLE.start();
func updateMovement(delta) -> void:
pass

View File

@@ -24,6 +24,7 @@ func getState() -> QuestState:
return questState;
func start():
print("Starting quest: " + questName);
questState = QuestState.ACTIVE;
currentObjective = 0;

View File

@@ -2,16 +2,18 @@ class_name Systems extends Node
const ItemSystem = preload("res://scripts/System/ItemSystem.gd");
const CutsceneSystem = preload("res://scripts/System/CutsceneSystem.gd");
const QuestSystem = preload("res://scripts/System/QuestSystem.gd");
const VNSystem = preload("res://scripts/System/VNSystem.gd");
var ITEM:ItemSystem;
var CUTSCENE:CutsceneSystem;
var QUEST:QuestSystem;
var VN:VNSystem;
func _ready():
ITEM = $Item;
CUTSCENE = $Cutscene;
QUEST = $Quest;
pass
VN = $VN;
func _process(delta):
pass

View File

@@ -0,0 +1,5 @@
class_name VNSystem extends Node
const VNTextbox = preload("res://scripts/UI/VNTextbox.gd")
func getTextbox() -> VNTextbox:
return get_tree().current_scene.get_node("UI/VNTextbox") as VNTextbox;

111
scripts/UI/VNTextbox.gd Normal file
View File

@@ -0,0 +1,111 @@
class_name VNTextbox extends PanelContainer
const VN_REVEAL_TIME = 0.01
const VISIBLE_LINES:int = 4
var label:RichTextLabel;
var text:String = ""
var parsedOutText = ""
var visibleCharacters:int = 0;
var revealTimer:float = 0;
var lineStarts:Array[int] = [];
var newlineIndexes:Array[int] = [];
var wrappedText:String = "";
var currentLine = 0;
var currentViewScrolled = true;
var isSpeedupDown = false;
var isMoreViews = false;
func _ready() -> void:
label = $MarginContainer/Label
func _process(delta: float) -> void:
if text == "":
return;
if currentViewScrolled:
if Input.is_action_just_pressed("interact"):
if isMoreViews:
visibleCharacters = 0;
currentLine += VISIBLE_LINES;
currentViewScrolled = false;
recalculateWrapping();
return
print("End of view");
return;
if visibleCharacters >= getCountOfCharactersToScrollInView():
currentViewScrolled = true;
print("Scrolled view");
if isMoreViews:
print("More views");
return;
if Input.is_action_just_pressed("interact"):
isSpeedupDown = true;
elif Input.is_action_just_released("interact"):
isSpeedupDown = false;
elif !Input.is_action_pressed("interact"):
isSpeedupDown = false;
revealTimer += delta;
if isSpeedupDown:
revealTimer += delta;
if revealTimer > VN_REVEAL_TIME:
revealTimer = 0;
visibleCharacters += 1;
label.visible_characters = visibleCharacters;
func getCountOfCharactersToScrollInView() -> int:
if lineStarts.size() <= VISIBLE_LINES:
return wrappedText.length();
if currentLine + VISIBLE_LINES >= lineStarts.size():
return wrappedText.length() - lineStarts[currentLine];
return lineStarts[min(lineStarts.size(), currentLine + VISIBLE_LINES)] - lineStarts[currentLine];
func recalculateWrapping():
# Reset label to default.
label.text = text;
label.visible_characters = -1;
label.fit_content = true;
isMoreViews = false;
# Determine where the wrapped newlines are
lineStarts = [ 0 ];
var line = 0;
var wasNewLine = false;
for i in range(0, text.length()):
var tLine = label.get_character_line(i);
if tLine == line:
wasNewLine = false
if text[i] == "\n":
wasNewLine = true
continue;
if !wasNewLine:
newlineIndexes.append(i);
lineStarts.append(i);
line = tLine;
# Create fake pre-wrapped text.
wrappedText = "";
for i in range(lineStarts[currentLine], text.length()):
if newlineIndexes.find(i) != -1 and i != lineStarts[currentLine]:
wrappedText += "\n";
wrappedText += text[i];
label.text = wrappedText;
label.fit_content = false;
label.visible_characters = 0;
if lineStarts.size() > currentLine + VISIBLE_LINES:
isMoreViews = true;
func setText(text:String) -> void:
self.text = text;
revealTimer = 0;
visibleCharacters = 0;
currentLine = 0;
currentViewScrolled = false;
recalculateWrapping();