C项目实践--贪吃蛇(2)
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)的更多相关文章
- C项目实践--贪吃蛇(1)
1.功能需求分析 1.1主要功能 i.游戏欢迎界面 ii.游戏执行功能,包括计算得分 iii.游戏结束界面 1.2游戏基本规则 游戏开始时蛇的长度是4个单位,并且按照当前方向不停地移动.移动范围是CO ...
- 【C语言项目】贪吃蛇游戏(上)
目录 00. 目录 01. 开发背景 02. 功能介绍 03. 欢迎界面设计 3.1 常用终端控制函数 3.2 设置文本颜色函数 3.3 设置光标位置函数 3.4 绘制字符画(蛇) 3.5 欢迎界面函 ...
- 【C语言项目】贪吃蛇游戏(下)
目录 00. 目录 07. 游戏逻辑 7.5 按下ESC键结束游戏 7.6 判断是否撞到墙 7.7 判断是否咬到自己 08. 游戏失败界面设计 8.1 游戏失败界面边框设计 8.2 撞墙失败界面 8. ...
- 小项目特供 贪吃蛇游戏(基于C语言)
C语言写贪吃蛇本来是打算去年暑假写的,结果因为ACM集训给耽搁了,因此借寒假的两天功夫写了这个贪吃蛇小项目,顺带把C语言重温了一次. 是发表博客的前一天开始写的,一共写了三个版本,第一天写了第一版,第 ...
- Android快乐贪吃蛇游戏实战项目开发教程-01项目概述与目录
一.项目简介 贪吃蛇是一个很经典的游戏,也很适合用来学习.本教程将和大家一起做一个Android版的贪吃蛇游戏. 我已经将做好的案例上传到了应用宝,无病毒.无广告,大家可以放心下载下来把玩一下.应用宝 ...
- C语言实现贪吃蛇
日期:2018.9.11 用时:150min 项目:贪吃蛇(C语言--数组 结构体实现) 开发工具:vs2013 关键知识:数组,结构体,图形库,键位操作 源代码: #include<std ...
- Unity3D游戏贪吃蛇大作战源码休闲益智手机小游戏完整项目
<贪吃蛇大作战>一款休闲竞技游戏,不仅比拼手速,更考验玩家的策略. 视频演示: http://player.youku.com/player.php/sid/XMzc5ODA2Njg1Ng ...
- JavaScript实践-简单的贪吃蛇小游戏
实现逻辑: //获取Html中的格子(行,列) //建立数组存储所有格子(x,y) //建立数组用于存储蛇身(x,y) //生成随机坐标(x,y)的函数 //随机创建蛇身并存储到蛇身数组 //创建食物 ...
- 初级练手项目——用Python一步一步实现“智能”贪吃蛇!
贪吃蛇作为一款经典的小游戏,想必大家一定并不陌生,今天我们就来用Python来设计与实现贪吃蛇游戏,回味一下童年的快乐.快跟着小编来看看吧! 基本环境配置 ●版本:Python3 ●系统:Wind ...
随机推荐
- Python之阻塞IO模型与非阻塞IO模型
Python之阻塞IO模型与非阻塞IO模型 IO模型 1 阻塞IO: 全程阻塞 2 非阻塞IO: 发送多次系统调用: 优点:wait for data时无阻塞 缺点:1 系统调用太多 2 数据不是实时 ...
- python-with管理文件上下文(基本文件操作)
什么是文件 文件是操作系统为用户提供的一个读写硬盘的虚拟单位,文件的操作就是文件的读.写. 操作过程:当我们双击文件 -<- 操作系统接收到指令请求(将用户或应用程序的读写操作转换成集体的硬盘指 ...
- 一个关于vue+mysql+express的全栈项目(三)------ 登录注册功能的实现(已经密码安全的设计)
本系列文章,主要是一个前端的视角来实现一些后端的功能,所以不会讲太多的前端东西,主要是分享做这个项目学到的一些东西,,,,, 好了闲话不多说,我们开始搭建后端服务,这里我们采用node的express ...
- tomcat官网改版后下载方式
位于disk/tomcat目录下 http://archive.apache.org/dist/tomcat/ 具体例如:http://archive.apache.org/dist/tomcat/t ...
- django1.11 启动错误:Generator expression must be parenthesized
错误信息: Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0 ...
- window查看哪些端口被占用命令
管理员方式运行cmd netstat -n
- 跳石头(codevs 4768)
题目描述 Description 一年一度的“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有N ...
- jQuery操作元素的class属性
今天在做一个菜单折叠插件的时候需要根据页面的url改变其class属性.jQuery操作元素的属性是非常方便的,在此记录一下: 1.给元素添加class属性: addClass(class) (1)添 ...
- 谈谈APP架构选型:React Native还是HBuilder
原文链接 导读:最近公司的一款新产品APP要进行研发,老大的意思想用H5来做混合APP以达到高效敏捷开发的目的.我自然就开始进行各种技术选型的调研,这里重点想说的是我最后挑选出的2款hybrid ap ...
- ACM-ICPC 2018 南京赛区网络预赛 L && BZOJ 2763 分层最短路
https://nanti.jisuanke.com/t/31001 题意 可以把k条边的权值变为0,求s到t的最短路 解析 分层最短路 我们建立k+1层图 层与层之间边权为0,i 向 i+1层转 ...