Curses

需要使用这个库,通过这个库来进行屏幕的刷新

详情请参考:  http://blog.csdn.net/hengqiaqia/article/details/77882270
    通过学习了解了 curses ,在来进行贪吃蛇的游戏分析    
    蛇的移动问题,这个是核心部分以及最困难的设计部分了,我采用的是蛇用双向链表的结构来构造出来,分别有一个head 和tail指针,用来添加和删除元素。这里若要实现移动的话(未碰到食物前),就是在链表的头部(head的下一个)插入一个新元素,记录下此时的坐标,用mvaddch(y,x,c)函数添加蛇的图形'@',与此同时,在链表尾部(tail的前一个)删除一个节点,同时这里的坐标用mvaddch(y,' ')添加了' '空白字符,实现删除效果,最后加上refresh(). 这样就可以看到蛇在“移动”了。当然,要是碰到食物的话,尾部节点处就不用删除,达到增长长度的效
    如何触发蛇的移动呢?如何实现均匀移动以及通过按键 ‘f’ 或 's' 改变运动速度呢?这里我采用的是信号计时中断调用的函数  signal(SIgalRM,Snake_Move) 和 间隔计数器来实现,通过产生相同间隔的时间片段来不断地调用Snake_Move()函数来执行相应的功能。加减速的功能是通过设定其他变量ttm,ttg来实现再此基本计数器上面再次分频的效果来加减速,ttm,ttg 越大,减速越明显,反之则相反效果。
    思路: 双链表,每个结点记录的是当前蛇身的坐标跟前驱后继指针。这样在蛇移动时在头结点前添加一个结点,用move()移动到蛇头坐标,打印蛇头;接着如果没有吃到食物的话,把尾结点删掉,用move()移动到蛇尾,打印空值。
//mysnake1.0.c
//编译命令:gcc mysnake1.0.c -lcurses -o mysnake1.0 -Wall
//用方向键控制蛇的方向
#include<curses.h>
#include<stdlib.h>
#include<unistd.h>
#include<time.h>
struct Snack
{int x[100],y[100];
    int node;
    int life;
    int direction;
}snack;                     //
struct Food
{ int X,Y;
    int set;
}food;                      //食物
struct timespec delay;
struct timespec dummy;
time_t timer;
int TIME=0;
long Time,Time1=0,Time2=0; 
int ptime[100];
int score=0;
int i,tem[2],k=0;
void color();               // 画布
void init();                //初始化
void draw();                //
void start_attr();          //
void output();
void play();                //开始
void judge();               //判断蛇的位置
int pause_time(int,int *); // 时间暂停
void d_e();
int main(int argc,char **argv)
{

    init();
    draw();
    play(); 
    return 0; 
} 
void d_e()              //开始选择困难的程度
{
    int location=18;
    int ch2=KEY_LEFT,which=0;
    char str[2][5]={"Easy","Hard"};
    while(ch2!='\n')
    {

        switch(ch2)
        {
            case (KEY_LEFT):
                if(location!=18)
            {location-=10;which=0;}
                break;
            case (KEY_RIGHT):
                if(location==18)
            {location+=10;which=1;}
                break;
        }
        mvprintw(8,10,"Please choose the difficulty!");
        mvprintw(10,23,"^_^");
        mvprintw(12,18,"Easy");
        mvprintw(12,28,"Hard"); 
        attron(A_REVERSE);
        mvprintw(12,location,"%s",str[which]);
        attroff(A_REVERSE);
        refresh();
        ch2=getch();} 
    /*Time2=time(NULL); ptime[k]=Time2-Time1; k++; */ 
    if(location==28) 
        delay.tv_nsec=100000000; 
    else 
        delay.tv_nsec=200000000;
}

