我正在尝试创建一个表面向量,它将包含用户输入的消息(它是一个聊天框)。但每当我向矢量添加新曲面并显示它们时,其他曲面就会显示在曲面矢量中。我不知道为什么会这样。我认为这是因为向量继续用.push_Back();
调整大小并且计算机在其他表面移动之前没有这样做,因此它们“卡在中间”并显示在表面的位置。
但当我检查时,它根本没有添加任何东西!我甚至试过.reserve( myVect.size() + 1);
,但唉,这只给了我同样的问题。
问题在于handle_input();
以及我认为如何显示消息。我无法在网络上的任何地方找到任何关于此问题的内容!
这是我的来源:
ofstream logFile;
SDL_Surface *text = NULL;
void apply_surface (int x, int y, SDL_Surface *source, SDL_Surface *destination, SDL_Rect *clip = NULL) {
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface(source, clip, screen, &offset);
}
vector <SDL_Surface*> surface_vect;
bool handle_input() {
if (event.type == SDL_KEYDOWN) {
std::string temp = str;
if ( str.length() <= 48) {
logFile << "str's length is <=48.\n";
if ( event.key.keysym.unicode == (Uint16) ' ' ) {
str += (char)event.key.keysym.unicode;
logFile << "Space bar was pressed.\n";
charcount += 1;
}
else if ( ( event.key.keysym.unicode >= (Uint16)'0') && (event.key.keysym.unicode <= (Uint16) '9' ) ) //Finally works!
{
charcount += 1;
str += (char)event.key.keysym.unicode;
logFile << "Number key: " <<(char)event.key.keysym.unicode << " pressed, and added to str.\n";
}
else if (( event.key.keysym.unicode >= (Uint16)'A' )&& (event.key.keysym.unicode <= (Uint16) 'Z') )
{
charcount += 1;
str += (char)event.key.keysym.unicode;
logFile << "Number key: " <<(char)event.key.keysym.unicode << " pressed, and added to str.\n";
}
else if ( (event.key.keysym.unicode >= (Uint16)'a' )&& (event.key.keysym.unicode <= (Uint16) 'z' ) )
{
charcount += 1;
str += (char)event.key.keysym.unicode;
logFile << "Number key: " <<(char)event.key.keysym.unicode << " pressed, and added to str.\n";
}
else if ( (event.key.keysym.unicode == SDLK_RETURN ) )
{
str = "";
surface_vect.reserve ( surface_vect.size() + 1);
if ( surface_vect.size() < surface_vect.capacity() ) { //PREVENTS AN ACCESS READING VIOLATION ERROR! THE ELEMENTS IN THE VECTOR WERE BECOMING TOO LARGE FOR THE VECTOR!!
surf_count += 1;
surface_vect.push_back ( text );
logFile << "surface_vect has: " << surf_count << " surfaces!";
}
}
if (event.key.keysym.unicode == SDLK_BACKSPACE && str.length() != 0) {
charcount -= 1;
str.erase(str.length() - 1);
logFile << "Backspace was pressed.\n";
}
if (str != temp) {
SDL_FreeSurface ( text ); //This frees up the text surface whenever the str changes.
text = TTF_RenderText_Solid(font, str.c_str(), textcolor); //Renders the text whenever that change occurs.
logFile << "Full text rendered: " << str.c_str() << " Number of surfaces in existence: " << c << " Number of characters in current surface: " << charcount << "\n";
}
//OK SO: the program separates the surfaces! Now to just make each surface different for each different message! To do this, we will put the "text" surface into the top of surface_vect, because that vector will be our messages body. Text will display all messages being typed, only when return is pressed is it added to the message surfaces body!
}
}
return true;
}
int main ( int argc, char* args[] )
{
time(¤tTime);
int count = 0;
text = TTF_RenderText_Solid(font, "First surface message!", textcolor);
surface_vect.push_back( text );
Timer myTime;
Timer fps;
if (init() == false ) {
return false;
}
logFile << "Everything initialized fine. \n" ;
if (load_files() == false) {
return false;
}
logFile << "All files loaded successfully.\n";
myTime.start(); //The time the loop started. Keeps track of the time.
while (quit == false )
{
fps.start(); //Frame timer.
std::stringstream time; //Something to convert the time into a string, along with a message.
while (SDL_PollEvent( &event ) ) {
count += 1;
if ( handle_input() == false ) {
logFile << "Handle_input() returned false on the: " << count << "th run through the while loop!";
return false;
}
if ( event.type == SDL_QUIT ) {
fps.stop();
myTime.stop();
quit = true; //Duh.
}
}
apply_surface(0,0, background, screen);
apply_surface ( 25, 435, text, screen ); //Render the text surface because its separate from the other surfaces! It needs its own render command.
for ( int c = 0; c <= surface_vect.size() - 1; c+=1 ) {
apply_surface(25, newY - (13 * c), surface_vect.at(c), screen);
}
if (SDL_Flip (screen) == - 1) {
return false;
}
frame += 1; //Frame counter. Used to
if( fps.get_ticks() < 1000 / FRAMES_PER_SECOND )
{
SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() );
}
}
clean_up();
return 0;
}
有更好的方法吗?它应该只是取用户文本,将其放入曲面矢量,并在上面显示它们。
答案 0 :(得分:0)
我不明白你对症状的描述,但是查看代码我猜你之后推入surface_vect
向量的文本不会显示,因为当用户按下返回键时你实际上是在做(我只保留相关部分):
surface_vect.push_back ( text );
SDL_FreeSurface ( text );
text = TTF_RenderText_Solid(font, str.c_str(), textcolor);
请记住text
变量和surface_vect
向量不包含实际曲面但指向曲面的指针,因此当您执行push_back时,不要将曲面的副本放入向量中,只是指针的副本。当你SDL_FreeSurface(text)
表面本身被清除时,这意味着你刚刚插入到矢量中的指针现在指向一个不会显示任何内容的清除表面......你可以通过执行text=NULL
来解决这个问题。在push_back之后(SDL_FreeSurface(text)
接受NULL并且不会做任何事情)
请注意,您的代码中存在许多其他小问题(例如您使用vector
,就像它是C数组一样,或者您应该使用list
代替它)但它不在问题的范围;)