贪吃蛇详解Windows编程(一)
来源:互联网 发布:java连接zookeeper报错 编辑:程序博客网 时间:2024/06/06 18:49
贪吃蛇可以用很多种语言写,但是基本的思路都是一样的,在这里我就用C/C++写,但不是纯C或者纯C++写,因为那样太没效率了,用Windows封装的API写会节省很多代码而且是有界面的。既然是详解,所以一篇文章肯定讲不完的,所以我会分开几篇讲。
一个小建议:如果只有C或C++基础而没学过Windows程序设计,那么只建议看看思路即可,如果简单的学过一些Windows可以看完全篇.
先说一下思路,不管做什么东西首先都先要有整体的大概布局以及思路,然后再一小步一小步的去完成,去堆积,到后面就完成了。
(建议看了思路有想法的先去自己写,实在不会再看效果会加倍。)
思路如下:
1.画游戏区和控制区
也许有人会问为什么要分两个区域,理由很简单啊,难道你想程序已运行就自动开始,然后没有暂停按钮没有加速按钮没有减速按钮没有分数显示吗?当然了也可以全部设置成键盘快捷键控制,但是那样有些人就不太会用,导致这个游戏只能你自己玩。
2.画出蛇身
区域画出来了,第二部当然先要去画蛇了,千万别一步登天的想马上让蛇动起来,那样你会很困难,新手就基本就不能完成了。画蛇身的时候只要随便给它几节就行,因为程序都是由特殊性到一般性。
3.让蛇动起来
蛇身画出来后就可以让它动了,我估计很多人包括我都在怎么让蛇身动起来这里卡住了,方法各种各样,但就是千万别用Sleep函数。在这里我们用SetTimer函数设置一个定时器,每隔多少ms就移动一次蛇身(这里我用整体移动而不是一节节移动,就是隔多少ms重画一次蛇身)这里的间隔就是速度了。
4.制作食物
既然蛇都动起来了,那肯定要有食物给它吃吧?先别管吃了食物蛇会干嘛,我们就只管制作食物先,这就是物理的分离法分析,各个部分独立出来分析,然后最后再合并。
5.让蛇吃食物
这里只是判断蛇吃到食物没有,还没让它增加长度
6.吃食物后让蛇身增长
这里只需要调用第5个步骤判断,然后让它是否增长就行
下面这些都是控制区的了,控制区可以随意设置,并无什么技术含量,只是一些个性化。
7.开始和暂停按钮
8.蛇的速度按钮
9.游戏等级
10时间计时
11.分数显示
。
。
。
我会采用片段讲解,最后会贴出全部代码,如果没兴趣看片段详解可以跳到最后一篇文章直接看全部代码。
实战讲解:
1.画游戏区和控制区
首先游戏区和控制区是相互独立的区域,所以要有边界宽度来分割它们,然后游戏区和控制区和父窗口之间也要有分隔,这样整体感才强。
代码片段如下:
//游戏区和控制区宽度高度,这里*10是蛇的Size,后面会懂的。#define GAME_WIDE 70 //游戏区宽度70*10#define GAME_HEIGHT 60 //游戏区高度60*10#define CTRL_WIDE 30 //控制区宽度30*10#define CTRL_HEIGHT 60 //控制区高度60*10#define BOUNDSIZE 10 //边界厚度10 //[其它代码]static int ixWind = 0, iyWind = 0;//窗口大小参数static int ixClient = 0, iyClient = 0;//客户区大小参数//[其它代码]case WM_CREATE: { //获取窗口大小 GetWindowRect(hWnd, &rect); ixWind = rect.right - rect.left; iyWind = rect.bottom - rect.top; //获取客户区大小 GetClientRect(hWnd, &rect); ixClient= rect.right - rect.left; iyClient= rect.bottom - rect.top; //修改窗口大小 int nWideth = BOUNDSIZE * 3 + (GAME_WIDE + CTRL_WIDE)*SNAKESIZE + (ixWind - ixClient); int nHeight = BOUNDSIZE * 2 + GAME_HEIGHT*SNAKESIZE + (iyWind - iyClient); MoveWindow(hWnd, 50, 50,nWideth ,nHeight ,TRUE); } break;[其它代码] case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); //游戏区画刷 static HBRUSH hBrush1 = CreateSolidBrush(RGB(58, 206, 66)); //控制区画刷 static HBRUSH hBrush2 = CreateSolidBrush(RGB(80, 87, 196)); //画游戏区 Rectangle(hdc, BOUNDSIZE, BOUNDSIZE, BOUNDSIZE+GAME_WIDE*SNAKESIZE, BOUNDSIZE+GAME_HEIGHT*SNAKESIZE); //填充游戏区颜色 SetRect(&rect, BOUNDSIZE, BOUNDSIZE, BOUNDSIZE + GAME_WIDE*SNAKESIZE, BOUNDSIZE + GAME_HEIGHT*SNAKESIZE); FillRect(hdc, &rect,hBrush1); //画控制区 Rectangle(hdc, BOUNDSIZE * 2 + GAME_WIDE*SNAKESIZE, BOUNDSIZE, BOUNDSIZE*2+(GAME_WIDE+CTRL_WIDE)*SNAKESIZE, BOUNDSIZE+CTRL_HEIGHT*SNAKESIZE); //填充控制区颜色 SetRect(&rect, BOUNDSIZE * 2 + GAME_WIDE*SNAKESIZE, BOUNDSIZE, BOUNDSIZE * 2 + (GAME_WIDE + CTRL_WIDE)*SNAKESIZE, BOUNDSIZE + CTRL_HEIGHT*SNAKESIZE); FillRect(hdc, &rect,hBrush2); EndPaint(hWnd, &ps); } break;
也许有人会问为什么可以在case里面定义变量,因为你在case到break;之间加了一对大括号,学过C的都知道块作用域吧?道理就是那样。里面的一些x,y坐标和宽度高度,你自己算一下就可以懂了,如果你懒的话,你就OVER了。
效果如图:
2.画出蛇身
画蛇身之前还要初始化蛇身
初始化要在WM_CREATE消息中初始化.
画蛇要在WM_PAINT消息中调用
代码片段如下:
#include<vector>//蛇的信息#define SNAKESIZE 10 //蛇的宽高都为10的小方块#define SNAKEMAX 100 //蛇身长度最大值为100std::vector<POINT> vSnakePoint;//声明蛇的坐标UCHAR ucSnakeHead = 4;//初始化蛇头为4,实际上是vSnakePoint[3];UCHAR ucSnakeTail = 0;//初始化蛇尾为0UCHAR ucSnakekLen = 4;//初始化蛇身长度为4[其它代码]//初始化蛇VOID InitSnake(){ //先清空坐标 vSnakePoint.clear(); //给蛇坐标分配空间 vSnakePoint.resize(SNAKEMAX); //游戏结束后再次初始化 ucSnakeHead = 4;//初始化蛇头为4,实际上是vSnakePoint[3]; ucSnakeTail = 0;//初始化蛇尾为0 ucSnakekLen = 4;//初始化蛇身长度为4 //初始化每一节的蛇身坐标 for (int i = 0;i < ucSnakekLen;i++) { vSnakePoint[i].x = i; vSnakePoint[i].y = 0; }}//画蛇身,hdc是在WM_PAINT消息中传进来的,所以画蛇要在那里调用这个函数VOID DrawSnake(HDC hdc){ //蛇的颜色画刷 static HBRUSH hBrush = CreateSolidBrush(RGB(0,243,222)); SelectObject(hdc, hBrush); //画蛇 for (int i = 0;i < ucSnakekLen;i++) { Rectangle(hdc, vSnakePoint[i].x*SNAKESIZE+BOUNDSIZE, vSnakePoint[i].y*SNAKESIZE+BOUNDSIZE, (vSnakePoint[i].x+1)*SNAKESIZE + BOUNDSIZE, (vSnakePoint[i].y+1)*SNAKESIZE + BOUNDSIZE); }}
千万不要看到这些长长的宏定义就怕,其实它们就是一个常数而已,你们都可以自己动手算算的,如果封装成类的话就不会有那么多宏定义出现在函数里了。
效果如图:
区域和蛇身都画完了,下一篇就讲解如何移动它!
- 贪吃蛇详解Windows编程(一)
- 贪吃蛇详解Windows编程(二)
- 贪吃蛇详解Windows编程(三)
- 贪吃蛇详解Windows编程(四)
- windows下c/c++编程实现 贪吃蛇简易版
- 【Windows编程】球球大作战(二) 贪吃蛇的实现
- JavaScript贪吃蛇(一)
- C#贪吃蛇一
- unity----贪吃蛇详解
- Windows API 贪吃蛇代码
- 贪吃蛇游戏编程学习
- C++贪吃蛇编程过程
- Java编程---贪吃蛇游戏
- javascript 贪吃蛇(一)
- java贪吃蛇游戏一
- 游戏编程笔记-起步(一)一个简单的游戏-贪吃蛇
- 用windows sdk写一个贪吃蛇
- 简单贪吃蛇的编程设计
- git 的基本用法
- 插入排序
- 设计模式六大原则(4):接口隔离原则
- 文章标题
- 【重走普及路】【分治】【经典算法】快速幂
- 贪吃蛇详解Windows编程(一)
- 徒手撸筛选法求素数
- 在windows环境下,使用Eclipse和gcc-Linaro工具链,对BeagleBone进行交叉编译和远程部署
- Boost学习笔记(2)
- BFPRT 算法java实现
- Hibernate Validation使用示例及讲解
- IOS cocoapods 第三方库的管理工具
- python email.message:比较电子邮件
- 人工神经网络之连接权重和阈值