Public Group

This topic is 3683 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I'm having trouble getting the equations for a radar to work in a HL2MP mod. I have a few questions in which I would find helpful if they were answered. How can I calculate where to put the marker on the radar (It's a simple square texture with a circle to represent the radar. I was thinking of making the client player the origin relative to the other players, then converting to polar coordinates and back to Cartesian when I put it on the radar which has a center at the point (60, 60). Is there a function to draw circles instead of squares. I couldn't find any in the class declaration. Here is what I have so far
#include "hud.h"
#include "cbase.h"
#include "iclientmode.h"
#include "hud_macros.h"
#include "vgui_controls/controls.h"
#include "vgui/ISurface.h"

#include "tier0/memdbgon.h"

using namespace vgui;

CRadarHud::CRadarHud( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudImport" )
{

Panel *pParent = g_pClientMode->GetViewport();
SetParent( pParent );

SetVisible( true );

m_nImport = surface()->CreateNewTextureID();
surface()->DrawSetTextureFile( m_nImport, "HUD/hud_radar" , true, true);

SetPaintBorderEnabled(false);
surface()->DrawSetTexture( m_nImport );
surface()->DrawTexturedRect( 2, 2, 128, 128 );

}

{
SetPaintBorderEnabled(false);
surface()->DrawSetTexture( m_nImport );
surface()->DrawTexturedRect( 2, 2, 128, 128 );

//	TODO:  We need to update the dots on the screen according to where the players are

// create player pointer
C_BasePlayer *pOtherPlayer = NULL;
surface()->DrawSetColor( 250, 250, 250, 10 );
surface()->DrawFilledRect(10, 60, 15, 65);

for(int i = 1; i <= gpGlobals->maxClients; i++ )
{
pOtherPlayer = UTIL_PlayerByIndex( i );

if(!pOtherPlayer)
continue;
if(!pOtherPlayer->IsAlive( ))
continue;
if(!pOtherPlayer->IsClient( ))
continue;
// draw everyone
/*if(pOtherPlayer->GetTeamNumber( ) != pPlayer->GetTeamNumber( ))
continue; // Don't draw enemies TODO radar amplifier */
if(pOtherPlayer == C_BasePlayer::GetLocalPlayer( ))
continue; // Don't draw self

C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
Vector offset = pOtherPlayer->GetAbsOrigin() - pLocalPlayer->GetAbsOrigin();
offset /= scale; // devide by scale

int drawX = offset.x + panelWidth/2; // add sixty because origin is
int drawY = offset.z + panelHeight/2; // actually located at (60, 60)
if ( drawX > 0 && drawY > 0
&& drawX < panelWidth && drawY < panelHeight )
{
// this clips to a square, which is less pretty but easier
surface()->DrawFilledRect( drawX-1, drawY-1, drawX+1, drawY+1 );
Msg( "x1:%f y1:%f x2:%f y2:%f \n", drawX-1, drawY-1, drawX+1, drawY+1 );

}// end if

} // end for loop
}

{
this->SetVisible(false);
else
this->SetVisible(true);
}

{
togglePrint();

BaseClass::OnThink();

}


Thank you for your time and effort, Joe [Edited by - cs_student on July 17, 2008 10:27:04 PM]

Share on other sites
I can't answer specifically because I haven't done vgui programming, but mathematically, you need to know the distance that your radar will sweep, first of all.

To find the position of each player on the radar, you would do something like this (pseudo code):

const float RADAR_SWEEP_DISTANCE = 1000.0f;float fRadarImageRadius = radarSurface->width(); // or height, assuming it's square. Also could adjust for borders.foreach player in players	// Ignore self and non-playing players	if player == localplayer || !player.isclient || ! player.alive continue	// Get vector pointing from local player to player being examined	vector3d vecDistanceToPlayer = player.position - localplayer.position;	// If out of radar range, don't put on the radar	if(!vecDistanceToPlayer.distanceSquaredBelowThreshold(RADAR_SWEEP_DISTANCE)) continue;	// If within range, divide by range to get normalized distance from radar center	vecDistanceToPlayer /= RADAR_SWEEP_DISTANCE;	// Then multiply by pixel distance from radar image's center to the radar image's edge	vecDistanceToPlayer *= fRadarImageRadius;	// Now, draw a circle, or another texture, centered on vecDistanceToPlayer + vecRadarImageCenterPoint

I apologize if I am mistaken, as I haven't tested this code.

Share on other sites
What I want to have is the relative position and proximity of the other player. Not just how far they are away from the client. ie If client is facing down the positive x direction (or pointed that way) and the other player is behind him, I want the dot to show up x units downward (indicating the player is behind the client) depending on how far the other player is from the client.

Does that make sense?

Here's a picture to further clarify

Joe

/bump

Share on other sites
/bump (I won't bump again, as I don't want to spam)

Share on other sites
It's late but..

int dX = centerX - otherPlayerX;int dY = centerY - otherPlayerY;int rX = radius * cos(dX);int rY = radius * sin(dY);

I have no clue how accurate it is, but I figure it might help you get in the right direction. You'll probably have to play around with the signs to get a full circle rather than only certain quadrants.

centerX/Y are the in game coordinates of the player,
otherPlayerX/Y are the in game coordinates of the player/enemy you want to draw on radar

rX/Y will be the OFFSET of the center of the radar.

Edit: and the radius might be swapped with linear distance between the 2, again not sure - its late

1. 1
2. 2
3. 3
4. 4
frob
15
5. 5

• 16
• 12
• 20
• 12
• 19
• Forum Statistics

• Total Topics
632163
• Total Posts
3004514

×