zoukankan      html  css  js  c++  java
  • 简单的《贪吃蛇》全局刷新法(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)会在下一篇局部更新和链表的方法中给出整个思路及代码。

  • 相关阅读:
    MFC菜单、工具栏和状态栏
    MFC控件
    MFC对话框
    MFC消息映射机制
    性能优化可使用的工具
    常见的内存问题分析思路
    k8s之Probe
    docker swarm
    keepalived配置虚拟ip(vip)实现双机热备以及自动切换主备
    linux安装openjdk1.8
  • 原文地址:https://www.cnblogs.com/ozel/p/7162096.html
Copyright © 2011-2022 走看看