| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 77388 人关注过本帖, 5 人收藏
标题:花费一周写的贪吃蛇代码
只看楼主 加入收藏
Fisher~
Rank: 4
等 级:业余侠客
帖 子:93
专家分:222
注 册:2012-11-10
结帖率:100%
收藏(5)
 问题点数:0 回复次数:35 
花费一周写的贪吃蛇代码
程序代码:
/***************************************
* 程序名称:贪吃蛇游戏                      *
* 编译环境:vs2008                          *
* 作者相关:往事随风<1034882113>*
* 修改时间:2013-04-13                      *
***************************************/

#include <graphics.h>
#include <conio.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <string.h>

// 引用 Windows Multimedia API
#pragma comment(lib,"Winmm.lib")

/***********宏定义区******************/
#define X    500            // 保存蛇节点坐标的个数
#define Y 500

int len = 640;
int wide = 480;
MCI_PLAY_PARMS mciplay;//定义播放参数mciplay
/***********结构定义区****************/
struct food
{
    int x;                        // 横坐标
    int y;                        // 纵坐标
    int flag;                    // 食物状态 1: 有食物; 0:没有食物
}food;

struct snake
{
    int x[X];                    // 蛇身横坐标
    int y[Y];
    int life;                    // 生命状态
    int node;                // 蛇的长度
    char direction;        // 蛇的方向
    int score;                // 分数
    int grade;                // 难度
    int speed;                // 速度
}snake;

/*************函数声明区**************/
void initsnake();                                        // 初始化一条蛇
void print_wall();                                    // 输出围墙
void out_food();                                    // 出现食物
void Gameover();                                    // 结束游戏
void Gamebegin();                                    // 开始游戏
void dead_case();                                    // 死亡情况(撞墙 撞自身)
void eat_food();                                        // 吃掉食物
void init_data();                                        // 初始化数据
void get_direction(char ch);                    // 得到方向
void print_snake();                                    // 输出蛇
void print_score();                                    // 输出分数
void set_grade();                                    // 设置等级
void RealseMusic(LPCTSTR strResName,char *DeviceStr);                // 播放资源文件中的音乐
void pass();                                            // 通关函数

/****************************************************/
// 提取指定模块中的资源文件
// 参数:
//        strDstFile:        目标文件名。提取的资源将保存在这里;
//        strResType:        资源类型;
//        strResName:        资源名称;
// 返回值:
//        true: 执行成功;
//        false: 执行失败。
/****************************************************/
bool ExtractResource(LPCTSTR strDstFile, LPCTSTR strResType, LPCTSTR strResName);    // 提取资源到临时文件

/************函数定义区***************/
void pass()
{
    if (snake.speed == 20)       
    {
        EndBatchDraw();
        IMAGE img;
        loadimage(&img,"IMAGE","PASS",len,wide,true);     // s输出通关图片
        putimage(0,0,&img);
        _getch();
        exit(0);
    }
}

