简体   繁体   中英

print characters of a string or array in C Fast

I'm coding a Game-Console and i save map of a game in character array and i need to print them colored (with different colors) in CMD so i write print_map function i attach it here , I used printf to print and SetConsoleTextAttribute to made them colored nut it was too slow printing.I need to print these characters of map fast so help me to print them colored and fast please.

void print_mapp(){
  clear();//clear screen
  int width,height,i,x,y;
  HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

  width = map_width;
  height = map_height;
  SetConsoleTextAttribute(hConsole,background_color);

  x=4;
  y=2;

  for(i=0;i<width*(height+1);i++){
    SetPosition(x,y);// set cursor to (x,y)
    if(map[i] == ' '){
        SetConsoleTextAttribute(hConsole,background_color);
        printf("%c",map[i]);
    }
    else if(map[i] == wall){
        SetConsoleTextAttribute(hConsole,wall_color);
        printf("%c",map[i]);
    }
    else if(map[i] == solidblock){
        SetConsoleTextAttribute(hConsole,solidblock_color);
        printf("%c",map[i]);

    }
    else if(map[i] == moveblock){
        SetConsoleTextAttribute(hConsole,moveblock_color);
        printf("%c",map[i]);

    }
    else if(map[i] == deathblock){
        SetConsoleTextAttribute(hConsole,death_blk_color);
        printf("%c",map[i]);

    }
    else if(map[i] == character){
        SetConsoleTextAttribute(hConsole,character_color);
        printf("%c",map[i]);

    }
    else if(map[i] == rpoint){
        SetConsoleTextAttribute(hConsole,rpoint_color);
        printf("%c",map[i]);

    }
    else if(map[i] == target){
        SetConsoleTextAttribute(hConsole,target_color);
        printf("%c",map[i]);

    }
    else if(map[i] == object){
        SetConsoleTextAttribute(hConsole,object_color);
        printf("%c",map[i]);

    }
    else if(map[i] == opp){
        SetConsoleTextAttribute(hConsole,opp_color);
        printf("%c",map[i]);

    }

    else if(map[i] == bullet){
        SetConsoleTextAttribute(hConsole,bullet_color);
        printf("%c",map[i]);

    }
    else if(map[i] == '\n'){
      SetConsoleTextAttribute(hConsole,background_color);
      printf("%c",map[i]);
      x = 3;
      y++;
    }
    else{
      SetConsoleTextAttribute(hConsole,wall_color);
      printf("%c",map[i]);

    }

    x++;
  }

}```

I would guess that every call to SetPosition() and SetConsoleTextAttribute() causes stdout to be flushed. That results in a flush for every char you print.

So you should try to only call them when the position or character attribute differs from what you expect them to be.

Using fputc() rather than printf("%c", ..) may also give a theoretical speedup, but not enough that it matters in practice. But some, (including me) thinks the code looks cleaner that way...

So here is a suggested improvement:

void
set_attrib(HANDLE h, WORD attr, WORD *old_attr)
{
  if (attr != *old_attr)
    {
      SetConsoleTextAttribute(h, attr);
      *old_attr = attr;
    }
}

void print_mapp()
{
  clear();//clear screen
  int width,height,i,x,y;
  HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

  width = map_width;
  height = map_height;

  WORD old_attr;

  SetConsoleTextAttribute(hConsole,background_color);
  old_attr = background_color;

  x=4;
  y=2;

  SetPosition(x,y);// set cursor to (x,y)


  for(i=0;i<width*(height+1);i++)
    {
      if(map[i] == ' '){
        set_attr(hConsole, background_color, &old_attr);
        fputc(map[i], stdout);
      }
      else if(map[i] == wall){
        set_attr(hConsole, wall_color, &old_attr);
        fputc(map[i], stdout);
      }
      ....  
      else if(map[i] == '\n'){
        set_attr(hConsole, background_color, &old_attr);
        fputc(map[i], stdout);
        x = 3;
        y++;
        SetPosition(x+1,y);// set cursor to (x,y)

      }
      else{
        set_attr(hConsole, wall_color, &old_attr);
        fputc(map[i], stdout);
      }

    x++;
  }

}

Other suggestions for speedup:

  1. You could print ansi color code, rather than calling SetConsoleTextAttribute()
  2. You could limit yourself to only print those lines that have changed after last call to print_mmap()

Some cleanup suggestions (won't have any significant effect on speed):

  1. Move fputc() outside of if and if else
  2. Rather have printable characters in map[i] , just have enums describing game-objects, and look up printable characters and attributes in a separate lookup-array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM