编程论坛's Archiver

yuleol 发表于 2006-7-5 23:35

一个经典小游戏(贪食蛇)

<P>本人刚学C不久,编了这个小游戏在windows2000+ccdos+tc2,0下编译通过!<BR>欢迎大家提意见!附件里有编译好的可执行文件和源码!<BR>[attach]9500[/attach]<BR><BR>/*============================================================<BR>贪食蛇游戏V1.0<BR>============================================================*/<BR>#include &lt;graphics.h&gt;<BR>#include &lt;stdlib.h&gt;<BR>#include &lt;stdio.h&gt;<BR>#include &lt;bios.h&gt;<BR>#include &lt;dos.h&gt;<BR>#define SPACE 0x3920<BR>#define UP 0x4800<BR>#define DOWN 0x5000<BR>#define LEFT 0x4b00<BR>#define RIGHT 0x4d00<BR>#define ESC 0x011b<BR>#define LONG 100/*定义最大蛇身长度!*/<BR>struct  container{<BR>    int left;<BR>    int top;<BR>    int right;<BR>    int bottom;<BR>    int sign; /*记号,0表示空白,1表示墙,2表示食物*/<BR>}lab[22][42];/*定义大容器存储结构*/</P>
<P>struct snakes{<BR>    int i;<BR>    int j;<BR>    int sign;/*0空白,1蛇头,2蛇身*/<BR>}snake[LONG];</P>
<P>int mark,grade,max;<BR>/*初始化图形显示*/<BR>int initialize(void)<BR>{<BR>    int gdriver, gmode,errorcode;<BR>    gdriver=VGA;<BR>    gmode=VGAHI;<BR>    initgraph(&amp;gdriver, &amp;gmode, "");<BR>    errorcode = graphresult();<BR>    if (errorcode != grOk)  /* an error occurred */<BR>   {<BR>      printf("Graphics error: %s\n", grapherrormsg(errorcode));<BR>      printf("Press any key to halt:");<BR>      getch();<BR>      exit(1);             /* return with error code */<BR>   }<BR>   return 0;<BR>}</P>
<P>void showcontainer(int i,int j)<BR>{/*显示容器函数*/<BR>     switch(lab[i][j].sign)<BR>     {<BR>         case 0: setfillstyle(SOLID_FILL,LIGHTBLUE);break;<BR>         case 1: setfillstyle(SOLID_FILL,RED); break;<BR>         case 2: setfillstyle(SOLID_FILL,LIGHTCYAN);break;<BR>     }<BR>     bar(lab[i][j].left,lab[i][j].top,lab[i][j].right,lab[i][j].bottom);<BR>}</P>
<P>/*生成容器函数*/<BR>void initialcontainer()<BR>{<BR>    int i,j,leftx=100,topy=50,rightx=110,bottomy=60;<BR>    for(i=0;i&lt;22;i++)<BR>      for(j=0;j&lt;42;j++)<BR>      {<BR>          lab[i][j].left=leftx+j*10;<BR>         lab[i][j].top=topy+i*10;<BR>         lab[i][j].right=rightx+j*10;<BR>         lab[i][j].bottom=bottomy+i*10;<BR>           lab[i][j].sign=0;<BR>       }<BR>    for(i=0;i&lt;22;i++)<BR>    {<BR>        lab[i][0].sign=1;<BR>        lab[i][41].sign=1;<BR>    }<BR>    for(j=0;j&lt;42;j++)<BR>    {<BR>        lab[0][j].sign=1;<BR>        lab[21][j].sign=1;<BR>    }<BR>    for(i=0;i&lt;22;i++)<BR>      for(j=0;j&lt;42;j++)<BR>        showcontainer(i,j);<BR>}</P>
<P>void initialsnake()<BR>{/*初始化蛇身*/<BR>    int i;<BR>    for(i=3;i&lt;LONG;i++)<BR>      snake[i].sign=0;<BR>    snake[0].i=10;<BR>    snake[0].j=3;<BR>    snake[0].sign=1;</P>
<P>    snake[1].i=10;<BR>    snake[1].j=2;<BR>    snake[1].sign=2;</P>
<P>    snake[2].i=10;<BR>    snake[2].j=1;<BR>    snake[2].sign=2;<BR>}</P>
<P>void showsnake()<BR>{/*显示蛇*/<BR>    int n,i,j;<BR>    for(n=0;n&lt;LONG &amp;&amp; snake[n].sign!=0;n++)<BR>    {<BR>        switch(snake[n].sign)<BR>        {<BR>            case 1:setfillstyle(SOLID_FILL,BLUE);break;<BR>            case 2:setfillstyle(SOLID_FILL,GREEN);break;<BR>        }<BR>        i=snake[n].i;<BR>        j=snake[n].j;<BR>        bar(lab[i][j].left,lab[i][j].top,lab[i][j].right,lab[i][j].bottom);<BR>    }<BR>}</P>
<P>void cleansnake()<BR>{/*擦除蛇*/<BR>    int n,i,j;<BR>    for(n=0;n&lt;LONG &amp;&amp; snake[n].sign!=0;n++)<BR>    {<BR>        setfillstyle(SOLID_FILL,LIGHTBLUE);<BR>        i=snake[n].i;<BR>        j=snake[n].j;<BR>        bar(lab[i][j].left,lab[i][j].top,lab[i][j].right,lab[i][j].bottom);<BR>    }<BR>}</P>
<P>void createfood()<BR>{/*创建食物*/<BR>    int n,i,j,flag;<BR>    srand((int)time(0));<BR>    do{<BR>        flag=1;<BR>        i=rand()%20+1;<BR>        j=rand()%40+1;<BR>        for(n=0;n&lt;LONG &amp;&amp; snake[n].sign!=0;n++)<BR>            if(i==snake[n].i &amp;&amp; j==snake[n].j)<BR>            {<BR>                flag=0;<BR>                break;<BR>            }<BR>    }while(flag==0);<BR>    lab[i][j].sign=2;<BR>    showcontainer(i,j);<BR>}<BR>void showmark()<BR>{/*显示分数和等及*/<BR>    char b[10],*p=b;<BR>    p=itoa(mark,p,10);<BR>    setfillstyle(SOLID_FILL,BLUE);<BR>    bar(200,20, 400, 40);<BR>    moveto(210,25);<BR>    outtext("score:");<BR>    outtext(p);<BR>    p=itoa(grade,p,10);<BR>    outtext("  grade:");<BR>    outtext(p);<BR>}<BR>int run(int i,int j)<BR>{<BR>    int n;<BR>    if(i&lt;1 || i&gt;20 || j&lt;1 || j&gt;40)<BR>        return 0;/*碰壁*/<BR>    for(n=0;n&lt;LONG &amp;&amp; snake[n].sign!=0;n++)<BR>        if(snake[n].i==i &amp;&amp; snake[n].j==j)<BR>          return 0;/*碰到自己*/<BR>    cleansnake();<BR>    if(lab[i][j].sign==2)<BR>    {/*遇到食物*/<BR>        snake[max].sign=2;<BR>        max++;<BR>        lab[i][j].sign=0;<BR>        mark=mark+100*grade;<BR>        if((max-3)%10==0)    grade++;<BR>        showmark();<BR>        createfood();<BR>    }<BR>    for(n=max;n&gt;=1;n--)<BR>    {<BR>        snake[n].i=snake[n-1].i;<BR>        snake[n].j=snake[n-1].j;<BR>    }<BR>    snake[0].i=i;<BR>    snake[0].j=j;<BR>    showsnake();<BR>    return 1;<BR>}<BR>void pause()<BR>{/*暂停*/<BR>    setfillstyle(SOLID_FILL,BLUE);<BR>    bar(120,300, 480, 350);<BR>    moveto(130,320);<BR>    outtext("Press any key to start...");<BR>    while(!bioskey(1)) sleep(1);<BR>    bar(120,300, 480, 350);<BR>    moveto(130,320);<BR>    outtext("Press SPACE to pause,ESC to exit...");<BR>}</P>
<P>int main(void)<BR>{<BR>    int i=10,j=3,flag=1,n;<BR>    int key=RIGHT,keytemp,keyreve=LEFT;<BR>    mark=0;<BR>    grade=1;<BR>    max=3;<BR>    initialize();/*初始化图形显示*/<BR>    setbkcolor(LIGHTBLUE);<BR>    setcolor(RED);<BR>    initialcontainer();<BR>    initialsnake();<BR>    showsnake();<BR>    createfood();<BR>    showmark();<BR>    pause();<BR>    while(flag==1)<BR>    {<BR>        if(bioskey(1))<BR>            keytemp=bioskey(0);<BR>        if(keytemp==ESC)<BR>          break;<BR>        if(keytemp==SPACE)<BR>        {<BR>            pause();<BR>            keytemp=key;<BR>        }<BR>        else<BR>        {<BR>            if(keytemp==UP || keytemp==DOWN || keytemp==RIGHT || keytemp==LEFT)<BR>              if(keytemp!=key &amp;&amp; keytemp!=keyreve)<BR>                key=keytemp;<BR>            switch(key)<BR>            {<BR>                case UP: i--;keyreve=DOWN;break;<BR>                case DOWN: i++;keyreve=UP;break;<BR>                case RIGHT: j++;keyreve=LEFT;break;<BR>                case LEFT:    j--;keyreve=RIGHT;break;<BR>            }<BR>            flag=run(i,j);<BR>            for(n=0;n&lt;20-grade*2;n++)<BR>                delay(9000);/*关于这个函数的使用,我一直弄不明白,按照资料说明这应该暂停了9秒钟,但是我在实际编译中,只暂字了不到十分之一秒~晕*/<BR>        }<BR>    }<BR>    setfillstyle(SOLID_FILL,BLUE);<BR>    bar(120,300, 480, 350);<BR>    moveto(130,310);<BR>    outtext("GAME OVER!");<BR>    moveto(130,330);<BR>    outtext("Press any key to exit...");<BR>    sleep(5);<BR>    fflush(stdin);<BR>    getch();<BR>    closegraph();/*关闭图形显示*/<BR>    return 0;<BR>}<BR></P>

