12.按键处理

函数名称:key_down

函数功能:按键处理函数,主要包括:1.刚开始或结束时的按键处理,游戏开始时,按任意键进入游戏,游戏运行过程中按回车键是游戏的暂停或开始的切换键;2.游戏运行过程中,按上、下、左、右键对蛇移动的方向进行控制。具体实现如下:

void key_down(WPARAM wParam)
{
    if(state != game_run)
    {
        if(wParam == VK_RETURN)
        {
            //在游戏不是运行状态时按下回车键
            //则运行游戏
            switch(state)
            {
            case game_start:
                    state = game_run;
                    break;
            case game_pause:
                state = game_run;
                //state = game_pause;
                break;
            case game_over:
                new_game();
                state = game_run;
                break;
            }
        }
    }
    else{
        //否则在游戏运行状态下
        switch(wParam)
        {
        case VK_UP: //向上键
            //dirt表示蛇当前的移动方向,属于全局变量
            if(dirt != DOWN)
            {
                dirt = UP;
            }
            break;
        case VK_LEFT: //左键
            if(dirt != RIGHT)
            {
                dirt = LEFT;
            }
            break;
        case VK_RIGHT:
            if(dirt != LEFT)
            {
                dirt = RIGHT;
            }
            break;
        case VK_DOWN:
            if(dirt != UP)
            {
                dirt = DOWN;
            }
            break;
        case VK_RETURN:
            state = game_pause;
            break;
        }
    }
    //刷新绘图窗口
    InvalidateRect(gameWND , NULL , TRUE);
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }13.改变窗口大小

函数名称:resize

函数功能:改变窗口大小时将调用本函数,根据窗口现有的大小,改变内存位图和字体等的大小,以便窗口绘图时适应新的窗口尺寸。具体实现如下:

void resize()
{
    HDC hdc ;
    LOGFONT lf; //字体逻辑结构
 
    //根据窗口的大小改变内存位图的大小
    hdc = GetDC(gameWND);
    GetClientRect(gameWND,&clientRC);
    SelectObject(memDC,memBMOld);
    DeleteObject(memBM);
    memBM = CreateCompatibleBitmap(hdc,clientRC.right,clientRC.bottom);
    memBMOld = (HBITMAP)SelectObject(memDC,memBM);
 
    //根据窗口的大小改变大字体的大小
    DeleteObject(bigFont);
    memset(&lf,0,sizeof(LOGFONT));
    lf.lfWidth = (clientRC.right - clientRC.left) / CHARS_IN_LINE;
    lf.lfHeight = (clientRC.bottom - clientRC.top) / 4;
    lf.lfItalic = 1;
    lf.lfWeight = FW_BOLD;
    bigFont = CreateFontIndirect(&lf);
    //根据窗口的大小改变小字体的大小
    DeleteObject(smallFont);
    lf.lfHeight = clientRC.bottom / (ROWS + 2);
    lf.lfWidth = lf.lfHeight*3 / 4;
    lf.lfItalic = 0;
    lf.lfWeight = FW_NORMAL;
    smallFont = CreateFontIndirect(&lf);
 
    ReleaseDC(gameWND,hdc);
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }14.初始化

函数名称:initialize

函数功能:初始化游戏。具体实现如下:

