课程设计之贪吃蛇小游戏制造

课程设计封面;

目 录

1 前言 1
2 需求分析 1
2.1 课程设计目的 1
2.2 课程设计任务 1
2.3 设计环境 1
2.4 开发语言 1
3 分析和设计 1
3.1 模块设计 1
3.2 系统流程图 1
3.3 主要模块的流程图 2
4 具体代码实现 2
5 课程设计总结 2
5.1 程序运行结果 / 预期运行结果 2
5.2 课程设计体会 2
参考文献 2
致 谢 2

1 前言
编写一个程序来实现贪吃蛇小游戏的运行。通过结构体以及结构体数组和各种函数的调用来实现该游戏的功能。
2 需求分析
2.1 课程设计目的
该课程设计主要是利用学习到的c语言来编写贪吃蛇小游戏。
2.2 课程设计任务
(1). 通过编写“贪吃蛇游戏”程序,掌握结构化,模块块化程序设计的思想,培养解决实际问题的能力。
(2). 设计好数组元素与蛇,食物的对应关系,实现按键控制方向。
(3) . 随机产生食物。
(4). 有分数统计,等功能。
2.3 设计环境
(1)WINDOWS 2000/2003/XP/7/Vista系统
(2)Visual C++或TC集成开发环境
2.4 开发语言
C语言
3 分析和设计
一;先了解关于该代码的课外知识。如下
1;#include

#include<conio.h>
#include<windows.h>
void gotoxy(int x ,int y)
{
    COORD c;//大写的COORD;
    c.X = x;
    c.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
}

这样子在最开始定义了之后,那么就可以在后面使用这个函数了。
3;a = getch();函数;这个可以不是;getchar哦。应该是兄弟吧;
getch();
头文件是#include<conio.h>
功能是;从键盘上读取一个字符,但不将读入的一个字符显示在屏幕上。
难点;getch的用法,使用getch时要打两个输入,
a=getch();
b=getch();
先判断a,即getch的返回值;按f1到f12就返回0反之返回224;
b才是真正的getch所接收的符号。
还有就是要注意的一点是;getch();并非标准C中的函数,不存在C语言中。所以在使用的时候要注意程序的可移植性;
4;system();函数;
头文件;#include<stdlib.h>;
system是一种windows操作系统下的函数语言;
现在我们只了解颜色和清屏,暂停;
暂停;system(“pause”);
清屏就是;system(“cls”);
颜色就举例子吧。
例如 system(“color 0A”); 其中color后面的0是背景色代号,A是前景色代号。各颜色代码如下:
0=黑色 1=蓝色 2=绿色 3=湖蓝色 4=红色 5=紫色 6=黄色 7=白色 8=灰色 9=淡蓝色 A=淡绿色 B=淡浅绿色 C=淡红色 D=淡紫色 E=淡黄色 F=亮白色
5;SetConsoleTextAttribute()函数;
SetConsoleTextAttribute是API设置控制台窗口字体颜色和背景色的函数;这个函数的使用主要是查找资料吧,参数太长了。
举个例子;
FOREGROUND_RED表示设置前景色为红色,即字体的颜色为红色;
FOREGROUND_INTENSITY 表示设置前景色为高亮显示,FOREGROUND_GREEN表示绿色,两个参数中间加“|”表示前景色为高亮绿色;
BACKGROUND_INTENSITY表示设置背景色为高亮显示,BACKGROUND_BLUE表示背景色为蓝色,BACKGROUND_INTENSITY |BACKGROUND_BLUE两个参数就使背景色为高亮蓝色。
要表示红色字体,白色背景可以使用SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_INTENSITY |FOREGROUND_INTENSITY | FOREGROUND_RED|BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
颜色得来是三个里面混合得来的,比如白色就是红蓝绿三色混合;
这只是了解一下,程序中具体的使用就要直接百度来控制颜色;
6;loop;
goto loop;
的使用。
Goto是跳转到程序指定的地方。
Loop;就是指goto要跳转的地方;
7;srand与rand;就是随机函数;专业的就是随机数发生器的初始化函数。
再看使用。两者是一起使用的,产生伪随机序列;
Srand()和其中的参数。来产生生成伪随机数序列的种子。如果参数没有变化那么,rand产生的随机数将不会变化,因此需要一个变化的参数;一般选择系统时间来改变系统的种子值,即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列。注意time(NULL)函数在time.h头文件里面。
rand()函数的使用;要与%搭配。rand()%(a)+b;b表示随机数会在b开始的(str),a就是end-str+1;则它的表达式就是给出了一个str到end的随机数;为什么一定a是end-str+1。代值,当想表示从2到100,就是rand()%(99)+2;产生99时就是出现2的随机数,产生98时就是出现100的随机数。
8;我们要从键盘上输入控制方向的键;那么我们就应该判断他是否读入成功,因此就要kbhit()函数;
作用就是;检查当前是否有键盘输入,若有则返回一个非0值,否则返回0
头文件;#include<conio.h>;
9;一旦出现问题;就要exit()函数来反应过来;
功能是;关闭所有文件,终止正在执行的进程
exit(1)表示异常退出.这个1是返回给操作系统的;
exit(0)表示正常退出;
10;f1到f12的数字表示;
因为f1到f12没有asc||码,则只能用扫描码;
F1======59;
F2======60;
F3======61;
F4======62;
其余依次类推;
11;控制方向的按键,方向键上下左右与WXAD是一样的asc||码,则不需要分开处理或者限制;
这里写图片描述
流程图
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
实现代码

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>
#include<conio.h>