jig 发表于 2006-7-6 09:10

不错,顶~~!!

SunShining 发表于 2006-7-6 11:03

不错..不过没有加速度..用delay() 做点文章就可以了[em01]

song4 发表于 2006-7-6 11:14

sleep呢

yuleol 发表于 2006-7-6 11:27

我有用delay()函数啊,但是用了delay(9000);感觉也没有停顿0.1秒,<BR><BR>而用sleep呢,最小停顿1秒~~<BR><BR>游戏又太慢~

SunShining 发表于 2006-7-6 11:38

<P>#include &lt;time.h&gt;<BR>#include &lt;stdio.h&gt;<BR>void my_delay(unsigned long ms);</P>
<P>int main(void)<BR>{<BR>   int i;<BR>   for(i=0;i&lt;10;i++)<BR>   {<BR>     printf("nihao ");</P>
<P>    my_delay(100);<BR>    }<BR>    printf("\n") ;</P>
<P>    return 0;<BR>}</P>
<P>void my_delay(unsigned long ms)<BR>{<BR>    double start_time = (double)clock() / CLOCKS_PER_SEC * 1000;<BR>    while ( (double)clock() / CLOCKS_PER_SEC * 1000 - start_time &lt; ms ) ;<BR>}</P>
<P><STRONG>标准C的模拟delay函数版本...不过不知道TC下如何.[em01]</STRONG><BR></P>

