Sign in to follow this  
kingpinzs

Help displaying my varibles on the screen

Recommended Posts

Ok well I can draw text to the Directdraw screen but now I am trying to dispaly my varibles. draws my text
void DrawFont(int x, int y, const char *pszText)
{
    RECT rectSrc;
    int location = 0;
    int letterSpacing;
    char curr;
 
    // Go through each character in the given string

    for (int i = 0; i < (int)strlen(pszText); i++)
    {
        // Get the current character

        curr = pszText[i];
        
        // Capital letter?

        if (curr >= 'A' && curr <= 'Z')
        {
            rectSrc.left = ALPHA_LARGE_STARTX + ((curr - 'A') * ALPHA_LARGE_WIDTH);
            rectSrc.top = ALPHA_LARGE_STARTY;
            rectSrc.right = rectSrc.left + ALPHA_LARGE_WIDTH - 1;
            rectSrc.bottom = rectSrc.top + ALPHA_LARGE_HEIGHT - 1;
 
            letterSpacing = ALPHA_LARGE_WIDTH;
        }
        
        // Small letter?

        else if (curr >= 'a' && curr <= 'z')
        {
            rectSrc.left = ALPHA_SMALL_STARTX + ((curr - 'a') * ALPHA_SMALL_WIDTH);
            rectSrc.top = ALPHA_SMALL_STARTY;
            rectSrc.right = rectSrc.left + ALPHA_SMALL_WIDTH - 1;
            rectSrc.bottom = rectSrc.top + ALPHA_SMALL_HEIGHT - 1;
 
            letterSpacing = ALPHA_SMALL_WIDTH;
        }
 
        // Number?

        else if (curr >= '0' && curr <= '9')
        {
            rectSrc.left = NUMERIC_STARTX + ((curr - '0') * NUMERIC_WIDTH);
            rectSrc.top = NUMERIC_STARTY;
            rectSrc.right = rectSrc.left + NUMERIC_WIDTH - 1;
            rectSrc.bottom = rectSrc.top + NUMERIC_HEIGHT - 1;
 
            letterSpacing = NUMERIC_WIDTH;
        }
        
        // Other (space or non-supported character)

        else
        {
            // If it's a space, move over one character (screen position)

            if (curr == ' ') location++;
            
            // Skip to the next character in the string

            continue;
        }
 
        // Draw this character to the backbuffer at the proper location

        lpBackBuffer->BltFast(x + (location++ * letterSpacing), y,
                             g_pText,
                             &rectSrc,
                             DDBLTFAST_WAIT | DDBLTFAST_NOCOLORKEY);
    }
}

Draws my tiles
void draw_tiles(void)
{
   
    RECT tile_src;
    
    for(Tileset.y=0; Tileset.y<Tileset.Screen_sizey;Tileset.y++)
    {for(Tileset.x=0; Tileset.x<Tileset.Screen_sizex; Tileset.x++)
    {  //what does this do?
      
      Tileset.scroll_x = Tileset.x + (Tileset.world_camerax/Tileset.Tile_size);//this allows scrolling on y axis
      Tileset.scroll_y = Tileset.y + (Tileset.world_cameray/Tileset.Tile_size);//this allows scrolling on x axis
        
      Tileset.offset_x = Tileset.scroll_x & (Tileset.Tile_size - 1); // not sure what this does
      Tileset.offset_y = Tileset.scroll_y & (Tileset.Tile_size - 1);      
          
          Tileset.tiles = map[Tileset.scroll_y][Tileset.scroll_x];
          
 if (Tileset.tiles <= 1 || Tileset.tiles >= 3)
{ Tileset.wakable = true;}

 else if (Tileset.tiles == 2)
{ Tileset.wakable = false;} 

char Ntiles = 'Tileset.tiles';


    tile_src.left =(Tileset.tiles - 1) *Tileset.Tile_size;
    tile_src.top = 0;
    tile_src.right= Tileset.tiles * Tileset.Tile_size;
    tile_src.bottom=Tileset.Tile_size;

     
dstr.left= (Tileset.x*Tileset.Tile_size) - Tileset.offset_x;
dstr.top= (Tileset.y*Tileset.Tile_size) - Tileset.offset_y ;
dstr.right = (Tileset.x*Tileset.Tile_size) - Tileset.offset_x + tile_src.right   ;
dstr.bottom = (Tileset.y*Tileset.Tile_size) - Tileset.offset_y + tile_src.bottom  ;

lpBackBuffer->Blt(&dstr,g_pddTile,&tile_src,DDBLT_WAIT,NULL);  
                 
}   }}  

