Sign in to follow this  
nooblet

[SDL] Inputting integers...

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
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
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
Quote:
Original post by nooblet
But how am I supposed to do that?
You already know how to render text, since you are doing it in load_files(). Try this every frame after you update the stringstreams:
SDL_FreeSurface(player_text);
player_text = TTF_RenderText_Solid(font, stream.str().c_str(), textColor);

Share this post


Link to post
Share on other sites
Quote:
Original post by nooblet
How do I check to see after every frame? Would I have to use a timer?
Every time you update the stringstreams, you also re-render their respective images. That seems to be near the top of your handle_input() function.

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