|
|
| |
| ZASOBY |
| |
| |
|
|
|
| |
|
| NASZ BUTTON |
|
|
| |
|
|
| |
|
| |
|
TUTORIALE - CODING
|
[ Dodaj ]
|
|
Statystyka trafień wyświetlana na HUD
| [ 2005-09-03 15:01:28 Dodał:
mefi Wyświetleń: 2220 Komentarzy: 5 ]
|
|
Dziś zrobimy sobie prostą statystykę trafień. Będzie ona pokazywała ile oddaliśmy strzałów, ile razy trafiliśmy w NPC i jak przedstawia się nasza celność w procentach. Wszystko to wyświetlimy na HUD.
Zaczniemy od modyfikacji pliku HUDLAYOUT.RES, który znajduje się w katalogu SCRIPTS. Na początku pliku dodajemy takie coś:
HudStat
{
"fieldName" "HudStat"
"visible" "1"
"enabled" "1"
"xpos" "555"
"ypos" "5"
"wide" "80"
"tall" "40"
"PaintBackgroundType" "0"
} |
W ten sposób stworzyliśmy nowy panel, który będzie się wyświetlał w prawym górnym rogu ekranu.
Teraz otwieramy kod gry i projekt serwera. W nim otwieramy plik PLAYER.H. Szukamy FlashlightTurnOff( void ) { }; i pod tym dopisujemy:
virtual void FlashlightTurnOff( void ) { };
int m_iIle_Shoot;
int m_iIle_Hit; |
W tych zmiennych będziemy przechowywać nasze dane do statystyki. Teraz otwieramy plik AI_BASENPC.CPP. Szukamy funkcji: CAI_BaseNPC::TraceAttack i w niej po bool bDebug = showhitlocation.GetBool(); dodajemy to:
bool bDebug = showhitlocation.GetBool();
CBasePlayer *pPlayer = AI_GetSinglePlayer();
pPlayer->m_iIle_Hit++; |
Jak widzicie najpierw trzeba utworzyć wskaźnik do klasy playera aby mieć dostęp do naszych zmiennych. Po trafieniu w NPC, zwiększamy zmienną o jeden.
Kolejnym krokiem jest zliczenie ilości oddanych strzałów. Czynność tą musimy wykonać dla każdej broni. Na razie zrobimy to dla pistoletu. A więc otwieramy plik WEAPON_PISTOL.CPP i po m_flSoonestPrimaryAttack = gpGlobals->curtime + PISTOL_FASTEST_REFIRE_TIME; dodajemy:
m_flSoonestPrimaryAttack = gpGlobals->curtime + PISTOL_FASTEST_REFIRE_TIME;
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
if (!pPlayer)
{
return;
}
pPlayer->m_iIle_Shoot++; |
Dobrze już mamy wszystkie dane teraz trzeba je wysłać do clienta i wyświetlić. Otwieramy plik HL2_USERMESSAGES.CPP i po usermessages->Register( "ResetHUD", 1); dopisujemy:
| usermessages->Register( "Stat", 6); |
W ten sposób zadeklarowaliśmy nowy "kanał" wysyłania informacji o nazwie Stat i pozwala on przesłać 6 bajtów. Jeżeli nie wiecie ile dokładnie będziecie przesyłać informacji wpiszcie -1.
Teraz otwieramy plik PLAYER.CPP w funkcji CBasePlayer::UpdateClientData nad CWorld *world = GetWorldEntity(); dodajemy:
UserMessageBegin( user, "Stat" );
WRITE_BYTE( m_iIle_Shoot );
WRITE_BYTE( m_iIle_Hit );
if ( m_iIle_Shoot!=0)
WRITE_FLOAT( float(m_iIle_Hit)/float(m_iIle_Shoot)*100);
else
WRITE_FLOAT( 0 );
MessageEnd(); |
W ten sposób wysłaliśmy do clienta nasze dane. W bloku MessageBegin i MessageEnd wpisujemy dane do wysłania. WRITE_BYTE oznacza, że wysyłąmy np. zmienną INT, czyli zmienna liczbowa. Tu macie spis jakie mamy możliwości wysyłania:
WRITE_BYTE
WRITE_CHAR
WRITE_SHORT
WRITE_WORD
WRITE_LONG
WRITE_FLOAT
WRITE_ANGLE
WRITE_COORD
WRITE_VEC3COORD
WRITE_VEC3NORMAL
WRITE_ANGLES
WRITE_STRING
WRITE_ENTITY
WRITE_BOOL
WRITE_UBITLONG
WRITE_SBITLONG
WRITE_BITS
Te poszczególne makra mają przypisaną swoją objętość czyli ile bajtów wysyłają. Np. dla WRITE_BYTE jest to 1 bajt, a dla WRITE_FLOAT 4 bajty. Pamiętacie jak jakiś czas temu pisaliśmy: Register( "Stat", 6);. Po zsumowanie WRITE_BYTE <1 bajt> + WRITE_BYTE<1 bajt> + WRITE_FLOAT <4 bajt> wychodzi nam razem 6 bajtow.
Jeszcze szybkie wyjaśnienie algorytmu działania bloku MessageBegin-MessageEnd. Najpierw wysyłamy ilość oddanych strzałów, później ilość trafień, dalej obliczamy naszą celność w procentach, ale trzeba pamiętać że na początku trafienia są równe zero, a jak pamiętacie ze szkoły "nie dziel cholero przez zero", dlatego jest jeszcze ten warunek: if ( m_iIle_Shoot!=0).
Czas zająć się wyświetleniem naszej statystyki. Otwieramy clienta i tworzymy nowy plik o nazwie HUD_STAT.CPP, który należy dodać do projektu. Treść tego pliku powinna wyglądać tak:
#include "cbase.h"
#include "hud.h"
#include "hudelement.h"
#include "hud_macros.h"
#include
#include
#include
#include
#include "vgui/ISurface.h"
#include "iclientmode.h"
using namespace vgui;
#include "text_message.h"
#include "tier0/memdbgon.h"
class CHudStat: public CHudElement , public vgui::Panel
{
DECLARE_CLASS_SIMPLE( CHudStat, vgui::Panel );
public:
CHudStat( const char *pElementName );
void Paint( void );
virtual void Init( void );
virtual void VidInit( void );
virtual void Reset( void );
void MsgFunc_Stat( bf_read &msg );
int m_iIle_S;
int m_iIle_H;
float m_iIle_A;
private:
vgui::Label *m_pLabel;
vgui::HScheme scheme;
};
DECLARE_HUDELEMENT( CHudStat );
DECLARE_HUD_MESSAGE( CHudStat, Stat );
void CHudStat::Init()
{
HOOK_HUD_MESSAGE( CHudStat, Stat );
Reset();
}
void CHudStat::Reset()
{
m_iIle_S = 0;
m_iIle_H = 0;
m_iIle_A = 0;
}
void CHudStat::VidInit()
{
Reset();
}
CHudStat::CHudStat( const char *pElementName ) : CHudElement( pElementName ), vgui::Panel( NULL, "HudStat" )
{
scheme = vgui::scheme()->LoadSchemeFromFile("resource/ClientScheme.res", "ClientScheme");
SetScheme(scheme);
vgui::Panel *pParent = g_pClientMode->GetViewport();
SetParent( pParent );
SetHiddenBits( 0 );
m_pLabel = vgui::SETUP_PANEL(new vgui::Label(this,"Label",""));
m_pLabel->SetScheme(scheme);
m_pLabel->SetFont(vgui::scheme()->GetIScheme(scheme)->GetFont("Default"));
m_pLabel->SetKeyBoardInputEnabled(false);
m_pLabel->SetMouseInputEnabled(false);
m_pLabel->SetPos(0,0);
m_pLabel->SetSize(GetWide(),GetTall());
m_pLabel->SetPaintBackgroundEnabled( false );
m_pLabel->SetPaintBorderEnabled( false );
m_pLabel->SetContentAlignment( vgui::Label::a_center );
SetBgColor(Color(0,0,0,0));
m_pLabel->SetBgColor(Color(0,0,0,0));
}
void CHudStat::Paint( void )
{
char text[256];
Q_snprintf( text, sizeof(text), "Strzalow: %d\nTrafien: %d\nCelnosc: %.0f %%", m_iIle_S, m_iIle_H, m_iIle_A );
m_pLabel->SetFgColor( Color(255,255,255,255) );
m_pLabel->SetText( text );
m_pLabel->SetVisible(true);
m_pLabel->SizeToContents();
m_pLabel->SetSize(GetWide(),GetTall());
}
void CHudStat::MsgFunc_Stat( bf_read &msg )
{
m_iIle_S = msg.ReadByte();
m_iIle_H = msg.ReadByte();
m_iIle_A = msg.ReadFloat();
} |
Nie będę opisywał tego kodu, gdyż nie ma w nim dużo logiki. Praktycznie definiuje on tylko wygląd i pozycji naszego tekstu. Pamiętajcie tylko, że przy odczycie wartości z serwera musicie zachować ta sama kolejność jaka była przy wysyłaniu danych.
Jeżeli wszystko dobrze wpiszecie to w grze powinniście zobaczyć takie coś.