#define height 28
#define width 60
#define n 400

void GameStart();//游戏开始 
void First_snack();//初始化的蛇 
int move();//蛇头的移动和数据的更新 
void move_snack();//蛇的其他部位移动 
void static_info();//静态数据 
void food_move();//食物的出现
int judge_head();//判断是否死亡 
int GameOver();//游戏结束 
void dynamic_info();//动态数据

int node;
int music;
int speed;
int direction;
int score;
int p;

struct SNACK
{
    int x;
    int y;
    int life;
}snack[n];
struct FOOD
{
    int x;
    int y;
}food;

void gotoxy(int x,int y)
{
    COORD c;
    c.X = x;
    c.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
}

void Game_frame()//框架; 
{
    int i;
    for(i = 1; i <= height; i++){//为什么竖是加1而横是加2; 
        gotoxy(0,i);
        printf("■");//因为这是中文状态下的; 
        gotoxy(width,i);
        printf("■");
    }
    for(i = 0; i <= width+1; i=i+2){
        gotoxy(i,0);
        printf("■");
        gotoxy(i,height+1);
        printf("■");
    }
}

void First_snack()//蛇的初始位置; 
{
    int i, j = 0;
    Game_frame();
    for(i = 0; i < node; i++){
        snack[i].x = 28-j;
        snack[i].y = 17;
        j = j-2;
        gotoxy(snack[i].x,snack[i].y);  printf("■");
    }
}

//蛇头移动和数据更新 
int move()
{
    int a,b ;
    static_info();
    int key_direction=3;
    while(!kbhit())//没按键进入 
    {
        loop://下次 
        gotoxy(food.x,food.y);printf("※");
        switch(key_direction)//头的移动; 
        {
            case 1 : move_snack();   snack[0].y=snack[0].y-1;gotoxy(snack[0].x,snack[0].y);printf("■");  break;//向上移
            case 2 : move_snack();   snack[0].y=snack[0].y+1;gotoxy(snack[0].x,snack[0].y);printf("■");  break;//向下移
            case 3 : move_snack();   snack[0].x=snack[0].x-2;gotoxy(snack[0].x,snack[0].y);printf("■");  break;//向左移
            case 4 : move_snack();   snack[0].x=snack[0].x+2;gotoxy(snack[0].x,snack[0].y);printf("■");  break;//向右移
        }
    dynamic_info();
    judge_head();
    if(p == 0){
        return 0;
    }
    Sleep(speed);//暂停的时间来控制速度 
    }
    a=getch();//getch的返回值 
    b=getch();//getch的接收的符号。 
    switch(a)
    {
    case 224:switch(b)//更改方向
             {//1---下;2代表上;3代表左;4代表右; 
                case 72:key_direction=1;if(direction==2)    key_direction=0;    break;
                case 75:key_direction=3;if(direction==4)    key_direction=0;    break;
                case 80:key_direction=2;if(direction==1)    key_direction=0;    break;
                case 77:key_direction=4;if(direction==3)    key_direction=0;    break;
             }break;
    case 0:  switch(b)//功能选项
             {
                case 59:speed-=20;break;
                case 60:speed+=20;break;
                case 61:music=music==1?0:1;break;
                case 62:system("color 0C");static_info();break;//红色
                case 63:system("color 0E");static_info();break;//黄色
                case 64:system("color 0A");static_info();break;//绿色
                case 65:system("color 0D");static_info();break;//紫色
                case 66:system("color 0F");static_info();break;//亮白色
                case 67:system("color 08");static_info();break;//灰色
             }break;
    default: goto loop;
    }
    if(key_direction)
        direction=key_direction;// 实现按反向键时暂停; 
    else
        goto loop;
    goto loop;//表示返回到loop位置, 
}