and im my game main I have DrawFont(100, 100, "Tile "); How can I have it display 'Tileset.tiles' How do I know which tile is one or two? How can I have my player not go over tile two? were in my game loop would I put if (Tileset.tiles <= 1 || Tileset.tiles >= 3) { Tileset.wakable = true;} else if (Tileset.tiles == 2) { Tileset.wakable = false;} I need for my player to tell the differnce between tile one and tile 2. So i need some way to print on the screen what tile the player is on. Does any one know how to do that?

Share this post


Link to post
Share on other sites
There are two ways that I'd consider, one which is more the 'C' way and then the 'C++' way.

Through C, this is usually accomplished by using the 'sprintf' function, which takes an output character buffer, a format string, and a list of variables as input, changing the contents of the output buffer to reflect the variables passed.

Thus, to display a variable's text:

char varText[100];
sprintf(varText, "%d", Tileset.tiles);
DrawFont(x, y, varText);

The trick after this is that you can write a function similar to sprintf which takes a variable number of parameters and sends them to the sprintf function, in the end being something such as:

DrawVariable(xCoor, yCoor, "Number of Tiles: %d", Tileset.tiles);

The C++ way involves overloading the >> operator with a function other than 'cout' such that it prints the variables like cout does. You might in addition have a separate function call which sets the initial (x,y) coordinate for drawing.

Share this post


Link to post
Share on other sites
So how about this question.


void draw_tiles(void)
{

RECT tile_src;

for(Tileset.y=0; Tileset.y<Tileset.Screen_sizey;Tileset.y++)
{for(Tileset.x=0; Tileset.x<Tileset.Screen_sizex; Tileset.x++)
{ //what does this do?

Tileset.scroll_x = Tileset.x + (Tileset.world_camerax/Tileset.Tile_size);//this allows scrolling on y axis
Tileset.scroll_y = Tileset.y + (Tileset.world_cameray/Tileset.Tile_size);//this allows scrolling on x axis
Tileset.offset_x = Tileset.scroll_x & (Tileset.Tile_size - 1); // not sure what this does
Tileset.offset_y = Tileset.scroll_y & (Tileset.Tile_size - 1);

Tileset.tiles = map[Tileset.scroll_y][Tileset.scroll_x];

if (Tileset.tiles <= 0 || Tileset.tiles >= 2)
{ Tileset.wakable = true;}

else if (Tileset.tiles == 1)
{ Tileset.wakable = false;}

tile_src.left =(Tileset.tiles - 1) *Tileset.Tile_size;
tile_src.top = 0;
tile_src.right= Tileset.tiles * Tileset.Tile_size;
tile_src.bottom=Tileset.Tile_size;

dstr.left= (Tileset.x*Tileset.Tile_size) - Tileset.offset_x;
dstr.top= (Tileset.y*Tileset.Tile_size) - Tileset.offset_y ;
dstr.right = (Tileset.x*Tileset.Tile_size) - Tileset.offset_x + tile_src.right ;
dstr.bottom = (Tileset.y*Tileset.Tile_size) - Tileset.offset_y + tile_src.bottom ;


lpBackBuffer->Blt(&dstr,g_pddTile,&tile_src,DDBLT_WAIT,NULL);

} }}



How does it print tile 1 , 2 and 3?
How does it know what tile is 1 ,2 or 3?

all I want is to find tile 2 and make it Tileset.wakable = false;


Share this post


Link to post
Share on other sites
to print a specif tile you either use a seprate texture or one texture with diffrent rects to specify what location you want to paoint

for walk able or not you need to do that youself, just have a 2d array for it
char map[10][10];

map[3][3]=1;

and when you mave your sprite have
0-255 eqaul walkabe, non walkable, slow walk or whatever

