Главная | Регистрация | Вход Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
HUD элемент с обработкой сообщений из собственной энтити
d00mt3amДата: Четверг, 29.01.2009, 17:40 | Сообщение # 1
Капитан Команды
Группа: ADMIN
Сообщений: 40
Репутация: 7
Статус: Offline
В данном учебнике будет рассмотрен процесс создания собственного HUD элемента для вывода простого текстового сообщения.
Сообщение будет отправлятся при помощи простой энтити на стороне сервера при помощи HUD-сообщения.
Также будет создана консольная переменная и комманда отвечающая за отображение элемента и присвоена новая клавиша для включения/выключения отображения данного элемента.
1. Создаем класс на стороне клиента
Для начала определимся с названием HUD элемента - пусть для данного учебника он будет HudMyTest, при создании собственного класса следуя общепринятой логике называем его добавляя букву C.
Создаем новый файл HudMyTest.cpp:

//Класс HUD элемента HudMyTest

#include "cbase.h"
#include "hud.h"
#include "hudelement.h"
#include "hud_macros.h"

#include <vgui_controls/Panel.h>
#include <vgui_controls/Frame.h>
#include <vgui/IScheme.h>
#include <vgui_controls/Label.h>
#include "iclientmode.h"

using namespace vgui;

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

//Объявление класса
class CHudMyTest : public CHudElement , public vgui::Panel
{
DECLARE_CLASS_SIMPLE( CHudMyTest, vgui::Panel );
public:
CHudMyTest( const char *pElementName ); //конструктор
void Init( void ); //вызывается сразу после создания элемента
void VidInit( void ); //тоже что и Init только вызывается один раз при загрузке карты
void Reset(); //вызывается при сбросе HUD
void Paint( void ); //данный метод вызывается в каждом фрейме, для отрисовки элемента на экране
void OnThink(void); //также вызывается в каждом фрейме, для обновления информации
void MsgFunc_MyTxtMessage( bf_read &msg );
private:
vgui::Label *m_pTxtLabel; //Ярлык с названием элемента
vgui::HScheme scheme; //Объект схемы для использования информации из схем
char m_pText[1024];
//C_BasePlayer *player; //указатель на объект игрока
};

//Регистрация класса для HUD элемента
DECLARE_HUDELEMENT( CHudMyTest );
//Регистрация приемника сообщений
DECLARE_HUD_MESSAGE( CHudMyTest, MyTxtMessage );

//Имплементация конструктора
CHudMyTest::CHudMyTest( const char *pElementName ) : CHudElement( pElementName ), vgui::Panel( NULL, "HudMyTest" )
{
//Установка бита отображения
SetHiddenBits( HIDEHUD_ALL );
//можно использовать комбинацию задающую условие при котором будет видимым наш элемент,
//например: HIDEHUD_NEEDSUIT | HIDEHUD_PLAYERDEAD устанавливает невидимость в случае отсутствия HEV-костюма и смерти игрока

//Загрузка и применение схемы для данного элемента
scheme = vgui::scheme()->LoadSchemeFromFile("resource/ClientScheme.res", "ClientScheme");
SetScheme(scheme);

//Установка родителя в иерархии экрана
vgui::Panel *pParent = g_pClientMode->GetViewport();
SetParent( pParent );

//Создание ярлыка для отображения текста
m_pTxtLabel = vgui::SETUP_PANEL(new vgui::Label(this,"NameLabel",""));

//Применение схемы к ярлыку
m_pTxtLabel->SetScheme(scheme);
//установка шрифта
m_pTxtLabel->SetFont(vgui::scheme()->GetIScheme(scheme)->GetFont("Default"));

//Не использовать ввод с клавиатуры и мыши
m_pTxtLabel->SetKeyBoardInputEnabled(false);
m_pTxtLabel->SetMouseInputEnabled(false);

//Установка расположения и размера
m_pTxtLabel->SetPos(0,0);
m_pTxtLabel->SetSize(GetWide(),GetTall());

//Не отображать фон и рамку
m_pTxtLabel->SetPaintBackgroundEnabled( false );
m_pTxtLabel->SetPaintBorderEnabled( false );

//Установка выравнивания текста, a_northwest означает влево-вверх
m_pTxtLabel->SetContentAlignment( vgui::Label::a_northwest );

//Прозрачный фон
SetPaintBackgroundEnabled( false );
SetBgColor(Color(0,0,0,0));
m_pTxtLabel->SetBgColor(Color(0,0,0,0));
}