yuleol 发表于 2006-7-6 11:47

先去吃饭,回来后测一下你这个函数

SunShining 发表于 2006-7-6 11:53

delay()与CPU处理速度有关.

yuleol 发表于 2006-7-6 11:57

错误 aa.c 21: 未定义的符号'CLOCKS_PER_SEC'在 my_delay 函数中<BR><BR>win-tc

SunShining 发表于 2006-7-6 12:16

C-FREE  无错误..[em02]

SunShining 发表于 2006-7-6 12:18

<P>[CODE]#include &lt;time.h&gt;<BR>#include &lt;stdio.h&gt;<BR>#ifndef  CLOCKS_PER_SEC<BR>#define  CLOCKS_PER_SEC 18<BR>#endif<BR>void my_delay(unsigned long ms);<BR>int main(void)<BR>{<BR>   int i;<BR>   for(i=0;i&lt;10;i++)<BR>   {</P>
<P>    my_delay(1000);<BR>    printf("nihao ");<BR>    }<BR>    printf("\n") ;<BR>    return 0;<BR>}<BR>void my_delay(unsigned long ms)<BR>{<BR>    double start_time = (double)clock() / CLOCKS_PER_SEC * 1000;<BR>    while ( (double)clock() / CLOCKS_PER_SEC * 1000 - start_time &lt; ms ) ;<BR>}[/CODE]<BR><BR>稍微改了一下..你去测试一下吧[em01]</P>

yuleol 发表于 2006-7-6 14:55

已经可以了,谢谢~

jig 发表于 2006-7-8 10:55

顶,8错,还有个时间停顿的,直接硬件操作,可是实现精确停顿,可惜我忘了具体怎么写,呵呵。LZ到网上去找找吧

gamebcc 发表于 2007-10-30 16:07

11楼的代码太有用了,小弟都不知道怎么谢了...<br>好感动啊~~~~

eakcon 发表于 2007-11-14 10:06

太有味了<BR>

van3d 发表于 2007-12-29 15:26

不错,如果可以把界面做的更好一点就更好了

sunkaidong 发表于 2007-12-29 19:56

都是强人,关于图形库函数的引入有什么好的使用文档吗?

sjyf 发表于 2008-1-26 10:10

我的是液晶显示器,怎么显示呢?
要修改那些图形初始化的代码?

awsw911 发表于 2008-2-27 13:05

[bc07] 都好厉害啊!!佩服啊

Love嵌入式 发表于 2008-3-9 10:54

Graphics error: Device driver file not found (EGAVGA.BGI)
Press any key to halt:

TC2.0下不能运行啊!!

页: [1] 2

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.