Share this post


Link to post
Share on other sites
OK I'm pretty sure the following are true for your scheme to work:
(1) Tile_size is a power of 2.
(2) There is an input bitmap with a bunch of tiles scrunched together on the same image.

Tileset.offset_x = Tileset.scroll_x & (Tileset.Tile_size - 1); // not sure what this does
This is the same as Tileset.offset_x = Tileset.scroll_x % Tileset-Tile_size; (ONLY if Tileset.Tile_size is an integer power of 2!). This means that scroll_x computes the total number of pixels along the entire map to scroll while offset_x is the offset within the current tile to display at, say, the left-hand screen border so it knows what part of the tile image to start drawing.

'tile_src' is a rectangle into the source image (the image with all the template graphics in it) and this is a rectangle around the tile type that will be displayed on the screen, based on Tileset.tiles.
'dstr' is a rectangle into the backbuffer the same size (ie the size of a single tile) as tile_src where the tile will be drawn to.

Thus, to get the tile type of a certain pixel on the screen (which is what I assume you want?), you need to take a look at this code:

dstr.left= (Tileset.x*Tileset.Tile_size) - Tileset.offset_x;
dstr.top= (Tileset.y*Tileset.Tile_size) - Tileset.offset_y ;
dstr.right = (Tileset.x*Tileset.Tile_size) - Tileset.offset_x + tile_src.right ;
dstr.bottom = (Tileset.y*Tileset.Tile_size) - Tileset.offset_y + tile_src.bottom ;

There are certain Tileset.x and Tileset.y values that will make a certain rect that contains your desired pixel on the real screen (ie 'dstr' will contain your pixel in the rect). You need to solve for Tileset.x and Tileset.y after replacing offset_x, etc. with the formulas earlier in the function inside the double-for loop. Once you solve for Tileset.x and Tileset.y, the tile type of that pixel is found by: Tileset.tiles = map[Tileset.scroll_y][Tileset.scroll_x];

I hope this helps -- if you need any further explanation, please reply!

