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. python中unicode, hex, bin之间的转换

    python中unicode, hex, bin之间的转换 背景 在smb中有个feature change notify, 需要改动文件权限dacl,然后确认是否有收到notify.一直得不到这个d ...

  2. LR百分比模式

    1  场景模式切换 Vuser Group Mode转换为Percentage Mode:如下 Scenario->Convert Scenairio to the VuserGroup Mod ...

  3. C 的指针和内存泄漏

    引言 对于任何使用 C 语言的人,如果问他们 C 语言的最大烦恼是什么,其中许多人可能会回答说是指针和内存泄漏.这些的确是消耗了开发人员大多数调试时间的事项.指针和内存泄漏对某些开发人员来说似乎令人畏 ...

  4. UVA11090 Going in Cycle!! 【SPFA】

    题意:求一个无向图的边权平均值最小的环 思路:假设环中Σwi/t<ans 那变形一下就是Σwi<ans*t → Σ(wi-ans)< 0 这样就可以二分答案做了 #include & ...

  5. jsonp跨域请求实现示例

    网上看了很多关于jsonp的资料,发现在本机运行后实现不了,有的是有错漏,有的是说的比较含糊,接合自己的情况,整了一个可运行的示例: 前言: ajax请求地址:http://192.168.1.102 ...

  6. mappedBy的作用

    mappedBy的意思就是"被映射",即mappedBy这方不用管关联关系,关联关系交给另一方处理 1.规律:凡是双向关联,mapped必设,因为根本都没必要在2个表中都存在一个外 ...

  7. 字符串匹配(codevs 1404)

    题目描述 Description 给你两个串A,B,可以得到从A的任意位开始的子串和B匹配的长度.给定K个询问,对于每个询问给定一个x,求出匹配长度恰为x的位置有多少个.N,M,K<=20000 ...

  8. python学习之-- redis模块操作 string

    redis 模块操作之--> String String:redis中的string在内存中按照一个key 对应一个 value来存储. 使用方法如下:set(name, value, ex=N ...

  9. CodeForces 592C The Big Race

    公倍数之间的情况都是一样的,有循环节. 注意min(a,b)>t的情况和最后一段的处理.C++写可能爆longlong,直接Java搞吧...... import java.io.Buffere ...

  10. eclipse 修改Java代码 不用重新启动tomcat

    例子: 1.在tomcat server.xml文件配置加上这句话: <Context debug="0" docBase="C:\Users\admin\Desk ...