//Имплементация других методов

void CHudMyTest::Init( void )
{
//Устанавливаем перехват сообщений
HOOK_HUD_MESSAGE( CHudMyTest, MyTxtMessage );
Reset();
}

void CHudMyTest::VidInit( void )
{
Reset();
}

void CHudMyTest::Reset( void )
{
//стираем содержимое текста
sprintf(m_pText, "Empty");
}

void CHudMyTest::Paint( void )
{
//определяем требуется ли отображать элемент
ConVar *is_vis = cvar->FindVar( "myhud_visible" );
if(!is_vis->GetBool()) return;
//записать текст
m_pTxtLabel->SetText(m_pText);
//сделать видимым
m_pTxtLabel->SetVisible(true);
//реорганизовать размеры к новому тексту
m_pTxtLabel->SizeToContents();
m_pTxtLabel->SetSize(GetWide(), GetTall());
//установить цвет
m_pTxtLabel->SetFgColor(Color(255,255,240,255));
}

void CHudMyTest::OnThink(void)
{
//определяем требуется ли изменить видимость элемента
ConVar *is_vis = cvar->FindVar( "myhud_visible" );
if(is_vis->GetBool()) SetVisible(true);
else SetVisible(false);
}

void CHudMyTest::MsgFunc_MyTxtMessage( bf_read &msg )

{
sprintf(m_pText, msg.ReadAndAllocateString());
}

//Создаем консольную переменную на стороне клиента для управления видимостью элемента
ConVar myhud_visible("myhud_visible", "0", FCVAR_NONE, "HudMyTest visibility", true, 0, true, 1);

//Создаем консольную комманду на стороне клиента для переключения видимости элемента
void CC_myhud_visible ( void )
{
ConVar *is_vis = cvar->FindVar( "myhud_visible" );
if(is_vis->GetBool())
engine->ClientCmd( "myhud_visible 0" );
else
engine->ClientCmd( "myhud_visible 1" );
}
static ConCommand myhud( "myhud", CC_myhud_visible, "parameter");

Подключаем файл к проекту клиента client. 2. Редактируем scripts/HudLayout.res
В файле HudLayout.res (в директории scripts вашего мода) добавляем новую секцию с описанием нашего элемента

HudMyTest
{
"fieldName" "HudMyTest"
"visible" "1"
"enabled" "1"
"xpos" "15"
"ypos" "200"
"wide" "150"
"tall" "150"
"PaintBackgroundType" "0"
}

Если в директории scripts вашего мода нет файла HudLayout.res, вытащите его из source engine.gcf 3. Привязываем комманду к клавише
В файлах cfg/config.cfg и cfg/default_config.cfg добавте комманду

bind "TAB" "myhud"

Если таких файлов нет, вытащите из source engine.gcf. 4. Создаем класс энтити для сообщения Создадим файл MyTxtMessage.cpp и поместим в него класс CMyTxtMessage который будет отвечать за экземпляр энтити на сервере для отправки сообщения на HUD:

//Класс CMyTxtMessage
#include "cbase.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

//объявляем класс
class CMyTxtMessage : public CLogicalEntity
{
public:
DECLARE_CLASS( CMyTxtMessage, CLogicalEntity );
DECLARE_DATADESC();
CMyTxtMessage( void ) {};
//Input-функция для передачи данных (вызывается при помощи каких-нибудь output на карте)
void InputSendMessage( inputdata_t &data );
//Текстовая переменная
string_t m_strText; };

