C++做拼图游戏Word下载.docx
《C++做拼图游戏Word下载.docx》由会员分享,可在线阅读,更多相关《C++做拼图游戏Word下载.docx(66页珍藏版)》请在冰豆网上搜索。
hInst
=
hInstance;
//
6.
7.
hWnd
CreateWindow(szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW
&
~WS_SIZEBOX
~WS_MAXIMIZEBOX,
//这里修改了,让WS_OVERLAPPEDWINDOW
~WS_MAXIMIZEBOX的目的是去掉最大化的按钮,同时禁止修改窗口大小
8.
CW_USEDEFAULT,
0,
/*CW_USEDEFAULT,
0*/800,
600,
/*这里的800和600就是窗口的大小,我采用的是800*600的,大家自己根据实际情况改*/NULL,
NULL,
NULL);
9.……
10.}
二、制作一些其他需要的资源
现在有窗口了,那么,我们要有其他的资源,比如各种图片,声音,还可以有鼠标指针。
我们先制作图片就行了,声音,鼠标指针以后再说。
因为图片资源是必须的,其他的是可选的。
我们需要一张背景图片。
随便找张图片,选个大小,我当然选的是800*600的。
然后打开PS去修改吧,我不教PS了,我改的结果是这样的,里面还有一些坐标要记下来的。
如图:
再来一张没坐标的,可以直接下载用。
不过因为CSDN的相册空间太小,所以给个地址吧,链接到XX相册,大家见谅。
记住,保存成BMP格式的,因为BMP的读取起来很容易,如果是JPG的,还要自己去写相应的读取函数。
转换的方法就是用画图打开图片,然后选择“文件->
另存为->
BMP(24位)”
然后,还要一张用来进行游戏的图,也就是要拼的图,这个更简单了,弄张400*400的就行了(因为我的游戏区大小是400*400)。
到现在为止,我们的准备工作已经完成了。
下面,就是编写代码的过程了。
三、设计功能
1.定义类
CPuzzleLogic,用来实现内部逻辑的行为
CPuzzleView,
用来实现视图显示方面的
CPuzzleMain
用来实现主程序,主要是把各部分的联系起来
如果还有其他需要的,以后再定义别的
创建类的时候可以用类向导,不过,VS2008和VS2005里没有,所以用以下方法:
先把解决方案管理器调到类视图里,在项目名称上单击鼠标右键,添加,类
选“C++类”,单击“添加”,在新窗口中写上类名,单击“确定”
如上图,再重复添加其他两个类。
在CPuzzleMain类的头文件上面的#pragmaonce后面加上
#include"
PuzzleLogic.h"
PuzzleView.h"
2.给类相应的功能
先在CPuzzleMain类里添加两个成员变量,分别是其他两个类的类型,用来以后引用里面的功能。
添加方法如下图:
在类视图里右键单击类名称,添加,添加变量
选成private可以防止类外访问到它,写上变量类型和变量名称,然后可以写几句注释
以同样的方法再添加另一个变量,当然,你也可以直接在头文件里写上,效果是一样的,只是这样的做法可以自动初始化系统有的类型,否则有时候会出错。
3.添加画图功能
我们设计一个画图的函数,这样的话,以后就不必每次都去写画图函数了
添加函数的方法:
在类视图里右键单击类名称,添加,添加函数,参考添加变量的图
在新窗口中输入返回类型,函数名,函数的参数,以及注释等等信息。
这样的好处是点击完成的时候,系统会自动添加到头文件中声明,和.cpp文件中的定义部分。
然后写代码吧。
(1)要先在CPuzzleView里加上两个成员变量
private:
HWNDm_hWnd;
//
保存窗口句柄
HBITMAPm_hBmpBack;
//保存背景图片
(2)把前面做好的图片复制到源代码文件夹的res文件夹里,如果没有的话,就自己新建一个,当然你也可以写别的名字,不过要自己记住,我这里就以res为例子。
(3)添加以下几个函数
1.//
画图,hBitmap表示指向图片的指针,x,y表示位图显示的横纵坐标,nWidth,nHeight位图的宽度和高度,srcX,srcY从位图的的哪个位置开始显示
2.void
CPuzzleView:
DrawPic(HBITMAP
hBitmap,
x,
y,
nWidth,
nHeight,
const
srcX=0,
srcY=0)
3.{
HDC
hdcMem;
//内存DC
hdcScr
GetDC(m_hWnd);
//获取屏幕的DC
hdcMem
CreateCompatibleDC(hdcScr);
//创建兼容屏幕的内存DC
SelectObject(
hdcMem,
hBitmap
);
//将图片绑定内存DC上
BitBlt(
hdcScr,
srcX,
srcY,
SRCCOPY
//将内存DC里的东西画到屏幕上
9.
DeleteDC(hdcMem);
//清除两个DC
10.
DeleteDC(hdcScr);
11.}
12.
13.//
初始化图像显示的对象
14.bool
InitView(HWND
hWnd)
15.{
16.
m_hWnd
//将窗口句柄传进来
17.
m_hBmpBack
(HBITMAP)LoadImage(NULL,
_T("
res\\background.bmp"
),
IMAGE_BITMAP,
LR_DEFAULTSIZE|LR_LOADFROMFILE);
//读取图片文件
18.
if(m_hBmpBack
==
NULL)
19.
{
20.
MessageBox(NULL,
读取背景文件失败"
Error"
MB_OK);
21.
return
false;
22.
}
23.
DrawPic(m_hBmpBack,
800,
600);
//画背景
24.
true;
25.}
26.
27.//
用于重绘
28.void
OnPaint(void)
29.{
30.
//重绘背景
31.}
在CPuzzleMain类里添加函数
执行初始化工作
2.bool
CPuzzleMain:
InitMain(HWND
m_View.InitView(hWnd);
6.}
7.//
用来重绘
8.void
9.{
m_View.OnPaint();
然后,在Puzzle.cpp中,也就是系统自动生成的文件里添加全局变量及头文件引用
PuzzleMain.h"
CPuzzleMaing_PuzzleMain;
//保存游戏实例
在下面的BOOLInitInstance(HINSTANCEhInstance,intnCmdShow)函数中,return前加上游戏的初始化代码
g_PuzzleMain.InitMain(hWnd);
在消息循环的函数中,找到
1.LRESULT
CALLBACK
WndProc(HWND
hWnd,
UINT
message,
WPARAM
wParam,
LPARAM
lParam)
3.…
4.case
WM_PAINT:
hdc
BeginPaint(hWnd,
ps);
TODO:
在此添加任意绘图代码...
g_PuzzleMain.OnPaint();
//添加绘图代码
EndPaint(hWnd,
break;
10.…
11.}
好了,现在编译并运行程序,就可以显示出来背景了。
简单介绍一下,在OnPaint()里会看到HDC类型的变量,比如
HDChMem;
这是声明了一个内存DC,所谓DC,网上说的是设备描述表(DeviceContext,DC),设备描述表(DeviceContext,DC)是一个信息结构体,包含物理输出设备及其驱动程序。
在Windows平台下,所有的图形操作都是通过它完成。
不用管他是什么结构体,只要知道用它可以操作图形图像,想显示在显示器里就要创建一个兼容显示设备的DC,然后就可以显示了,比如
1.HDC
m;
2.
//获取屏幕的DC
这个过程是先创建内存DC,然后获取了屏幕DC,再设置内存DC兼容屏幕DC,其实就是这两个的信息是一致的了,然后把图片绑定到内存DC里,这样,内存DC里就有了图片,但是,这时还看不到图片,我们最后用BitBlt函数把内存DC里的东西复制到屏幕DC上,这样就能显示出来,我们就看到了。
如果还是不明白的话,请上网XX,Google一下,有很多解释的。
1.case
WM_PAINT是windows应用程序的重绘消息,当收到这个消息的时候,就意味着屏幕要发生变化了,需要重绘,一般的,当你把窗口移到屏幕外,再移回来,就要发生重绘等等,我们在这加上重绘代码,使我们的程序在移动或者被覆盖的时候还能显示回来。
虽然上面我们已经写了很多代码了,也能显示背景了,但是有时候会经常改以前的东西,甚至推翻重做。
下面是读取游戏的要拼的图片了。
首先,我们要确定逻辑保存方式,我采用的是一个一维数组表示。
而且为了可以切割成任意块数,所以定义成了一个指针类型。
这是在CPuzzleLogic里定义的
1.int*
m_Block;
//用来保存当前局面的
m_BlockNum;
//保存此局横向要分成多少块
因为拼图是一个正方形的,所以只用了一个表示横向的有多少块的变量
还要进行初始化,在CPuzzleLogic里添加了一个初始化函数,当然现在的函数还做不到真正初始化,只是提供了一种测试方法。
BlockNum为要切割的方块数,只在横向或纵向的
CPuzzleLogic:
InitLogic(int
BlockNum)
m_BlockNum
BlockNum;
m_Block
new
int[BlockNum*BlockNum];
for(int
i=0;
i<
++i)
j=0;
j<
++j)
num
BlockNum
-
i
-1;
11.
m_Block[i*BlockNum+j]
num*10+j;
13.
14.
15.}
而且,修改了一个初始化的函数,增加了读取其他图片的功能。
不仅仅是读取背景图片了
然后就是CPuzzleView类里的内容了。
改动较大。
请仔细看。
下面还定义了很多必要的变量,主要是表示坐标等等。
bool
BlockNum=3);
3.private:
//保存图案
HBITMAP
m_hBmpGame;
//保存小图案
m_hBmpGameSmall;
//右上角的坐标及大小
static
m_Small_x=560;
m_Small_y=70;
m_Small_width=200;
m_Small_height=200;
//图片游戏区的大小及坐标
m_Game_x
70;
15.
m_Game_y
100;
m_Game_width
400;
m_Game_height
m_FrameNum;
//表示要分隔的块数(一排的)
int*
//表示当前状态
m_IsGameStarted;
//游戏是否已经开始
21.public:
读取图像列表(就是拆开图像)
LoadBMPList(int
*Block);
设置游戏是否已经开始
25.
void
SetGameStarted(bool
bStarted);
然后初始化的函数有所改动,增加了一个参数,里面又读取了其他的几个图片。
这里面也没什么要特别说明的。
1.#define
GETX(x)
(x+70)
2.#define
GETY(y)
(y+100)
3.//
4.bool
5.{
……
//读取图案
m_hBmpGame
res\\game.bmp"
NULL)
//判断是否读取图片成功
读取图案文件失败"
m_hBmpGameSmall
res\\gamesmall.bmp"
if(m_hBmpGameSmall
读取小图案文件失败"
m_FrameNum
int[m_FrameNum*m_FrameNum];
//这个就是申请内存空间
OnPaint();
24.}
26.下一个是以下两个函数,也没什么特别说明的。
27.
28.//
29.bool
*Block)
30.{
31.
memcpy(m_Block,
Block,
sizeof(int)*m_FrameNum*m_FrameNum);
32.
//m_Block
Block;
33.
//OnPaint();
34.
35.}
36.
37.
38.//
39.void
bStarted)
40.{
41.
m_IsGameStarted
bStarted;
42.
43.}
最关键的是重绘函数,彻底的更改了,上次的教程里只是为了显示一下背景,而现在要显示的东西多了,就不能再用原来的那个了。
先看代码: