Starting new VN Structure
This commit is contained in:
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
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user