//объявление данных энтити в таблице данных движка
BEGIN_DATADESC( CMyTxtMessage )

DEFINE_KEYFIELD( m_strText, FIELD_STRING, "text" ),

DEFINE_INPUTFUNC( FIELD_STRING, "SendMessage", InputSendMessage ),

END_DATADESC()

void CMyTxtMessage::InputSendMessage( inputdata_t &data )
{
//Мы хотим отправлять сообщение локальному игроку
CSingleUserRecipientFilter user( UTIL_PlayerByIndex(1) );
user.MakeReliable();

//Начало блока сообщения
UserMessageBegin( user, "MyTxtMessage" );

//Отправка текста клиенту
WRITE_STRING( STRING( m_strText ) );

//Конец блока сообщения
MessageEnd();
}

//Связываем имя энтити для Hammer с классом энтити
LINK_ENTITY_TO_CLASS( my_txt_message, CMyTxtMessage );

Добавляем файл в проект сервера hl.
Теперь следует зарегистрировать HUD сообщение.
Для этого потребуется внести изменения в файлы client/usermessages.cpp и shared/hl2_usermessages.cpp добавим в обоих функциях RegisterUserMessages регистрацию сообщения "MyTxtMessage"
Должно получиться так:

void RegisterUserMessages( void )
{
usermessages->Register( "Geiger", 1 );
usermessages->Register( "Train", 1 );
usermessages->Register( "HudText", -1 );

..........

usermessages->Register( "TextMsg", -1 );
}

Следует обратить внимание что регистрация сообщения производится как на сервере (sharedhl2_usermessages.cpp) так и на клиенте (clientusermessages.cpp)
5. Создаем запись для энтити в .FGD файле
Для того чтоб можно было добавить энтить на карте создаем запись в FGD файле вашего мода:

@PointClass base(Targetname) size(-8 -8 -8, 8 8 8) = my_txt_message : "My text message entity"
[
text(string) : "Value" : "Hello mod" : "Message value"
input SendMessage(void) : "Input Action"
output OnMessage(void) : "Output Action"
]

Eсли у вас используется FGD от Half-Life 2, создайте новый пустой текстовый файл с расширением FGD куда поместите данную запись, затем подключите этот файл с помощью опции меню настройки текущего проекта в Hammer. 6. Размещаем энтити на карте
Если правильно была создана запись в FGD файле, теперь можно добавить на карту новые энтити через инструмент добавления точечных энтитей в Hammer.
Добавляем две энтити my_txt_message и в поле Name пишем разные имена - Mymsg1Mymsg2, затем создаем два триггера trigger_multiple и также называем по разному - Trig1 и Trig2, и не забудть закрасить триггеры текстурой tools/toolstrigger.
Должно плучиться нечто похожее на этот рисунок:

В поле Value у Mymsg1 пишем текст "Hello from First!":

А для Mymsg2 пишем "Hello from Second!"
Далее выбираем первый триггер Trig1 и устанавливаем в закладке Outputs связь с Mymsg1, так чтоб триггер реагировал на касание игрока, посилая output триггера в input энтити, как иллюстрирует рисунок ниже:

То же самое проделываем с второй парой Trig2 и Mymsg2
7. Финальные шаги
Компилируем DLL-ы client и server в Visual Studio (меню Build->Build Solution) и компилируем карту где мы размещали энтити.
Запускаем мод, запускаем данную карту, при нажатии клавиши TAB должно переключаться отображение нового HUD элемента с надписью "Empty".
Подходим к первому месту где мы установили триггер связанный с первой энтитью (Mymsg1), как только сработает триггер увидем сменившуюся надпись "Hello from First!", теперь подходим к труггому тригеру, видим новую надпись "Hello from Second!".
Дальше вы уже самостоятельно сможите наращивать функциональность для подобных серверных энтитей и добавлять в интерфейс мода собственные элементы модифицировав под свои потребности.
Автор: DarkLight


 
  • Страница 1 из 1
  • 1
Поиск:

Copyright MyCorp © 2026
Хостинг от uCoz