int pause_time(int k,int *PTIME)        //时间的暂停
{
    int j;int sum=0;
    for(j=0;j<k;j++)
        sum=sum+ptime[j];
    return sum;
}
void judge()                    // 蛇的位置
{
    if(snack.direction==1)
        snack.y[0]--;
    else if(snack.direction==2)
        snack.y[0]++;
    else if(snack.direction==3)
        snack.x[0]--;
    else 
        snack.x[0]++;
}
void color()                //周围的墙
{ 
    start_color();
    init_pair(1,COLOR_GREEN,COLOR_RED);
    attron(COLOR_PAIR(1));
    for(i=0;i<50;i++)
        mvaddch(0,i,'■');
    for(i=0;i<20;i++)
        mvaddch(i,0,'■');
    for(i=49;i>=0;i--)
        mvaddch(19,'■');
    for(i=19;i>=0;i--)
        mvaddch(i,49,'■');//Box(stdscr,'*','*');

    attroff(COLOR_PAIR(1));
}
void init()
{
    initscr();
    raw();
    noecho();
    keypad(stdscr,TRUE);
    curs_set(0);
    nodelay(stdscr,TRUE);
}
void draw()                 //蛇开始 以及食物
{
    snack.x[0]=6;
    snack.y[0]=3;
    snack.x[1]=5;
    snack.y[1]=3;
    snack.x[2]=4;
    snack.y[2]=3;
    snack.life=0;
    snack.node=1;
    snack.direction=4;
    food.set=0;
    color();
    d_e();
    for(i=0;i<snack.node;i++) 
        mvprintw(snack.y[i],snack.x[i],"$");
    refresh();

    timer=time(NULL);
}
void output()               //打印输出显示
{ color(); 
    mvprintw(20,"score=%d",score);
    mvprintw(20,43,"Node=%d",snack.node);
    mvprintw(21,"Time=%ds",TIME);
    attroff(A_REVERSE);
    refresh();
}
void start_attr()
{
    attron(A_REVERSE);
}

