[SDL] Inputting integers...

Started by
12 comments, last by nooblet 15 years, 6 months ago
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!
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;}
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.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Awesome :). rip-off it worked perfectly :) I appreciate it :).
Using the GPWiki's example for using SDL_Ttf, your logic could look like this:
// Global variablesSDL_Surface * playerHPSurface;...// Initialization codeplayerHPSurface = 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 HPSDL_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, YDrawSurface(playerHPSurface, 0, 0);// Cleanup codeSDL_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:
// GlobalSDL_Surface * digits[10] = {0};// Initialize codefor(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 HPchar 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 ~
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?
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.
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.
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.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

But how am I supposed to do that?

This topic is closed to new replies.

Advertisement