Files
dl/project/dl_test/ui_sprite.cpp
T
2026-09-16 14:07:40 +08:00

692 lines
17 KiB
C++

#include "ui_sprite.h"
UISprite::UISprite()
{
UI::Panel* panel = CreatePanel("root");
panel->SetPosScale({ 0.0f, 0.0f });
panel->SetPosPixel(POS_CONTENT);
panel->SetLocator(createLocatorX(200, 3, 100));
UI::Panel* panel_menu = CreatePanel("menu");
panel_menu->SetLocator(createLocatorX(128, 4));
g_ui->SetPanelParent(panel_menu, panel);
{
UI::ButtonSprite* btn = g_ui->CreateButtonSpriteDefault(
UI::ButtonStyle::LONG);
btn->SetMode(UI::ButtonMode::RADIO);
btn->SetString("基础控制");
panel_menu->Add(btn);
}
{
UI::ButtonSprite* btn = g_ui->CreateButtonSpriteDefault(
UI::ButtonStyle::LONG);
btn->SetMode(UI::ButtonMode::RADIO);
btn->SetString("特效绘制");
panel_menu->Add(btn);
}
{
UI::ButtonSprite* btn = g_ui->CreateButtonSpriteDefault(
UI::ButtonStyle::LONG);
btn->SetMode(UI::ButtonMode::RADIO);
btn->SetString("层级嵌套");
panel_menu->Add(btn);
}
{
UI::ButtonSprite* btn = g_ui->CreateButtonSpriteDefault(
UI::ButtonStyle::LONG);
btn->SetMode(UI::ButtonMode::RADIO);
btn->SetString("性能测试");
panel_menu->Add(btn);
}
{
UI::ButtonSprite* btn = g_ui->CreateButtonSpriteDefault(
UI::ButtonStyle::LONG);
btn->SetMode(UI::ButtonMode::RADIO);
btn->SetString("瓦片地图");
panel_menu->Add(btn);
}
{
UI::ButtonSprite* btn = g_ui->CreateButtonSpriteDefault(
UI::ButtonStyle::LONG);
btn->SetMode(UI::ButtonMode::RADIO);
btn->SetString("帧动画");
panel_menu->Add(btn);
}
{
UI::ButtonSprite* btn = g_ui->CreateButtonSpriteDefault(
UI::ButtonStyle::LONG);
btn->SetMode(UI::ButtonMode::RADIO);
btn->SetString("粒子系统");
panel_menu->Add(btn);
}
_panelMenu = panel_menu;
//
{
UI::Panel* panel_base = CreatePanel("base");
panel_base->SetAutoRun(false);
panel_base->SetPosPixel({ 0, 320 });
panel_base->SetLocator(createLocatorY(32, 2, 64));
g_ui->SetPanelParent(panel_base, panel_menu);
std::array vec_control = { "X+", "X-", "Y+", "Y-", "S+", "S-", "R+", "R-", "A+", "A-" };
for (auto& iter : vec_control)
{
UI::ButtonSprite* btn = g_ui->CreateButtonSpriteDefault(
UI::ButtonStyle::NORMAL);
btn->SetString(iter);
panel_base->Add(btn);
}
_panelBase = panel_base;
_sprPanda = g_factory->CreateSprite("panda");
QuadParam p;
p._exAnchor = "center";
p._exScale = 0.25f;
_sprPanda->SetQuad(p);
_sprPanda->SetOrder(0.75f);
_sprPanda->CreateCoor();
_sprPanda->GetCoor()->SetParent(panel_menu->GetCoorRef());
_sprPanda->GetCoor()->SetPosition({ 233, 177 });
}
{
UI::Panel* panel = CreatePanel("link");
panel->SetAutoRun(false);
panel->SetPosPixel({ -150, 100 });
panel->SetLocator(createLocatorY(32, 2, 64));
g_ui->SetPanelParent(panel, panel_menu);
std::array vec_control = { "太阳为中心", "地球为中心" };
for (auto& iter : vec_control)
{
UI::ButtonSprite* btn = g_ui->CreateButtonSpriteDefault(
UI::ButtonStyle::NORMAL);
btn->SetString(iter);
btn->SetMode(UI::ButtonMode::RADIO);
panel->Add(btn);
}
{
UI::EditBox* edt = g_ui->CreateEditBoxDefault(true);
panel->Add(edt);
_edtSpeed = edt;
}
_panelLink = panel;
_sprSun = g_factory->CreateSprite("snowball");
_sprSun->CreateCoor();
_sprSun->GetCoor()->SetScale(4.0f);
_sprSun->SetColor(ColorDef::RED);
_sprSun->GetCoor()->SetParent(panel_menu->GetCoorRef());
_sprSun->GetCoor()->SetPosition({ 233, 177 });
_sprEarth = g_factory->CreateSprite("snowball");
_sprEarth->CreateCoor();
_sprEarth->GetCoor()->SetScale(0.5);
_sprEarth->SetColor(ColorDef::GREEN);
_sprMoon = g_factory->CreateSprite("snowball");
_sprMoon->CreateCoor();
_sprMoon->GetCoor()->SetScale(0.5f);
_sprMoon->SetColor(ColorDef::GRAY);
//
_sprEarth->GetCoor()->SetParent(_sprSun->GetCoor());
_sprEarth->GetCoor()->SetPosition({ 50, 0 });
_sprMoon->GetCoor()->SetParent(_sprEarth->GetCoor());
_sprMoon->GetCoor()->SetPosition({ 40, 0 });
_tMoon.Set(0.05f);
}
{
UI::Panel* panel = CreatePanel("effect");
panel->SetAutoRun(false);
panel->SetPosPixel({ 0, 320 });
panel->SetLocator(createLocatorY(32, 2, 64));
g_ui->SetPanelParent(panel, panel_menu);
std::array vec_control = { "Z+", "Z-", "A+", "A-" };
for (auto& iter : vec_control)
{
UI::ButtonSprite* btn = g_ui->CreateButtonSpriteDefault(
UI::ButtonStyle::NORMAL);
btn->SetString(iter);
panel->Add(btn);
}
_panelEffect = panel;
_sprBoard = g_factory->CreateSpriteDefault();
_sprBoard->SetQuad(createQuad(Size{500, 240}, false));
_sprBoard->SetOrder(0.75f);
_sprBoard->CreateCoor();
_sprBoard->GetCoor()->SetParent(panel_menu->GetCoorRef());
_sprBoard->GetCoor()->SetPosition({ 0, 60 });
_sprBoard->SetColor(ColorDef::BLACK);
_aniEffect = g_factory->CreateAnimation("effect.boom", "normal");
_aniEffect->SetBlend(Sprite::Blend::EFFECT);
_aniEffect->CreateCoor();
_aniEffect->GetCoor()->SetParent(panel_menu->GetCoorRef());
_aniEffect->GetCoor()->SetPosition({ 50 + 100 * 0, 177 });
_aniEffect->SetPlayCountMax(0);
_aniEffect->Play(g_time->GetFrameTkc());
_aniEffect->SetOrder(0.75f);
_aniEffectOver = g_factory->CloneAnimation(_aniEffect);
_aniEffectOver->SetOrder(0.65f);
_aniEffectOver->GetCoor()->SetPosition({ 50 + 100 * 1, 177 });
_aniEffectUnder = g_factory->CloneAnimation(_aniEffect);
_aniEffectUnder->SetOrder(0.85f);
_aniEffectUnder->GetCoor()->SetPosition({ 50 + 100 * 2, 177 });
_aniEffectColor = g_factory->CloneAnimation(_aniEffect);
_aniEffectColor->SetOrder(0.65f);
_aniEffectColor->SetColor(ColorDef::GREEN);
_aniEffectColor->GetCoor()->SetPosition({ 50 + 100 * 3, 177 });
_aniEffectAlpha = g_factory->CloneAnimation(_aniEffect);
_aniEffectAlpha->SetOrder(0.65f);
_aniEffectAlpha->SetColor(createColor(ColorDef::WHITE, 0.25f));
_aniEffectAlpha->GetCoor()->SetPosition({ 50 + 100 * 4, 177 });
_aniNormal = g_factory->CreateAnimation("ani.drink", "normal");
_aniNormal->CreateCoor();
_aniNormal->GetCoor()->SetParent(panel_menu->GetCoorRef());
_aniNormal->GetCoor()->SetPosition({ 165 + 100 * 0, 273 + 40 * 1 });
_aniNormal->SetPlayCountMax(0);
_aniNormal->Play(g_time->GetFrameTkc());
_aniNormal->SetOrder(0.75f);
_aniGray = g_factory->CloneAnimation(_aniNormal);
_aniGray->GetCoor()->SetPosition({ 165 + 100 * 1, 273 + 40 * 1 });
_aniGray->SetBlend(Sprite::Blend::GRAY);
}
//
{
UI::Panel* panel = CreatePanel("perormance");
panel->SetAutoRun(false);
panel->SetPosPixel({ 0, 320 });
panel->SetLocator(createLocatorY(32, 2, 64));
g_ui->SetPanelParent(panel, panel_menu);
std::array vec_control = { "+", "-" };
for (auto& iter : vec_control)
{
UI::ButtonSprite* btn = g_ui->CreateButtonSpriteDefault(
UI::ButtonStyle::NORMAL);
btn->SetString(iter);
panel->Add(btn);
}
std::array vec_switch = { "使用Coor", "绘制" };
for (auto& iter : vec_switch)
{
UI::ButtonSprite* btn = g_ui->CreateButtonSpriteDefault(
UI::ButtonStyle::SWITCH);
btn->SetString(iter);
panel->Add(btn);
}
_panelPerformance = panel;
}
_init_tile_map();
std::array<std::string, 6> arr_ani = {
"stand",
"run",
"attack",
"hit",
"death",
"roll"
};
for (auto& iter : arr_ani)
{
gcAnimation ani = g_factory->CreateAnimation("player", iter, 0);
ani->SetSampler(Sprite::Sampler::PIXEL);
ani->CreateCoor();
ani->GetCoor()->SetScale(2.0_f);
ani->GetCoor()->SetParent(panel_menu->GetCoorRef());
ani->GetCoor()->SetPosition({ 233, 177 });
if (iter == "stand")
ani->SetPlayCountMax(0);
_fsmAni.AddState(iter, ani);
}
_fsmAni.SetState("stand");
_txtAni = g_factory->CreateTextDefault();
_txtAni->GetCoor()->SetParent(_panelMenu->GetCoorRef());
_txtAni->GetCoor()->SetPosition({ 0, 100 });
{
_par = g_particle->Create("fire");
_par->SetPosition({ 400, 350 });
_par->SetSprite(g_factory->CreateSprite("particle.close7"));
_parMouse = g_particle->Create("mouse");
_parMouse->SetSprite(g_factory->CreateSprite("particle.tuowei"));
_parClick = g_particle->Create("click");
_parClick->SetSprite(g_factory->CreateSprite("particle.coin"));
}
}
UISprite::~UISprite()
{
g_particle->Delete(_par);
g_particle->Delete(_parMouse);
g_particle->Delete(_parClick);
}
void UISprite::Update()
{
size_t index = _panelMenu->GetSelectIndex();
if (index == 0)
_update_base();
else if (index == 1)
_update_effect();
else if (index == 2)
_udpate_link();
else if (index == 3)
_update_performance();
else if (index == 4)
_update_tile();
else if (index == 5)
_update_animation();
else if (index == 6)
_update_particle();
}
constexpr Position SIZE_MAP_NODE = { 32, 32 };
void UISprite::_update_base()
{
_panelBase->Update();
size_t i = _panelBase->GetDownIndex();
Float speed = 100 * g_time->GetDelta();
Float speed_scale = 1.0_f * g_time->GetDelta();
Float speed_rotate = (Float)Math::PI(1) * g_time->GetDelta();
Float speed_alpha = 0.2_f * g_time->GetDelta();
if (i == 0)
_sprPanda->GetCoor()->DtPosition({ speed, 0 });
else if (i == 1)
_sprPanda->GetCoor()->DtPosition({ -speed, 0 });
else if (i == 2)
_sprPanda->GetCoor()->DtPosition({ 0, speed });
else if (i == 3)
_sprPanda->GetCoor()->DtPosition({ 0, -speed });
else if (i == 4)
_sprPanda->GetCoor()->DtScale(speed_scale);
else if (i == 5)
_sprPanda->GetCoor()->DtScale(-speed_scale);
else if (i == 6)
_sprPanda->GetCoor()->DtRotate(speed_rotate);
else if (i == 7)
_sprPanda->GetCoor()->DtRotate(-speed_rotate);
else if (i == 8)
_sprPanda->SetColor(_sprPanda->GetColor() + Color{ 0, 0, 0, speed_alpha });
else if (i == 9)
_sprPanda->SetColor(_sprPanda->GetColor() + Color{ 0, 0, 0, -speed_alpha });
_sprPanda->Render();
if (_sprPanda->IsPickup())
{
_sprPandaEffect = g_factory->CloneSprite(_sprPanda);
_sprPandaEffect->SetBright(1.25f);
_sprPandaEffect->Render();
}
}
void UISprite::_update_effect()
{
_panelEffect->Update();
size_t i = _panelEffect->GetDownIndex();
Float speed = 100 * g_time->GetDelta();
Float speed_order = 1.0_f * g_time->GetDelta();
Float speed_alpha = 0.2_f * g_time->GetDelta();
if (i == 0)
_sprBoard->SetOrder(_sprBoard->GetOrder() + speed_order);
else if (i == 1)
_sprBoard->SetOrder(_sprBoard->GetOrder() - speed_order);
else if (i == 2)
_sprBoard->SetColor(_sprBoard->GetColor() + Color{ 0, 0, 0, speed_alpha });
else if (i == 3)
_sprBoard->SetColor(_sprBoard->GetColor() + Color{ 0, 0, 0, -speed_alpha });
_sprBoard->Render();
gcText txt = g_factory->RenderText();
txt->GetCoor()->SetParent(_sprBoard->GetCoor());
txt->SetString(fmt::format("z: {}\na: {}", _sprBoard->GetOrder(), _sprBoard->GetColor()[3]));
txt->SetOrder(0.1f);
txt->SetColor(ColorDef::GREEN);
_aniEffect->Render();
_aniEffectOver->Render();
_aniEffectUnder->Render();
_aniEffectColor->Render();
_aniEffectAlpha->Render();
_aniNormal->Render();
_aniGray->Render();
auto fn_render_text = [](gcAnimation ani) {
gcText txt = g_factory->RenderText();
txt->GetCoor()->SetParent(ani->GetCoor());
txt->SetString(fmt::format("z: {}\na: {}", ani->GetOrder(), ani->GetColor()[3]));
txt->SetOrder(0.1f);
};
fn_render_text(_aniEffect);
fn_render_text(_aniEffectOver);
fn_render_text(_aniEffectUnder);
fn_render_text(_aniEffectColor);
fn_render_text(_aniEffectAlpha);
fn_render_text(_aniNormal);
fn_render_text(_aniGray);
}
void UISprite::_udpate_link()
{
_panelLink->Update();
static float k = 1;
if (_edtSpeed->IsChange())
{
k = String::toFloat(_edtSpeed->GetString());
if(k != 0)
_tMoon.Set(0.05f / k);
}
_sprSun->GetCoor()->DtRotate(g_time->GetDelta() * Math::PIF(1, 4) * k);
_sprEarth->GetCoor()->DtRotate(g_time->GetDelta() * Math::PIF(1, 4) * 1.5f * k);
_sprMoon->GetCoor()->DtRotate(g_time->GetDelta() * Math::PIF(1, 4) * 2.0f * k);
_sprSun->Render();
_sprEarth->Render();
_sprMoon->Render();
if (_tMoon.Run(g_time->GetDelta()))
{
_allMoonPos.push_back(_sprMoon->GetCoor()->ThisToWorld({}));
}
g_gfx->SetCoor(nullptr);
g_gfx->SetColor(ColorDef::WHITE);
for (auto& iter : _allMoonPos)
{
g_gfx->Dot2D(iter);
}
}
void UISprite::_update_performance()
{
_panelPerformance->Update();
size_t i = _panelPerformance->GetClickIndex();
if (i == 0)
_add_test();
else if (i == 1)
_del_test();
_bUseCoor = _panelPerformance->ExGetButton(2)->IsSelect();
_bRender = _panelPerformance->ExGetButton(3)->IsSelect();
Position size_window = toPosition(g_system->GetWindowSize());
for (auto& ball : _vecBall)
{
Position pos;
Position pos_dt = ball._v * g_time->GetDelta();
if (_bUseCoor)
{
if (!ball._spr->IsOwnCoor())
{
ball._spr->CreateCoor();
ball._spr->GetCoor()->SetPosition(toPosition(g_system->GetWindowSize() / 2u));
ball._spr->GetCoor()->SetRotate(Random::Float(0.0f, (float)Math::PI(2)));
ball._spr->GetCoor()->SetScale(Random::Float(0.5f, 2.0f));
}
pos = ball._spr->GetCoor()->GetPosition();
}
else
{
if (ball._spr->IsOwnCoor())
{
ball._spr->DeleteCoor();
}
pos = ball._pos;
}
Position pos_next = pos + pos_dt;
if (pos_next[0] < 0)
{
ball._v[0] = -ball._v[0];
pos_next[0] = 0;
}
else if (pos_next[0] > size_window[0])
{
ball._v[0] = -ball._v[0];
pos_next[0] = size_window[0];
}
if (pos_next[1] < 0)
{
ball._v[1] = -ball._v[1];
pos_next[1] = 0;
}
else if (pos_next[1] > size_window[1])
{
ball._v[1] = -ball._v[1];
pos_next[1] = size_window[1];
}
if (_bUseCoor)
ball._spr->GetCoor()->SetPosition(pos_next);
else
{
ball._pos = pos_next;
ball._spr->//SetQuad(ball._spr->GetQuad() + pos_next - pos);
DtQuadOffset(pos_next - pos);
}
if (_bRender)
{
ball._spr->Render();
}
}
if (!_bRender)
{
gcText txt = g_factory->RenderText();
txt->GetCoor()->SetPosition(toPosition(g_input->GetCursorPosition()));
txt->SetString(fmt::format("ball num: {}", _vecBall.size()));
}
}
void UISprite::_add_test()
{
std::vector<std::string> vec = g_factory->GetFolderAllSpriteName("icon");
for (size_t i = 0; i < 5000; ++i)
{
Ball ball;
Float v = Random::Float(0_f, 100.0_f);
Float direction = Random::Float(0_f, (Float)Math::PI(2));
// 初速度
ball._v[0] = v * cos(direction);
ball._v[1] = v * sin(direction);
ball._spr = g_factory->CreateSprite(Random::Select(vec));
ball._spr->SetOrder(0.95f);
if (_bUseCoor)
{
ball._spr->CreateCoor();
ball._spr->GetCoor()->SetPosition(toPosition(g_system->GetWindowSize() / 2u));
ball._spr->GetCoor()->SetRotate(Random::Float(0.0f, (float)Math::PI(2)));
ball._spr->GetCoor()->SetScale(Random::Float(0.5f, 2.0f));
}
else
{
ball._pos = toPosition(g_system->GetWindowSize() / 2u);
}
_vecBall.push_back(ball);
}
}
void UISprite::_init_tile_map()
{
_txtTileMap = g_ui->CreateTextDefault();
_txtTileMap->GetCoor()->SetPosition({ 317, 200 });
GetPanelRoot()->Add(_txtTileMap);
_coorTileMap = g_factory->GetRootCoor(1);
_coorTileMap->SetPosition(toPosition(g_system->GetWindowSize() / 2u));
_tileMap.Resize({ 10, 10 });
for (unsigned j = 0; j < _tileMap.GetHeight(); ++j)
{
for (unsigned i = 0; i < _tileMap.GetWidth(); ++i)
{
MapNode& node = _tileMap.GetRef(j, i);
node._spr = g_factory->CreateSpriteRandom("tile.all");
node._spr->SetSampler(Sprite::Sampler::PIXEL);
node._spr->SetQuad(node._spr->GetQuad() + toPosition(i, j) * SIZE_MAP_NODE);
node._spr->SetCoor(_coorTileMap);
}
}
}
void UISprite::_update_tile()
{
Position dt_scroll = g_input->GetScrollDelta();
float s = dt_scroll[1];
//log_msg("{}", to_string(dt_scroll));
if (s)
{
_coorTileMap->DtScale(s * 0.1f);
_txtTileMap->SetString(fmt::format("缩放:{}",
_coorTileMap->GetScale()[0]));
}
for (MapNode& node : _tileMap)
{
node._spr->Render();
}
}
void UISprite::_update_animation()
{
static size_t count_attack = 0;
bool run = g_input->KeyState(KeyCode::A)
|| g_input->KeyState(KeyCode::S)
|| g_input->KeyState(KeyCode::D)
|| g_input->KeyState(KeyCode::W);
bool attack = g_input->KeyState(KeyCode::J);
bool roll = g_input->KeyState(KeyCode::SPACE);
if (attack)
run = false;
if (roll)
{
run = false;
attack = false;
}
auto fn_attack = [&]() {
count_attack++;
if (count_attack < 3)
_fsmAni.SetState("attack");
else if (count_attack < 5)
_fsmAni.SetState("hit");
else
{
count_attack = 0;
_fsmAni.SetState("death");
}
};
if (_fsmAni._state == "stand")
{
if (attack)
fn_attack();
else if (run)
_fsmAni.SetState("run");
else if (roll)
_fsmAni.SetState("roll");
}
else if (_fsmAni._state == "death")
{
if (run)
_fsmAni.SetState("stand");
}
else
{
gcAnimation cur = _fsmAni.GetAnimaitonCurrent();
if (cur->IsPlayEnd())
{
if (cur->GetName() == "player:run")
{
if (run)
_fsmAni.SetState("run");
else
_fsmAni.SetState("stand");
}
else if (cur->GetName() == "player:attack")
{
if (attack)
fn_attack();
else
_fsmAni.SetState("stand");
}
else
{
if (_fsmAni._state != "death")
_fsmAni.SetState("stand");
}
}
}
_fsmAni.Render();
gcAnimation cur = _fsmAni.GetAnimaitonCurrent();
if (cur)
{
_txtAni->SetString(cur->Dump(g_time->GetFrameTkc()));
_txtAni->Render();
}
gcText txt = g_factory->RenderText();
txt->GetCoor()->SetParent(_panelMenu->GetCoorRef());
txt->GetCoor()->SetPosition({ 0, 300 });
txt->SetString("wasd移动,j攻击,space滚动");
}
void UISprite::_update_particle()
{
if (g_input->KeyDown(MouseCode::LEFT))
{
_parClick->Replay();
}
_parMouse->SetPositionEmitter(g_input->GetCursorPos());
_parClick->SetPositionEmitter(g_input->GetCursorPos());
_par->Render();
_parMouse->Render();
_parClick->Render();
}