#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 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 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(); }