void play()
{
    while(1)
    { 
        Time=time(NULL);
        TIME=Time-timer-pause_time(k,ptime);
        clear(); 
        if(food.set==0)
        {
            food.X=rand()%50;
            while(food.X==0||food.X==49)
                food.X=rand()%50;
            food.Y=rand()%20;
            while(food.Y==0||food.Y==19)
                food.Y=rand()%20;
            food.set=1;
        } 
        tem[0]=snack.y[snack.node-1];tem[1]=snack.x[snack.node-1];
        for(i=snack.node-1;i>0;i--)
        { 
            snack.x[i]=snack.x[i-1];
            snack.y[i]=snack.y[i-1];
        }
        int ch=0;
        ch=getch();
        switch(ch)
        { 
            case(KEY_UP):
                if(snack.direction==3||snack.direction==4)
            {
                snack.y[0]--; 
                snack.direction=1;
            }
                else if(snack.direction==1)
                    snack.y[0]--;
                else
                    snack.y[0]++;
                break;
            case(KEY_DOWN):
                if(snack.direction==3||snack.direction==4)
            {
                snack.y[0]++;
                snack.direction=2;
            }
                else if(snack.direction==1)
                    snack.y[0]--;
                else
                    snack.y[0]++;
                break;
            case(KEY_LEFT):
                if(snack.direction==1||snack.direction==2)
            {
                snack.x[0]--;
                snack.direction=3;
            }
                else if(snack.direction==3)
                    snack.x[0]--;
                else
                    snack.x[0]++;
                break;
            case(KEY_RIGHT):
                if(snack.direction==1||snack.direction==2)
            {
                snack.x[0]++;
                snack.direction=4;
            }
                else if(snack.direction==3)
                    snack.x[0]--;
                else
                    snack.x[0]++;
                break;
            case 'p':case 'P':
                Time1=time(NULL);
                judge();
                for(i=0;i<snack.node;i++)
                    mvprintw(snack.y[i],">");
                mvaddch(food.Y,food.X,'$');
                start_attr();
                mvprintw(9,"Pause!Press 'p' to continue!"); 
                output(); 
                while(getch()!='p')
                    ; 
                Time2=time(NULL);
                ptime[k]=Time2-Time1;
                k++; 
                break;

            case 'q':case 'Q':
                Time1=time(NULL);
                judge();
                for(i=0;i<snack.node;i++)
                    mvprintw(snack.y[i],">"); 


                mvaddch(food.Y,'$');
                start_attr();
                mvprintw(10,22,"Quit!"); 
                output();
                int location=18;
                int ch2=KEY_LEFT,which=0;
                char str[2][5]={"No","Yes"};
                while(ch2!='\n')
                {

                    switch(ch2)
                    {
                        case (KEY_LEFT):
                            if(location!=18)
                        {location-=10;which=0;}
                            break;
                        case (KEY_RIGHT):
                            if(location==18)
                        {location+=10;which=1;}
                            break;
                    }
                    mvprintw(12,"No");
                    mvprintw(12,"Yes"); 
                    attron(A_REVERSE);
                    mvprintw(12,str[which]);
                    attroff(A_REVERSE);
                    refresh();
                    ch2=getch();} 
                Time2=time(NULL);
                ptime[k]=Time2-Time1;
                k++; 
                if(location==18) 
                    break; 
                else 
                { 
                    clear(); 
                    endwin();
                    exit(1);
                }
            default:
                judge();
                break;
        }
        for(i=1;i<snack.node;i++)
            if((snack.x[0]==snack.x[i]&&snack.y[0]==snack.y[i])||snack.x[0]==0||snack.y[0]==0||snack.x[0]==49||snack.y[0]==19)
            { for(i=1;i<snack.node;i++)
                {snack.x[i-1]=snack.x[i];snack.y[i-1]=snack.y[i];}
                snack.y[snack.node-1]=tem[0];
                snack.x[snack.node-1]=tem[1];
                for(i=0;i<snack.node;i++)
                    mvprintw(snack.y[i],">"); 
                mvaddch(food.Y,"You lose!");
                mvprintw(11,"Do you want again?(y/n)"); 
                output();
                snack.life=1;
                //sleep(1);

                break;
            }
        if(snack.x[0]==food.X&&snack.y[0]==food.Y)
        {
            food.set=0;
            snack.node++;
            score+=10;
            for(i=snack.node-1;i>0;i--)
            {
                snack.x[i]=snack.x[i-1];
                snack.y[i]=snack.y[i-1];
            }
            judge();
        }
        if(snack.life==0)
        { ;
            for(i=0;i<snack.node;i++)
                //身体
                mvprintw(snack.y[i],">");
            //attron(A_INVIS);
            //食物
            mvaddch(food.Y,'$');
            //sleep(1);

            //attroff(A_INVIS);

            start_attr();
            output();
            nanosleep(&delay,&dummy);//sleep(2);

        }

        else 
        {
            char ch1;
            while((ch1=getch()))
                if(ch1=='y'||ch1=='Y')
                { clear();
                    for(i=0;i<snack.node;i++)
                        snack.x[i]=snack.y[i]=-1;
                    TIME=Time1=Time2=k=0;
                    score=0;
                    draw();
                    snack.life=0; 
                    break;
                }
                else if(ch1=='n'||ch1=='N')
                {
                    //退出
                    endwin();
                    exit(1);
                }
                else continue;
        }
    }
}

来一张效果图:
效果图有点大,发不上来,已传云盘,以下链接:
https://pan.baidu.com/s/1ck3cgI