void initialize()
{
    PAINTSTRUCT ps;
    LOGFONT lf;
    HDC hdc;
    int i;
 
    hdc = GetDC(gameWND);
    GetClientRect(gameWND,&clientRC); //取得客户区绘图窗口的大小
    memDC = CreateCompatibleDC(hdc); //创建内存DC
    memBM = CreateCompatibleBitmap(hdc,clientRC.right,clientRC.bottom);//创建内存位图
    memBMOld = (HBITMAP)SelectObject(memDC,memBM);
    blackBrush = CreateSolidBrush(BLACK);//创建画笔和字体等
    snakeBrush = CreateSolidBrush(GREEN);
    for(i = 0; i < FOOD_COUNT; i++)
    {
        foodBrush[i] = CreateSolidBrush(food_color[i]);
    }
    grayPen  = CreatePen(PS_SOLID , 1, GRAY);
    memset(&lf, 0, sizeof(LOGFONT));
    //设置字体属性
    lf.lfWidth = (clientRC.right- clientRC.left) / CHARS_IN_LINE;
    lf.lfHeight = (clientRC.bottom - clientRC.top) / 4;
    lf.lfItalic = 1;
    lf.lfWeight = FW_BOLD;
    bigFont = CreateFontIndirect(&lf);
    lf.lfHeight = clientRC.bottom / (ROWS + 2);
    lf.lfWeight = lf.lfHeight*3/4;
    lf.lfItalic = 0;
    lf.lfWeight = FW_NORMAL;
    smallFont = CreateFontIndirect(&lf);
    ReleaseDC(gameWND,hdc);
    EndPaint(gameWND,&ps);
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

15.释放资源

函数名称:finalize

函数功能:游戏结束之前,释放初始化游戏时创建的资源。具体实现如下:

void finalize()
{
    int i = 0;
    DeleteObject(blackBrush);
    DeleteObject(snakeBrush);
    for(i = 0; i < FOOD_COUNT; i++)
    {
        DeleteObject(foodBrush[i]);
    }
 
    DeleteObject(grayPen);
    DeleteObject(bigFont);
    DeleteObject(smallFont);
    SelectObject(memDC,memBMOld);
    DeleteObject(memBM);
    DeleteDC(memDC);
}

16.回调函数

函数名称:WndProc

函数功能:用来处理windows消息。具体实现如下:

//响应Windows消息的回调函数,用来处理windows消息
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case WM_SIZE: //改变窗口大小
        resize();
        return 0;
    case WM_ERASEBKGND:
        return 0;
    case WM_PAINT:  //绘制内存位图到窗口
        paint();
        return 0;
    case WM_KEYDOWN:
        key_down(wParam); //用户操作处理
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }17.程序入口

函数名称:WinMain

函数功能:Windows程序的入口,类似于DOS程序的main函数,所以这个函数名必须是WinMain。具体实现如下:

int WINAPI WinMain(HINSTANCE  hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    MSG msg;
    WNDCLASS wndclass; //窗口类
 
    //窗口类属性
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = APP_NAME;
    RegisterClass(&wndclass); //注册窗口类
    //创建窗口
    gameWND = CreateWindow(APP_NAME,
        APP_TITLE,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,NULL,
        hInstance, NULL);
    //初始化游戏资源
    initialize();
    //显示窗口
    ShowWindow(gameWND, iCmdShow);
    UpdateWindow(gameWND);//更新窗口
    new_game();//新游戏
    for(;;)//进入windows消息循环, 直到接收到退出消息为止
    {
        if(state == game_run)
        {
            run_game();
        }
        if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
        {
            if(GetMessage(&msg,NULL,0,0))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }else{
                break;
            }
        }
    }
    finalize(); //释放资源
    return msg.wParam;//返回消息参数
 
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }自此整个项目功能基本实现完毕

5.系统操作过程

游戏运行后,首先进入欢迎主界面,如图:

在欢迎主界面中按任意键进入贪吃蛇游戏,游戏界面如图:

游戏结束界面如图:

6.总结与Bug记录

Bug.1

系统提示Char* 与LPCWSTR 不兼容,就是就在每个char*变量前加上(LPCWSTR)强制转换,就没有提示错误信息了,但是运行之后,发现字符串显示为乱码。 上网查资料其中有一方案说,通过右键项目属性将Unicode字符串更改为多字节字符串即可。按照执行,乱码解决。

总结

下一步待实现功能:

1.随着贪吃蛇吃的食物的增多,应该适当加快其运动速度以增加游戏难度

2.游戏桌面的大小应适应不同分辨率屏幕自动按相应大小显示,使得全屏时,游戏桌面及提示信息全部在同一屏幕上显示。

