Starting new VN Structure
This commit is contained in:
11
archive/visualnovel/ui/CMakeLists.txt
Normal file
11
archive/visualnovel/ui/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
# Copyright (c) 2022 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
VisualNovelFader.cpp
|
||||
VisualNovelTextbox.cpp
|
||||
)
|
25
archive/visualnovel/ui/VisualNovelFader.cpp
Normal file
25
archive/visualnovel/ui/VisualNovelFader.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "VisualNovelFader.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
VisualNovelFader::VisualNovelFader(UICanvas *canvas) : UISprite(canvas) {
|
||||
|
||||
}
|
||||
|
||||
VisualNovelFader * VisualNovelFader::create(UICanvas *canvas) {
|
||||
assertNotNull(canvas);
|
||||
|
||||
auto item = canvas->addElement<VisualNovelFader>();
|
||||
item->setTransform(
|
||||
UI_COMPONENT_ALIGN_STRETCH, UI_COMPONENT_ALIGN_STRETCH,
|
||||
glm::vec4(0, 0, 0, 0),
|
||||
0.0f
|
||||
);
|
||||
item->color = COLOR_BLACK_TRANSPARENT;
|
||||
return item;
|
||||
}
|
32
archive/visualnovel/ui/VisualNovelFader.hpp
Normal file
32
archive/visualnovel/ui/VisualNovelFader.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "ui/UISprite.hpp"
|
||||
#include "ui/UIEmpty.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class VisualNovelFader : public UISprite {
|
||||
private:
|
||||
|
||||
public:
|
||||
/**
|
||||
* Quickly create a visual novel fader.
|
||||
*
|
||||
* @param canvas Canvas the fader belongs to.
|
||||
* @return Created VN Fader.
|
||||
*/
|
||||
static VisualNovelFader * create(UICanvas *canvas);
|
||||
|
||||
/**
|
||||
* Construct a new Visual Novel Fader. VN Fader is just a sprite that is
|
||||
* easily found by the VN Manager for the purpose of adding transitions to
|
||||
* a VN scene.
|
||||
*
|
||||
* @param canvas Canvas for this component.
|
||||
*/
|
||||
VisualNovelFader(UICanvas *canvas);
|
||||
};
|
||||
}
|
250
archive/visualnovel/ui/VisualNovelTextbox.cpp
Normal file
250
archive/visualnovel/ui/VisualNovelTextbox.cpp
Normal file
@ -0,0 +1,250 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "VisualNovelTextbox.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
#include "visualnovel/VisualNovelManager.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
VisualNovelTextbox::VisualNovelTextbox(UICanvas *canvas) :
|
||||
UIComponent(canvas),
|
||||
selfParent(canvas),
|
||||
border(canvas),
|
||||
label(canvas)
|
||||
{
|
||||
// Self Parent
|
||||
this->selfParent.setTransform(
|
||||
UI_COMPONENT_ALIGN_STRETCH, UI_COMPONENT_ALIGN_STRETCH,
|
||||
glm::vec4(0, 0, 0, 0),
|
||||
0.0f
|
||||
);
|
||||
|
||||
// Border
|
||||
this->selfParent.addChild(&this->border);
|
||||
this->border.setTransform(
|
||||
UI_COMPONENT_ALIGN_STRETCH, UI_COMPONENT_ALIGN_STRETCH,
|
||||
glm::vec4(0, 0, 0, 0),
|
||||
0.0f
|
||||
);
|
||||
|
||||
// Label
|
||||
this->selfParent.addChild(&this->label);
|
||||
this->label.startQuad = 0;
|
||||
this->label.quadCount = 0;
|
||||
|
||||
this->canvas->getScene()->eventSceneUnpausedUpdate.addListener(
|
||||
this, &VisualNovelTextbox::textboxOnSceneUpdate
|
||||
);
|
||||
}
|
||||
|
||||
void VisualNovelTextbox::show() {
|
||||
if(this->isVisible()) return;
|
||||
this->visible = true;
|
||||
this->addChild(&this->selfParent);
|
||||
|
||||
if(this->talkSound != nullptr) {
|
||||
auto vnManager = this->getVisualNovelManager();
|
||||
assertNotNull(vnManager);
|
||||
assertNotNull(vnManager->audioCharacter);
|
||||
|
||||
vnManager->audioCharacter->stop();
|
||||
vnManager->audioCharacter->setAudioData(this->talkSound);
|
||||
vnManager->audioCharacter->loop = true;
|
||||
vnManager->audioCharacter->play();
|
||||
}
|
||||
}
|
||||
|
||||
void VisualNovelTextbox::hide() {
|
||||
if(!this->isVisible()) return;
|
||||
|
||||
if(this->talkSound != nullptr) {
|
||||
auto vnManager = this->getVisualNovelManager();
|
||||
assertNotNull(vnManager);
|
||||
assertNotNull(vnManager->audioCharacter);
|
||||
vnManager->audioCharacter->stop();
|
||||
}
|
||||
|
||||
this->visible = false;
|
||||
this->removeChild(&this->selfParent);
|
||||
this->eventHidden.invoke();
|
||||
}
|
||||
|
||||
bool_t VisualNovelTextbox::isVisible() {
|
||||
return this->visible;
|
||||
}
|
||||
|
||||
VisualNovelManager * VisualNovelTextbox::getVisualNovelManager() {
|
||||
return this->getScene()->findComponent<VisualNovelManager>();
|
||||
}
|
||||
|
||||
void VisualNovelTextbox::updatePositions() {
|
||||
UIComponent::updatePositions();
|
||||
|
||||
this->lineCurrent = 0;
|
||||
this->timeCharacter = 0;
|
||||
|
||||
this->label.setTransform(
|
||||
UI_COMPONENT_ALIGN_STRETCH,
|
||||
UI_COMPONENT_ALIGN_STRETCH,
|
||||
glm::vec4(
|
||||
this->border.getBorderSize() + this->labelPadding,
|
||||
this->border.getBorderSize() + this->labelPadding
|
||||
),
|
||||
1.0f
|
||||
);
|
||||
|
||||
this->label.startQuad = 0;
|
||||
this->label.quadCount = 0;
|
||||
}
|
||||
|
||||
void VisualNovelTextbox::textboxOnSceneUpdate() {
|
||||
DawnGame *game = this->canvas->getGame();
|
||||
|
||||
if(this->hasRevealedAllCurrentCharacters()) {
|
||||
if(this->hasRevealedAllCharacters()) {
|
||||
if(game->inputManager.isPressed(INPUT_BIND_ACCEPT)) {
|
||||
this->hide();
|
||||
}
|
||||
} else {
|
||||
if(game->inputManager.isPressed(INPUT_BIND_ACCEPT)) {
|
||||
this->lineCurrent += this->getCountOfVisibleLines();
|
||||
this->label.startQuad = 0;
|
||||
for(int32_t i = 0; i < this->lineCurrent; i++) {
|
||||
this->label.startQuad += this->label.measure.getQuadsOnLine(i);
|
||||
}
|
||||
this->label.quadCount = 0;
|
||||
this->timeCharacter = 0.0f;
|
||||
|
||||
this->label.setTransform(
|
||||
UI_COMPONENT_ALIGN_STRETCH,
|
||||
UI_COMPONENT_ALIGN_STRETCH,
|
||||
glm::vec4(
|
||||
glm::vec2(
|
||||
this->border.getBorderSize().x + this->labelPadding.x,
|
||||
this->border.getBorderSize().y + this->labelPadding.y -
|
||||
this->label.measure.getHeightOfLineCount(this->lineCurrent)
|
||||
),
|
||||
this->border.getBorderSize() + this->labelPadding
|
||||
),
|
||||
5.0f
|
||||
);
|
||||
this->eventNewPage.invoke();
|
||||
}
|
||||
}
|
||||
|
||||
if(this->talkSound != nullptr) {
|
||||
auto vnManager = this->getVisualNovelManager();
|
||||
assertNotNull(vnManager);
|
||||
assertNotNull(vnManager->audioCharacter);
|
||||
vnManager->audioCharacter->stop();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
auto lastTimeCharacter = mathFloor<int32_t>(this->timeCharacter);
|
||||
if(game->inputManager.isDown(INPUT_BIND_ACCEPT)) {
|
||||
this->timeCharacter += game->timeManager.delta * VISUAL_NOVEL_TEXTBOX_SPEED_FASTER;
|
||||
} else {
|
||||
this->timeCharacter += game->timeManager.delta * VISUAL_NOVEL_TEXTBOX_SPEED;
|
||||
}
|
||||
auto newTimeCharacter = mathFloor<int32_t>(this->timeCharacter);
|
||||
if(newTimeCharacter == lastTimeCharacter) return;
|
||||
|
||||
this->label.quadCount = newTimeCharacter;
|
||||
this->eventCharacterRevealed.invoke();
|
||||
}
|
||||
|
||||
int32_t VisualNovelTextbox::getCountOfVisibleLines() {
|
||||
int32_t i = 1;
|
||||
glm::vec2 innerSize = this->border.getInnerSize() - this->labelPadding;
|
||||
|
||||
for(i = this->label.measure.getLineCount(); i > 0; --i) {
|
||||
if(innerSize.y >= this->label.measure.getHeightOfLineCount(i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return this->label.measure.getLineCount();
|
||||
}
|
||||
|
||||
std::vector<struct ShaderPassItem> VisualNovelTextbox::getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) {
|
||||
return std::vector<struct ShaderPassItem>();
|
||||
}
|
||||
|
||||
void VisualNovelTextbox::setFont(Font *font) {
|
||||
this->label.setFont(font);
|
||||
this->label.updateMesh();
|
||||
}
|
||||
|
||||
void VisualNovelTextbox::setText(std::string key, float_t fontSize) {
|
||||
this->label.setText(key);
|
||||
this->label.setFontSize(fontSize);
|
||||
this->label.updateMesh();
|
||||
}
|
||||
|
||||
void VisualNovelTextbox::setCharacter(VisualNovelCharacter *character) {
|
||||
this->character = character;
|
||||
this->talkSound = nullptr;
|
||||
}
|
||||
|
||||
void VisualNovelTextbox::setTalkingSound(AudioAsset *asset) {
|
||||
this->talkSound = asset;
|
||||
}
|
||||
|
||||
void VisualNovelTextbox::setText(std::string key) {
|
||||
this->label.setText(key);
|
||||
this->label.updateMesh();
|
||||
}
|
||||
|
||||
void VisualNovelTextbox::setFontSize(float_t fontSize) {
|
||||
this->label.setFontSize(fontSize);
|
||||
this->label.updateMesh();
|
||||
}
|
||||
|
||||
float_t VisualNovelTextbox::getFontSize() {
|
||||
return this->label.getFontSize();
|
||||
}
|
||||
|
||||
void VisualNovelTextbox::setLabelPadding(glm::vec2 padding) {
|
||||
this->labelPadding = padding;
|
||||
this->updatePositions();
|
||||
}
|
||||
|
||||
glm::vec2 VisualNovelTextbox::getLabelPadding() {
|
||||
return this->labelPadding;
|
||||
}
|
||||
|
||||
bool_t VisualNovelTextbox::hasRevealedAllCurrentCharacters() {
|
||||
int32_t quadsTotal = 0;
|
||||
for(
|
||||
int32_t i = this->lineCurrent;
|
||||
i < mathMin<int32_t>(
|
||||
this->label.measure.getLineCount(),
|
||||
this->lineCurrent + this->getCountOfVisibleLines()
|
||||
);
|
||||
i++
|
||||
) {
|
||||
quadsTotal += this->label.measure.getQuadsOnLine(i);
|
||||
}
|
||||
return mathFloor<int32_t>(this->timeCharacter) >= quadsTotal;
|
||||
}
|
||||
|
||||
bool_t VisualNovelTextbox::hasRevealedAllCharacters() {
|
||||
return (
|
||||
this->lineCurrent + this->getCountOfVisibleLines() >=
|
||||
this->label.measure.getLineCount()
|
||||
);
|
||||
}
|
||||
|
||||
VisualNovelTextbox::~VisualNovelTextbox() {
|
||||
this->canvas->getScene()->eventSceneUnpausedUpdate.removeListener(
|
||||
this, &VisualNovelTextbox::textboxOnSceneUpdate
|
||||
);
|
||||
}
|
167
archive/visualnovel/ui/VisualNovelTextbox.hpp
Normal file
167
archive/visualnovel/ui/VisualNovelTextbox.hpp
Normal file
@ -0,0 +1,167 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "ui/UISprite.hpp"
|
||||
#include "ui/UIBorder.hpp"
|
||||
#include "ui/UILabel.hpp"
|
||||
#include "ui/UIEmpty.hpp"
|
||||
#include "util/mathutils.hpp"
|
||||
#include "visualnovel/components/VisualNovelCharacter.hpp"
|
||||
|
||||
#define VISUAL_NOVEL_TEXTBOX_SPEED 25.0f
|
||||
#define VISUAL_NOVEL_TEXTBOX_SPEED_FASTER 40.0f
|
||||
|
||||
namespace Dawn {
|
||||
class VisualNovelManager;
|
||||
|
||||
class VisualNovelTextbox : public UIComponent {
|
||||
private:
|
||||
int32_t lineCurrent = 0;
|
||||
glm::vec2 labelPadding = glm::vec2(0, 0);
|
||||
UIEmpty selfParent;
|
||||
float_t timeCharacter = 0.0f;
|
||||
bool_t visible = false;
|
||||
VisualNovelCharacter *character = nullptr;
|
||||
AudioAsset *talkSound = nullptr;
|
||||
|
||||
void updatePositions() override;
|
||||
|
||||
std::vector<struct ShaderPassItem> getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) override;
|
||||
|
||||
/**
|
||||
* Listens for scene updates.
|
||||
*/
|
||||
void textboxOnSceneUpdate();
|
||||
|
||||
/**
|
||||
* Returns the count of visible lines within the textbox. Mostly used for
|
||||
* when we need to decide how to wrap.
|
||||
*
|
||||
* @return The count of visible lines.
|
||||
*/
|
||||
int32_t getCountOfVisibleLines();
|
||||
|
||||
public:
|
||||
UIBorder border;
|
||||
UILabel label;
|
||||
|
||||
Event<> eventCharacterRevealed;
|
||||
Event<> eventCurrentCharactersRevealed;
|
||||
Event<> eventNewPage;
|
||||
Event<> eventAllCharactersRevealed;
|
||||
Event<> eventHidden;
|
||||
Event<> eventVisible;
|
||||
|
||||
/**
|
||||
* Constructs a VN Textbox.
|
||||
*
|
||||
* @param canvas Canvas that this textbox belongs to.
|
||||
*/
|
||||
VisualNovelTextbox(UICanvas *canvas);
|
||||
|
||||
void show();
|
||||
void hide();
|
||||
bool_t isVisible();
|
||||
|
||||
/**
|
||||
* Returns the visual novel manager (if applicable).
|
||||
*
|
||||
* @return Visual Novel Manager instance.
|
||||
*/
|
||||
VisualNovelManager * getVisualNovelManager();
|
||||
|
||||
/**
|
||||
* Sets the font for this vn textbox. Passed to the underlying label.
|
||||
*
|
||||
* @param font Font to set for this textbox.
|
||||
*/
|
||||
void setFont(Font *font);
|
||||
|
||||
/**
|
||||
* Sets the string (label) for this textbox.
|
||||
*
|
||||
* @param text Localized string key to set.
|
||||
* @param fontSize Font size of the string.
|
||||
*/
|
||||
void setText(std::string key, float_t fontSize);
|
||||
|
||||
/**
|
||||
* Sets the string (label) for this textbox.
|
||||
*
|
||||
* @param text Localized string key to set.
|
||||
*/
|
||||
void setText(std::string key);
|
||||
|
||||
/**
|
||||
* Sets the VN Character for this text.
|
||||
*
|
||||
* @param character Character to set.
|
||||
*/
|
||||
void setCharacter(VisualNovelCharacter *character);
|
||||
|
||||
/**
|
||||
* Set the sound to use whenever the text is scrolling to represent a
|
||||
* character talking.
|
||||
*
|
||||
* @param sound Sound asset to use.
|
||||
*/
|
||||
void setTalkingSound(AudioAsset *sound);
|
||||
|
||||
/**
|
||||
* Sets the font size to use.
|
||||
*
|
||||
* @param fontSize Font size to use.
|
||||
*/
|
||||
void setFontSize(float_t fontSize);
|
||||
|
||||
/**
|
||||
* Returns the current font size.
|
||||
*
|
||||
* @return Font size.
|
||||
*/
|
||||
float_t getFontSize();
|
||||
|
||||
/**
|
||||
* Sets the padding of the label. This will increase the spacing between
|
||||
* the text and the border.
|
||||
*
|
||||
* @param padding Padding to set.
|
||||
*/
|
||||
void setLabelPadding(glm::vec2 padding);
|
||||
|
||||
/**
|
||||
* Returns the current label padding.
|
||||
*
|
||||
* @return The current label padding.
|
||||
*/
|
||||
glm::vec2 getLabelPadding();
|
||||
|
||||
/**
|
||||
* Returns true if all of the characters that can be made visible for the
|
||||
* current textbox size have finished revealing, or false if not.
|
||||
*
|
||||
* @return True if above statement is met.
|
||||
*/
|
||||
bool_t hasRevealedAllCurrentCharacters();
|
||||
|
||||
/**
|
||||
* Returns true only when every character passed previously in setText
|
||||
* has been revealed by scrolling.
|
||||
*
|
||||
* @return True if above statement is true.
|
||||
*/
|
||||
bool_t hasRevealedAllCharacters();
|
||||
|
||||
/**
|
||||
* Cleans the VN Textbox.
|
||||
*/
|
||||
~VisualNovelTextbox();
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user