bool ExtractResource(LPCTSTR strDstFile, LPCTSTR strResType, LPCTSTR strResName)
{
    // 创建文件
    HANDLE hFile = ::CreateFile(strDstFile, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS,   
                                                FILE_ATTRIBUTE_TEMPORARY, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
        return false;

    // 查找资源文件中、加载资源到内存、得到资源大小
    HRSRC    hRes    = ::FindResource(NULL, strResName, strResType);
    HGLOBAL    hMem    = ::LoadResource(NULL, hRes);
    DWORD    dwSize    = ::SizeofResource(NULL, hRes);

    // 写入文件
    DWORD dwWrite = 0;      // 返回写入字节
    ::WriteFile(hFile, hMem, dwSize, &dwWrite, NULL);
    ::CloseHandle(hFile);

    return true;
}

void RealseMusic(LPCTSTR strResName,char *DeviceStr)
{
    // 产生临时文件的文件名
    TCHAR tmpmp3[_MAX_PATH];
    ::GetTempPath(_MAX_PATH, tmpmp3);
    _tcscat_s(tmpmp3,strResName);                        // VC 请用 _tcscat函数

    // 将 MP3 资源提取为临时文件
    ExtractResource(tmpmp3, "MP3",strResName);

    // 打开音乐
    TCHAR mcicmd[300];
    _stprintf_s(mcicmd,"open \"%s\" alias %s",tmpmp3,DeviceStr);
    mciSendString(mcicmd, NULL, 0, NULL);

    // 播放音乐
//    mciSendString("play mymusic", NULL, 0, NULL);
}

void set_grade()
{
    int grade = 0;
   
    if (snake.speed > 30)
    {   
        grade = snake.score / 100 + 1;
        if (snake.grade != grade)
        {
            snake.grade = grade;    // 最高只有7级
            snake.speed -= 30;
        }
    }
}

void print_score()
{
    char score[10] = "0";
    char grade[3] = "0";
    int x = 0, y1 = 0,y2 = 0;
   
    x =( len /3 + len % 3) * 2;
    y1 = wide / 5;
    y2 = wide / 3;
    set_grade();
    _itoa_s(snake.score,score,10);
    _itoa_s(snake.grade,grade,10);

    setbkmode(TRANSPARENT);                                // 设置文字背景透明
    setcolor(RGB(255,255,0));                                    // 设置文字颜色
    outtextxy(x + len / 10,y1,"分数:");
    outtextxy(x + len / 6,y1,score);
    outtextxy(x + len / 10,y2,"操作说明");
    outtextxy(x + len / 10,y2 + 20,"a:向左走");
    outtextxy(x + len / 10,y2 + 40,"d:向右走");
    outtextxy(x + len / 10,y2 + 60,"w:向上走");
    outtextxy(x + len / 10,y2 + 80,"s:向下走");
    outtextxy(x + len / 10,y1 * 4,"等级:");
    outtextxy(x + len / 10 + 40,y1 * 4,grade);
    outtextxy(x + len / 10 + 50,y1 * 4,"");
}

void print_snake()
{
    int i;

    setfillcolor(BLACK);                        // 设置当前填充色为黑色
    /* 输出蛇 */
    for (i = 0; i < snake.node; i++)
        fillrectangle(snake.x[i],snake.y[i],snake.x[i] + 10,snake.y[i] + 10);
    for (i = snake.node; i > 0; i--)        // 蛇体坐标除了蛇头都读取前一位坐标
    {
        snake.x[i] = snake.x[i - 1];
        snake.y[i] = snake.y[i - 1];
    }
}

void get_direction(char ch)
{
    /* 排除反方向 */
    if (snake.direction != 'a' &&  ch == 'd')
        snake.direction = 'd';
    else if (snake.direction != 'd' &&  ch == 'a')
        snake.direction = 'a';
    else if (snake.direction != 'w' &&  ch == 's')
        snake.direction = 's';
    else if (snake.direction != 's' &&  ch == 'w')
        snake.direction = 'w';

    /* 蛇移动过程中的方向 */
    switch (snake.direction)
    {
    case 'a': snake.x[0] -= 10; break;
    case 'd': snake.x[0] += 10;break;                       
    case 'w': snake.y[0] -= 10;break;
    case 's': snake.y[0] += 10;break;
    }
}

void init_data()
{
    /***初始化***/
    snake.score = 0;
    snake.x[0] = 20,snake.y[0] = 30;
    snake.node = 1;
    snake.life = 1;                                    // 1表示活着
    food.flag = 0;
    snake.grade = 1;
    snake.speed = 200;
}

void eat_food()
{
    mciplay.dwFrom = 0;
    /* 吃掉食物 */
    if (snake.x[0] == food.x && snake.y[0] == food.y)
    {
        // 播放吃的音乐
        mciSendString("seek AteMusic to 0",0,0,0);
        mciSendString("play AteMusic",NULL,0,0);
        setfillcolor(RGB(219,49,0));               
        fillrectangle(food.x,food.y,food.x + 10,food.y + 10);            // 擦掉食物

           
        snake.node++;                            // 蛇长加1
        food.flag = 0;                            // 改变食物状态
        snake.score += 10;                    // 改变分数   
    }
}

void dead_case()
{
    int i = 0;
    int x = 0;
    x =( len /3 + len % 3) * 2;

    /*  判断撞到自身 */
    for (i = 2; i < snake.node; i++)               
    {
        if (snake.x[i] == snake.x[0] && snake.y[i] == snake.y[0])
        {
            snake.life = 0;
            break;
        }
    }

    /* 判断是否撞墙 */
    if (snake.x[0] > x || snake.x[0] < 10 || snake.y[0] < 10 || snake.y[0] > 470)
        snake.life = 0;
}

void Gamebegin()
{
    IMAGE image;
    MOUSEMSG msg;

    // 初始化
    RealseMusic("BeginMusic.mp3","BeginMusic");
    RealseMusic("AteMusic.mp3","AteMusic");
    // 播放开始的音乐
    mciSendString("play BeginMusic", NULL, 0, NULL);

    loadimage(&image,"IMAGE","StartCover",len,wide,true);        // s输出开始图片
    putimage(0,0,&image);

//    setbkmode(TRANSPARENT);                                // 设置文字背景透明
//    setcolor(RGB(255,255,0));                                    // 设置文字颜色
//    outtextxy(len / 3 + 50,wide * 4 / 5,"按任意键继续");

    while (1)                                                        // 等待鼠标点击
    {
        msg = GetMouseMsg();
        if (msg.uMsg ==WM_LBUTTONDOWN)
            break;
    }
    mciSendString("close BeginMusic",NULL,0,NULL);        // 关闭开始音乐
    setbkcolor(RGB(219,49,0));        // 设置屏幕背景色为褐色
    cleardevice();                   
    print_wall();                            // 输出围墙
}

void Gameover()
{

    cleardevice();                            // 清屏
    IMAGE image;                        // 定义图片对像
    char score[10] = "0";                // 临时存储成绩

    loadimage(&image,"IMAGE","End",len,wide,true);        // 获取图片
    putimage(0,0,&image);                        // 输出图片
    setcolor(RED);
    _itoa_s(snake.score,score,10);                // 转换分数为自符
    outtextxy(270,160,"分数:");                // 输出分数
    outtextxy(320,160,score);
    outtextxy(270,180,"GAME OVER");
}

void out_food()
{
    int x = 0;

    x =( len /3 + len % 3) * 2;

    srand((unsigned)time(NULL));
    if (food.flag == 0)                                // 获取食物坐标
    {
        food.x = rand() % (x - 30) + 10;        // 避免出现在围墙范围
        food.y = rand() % 450 + 10;
        food.flag = 1;
    }
    while (food.x % 10 != 0)                    // 保证食物在格子里面要不吃不到
        food.x++;
    while (food.y % 10 != 0)
        food.y++;
    setfillcolor(RED);
    if (food.flag == 1)                                // 输出食物
        fillrectangle(food.x,food.y,food.x + 10,food.y + 10);
}

/* 画出围墙 */
void print_wall()
{   
    int i =0;
    int x = 0;

    x =( len /3 + len % 3) * 2;
    setfillcolor(RGB(220,115,10));                            // 设置围墙填充色
    for (i = 0; i < wide; i += 10)
    {
        fillrectangle(0,i,10,i + 10);                            // 左边围墙
        fillrectangle(x,i,x + 10,i + 10);                        // 中间围墙
        fillrectangle(len - 10,i,len,i + 10);                // 右边围墙                               
    }
    for (i = 0; i < len; i += 10)
    {
        fillrectangle(i,0,i + 10,10);                            // 上边围墙
        fillrectangle(i,wide - 10,i + 10,wide);            // 下边围墙
    }
}

void snake_game()
{
    char ch = '0';
   
    init_data();
   
    print_score();
    setfillcolor(BLACK);                            // 设置当前填充色为黑色
    /* 开始时显示一个点蛇头 */
    solidrectangle(snake.x[0],snake.y[0],snake.x[0] + 10,snake.y[0] + 10);

    snake.direction = _getch();                // 得到方向

    BeginBatchDraw();
    while (ch != 27)                                    // 按下esc键就退出循环
    {   
        print_wall();
        out_food();                                    // 输出食物

        if (_kbhit())
            ch = _getch();
       
        get_direction(ch);
        print_snake();
        dead_case();        // 蛇是否撞墙或者撞到自身
        /* 判断生命状态 */
        if (snake.life == 0)
            break;   
        eat_food();
        print_score();
        FlushBatchDraw();
        Sleep(snake.speed);
        cleardevice();
        pass();                // 判断通关
    }
    EndBatchDraw();
}

void main()
{
    initgraph(len,wide);

    Gamebegin();
    snake_game();
    Gameover();

    _getch();
    closegraph();
}
主要时间用在了资源的内嵌和调用上,程序功能的实现用了两个下午,添加音乐资源和图片资源花费了很长时间,共400行代码还有很多bug
这是实现了任何机子上一个exe就能运行的exe文件地址以及很多的资料
http://pan.baidu.com/share/link?shareid=401364&uk=2988506976
搜索更多相关主题的帖子: 时间 include 贪吃蛇 
2013-04-15 17:34
U201010009
Rank: 3Rank: 3
等 级:论坛游侠
威 望:6
帖 子:73
专家分:178
注 册:2013-2-25
收藏
得分:0 
楼主高手,不知道怎么学C语言,请楼主教我
2013-04-15 18:57
woailuo2010
Rank: 2
等 级:论坛游民
帖 子:27
专家分:19
注 册:2013-3-1
收藏
得分:0 
楼主,请问我把网上的游戏代码拷到电脑上运行的时候,怎么总是说我的一些调用函数没有定义,你的程序我运行时错误是d:\vc98\include\easyx.h(35) : fatal error C1189: #error :  EasyX is only for C++
执行 cl.exe 时出错.



求楼主指教,,

错过的青春,我用行动补回来!
2013-04-15 19:34
woailuo2010
Rank: 2
等 级:论坛游民
帖 子:27
专家分:19
注 册:2013-3-1
收藏
得分:0 
刚刚看到楼主用的是VS2008,这个我还没有接触过,请指教!

错过的青春,我用行动补回来!
2013-04-15 19:41
wlllch
Rank: 2
等 级:论坛游民
帖 子:32
专家分:21
注 册:2013-3-28
收藏
得分:0 
厉害

新手上路,说错不要见怪。
2013-04-15 21:20
Fisher~
Rank: 4
等 级:业余侠客
帖 子:93
专家分:222
注 册:2012-11-10
收藏
得分:0 
回复 3楼 woailuo2010
这个错误的意思是easyx只能用于c++,我是下载了easyx才能用图形界面的,你是不是改后缀名字了我的是cpp,你是不是改为.c了,这个后缀为cpp就能解决你的问题了
2013-04-15 21:50
Fisher~
Rank: 4
等 级:业余侠客
帖 子:93
专家分:222
注 册:2012-11-10
收藏
得分:0 
回复 4楼 woailuo2010
另一种强大的编译器而已,我喜欢而已,不喜欢vc6.0的界面所以一直用的这个
2013-04-15 21:51
Fisher~
Rank: 4
等 级:业余侠客
帖 子:93
专家分:222
注 册:2012-11-10
收藏
得分:0 
回复 2楼 U201010009
先看书,在网上有很多资料我的百度网盘应该有一些把主要的c方面都在CSDN里面,你可以看看这本书
http://download.
我有第二版不过太大了暂时传不了,这个是第一版的,其实看任何书都可以多练习入门还是很简单的
2013-04-15 21:58
书中先生
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2012-11-25
收藏
得分:0 
大爷的,编译不行,graphics.h图形函数,有问题。
2013-04-15 22:14
kfxw
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2013-2-11
收藏
得分:0 
楼主提供的资料太丰富了。话说楼主都看完了?目测我要看好长时间呢。
2013-04-15 22:25
快速回复:花费一周写的贪吃蛇代码
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.042220 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved