Jump to content
  • Advertisement
Sign in to follow this  
nooblet

[SDL] Inputting integers...

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey all, If I am using SDL_ttf to output some text onto my game, how would I display a integer onto the screen? Basically what I am trying to do is show the players health decrease. Basically what I want to do is like this: example: The monster hits the player for 40 damage, the player's health is now at 60 (100-40 = 60). So I want it to display at the top left corner of the screen like this... Player: 60 , and on the very top-right of the screen display Monster: 100 I hope you guy's can understand that and give me some help! Thanks in advanced!

Share this post


Link to post
Share on other sites
Advertisement
You need to convert the integer to text. How to do this varies with the programming language used.

As an example, in C++ one could use std::stringstream:

#include <sstream>

SDL_Surface *displayHealth(TTF_Font *font, int health)
{
const SDL_Color colour = /* whatever */;

std::stringstream stream;
stream << "Player's health: " << health;

SDL_Surface *surface = TTF_RenderText_Solid(font,stream.str().c_str(),colour);
return surface;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by nooblet
If I am using SDL_ttf to output some text onto my game, how would I display a integer onto the screen?
I assume that you have figured out how to display a string on the screen? If you have managed to accomplish that, then you actually need to know how to convert an integer into a string: in C you could use snprintf(), and in C++ you should use std::ostringstream.

Share this post


Link to post
Share on other sites
Using the GPWiki's example for using SDL_Ttf, your logic could look like this:

// Global variables
SDL_Surface * playerHPSurface;

...

// Initialization code
playerHPSurface = drawtext(font, 255, 0, 0, 255, 0, 0, 0, 0, "100", solid);

...

// Player's HP change event code
// playerHP is an integer that represents the current HP
SDL_FreeSurface(playerHPSurface);
char strHP[32] = {0};
_snprintf(strHP, 31, "%i", playerHP);
playerHPSurface = drawtext(font, 255, 0, 0, 255, 0, 0, 0, 0, strHP, solid);

...

// Draw code - whatever you use to draw the surface to the screen at X, Y
DrawSurface(playerHPSurface, 0, 0);

// Cleanup code
SDL_FreeSurface(playerHPSurface);

Now this should "work", but over time a lot of HP changes would result in a lot of surface allocation and freeing. If this gets to be a problem, you would have to do this instead:

// Global
SDL_Surface * digits[10] = {0};

// Initialize code
for(int x = 0; x < 10; ++x)
{
char digits[2] = {0};
_snprintf(digits, 1, "%i", x);
digits[x] = drawtext(font, 255, 0, 0, 255, 0, 0, 0, 0, digits, solid);
}

// Draw code
// playerHP is an integer that represents the current HP
char hpText[32] = {0};
_snprintf(hpText, 31, "%i", playerHP);
int curX = 0;
for(int x = 0; x < strlen(hpText); ++x)
{
int digit = [hpText] - '0';
DrawSurface(playerHPSurface, curX, 0);
curX += 10; // Or however many pixels wide to space it
}

// Cleanup code
// loop and free digits!


That approach would allow for less allocations and freeing and allow you to easily build up any score value!

Give those both a try and see how it works for you. Good luck [smile]

[edit]Too long ~

Share this post


Link to post
Share on other sites
Well I tried rip-off's example but it doesn't update the zombies HP when I attack him, and your code is hard to read =[ . Any help?

Share this post


Link to post
Share on other sites
Quote:

Any help?

Nope. [smile]

You need to give us more information. The code I gave you should work, indeed you said yourself that it did earlier. The probable cause then is that the calling code has bugs in it. Without seeing that code, there is nothing we can do to help you.

Share this post


Link to post
Share on other sites
Heh, sorry about that :). Basically, I punch the zombie, it does no damage.

main.cpp

#include <SDL/SDL.h>
#include <SDL/SDL_mixer.h>
#include <SDL/SDL_ttf.h>
#include <string>
#include <sstream>
#include <time.h>

#include "gFunctions.h"



int main(int argc, char* argv[])
{
start_game();
load_files();

Mix_PlayMusic(bgmusic, -1);
Mix_PlayChannel(-1, start, 0);

while(IsRunning)
{

draw_image(0, 0, background, screen);
draw_image(PlayerX, PlayerY, player, screen);
draw_image(ZombieX, ZombieY, zombie, screen);
draw_image(50, 0, player_text, screen);
draw_image(450, 0, zombie_text, screen);
draw_image(250, 50, random_text, screen); // DEBUG

if(ZombieHP <= 0)
{
zombie = zombie_crouch;
}

handle_input();
handle_collision();


SDL_Flip(screen);
}

return 1;
}



gFunctions.h

#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include <string>
#include <sstream>
#include <time.h>

SDL_Event event;

int PlayerX = 0;
int PlayerY = 300;
int PlayerF = 1;
int PlayerHP = 100;

int ZombieX = 570;
int ZombieY = 300;
int ZombieHP = 100;

int PlayerDMG = 32;
int ZombieDMG = 0;

TTF_Font *font = NULL;

SDL_Color textColor = { 0, 0, 0 };

SDL_Surface *screen = NULL;
SDL_Surface *background = NULL;

SDL_Surface *levelone = NULL;
SDL_Surface *leveltwo = NULL;

SDL_Surface *player = NULL;
SDL_Surface *player_right = NULL;
SDL_Surface *player_left = NULL;
SDL_Surface *player_crouch = NULL;
SDL_Surface *player_crouch_left = NULL;
SDL_Surface *player_text = NULL;

SDL_Surface *zombie = NULL;
SDL_Surface *zombie_left = NULL;
SDL_Surface *zombie_crouch = NULL;
SDL_Surface *zombie_text = NULL;

SDL_Surface *random_text = NULL;

std::stringstream stream;
std::stringstream zombiestream;
std::stringstream randomstream;

Mix_Music *bgmusic = NULL;

Mix_Chunk *start = NULL;
Mix_Chunk *hit = NULL;
Mix_Chunk *killed = NULL;
Mix_Chunk *boing = NULL;

bool IsRunning = true;

SDL_Surface *load_image(std::string filename)
{
SDL_Surface *loadedImage = NULL;
SDL_Surface *optimizedImage = NULL;

loadedImage = SDL_LoadBMP(filename.c_str());
if(loadedImage != NULL)
{
optimizedImage = SDL_DisplayFormat(loadedImage);

SDL_FreeSurface(loadedImage);
if(optimizedImage != NULL)
{
Uint32 colorkey = SDL_MapRGB(optimizedImage->format, 0xFF, 0xFF, 0xFF);
SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, colorkey);
}
}

return optimizedImage;
}


