经过昨天的苦战,终于完成了纯C版的打飞机游戏——使用微信打飞机游戏的素材,不过玩法有些不同,下面会有详述

一、概述游戏的玩法、实现效果

1. 游戏第一步,简单判断一下,给你一个准备的时间:

2.选择"是"进入游戏界面:

3. 分数的记法规则和微信版的一样——小飞机1000、中号飞机6000、大boss10000

4. 使用鼠标点击响应的飞机,能实现爆炸效果

5. 你需要在飞机消失之前干掉它,否则游戏就结束了

6. 同样支持微信中暂停和继续的功能(左上角图标可以看见)

7. 当游戏结束的时候,还会提示你是否继续重玩

二、写游戏过程中的一些心得

1. 链表和数组的纠结:

大家应该都知道 , 要想不断的加飞机、删除飞机,那么首选链表这个数据结构,因为它的优点就是插入、删除的时间复杂度小。

的确,不过对于应该是使用链表还是简单的数组,我一开始确实纠结了很久,最终大家猜猜我选择的是什么呢?

呵呵,我选择了简单的数组,原因如下: 我的算法总是在数组的最后添加飞机,飞机的数量有限(不多 , 最多10个),如果使用链表有些大材小用

使用越简单的方式效率也就相应的越高

2. 内存的泄漏

从表面上听着像是很严重——没错,它确实是我编写过程中的一个BUG。当我完成第一个初始版本时,我迫不及待的运行了一下,开始没什么问题,运行尚好。

不过问题不一会儿就出现了——飞机不动了,程序瞬间崩溃……

我还试了几次,最终都是一样的而结果——于是我就想: 首先确定这应该是内存泄漏的问题,但是没使用链表(指针),那会是什么呢?

原来问题出现在一个很低级的错误上:

由于我使用双缓冲技术来贴位图,那么必定会创建一个兼容的内存Bitmap,然后我却没有在不使用它时释放它所占的内存,那么问题自然就出现了。

在此,我必须再次强调一下,释放资源所占内存的重要性

三、代码阶段

这次呢,我不打算详细的讲解代码细节了,因为大部分技术都是之前详述过的,例如贴位图、透明位图、双缓冲技术==

但是呢,我还是将头文件中的一些声明注解一下,方便各位参看源代码:

#ifndef BEATPLANE_H

//调用TransparentBlt函数所需导入的库
#pragma comment(lib, "Msimg32.lib") //自定义消息——开始或重玩
#define WM_START (WM_USER+100) #define TIMER 100//定时器ID
#define WNDWIDTH 380//窗口宽度
#define WNDHEIGHT 550//窗口高度
#define SMALL 2 //飞机的类型——大中小
#define MIDDLE 3
#define BIG 4
#define GRADE 200000//等级 200000一个等级
#define MAX 10//窗口中一次显示最多的飞机数 //飞机结构体
typedef struct
{
HBITMAP hBmp;//飞机位图
POINT pos; //飞机当前的位置
SIZE size;//飞机的大小
int moveSpeed;//飞机当前飞行的速度
int type;//飞机的类型(大中小)
}Plane, *PPlane; //play结构体(控制继续或暂停)
typedef struct
{
HBITMAP hBmp;//状态位图(暂停或继续)
SIZE size;//位图大小
BOOL isPaused;//状态(暂停或继续)
}Pause; int iBmpNames[] = {IDB_BK, IDB_SMALL, IDB_MIDDLE, IDB_BIG};
Plane pPlaneArr[MAX];//飞机数组
Pause pauseBmp;//暂停、继续
HBITMAP hBmp[4];//背景、大中小飞机位图句柄
int iCurLen;//当前飞机数
int score;//标记分数
int grade;//等级(用于变速)
BOOL isBigAdd=FALSE;//判断打飞机是否已经添加 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//回调函数
VOID StickPlanes(HDC);//用双缓冲贴飞机位图
VOID AddPlane(int, int);//添加飞机
BOOL Beat(HWND, POINT);//判断打飞机是否成功
VOID Boost(HWND, PPlane);//实现爆炸效果
VOID DeletePlane(int);//删除指定索引的飞机
BOOL Paused(POINT);//判断是否点击了暂停 #endif

四、最后我做了一个gif,当做一个演示吧^_^

纯C版微信打飞机游戏

随机推荐

  1. 解决nginx上传模块nginx_upload_module传递GET参数

    解决nginx上传模块nginx_upload_module传递GET参数的方法总结 最近用户反映我们的系统只能上传50M大小的文件, 希望能够支持上传更大的文件. 很显然PHP无法轻易实现大文件上传 ...

  2. SSAS父子层次结构的增强-UnaryOperatorColumn属性

    上次我有讲到自定义汇总,这次的内容跟上次的差不多也算是自定义汇总,实现的方式不同而已!使用的是UnaryOperatorColumn属性. 这个属性说明: 一元运算符用于将成员自定义汇总到父级,汇总运 ...

  3. IDEA12 KeyGen Download List

    When you use IDEA to develop Java, you can use the following file to generate lincese. Because CNBlo ...

  4. SQL Server中各个系统表的作用

    sysaltfiles            主数据库               保存数据库的文件 syscharsets         主数据库               字符集与排序顺序 s ...

  5. rails跑通第一个demo

    rails -h 查看帮助 Usage: rails new APP_PATH [options] Options: -r, [--ruby=PATH] # Path to the Ruby bina ...

  6. 为何visua studio看不到C++项目的LOG?

    最近工程中添加了一个用C++编写的项目 它作为了我正式使用项目的引用 但是当我debug的时候 居然没有看到应该有的LOG 最后找到了解决方法,如下图所示: 右击你的正式项目,属性 改变调试器类型中的 ...

  7. 线性表之顺序表(C语言实现)

    线性表是从数据元素的逻辑结构上定义的. 这种数据元素的逻辑结构的特征如下: 1.除开第一个和最后一个元素之外.所有元素都有一个前驱元素和后继元素. 2.第一个元素无前驱元素,但有后继元素. 3.最后一 ...

  8. Tsinghua dsa mooc pa1

    第一题Range 关键:二分查找,查找不大于一个数的最大下标. #include <cstdlib> #include <cstdio> 4 int compare (cons ...

  9. oracle em命令行配置及界面按钮乱码问题解决方法

    一.配置EM dbconsole db [oracle@rusky ~]$ lsnrctl start [oracle@rusky ~]$ emctl start dbconsoleTZ set to ...

  10. C#获取URL参数值(NameValueCollection)

    在写程序的时候,我们经常需要对页面进行传参数,比如page?id=1234,那么在page这个页面中就直接可以使用string id = Request.QueryString["id&qu ...