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基础——6(字符编码,文件操作)
今日内容: 1.字符编码: 人识别的语言与机器识别的语言转化的媒介 ***** 2.字符与字节: 字符占多少字节,字符串转化 *** 3.文件操作: 操作硬盘中的一块区域:读写操作 ...
- python mock模块使用(二)
本篇继续介绍mock里面另一种实现方式,patch装饰器的使用,patch() 作为函数装饰器,为您创建模拟并将其传递到装饰函数 官方文档地址 patch简介 1.unittest.mock.patc ...
- Fidder详解-工具简介(保存会话、decode解码、Repaly、自定义会话框、隐藏会话、会话排序)
前言 本文会对Fidder这款工具的一些重要功能,进行详细讲解,带大家进入Fidder的世界,本文会让你明白,Fidder不仅是一个抓包分析工具,也是一个请求发送工具,更加可以当作为Mock Serv ...
- Halloween Costumes(区间DP)
Gappu has a very busy weekend ahead of him. Because, next weekend is Halloween, and he is planning t ...
- BZOJ 3175: [Tjoi2013]攻击装置
捉水题真是捉上瘾了TUT Description 给定一个01矩阵,其中你可以在0的位置放置攻击装置.每一个攻击装置(x,y)都可以按照“日”字攻击其周围的 8个位置(x-1,y-2),(x-2,y- ...
- VS Code 列编辑功能说明
新版本v1.13.1或者附近的版本中的列编辑功能已经调整. 一.多光标插入功能 Alt+鼠标左键,添加多光标输入 二.自由多行选择 Alt键+鼠标左键拖动选择各行的部分内容 三.列选择 Shift+A ...
- Http、TCP/IP、Socket的区别
网络由下往上分为 物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 通过初步的了解,我知道IP协议对应于网络层,TCP协议对应于传输层,而HTTP协议对应于应用层, 三者从本质上来说没有可 ...
- 《TCP/IP详解卷1:协议》——第6章 ICMP:Internet控制报文协议(转载)
1.引言 ICMP被认为是IP层的一个组成部分,它传递差错报文以及其他需要注意的信息.ICMP报文通常被IP层或更高层协议(TCP或UDP)使用.一些ICMP报文把差错报文返回给用户进程. ICMP报 ...
- Back弹出AlertDialog
package com.pingyijinren.helloworld.activity; import android.content.DialogInterface; import android ...
- Maven 手动添加本地jar包
mvn install:install-file -Dfile=jar绝对路径 -DgroupId=项目组织唯一的标识符 -DartifactId=项目的唯一的标识符 -Dversion=jar版本 ...