void draw_image(int x, int y, SDL_Surface *src, SDL_Surface *dst)
{
SDL_Rect offset;

offset.x = x;
offset.y = y;

SDL_BlitSurface(src, NULL, dst, &offset);
}

bool start_game()
{
SDL_Init(SDL_INIT_EVERYTHING);
TTF_Init();

screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 );

SDL_WM_SetCaption("Zombie Attack!", NULL);

return true;
}

bool load_files()
{

font = TTF_OpenFont("arial.ttf", 28);

player_text = TTF_RenderText_Solid(font, stream.str().c_str(), textColor);
zombie_text = TTF_RenderText_Solid(font, zombiestream.str().c_str(), textColor);
random_text = TTF_RenderText_Solid(font, randomstream.str().c_str(), textColor);
player_right = load_image("gfx/player.bmp");
player_left = load_image("gfx/player_left.bmp");
player_crouch = load_image("gfx/player_crouch.bmp");
player_crouch_left = load_image("gfx/player_crouch_left.bmp");

zombie_left = load_image("gfx/zombie.bmp");
zombie_crouch = load_image("gfx/zombie_crouch.bmp");

levelone = SDL_LoadBMP("gfx/backgrounds/bk6.bmp");
leveltwo = SDL_LoadBMP("gfx/backgrounds/bk8.bmp");

bgmusic = Mix_LoadMUS( "media/bgmusic.wav" );
hit = Mix_LoadWAV( "media/punch.wav" );
start = Mix_LoadWAV( "media/get_some.wav" );
killed = Mix_LoadWAV( "media/gotta_hurt.wav" );
boing = Mix_LoadWAV( "media/boing.wav" );

player = player_right;
zombie = zombie_left;
background = levelone;

return true;
}

void handle_input()
{
SDL_PollEvent(&event);

stream << "Player: " << PlayerHP;
zombiestream << "Zombie: " << ZombieHP;
randomstream << "PlayerDMG: " << PlayerDMG;

if(event.type == SDL_KEYDOWN)
{
switch(event.key.keysym.sym)
{
case SDLK_UP:
if(PlayerY + 150 >= 450)
{
PlayerY -= 55;
Mix_PlayChannel(-1, boing, 0);
}
break;
case SDLK_RIGHT:
PlayerF = 1;
player = player_right;
PlayerX += 7; break;
case SDLK_LEFT:
PlayerF = 2;
player = player_left;
PlayerX -= 7; break;
case SDLK_DOWN:
if(PlayerF == 1) { player = player_crouch; } if(PlayerF == 2) { player = player_crouch_left; } break;
case SDLK_SPACE:
if(PlayerX + 65 >= ZombieX)
{
Mix_PlayChannel(-1, hit, 0);
ZombieHP -= PlayerDMG;
}
break;
}
}
else if(event.type == SDL_KEYUP)
{
switch(event.key.keysym.sym)
{
case SDLK_RIGHT:
PlayerX -= 0; break;
case SDLK_LEFT:
PlayerX += 0; break;
case SDLK_DOWN:
if(PlayerF == 1) { player = player_right; } if(PlayerF == 2) { player = player_left; } break;
}
}

if(event.type == SDL_QUIT)
{
IsRunning = false;
}
}

void handle_collision()
{
if(PlayerY + 150 < 450)
{
PlayerY += 3;
if(PlayerY + 150 >= 450)
{
PlayerY = 300;
}
}

if(PlayerX < 0)
{
PlayerX += 7;
}
else if(PlayerX + 65 > 640)
{
PlayerX -= 7;
}
if(PlayerY + 150 <= 200)
{
PlayerY += 10;
}
}

void end_game()
{
SDL_FreeSurface(player_right);
SDL_FreeSurface(player_crouch);
SDL_FreeSurface(player_left);
SDL_FreeSurface(player_crouch_left);
SDL_FreeSurface(zombie_left);
SDL_FreeSurface(zombie_crouch);
SDL_FreeSurface(levelone);
SDL_FreeSurface(leveltwo);
Mix_FreeChunk( hit );
Mix_FreeChunk( start );
Mix_FreeChunk( killed );

SDL_Quit();
}



I know the source code is messy, but I never intended on releasing it =p. Anyways, hopefully I can get some help now.

Share this post


Link to post
Share on other sites
You only render the text one (in load_files). Instead you need to re-render the text every frame (i.e. free the SDL_Surface, regenerate it, render it), or better yet, every time the hitpoints change.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!