Ubuntu C语言 curses 贪吃蛇 小游戏的更多相关文章

  1. 用canvas做一个DVD待机动画的实现代码

    这篇文章主要介绍了用canvas做一个DVD待机动画的实现代码的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  2. H5 canvas实现贪吃蛇小游戏

    本篇文章主要介绍了H5 canvas实现贪吃蛇小游戏,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  3. ios – didUpdateLocations从未调用过

    我正在尝试获取用户的位置.为此,我在info.plist中设置了以下属性:我还在viewDidLoad方法中添加了以下代码以及下面的函数.问题是locationManager(manager,didUpdate…

  4. ios – 重命名并重写为Swift后对象解码崩溃

    由于我们已经重命名了(Bestemming–>Place)类并将其从Objective-c重写为Swift,因此一些用户会遇到崩溃.我们正在尝试使用NSCoding原则从NSUserDefaults加载对象.碰撞:班级:从NSUserDefaults阅读:崩溃日志说它在第0行崩溃,这是注释所以我认为它在init方法中崩溃,我认为它与一个null为空但不能为null的对象有关.我尝试过的:>尝试在S

  5. 适用于iOS的Google Maps SDK不断增加内存使用量

    我已经构建了一个在地图上显示标记的简单应用程序,我从服务器的JSON文件加载其x,y,标记是可点击的,所以一旦你在任何标记上它将你带到另一个UIViewController(我们将它命名为BViewController).我已经监视了内存使用情况,所以每次我从BViewController返回到MapViewController(里面的地图)时,它只是内存使用量的两倍我尝试将其设置为nill或从s

  6. ios – 未提示在应用程序中启用位置服务

    更新:这不是重复.我已经在info.plist中添加了所需的密钥,如我原始问题中所述,问题仍然存在.我已经尝试了各种组合的所有三个键.在任何人感到不安之前,我已阅读了许多AppleDev论坛帖子和堆栈溢出帖子,无法弄清楚为什么我的应用程序拒绝提示用户允许使用时授权.我已将以下密钥添加到我的Info.plist文件中,并附带一个String值:然后我写了(在Swift和Obj-C中)应该提示用户的代

  7. ios – 在UIViewController显示为3DTouch预览时检测UITouches

    是否有可能从UIViewController检测触摸并获取触摸的位置,UIViewController当前用作3DTouch的previewingContext视图控制器?

  8. ios – Google地图折线不完美呈现

    我正在使用最新的GoogleMapsAPIforiOS绘制折线.我正在逐点构造折线,但是当我缩小折线从地图中消失(不是字面上的术语)时,它不能正常渲染,当我放大时,它只会显示线条.这是放大时折线的显示方式这是缩小时的显示方式这里是我绘制折线的功能我有覆盖init:为RCpolyline是这样的东西和drawpolylineFromPoint:toPoint:这样做解决方法我发现这个故障,我正在制作

  9. ios – CLGeocoder错误. GEOErrorDomain代码= -3

    有没有关于apple的地理编码请求的文档?谢谢你提前.更新这是我的整个代码请求解决方法在搜索到答案后,它在Apples文档中!

  10. ios – Sprite Kit – 确定滑动精灵的滑动手势向量

    我有一个游戏,圆形物体从屏幕底部向上射击,我希望能够滑动它们以向我的滑动方向轻弹它们.我的问题是,我不知道如何计算滑动的矢量/方向,以便使圆形物体以适当的速度在正确的方向上被轻弹.我正在使用的静态矢量“(5,5)”需要通过滑动的滑动速度和方向来计算.此外,我需要确保一旦我第一次接触到对象,就不再发生这种情况,以避免双重击中对象.这是我目前正在做的事情:解决方法以下是如何检测滑动手势的示例:首先,定

随机推荐

  1. crontab发送一个月份的电子邮件

    ubuntu14.04邮件服务器:Postfixroot收到来自crontab的十几封电子邮件.这些邮件包含PHP警告.>我已经解决了这些警告的原因.>我已修复每个cronjobs不发送电子邮件(输出发送到>/dev/null2>&1)>我删除了之前的所有电子邮件/var/mail/root/var/spool/mail/root但我仍然每小时收到十几封电子邮件.这些电子邮件来自cronjobs,

  2. 模拟两个ubuntu服务器计算机之间的慢速连接

    我想模拟以下场景:假设我有4台ubuntu服务器机器A,B,C和D.我想在机器A和机器C之间减少20%的网络带宽,在A和B之间减少10%.使用网络模拟/限制工具来做到这一点?

  3. ubuntu-12.04 – 如何在ubuntu 12.04中卸载从源安装的redis?

    我从源代码在Ubuntu12.04上安装了redis-server.但在某些时候它无法完全安装,最后一次makeinstallcmd失败.然后我刚刚通过apt包安装.现在我很困惑哪个安装正在运行哪个conf文件?实际上我想卸载/删除通过源安装的所有内容,只是想安装一个包.转到源代码树并尝试以下命令:如果这不起作用,您可以列出软件自行安装所需的步骤:

  4. ubuntu – “apt-get source”无法找到包但“apt-get install”和“apt-get cache”可以找到它

    我正在尝试下载软件包的源代码,但是当我运行时它无法找到.但是当我运行apt-cache搜索squid3时,它会找到它.它也适用于apt-getinstallsquid3.我使用的是Ubuntu11.04服务器,这是我的/etc/apt/sources.list我已经多次更新了.我尝试了很多不同的debs,并没有发现任何其他地方的错误.这里的问题是你的二进制包(deb)与你的源包(deb-src)不

  5. ubuntu – 有没有办法检测nginx何时完成正常关闭?

    &&touchrestarted),因为即使Nginx没有完成其关闭,touch命令也会立即执行.有没有好办法呢?这样的事情怎么样?因此,pgrep将查找任何Nginx进程,而while循环将让它坐在那里直到它们全部消失.你可以改变一些有用的东西,比如睡1;/etc/init.d/Nginx停止,以便它会休眠一秒钟,然后尝试使用init.d脚本停止Nginx.你也可以在某处放置一个计数器,这样你就可以在需要太长时间时发出轰击信号.

  6. ubuntu – 如何将所有外发电子邮件从postfix重定向到单个地址进行测试

    我正在为基于Web的应用程序设置测试服务器,该应用程序发送一些电子邮件通知.有时候测试是使用真实的客户数据进行的,因此我需要保证服务器在我们测试时无法向真实客户发送电子邮件.我想要的是配置postfix,以便它接收任何外发电子邮件并将其重定向到一个电子邮件地址,而不是传递到真正的目的地.我正在运行ubuntu服务器9.10.先感谢您设置本地用户以接收所有被困邮件:你需要在main.cf中添加:然后

  7. ubuntu – vagrant无法连接到虚拟框

    当我使用基本的Vagrantfile,只配置了两条线:我看到我的虚拟框打开,但是我的流氓日志多次显示此行直到超时:然后,超时后的一段时间,虚拟框框终于要求我登录,但是太久了!所以我用流氓/流氓记录.然后在我的物理机器上,如果我“流氓ssh”.没有事情发生,直到:怎么了?

  8. ubuntu – Nginx – 转发HTTP AUTH – 用户?

    我和Nginx和Jenkins有些麻烦.我尝试使用Nginx作为Jenkins实例的反向代理,使用HTTP基本身份验证.它到目前为止工作,但我不知道如何传递带有AUTH用户名的标头?}尝试将此指令添加到您的位置块

  9. Debian / Ubuntu – 删除后如何恢复/ var / cache / apt结构?

    我在ubuntu服务器上的空间不足,所以我做了这个命令以节省空间但是现在在尝试使用apt时,我会收到以下错误:等等显然我删除了一些目录结构.有没有办法做apt-getrebuild-var-tree或类似的?

  10. 检查ubuntu上安装的rubygems版本?

    如何查看我的ubuntu盒子上安装的rubygems版本?只是一个想法,列出已安装的软件包和grep为ruby或宝石或其他:)dpkg–get-selections

返回
顶部