C项目实践--贪吃蛇(2)的更多相关文章

  1. C项目实践--贪吃蛇(1)

    1.功能需求分析 1.1主要功能 i.游戏欢迎界面 ii.游戏执行功能,包括计算得分 iii.游戏结束界面 1.2游戏基本规则 游戏开始时蛇的长度是4个单位,并且按照当前方向不停地移动.移动范围是CO ...

  2. 【C语言项目】贪吃蛇游戏(上)

    目录 00. 目录 01. 开发背景 02. 功能介绍 03. 欢迎界面设计 3.1 常用终端控制函数 3.2 设置文本颜色函数 3.3 设置光标位置函数 3.4 绘制字符画(蛇) 3.5 欢迎界面函 ...

  3. 【C语言项目】贪吃蛇游戏(下)

    目录 00. 目录 07. 游戏逻辑 7.5 按下ESC键结束游戏 7.6 判断是否撞到墙 7.7 判断是否咬到自己 08. 游戏失败界面设计 8.1 游戏失败界面边框设计 8.2 撞墙失败界面 8. ...

  4. 小项目特供 贪吃蛇游戏(基于C语言)

    C语言写贪吃蛇本来是打算去年暑假写的,结果因为ACM集训给耽搁了,因此借寒假的两天功夫写了这个贪吃蛇小项目,顺带把C语言重温了一次. 是发表博客的前一天开始写的,一共写了三个版本,第一天写了第一版,第 ...

  5. Android快乐贪吃蛇游戏实战项目开发教程-01项目概述与目录

    一.项目简介 贪吃蛇是一个很经典的游戏,也很适合用来学习.本教程将和大家一起做一个Android版的贪吃蛇游戏. 我已经将做好的案例上传到了应用宝,无病毒.无广告,大家可以放心下载下来把玩一下.应用宝 ...

  6. C语言实现贪吃蛇

    日期:2018.9.11 用时:150min 项目:贪吃蛇(C语言--数组   结构体实现) 开发工具:vs2013 关键知识:数组,结构体,图形库,键位操作 源代码: #include<std ...

  7. Unity3D游戏贪吃蛇大作战源码休闲益智手机小游戏完整项目

    <贪吃蛇大作战>一款休闲竞技游戏,不仅比拼手速,更考验玩家的策略. 视频演示: http://player.youku.com/player.php/sid/XMzc5ODA2Njg1Ng ...

  8. JavaScript实践-简单的贪吃蛇小游戏

    实现逻辑: //获取Html中的格子(行,列) //建立数组存储所有格子(x,y) //建立数组用于存储蛇身(x,y) //生成随机坐标(x,y)的函数 //随机创建蛇身并存储到蛇身数组 //创建食物 ...

  9. 初级练手项目——用Python一步一步实现“智能”贪吃蛇!

    贪吃蛇作为一款经典的小游戏,想必大家一定并不陌生,今天我们就来用Python来设计与实现贪吃蛇游戏,回味一下童年的快乐.快跟着小编来看看吧! ​ 基本环境配置 ●版本:Python3 ●系统:Wind ...

随机推荐

  1. LeetCode(86) Partition List

    题目 Given a linked list and a value x, partition it such that all nodes less than x come before nodes ...

  2. python3--产生偏移和元素:enumerate

    之前,我们讨论过通过range来产生字符串中元素的偏移值.而不是那些偏移值处的元素.不过,在有些程序中.我们两者都需要,要用的元素以及值个元素的偏移值.从传统意义来讲,这是简单的for循环,他同时也持 ...

  3. Charm Bracelet(01背包)

    Bessie has gone to the mall's jewelry store and spies a charm bracelet. Of course, she'd like to fil ...

  4. C#中为什么不能再方法里定义静态变量(Static)

    c#的静态变量是在对象生成的时候分配内存空间的,而不是函数执行的时候. 如果在函数里定义,那么这个变量就需要在函数执行的时候分配内存空间,这是C#不允许的,至于为什么不允许,个是因为垃圾回收机制的问题 ...

  5. DataTable 转JSON数据

    /// <summary> /// 将datatable转换为json /// </summary> /// <param name="dtb"> ...

  6. 【枚举】Southwestern Europe Regional Contest H - Sheldon Numbers

    https://vjudge.net/contest/174235#problem/H [题意] 求[x,y]之间有多少个Sheldon Number Sheldon Number是二进制满足以下条件 ...

  7. 最长链(codevs 1814)

    题目描述 Description 现给出一棵N个结点二叉树,问这棵二叉树中最长链的长度为多少,保证了1号结点为二叉树的根. 输入描述 Input Description 输入的第1行为包含了一个正整数 ...

  8. Codeforces Round #292 (Div. 2) D. Drazil and Tiles [拓扑排序 dfs]

    传送门 D. Drazil and Tiles time limit per test 2 seconds memory limit per test 256 megabytes Drazil cre ...

  9. msp430项目编程07

    msp430中项目---简单计算器 1.扫描键盘工作原理 2.电路原理说明 3.代码(显示部分) 4.代码(功能实现) 5.项目总结 msp430项目编程 msp430入门学习

  10. iOS 如何查看崩溃日志

    参考网址: [转载]https://www.jianshu.com/p/4de55d73c82b [转载]https://blog.csdn.net/qq_26544491/article/detai ...