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 ...
随机推荐
- 剑指Offer(书):二进制中1的个数
题目:输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 分析:下面这两种方法都可以,不过第二种更好一些. public int numberOf1(int n) { int count ...
- pwnable.kr cmd1之write up
看一下源代码: #include <stdio.h> #include <string.h> int filter(char* cmd){ ; r += strstr(cmd, ...
- Mysql的常见几种错误:1045,1044
Mysql的常见几种错误: 一.在进入 mysql 数据库时出错 # mysql -u root -p Enter password: ERROR 1045 (28000): Access den ...
- 【HDOJ6324】Grab The Tree(博弈)
题意: 思路: #include <stdio.h> #include <vector> #include <algorithm> #include <str ...
- 汕头市赛srm8 C-3
n<=100000个点m<=300000条边有权无向联通图,给出K<=10000个特殊点求K个点中任意两点最短路的最小值. 方法一:K小,随便搞.先构造最短路树,在最短路树上Dijk ...
- springmvc和dubbo整合时,不配置spring listener报错找不到/WEB-INF/config/applicationContext.xml
原因,dubbo2.6.3版本开始就需要先在listener中配置容器,否则报错,2.6.2版本则不需要
- 【zTree】zTree根据后台数据生成树并动态设置前面的节点复选框的选中状态
0.页面中准备树的ul <ul id="treeDemo10" class="ztree" style="display: none;" ...
- Hibernate学习笔记(三)
我是从b站视频上学习的hibernate框架,其中有很多和当前版本不符合之处,我在笔记中进行了修改以下是b站视频地址:https://www.bilibili.com/video/av14626440 ...
- asterisk 相关数据库配置 使用
Linux/Unix下ODBC的安装: 先下载最新的unixODBC源码包(http://www.unixodbc.org/unixODBC-2.2.1.tar.gz)放到/usr/local下,然后 ...
- 多平台密码绕过及提权工具Kon-Boot的使用与防范
在单用户的机器上密码可能没那么重要,但是一旦有多个用户可以使用这台机器,密码就显得十分必要了(比如有儿童账户的电脑).所以说为你的电脑增设一条防线的最常用,最简单的方法就是用密码将你的电脑保护起来,但 ...