gpt4 book ai didi

c++ - SDL_TTF 慢打印效果

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:15:58 25 4
gpt4 key购买 nike

所以,我正在开发一个命令提示符游戏,现在我从小处着手。我已经掌握了打印速度较慢的文本系统的基础知识,但我遇到了一个我不确定如何解决的问题。

基本上;文本会拉伸(stretch)以适合预定义的框: preview预定义框是指我定义为 srcrect 和 dstrect 的 SDL_Rect。

现在,一个解决方案是简单地扩展 SDL_Rect 以适合我的文本,并且由于我使用的是等宽字体,这将相当容易。但是我只是在想; “一定有更好的方法!”。

最后,如果你需要的话,这是我的代码:

#include<iostream>
#include<SDL.h>
#include<string>
#include<SDL_ttf.h>

std::string text = "";
std::string textToAdd = "Hello there, how are you doing?";
int pos = 0;

void handleEvents(SDL_Event e, bool* quit){
while(SDL_PollEvent(&e) > 0){
if(e.type == SDL_QUIT){
*quit = true;
}
}
}

void render(SDL_Renderer* renderer, SDL_Texture* textToRender, SDL_Rect srcrect, SDL_Rect dstrect){
SDL_RenderClear(renderer);

SDL_RenderCopy(renderer, textToRender, &srcrect, &dstrect);

SDL_RenderPresent(renderer);
}

Uint32 calcText(Uint32 interval, void *param){
if(pos < textToAdd.length()){
text = text + textToAdd[pos];
pos++;
}
return interval;
}

int main( int argc, char *argv[] ) {
SDL_Init(SDL_INIT_EVERYTHING);
TTF_Init();
SDL_Window* window = SDL_CreateWindow("Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 600, SDL_RENDERER_ACCELERATED);
SDL_Renderer* renderer = SDL_CreateRenderer(window, 0, 0);

bool quit = false;
SDL_Event e;

SDL_TimerID repeatText = SDL_AddTimer(70, calcText, NULL);

TTF_Font* font = TTF_OpenFont("Hack-Regular.ttf", 28);
SDL_Color color = {255, 255, 255};
SDL_Surface* textSurface;
SDL_Texture* textTexture;

SDL_Rect srcrect;
SDL_Rect dstrect;

srcrect.x = 0;
srcrect.y = 0;
srcrect.w = 580;
srcrect.h = 32;
dstrect.x = 10;
dstrect.y = 10;
dstrect.w = 580;
dstrect.h = 32;

while(!quit){
handleEvents(e, &quit);
render(renderer, textTexture, srcrect, dstrect);



textSurface = TTF_RenderText_Solid(font, text.c_str(), color);
textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
}

SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);

window = NULL;
renderer = NULL;
TTF_Quit();
SDL_Quit();
return 0;
}

最佳答案

我用了一些不同的方法来制作它。首先,我建议您阅读本教程:http://lazyfoo.net/tutorials/SDL/index.php .其次:尝试在关键点使用初始化检查,如本例所示:

//...
if (!myInitFunction())
{
//error message and quit without crash
}
else
{
//continue game
}
//...

让我们回到您的问题:

是的,这是可能的,你想要什么,从 surface->w 获取 dstrect.w。但不是那么简单。因为在第一次运行 while 循环时,如果我们执行 dstrect.w = surcface->h 就会崩溃,那么您的游戏就会崩溃。为什么?因为字符串等于什么都没有:"".

为避免这种情况,您应该简单地以一个带空格的字符串开始,或者在开始之前将 'H' 字符放入字符串中。 (实际上我没有使用 SDL_TimerID 而是用另一种方式实现的,但我不想让它复杂化。)

此外,您应该遵循“顺序规则”:INPUT >>> HANDLING >>> RENDER

所以你的代码应该是这样的:

//...
std::string text = "H";
std::string textToAdd = "ello there, how are you doing?";
//...
while(!quit)
{
handleEvents(e, &quit);

textSurface = TTF_RenderText_Solid(font, text.c_str(), color);
dstrect.w = textSurface->w; //change the width of rectangle
textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);

render(renderer, textTexture, srcrect, dstrect);
}
//...

另一个建议是尝试泛化这个渲染方法,如果你没有做过的话,尝试在控制台应用程序中做。

重要编辑:我让它重复文本,然后速度变慢了。我意识到有内存泄漏!因此,在使用之后或重新创建表面之前,您必须使用 SDL_FreeSurface 删除它并使用 SDL_DestroyTexture 删除纹理。

编辑 2:因此,回应您的评论,这是您的 while 循环:

{
handleEvents(e, &quit);

if (textSurface != NULL)
{
SDL_FreeSurface(textSurface);
//textSurface = NULL; //optional
}
textSurface = TTF_RenderText_Solid(font, text.c_str(), color);
dstrect.w = textSurface->w; //change the width of rectangle

if (textTexture != NULL)
{
SDL_DestroyTexture(textTexture);
//textTexture = NULL;
}
textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);

render(renderer, textTexture, srcrect, dstrect);
}

注意:您必须将 SurfaceTexture 指针声明为 NULL,这样 if 部分才能工作。

关于c++ - SDL_TTF 慢打印效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33578369/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com