[Edited by - mnansgar on December 5, 2004 5:56:57 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Kaze
to print a specif tile you either use a seprate texture or one texture with diffrent rects to specify what location you want to paoint

for walk able or not you need to do that youself, just have a 2d array for it
char map[10][10];

map[3][3]=1;

and when you mave your sprite have
0-255 eqaul walkabe, non walkable, slow walk or whatever


So For every tile that I want nonwalkable I have to plot them out?

I thought because It knows were the second tile is that it would be able to do that for me.

Share this post


Link to post
Share on other sites
im not sure what you mean, directx is a graphics engin, not a game engine so you have to figutre out collison detection yourself, there are hundreds of ways you could do it, try looking at a few tile articles on this site

Share this post


Link to post
Share on other sites
mnansgar so I am trying to get what you are saying because I belive that is what I am looking for.

I think I kind understand. using this I need to make some kind of formula to find the tile numbers.


You need to solve for Tileset.x and Tileset.y after replacing offset_x, etc


dstr.left= (Tileset.x*Tileset.Tile_size) - Tileset.offset_x;
dstr.top= (Tileset.y*Tileset.Tile_size) - Tileset.offset_y ;
dstr.right = (Tileset.x*Tileset.Tile_size) - Tileset.offset_x + tile_src.right ;
dstr.bottom = (Tileset.y*Tileset.Tile_size) - Tileset.offset_y + tile_src.bottom ;


Can you explain this a little more or show me in psudoe code?

Share this post


Link to post
Share on other sites
Well, I don't have time to work it precisely out, but this should be pretty close if not it:

dstr.left= (Tileset.x*Tileset.Tile_size) - Tileset.offset_x;
dstr.top= (Tileset.y*Tileset.Tile_size) - Tileset.offset_y ;

Since we know that Tileset.offset_x is < Tileset.Tile_size (IF Tile_size is a power of 2, as intended in the code you presented), we can probably eliminate it from the equation if we divide dstr.left by Tile_size (due to automatic truncation with division which would accommodate for an additional Tile_size). So:

x = floor(screen_pointx / Tileset.Tile_size), and
y = floor(screen_pointy / Tileset.Tile_size)

Then when to look it up in the global map we need to take into consideration where the camera is in the world:

tiles = map[Tileset.scroll_y + y][Tileset.scroll_x + x];

The actual equations are probably *very* close to the above, perhaps with a +/- 1 in each bracket in the tiles equation (eg one tile off is my guess, if it's off at all) -- see what it returns and compare it with the map to see how close it is, or work it out exactly by yourself. I hope this helps!

Share this post


Link to post
Share on other sites
I don't quite understand the question but maybe some of this might help:

// given world x and y values, convert them to screen x and y values
void world_to_screen( int *x, int *y )
{
*x -= scrollx;
*y -= scrolly;
}

// given screen x and y values, convert them to world x and y values
void screen_to_world( int *x, int *y )
{
*x += scrollx;
*y += scrolly;
}

// given world coordinates, convert them to tilemap coordinates
void world_to_tilemap( int *x, int *y )
{
*x /= tile_width;
*y /= tile_height;
}

// given tilemap coordinates, fill a rectangle with that tiles world coordinates
void tilemap_to_world_tile_rect( int x, int y, RECT *rc )
{
rc->left = x*tile_width;
rc->top = y*tile_height;
rc->right = rc->left+tile_width;
rc->bottom = rc->top+tile_height;
}


It looks like you are trying to tackle collision detection which can be confusing for anyone. With the pseudo code I gave you, you might want to try this out:

// destx and desty are the coordinates you WANT to move the character to but
// haven't yet.
// destx is player.worldx + movex
// desty is player.worldy + movey
bool player_can_move_to( int destx, int desty )
{
int tilex, tiley;

// get the tilemap coordinates
tilex = destx;
tiley = desty;
world_to_tilemap( &tilex, &tiley );

// check if the tile is walkable or not
if ( map[tilex][tiley] == 1 )
return FALSE; // tile is not walkable

return TRUE;
}

It is very important to check this before you move or your character may appear to jump back when he collides with a non walkable tile.

The above example is a very simple and not very exact way of detecting collision between a player and a non walkable tile. A better way would be to use a bounding rectangle around the player and see if that collides with any neighboring non-walkable tiles.

Much like using an anchor point for a sprite so that it gets drawn in the correct spot, my collision rectangle is usually just an offset around the players position. For example, lets say I have a sprite that is 32x32 pixels and his anchor point is right in the middle of his feet. The anchor point would look something like (16,31) which is an offset from the top left of the sprite (0,0) or it's origin. Using this same theory, we can say I want my sprite to have an 8x6 pixel bounding box using it's anchor point as it's origin. The bounding box's coordinates would look something like ( -4,-3, 4,3 ). Here is an example of how this would get implemented using this sprite:

bool player_can_move( Player *player, int destx, int desty )
{
RECT player_rect, tile_rect, temp;
int tilex, tiley;

// get the tilemap coordinates
tilex = destx;
tiley = desty;
world_to_tilemap( &tilex, &tiley );

// get the world coordinates of the players bounding box
// if he were to move to that position.
// Note: CopyRect, OffsetRect and IntersectRect are Win32 specific
// but you should have access to similar functions handy anyway.
CopyRect( &player_rect, &player->bounding_box );
OffsetRect( &player_rect, destx, desty );

// before we only checked if we were on a non waklable tile
// now we are going to check if we are colliding with any non walkable tiles
// around us as well

// check if the tile is walkable or not
// we are on it so we don't have to check the bounding box
if ( map[tilex][tiley] == 1 )
return FALSE; // tile is not walkable

// check the 8 tiles around us
for ( int offy = -1; offy <= 1; offy++ )
{
for ( int offx = -1; offx <= 1; offx++ )
{
if ( map[tilex+offx][tiley+offy] == 1 ) // non walkable
{
tilemap_to_world_tile_rect(tilex+offx, tiley+offy, &tile_rect);
if ( IntersectRect( &temp, &player_rect, &tile_rect ) )
return FALSE; // BAM!
}
}
}
return TRUE;
}

That isn't optimized but should provide a solid base for simple bounding box collision in your case.

Hope that helped.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this