|
|
|
| |
| KOMENTARZE |
|
|
|
gdzie ty sie tego nauczyles???
|
| |
| [ 2005-09-03 16:20:54 Dodał:
mefi ]
|
|
|
Uczę się na kodzie HL2, bo w necie czegoś takiego raczej nie znajdziesz, ale tutoriali kilka jest, które czasem pomagają coś połączyć w całość. He dziś zaczynam robić Mod-a |
| |
| [ 2007-05-19 20:56:07 Dodał:
sobieh ]
|
|
|
nie
BasePlayer *pPlayer = ToBasePlayer( GetOwner() );
tylko:
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
zjadłeś "C"
|
| |
| [ 2007-05-20 10:17:18 Dodał:
mefi ]
|
|
|
|
No fakt już poprawiam, thx |
| |
|
|
Super, w połączeniu z tutkiem TeWu o HUD, daje to całkiem nowe możliwości
BTW, właśnie, z tutkami w necie ciężko, a czasami jak patrzę w kod to wydaje mi się że widzę jedną wielką plamę CPP (?) |
|
|
|
|
|
| |
|
|
| |
| SHOUTBOX |
|
MoonBlaze: ciasto is a lie |
|
zwieracz: Przyłącz się do mnie, mam ciasto |
|
Jodla: <kontemplujac stwierdza iz obecna rzeczywistosc jest do bani> |
|
MoonBlaze: sm_ban @Dabu 1 |
|
Dabu: Ta strona umarła, zapraszam lepiej na heacrab.pl :D [/koniec reklamy] |
|
Jodla: open beta nowego gmoda a tu 0 info na stronie ...może czas to zmienic zwłaszcza iż screeny z GM13 wygladaja apetycznie |
|
Dabu: web 3.0 |
|
Elektryk: Link |
|
Tracha: Ruski gracz! |
|
zwieracz: Za moich czasów, to się bawilismy przy takiej gierce, gdzie zając łapaj kury za jaja. A moze to był wilk. |
|
| |
|
|
|