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基础——6(字符编码,文件操作)

    今日内容: 1.字符编码: 人识别的语言与机器识别的语言转化的媒介 *****     2.字符与字节: 字符占多少字节,字符串转化 ***     3.文件操作: 操作硬盘中的一块区域:读写操作  ...

  2. python mock模块使用(二)

    本篇继续介绍mock里面另一种实现方式,patch装饰器的使用,patch() 作为函数装饰器,为您创建模拟并将其传递到装饰函数 官方文档地址 patch简介 1.unittest.mock.patc ...

  3. Fidder详解-工具简介(保存会话、decode解码、Repaly、自定义会话框、隐藏会话、会话排序)

    前言 本文会对Fidder这款工具的一些重要功能,进行详细讲解,带大家进入Fidder的世界,本文会让你明白,Fidder不仅是一个抓包分析工具,也是一个请求发送工具,更加可以当作为Mock Serv ...

  4. Halloween Costumes(区间DP)

    Gappu has a very busy weekend ahead of him. Because, next weekend is Halloween, and he is planning t ...

  5. BZOJ 3175: [Tjoi2013]攻击装置

    捉水题真是捉上瘾了TUT Description 给定一个01矩阵,其中你可以在0的位置放置攻击装置.每一个攻击装置(x,y)都可以按照“日”字攻击其周围的 8个位置(x-1,y-2),(x-2,y- ...

  6. VS Code 列编辑功能说明

    新版本v1.13.1或者附近的版本中的列编辑功能已经调整. 一.多光标插入功能 Alt+鼠标左键,添加多光标输入 二.自由多行选择 Alt键+鼠标左键拖动选择各行的部分内容 三.列选择 Shift+A ...

  7. Http、TCP/IP、Socket的区别

    网络由下往上分为 物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 通过初步的了解,我知道IP协议对应于网络层,TCP协议对应于传输层,而HTTP协议对应于应用层, 三者从本质上来说没有可 ...

  8. 《TCP/IP详解卷1:协议》——第6章 ICMP:Internet控制报文协议(转载)

    1.引言 ICMP被认为是IP层的一个组成部分,它传递差错报文以及其他需要注意的信息.ICMP报文通常被IP层或更高层协议(TCP或UDP)使用.一些ICMP报文把差错报文返回给用户进程. ICMP报 ...

  9. Back弹出AlertDialog

    package com.pingyijinren.helloworld.activity; import android.content.DialogInterface; import android ...

  10. Maven 手动添加本地jar包

    mvn install:install-file -Dfile=jar绝对路径 -DgroupId=项目组织唯一的标识符 -DartifactId=项目的唯一的标识符 -Dversion=jar版本 ...