//蛇的其他部位移动 
void move_snack()
{
    int i ;
    gotoxy(snack[node-1].x,snack[node-1].y); //清除蛇尾
    printf(" ");
    for(i=node-1;i>=1;i--)
    {
        snack[i]=snack[i-1];
        gotoxy(snack[i].x,snack[i].y); printf("◆");
    }
}

int judge_head()
{
    int i=0;
    if(snack[0].x==0 || snack[0].x==width || snack[0].y==0 || snack[0].y==height+1){
        GameOver();//首先判断是不是撞墙了
        return p = 0;
    }   
    for(i=node-1;i>=1;i--)//判断是不是咬着自己了
    {
            if(snack[0].x==snack[i].x&&snack[0].y==snack[i].y){
                GameOver();
                return p = 0;
            }
    }
    if(snack[0].x==food.x && snack[0].y==food.y)//如果吃到食物,给尾巴加上一节
    {
        if(music)
            putchar(7);//响铃
        score+=100;
        node++;
        snack[node-1]=snack[node-2];
        gotoxy(snack[node-1].x,snack[node-1].y);printf("◆");
        food_move();
    }
}

void food_move()//食物出现; 
{
    srand(time(NULL));
    do
    {
        food.x = rand()%(width-3)+2;
    }while(food.x%2!=0); 
    food.y = rand()%(height-1)+1;
    gotoxy(food.x,food.y);printf("◆");//身体  //看调用的地方和作用;
}

void static_info()//静态信息 
{
    gotoxy(width+4,2);printf("%c %c %c %c控制",24,25,26,27);
    gotoxy(width+4,3);printf("按任意键暂停");
    gotoxy(width+4,4);printf("F1加速,F2减速");
    gotoxy(width+4,5);printf("F3开关声音");
    gotoxy(width+4,7);printf("蛇速度:");
    gotoxy(width+4,8);printf("蛇长度:");
    gotoxy(width+4,9);printf("得分:");
    gotoxy(width+4,11);printf("蛇头位置:");
    gotoxy(width+4,13);printf("食物位置:");
    gotoxy(width+4,15);printf("声音:");
    gotoxy(width+4,16);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_INTENSITY);printf("F4:■");//红色
    gotoxy(width+4,18);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY);printf("F5:■");//黄色
    gotoxy(width+4,20);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_INTENSITY);printf("F6:■");//绿色
    gotoxy(width+4,22);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_INTENSITY);printf("F7:■");//紫色
    gotoxy(width+4,24);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_INTENSITY);printf("F8:■");//亮白色
    gotoxy(width+4,26);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);printf("F9:■");//灰色
} 

void dynamic_info()//动态信息 
{
    gotoxy(width+13,7);printf("%4d",500-speed);
    gotoxy(width+13,8);printf("%4d",node);
    gotoxy(width+13,9);printf("%4d",score);
    gotoxy(width+13,13);printf("%2d,%2d",food.x,food.y);
    gotoxy(width+13,11);printf("%2d,%2d",snack[0].x,snack[0].y);
    gotoxy(width+9,15);music==1?printf("开"):printf("关");
}

void GameStart()                    //首界面
{
    Game_frame();
    gotoxy(25,10);printf("贪吃蛇游戏");
    gotoxy(22,17);system("pause");
}
int GameOver()
{
    system("cls");
    Game_frame();//因为前面清屏了。 
    gotoxy(25,10);printf("Game Over");
    gotoxy(25,12);printf("得分:%d",score);
    gotoxy(20,14);printf("重复游戏请按p键\n");
    return 0;
}
int main()
{
    char a;
    loop:
    p = 1;
    system("cls");
    system("mode con: cols=80 line=31"); 
    GameStart();
    system("cls");
    node = 4;
    music = 1;
    speed=280;
    direction = 3;
    score = 0;
    First_snack();
    food_move();
    move(); 
    a = getch();
    if(a == 'p'){
        goto loop;
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值