简单的《贪吃蛇》全局刷新法(C语言,字符界面)

学C语言一年了, 一直想写个游戏练练手。 这次放假没有课设, 想写个贪吃蛇。 在网上找了一些资料, 有的很复杂几百行, 有的很简单几十行。 参照其他人的想法终于是写出了自己的 小「贪吃蛇」。

 

第一种方法是, 定义一个二维数组 map[][] , 用例如 1,2,3 等数字标记墙,蛇身和食物。 根据键盘动作修改数组,再根据权值打印 map 。

 1 int main(void){
 2     
 3     int direction = UP;    //初始方向向上 
 4     init_game();            //初始化游戏界面 
 5     for(; ;){
 6         direction = get_dir(direction);
 7         move_snake(direction);        //贪吃蛇做下一步的动作 
 8         flag_map();            //标记 map 数组 
 9         print_map();        //按照数组打印图形 
10         Sleep(500);            //延迟 x ms 
11         if(!is_alive())
12             break;
13     }
14     printf("	Game Over !
");
15     return 0;
16 }

get_dir( direction ) 函数功能为获取键盘方向, 返回按下的方向键的值。 根据键盘码可知, 方向键对应的值我们可以定义 : 

#define    LEFT    75    
#define    UP        72    
#define    RIGHT    77    
#define    DOWN    80

 标记 map 和打印 map 的函数很简单, 只是数组的循环并判断 : 

 1 void flag_map(){
 2     int i, j;
 3     Snake *p = NULL;
 4     for(i=0; i<ROWS; i++){
 5         for(j=0; j<COLUMNS; j++){
 6             if(i==0 || i==ROWS-1 || j==0 || j==COLUMNS-1)
 7                 map[i][j] = 1;                                    // 1 表示墙 
 8             else
 9                 map[i][j] = 0;                                    // 0 表示空 
10         }
11     }
12     for(p = head; p; p = p->next)                        //2 表示蛇 
13         map[p->cor.Y][p->cor.X] = 2;
14     //3 表示食物, 首先得CreatFood() 
15     map[Food.y][Food.x] = 3;
16 }
17 
18 void print_map(){
19     int i, j;
20     system("cls");
21     for(i=0; i<ROWS; i++){             
22         for(j=0; j<COLUMNS; j++){
23             if(map[i][j] == 1)
24                 printf("#");
25             else if(map[i][j] == 2)         
26                 printf("*");
27             else if(map[i][j] == 3)
28                 printf("@");//
29             else
30                 printf(" ");
31         }
32         putchar('
');
33     }

这种写法简单,但是低效, 更大的问题是由于每次的动作都通过清除屏幕, 再打印整个数组实现的所以有可能会出现闪屏现象。

所以这种方法不够好, 墙打印一次就够了, 不需要再打印, 蛇只需要随着蛇头坐标的改变而打印, 按照是否吃到了食物选择该不该去尾, 食物只需要被吃的时候打印。 这些我们该怎么实现呢?  

为了局部刷新,用到了gotoxy()函数,TC自带(不知道TC是啥),所以自己写一个,其实就是一个转到x,y坐标的一个函数。

void gotoxy(COORD pt)

{

    HANDLE hout;

    hout = GetStdHandle(STD_OUTPUT_HANDLE);

    SetConsoleCursorPosition(hout, pt);

}

HANDLE(句柄)在windows编程中是一个十分重要的概念。在window编程中,对于一个Object(对象)我们只能通过Handle来访问它。觉得不好理解的同学把句柄当作指针来看待就好了。

GetStdHandle函数获取一个指向特定标准设备的句柄,包括标准输入,标准输出和标准错误。STD_OUTPUT_HANDLE正是代表标准输出(也就是显示屏)的宏。

SetConsoleCursorPosition函数用于设置控制台光标的位置。

有了这个我们就可以思考新的方法了, 即局部更新。 在此只是给了一个想法, 没有给出数据结构, 蛇的移动函数(核心), 创建食物的算法。 (H b)会在下一篇局部更新和链表的方法中给出整个思路及代码。

原文地址:https://www.cnblogs.com/ozel/p/7162096.html