鱼C论坛

 找回密码
 立即注册
查看: 3450|回复: 7

[技术交流] 用VC6.0做人物走迷宫(上集)

[复制链接]
发表于 2013-9-23 12:50:02 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

                 零基础用VC6.0做人物走迷宫(上集)


程序运行后,窗口里,是一个简单的迷宫。人物可以随着键盘移动。下面说说如何用VC6.0制作以下迷宫





上集中,我们首先制作一个带有人物的窗口:如下







1、新建工程win32application————空白工程(工程名取为game32)

2、在新工程中,新建C/C++ Heand file  (取名为game32) 添加到game32工程中

3、在head file 文件夹中,打开我们新建的game32.h  空白文件(head file文件),加入#include <afxwin.h>

1.png

afxwin.h 就是MFC的库类。

4、我们需要去新建资源文件添加到工程中 (虽然本例子没用到资源,但习惯上还是要建个资源文件,资源就是指图片,声音等外部来的资源)

步骤:新建——资源脚本(resourcescript)取名game————添加到工程

2.png


5、设置资源文件包含的资源内容


3.jpg

我们新建好资源文件后,会自动弹出资源文件窗口,在窗口中选中文件右击————选则资源包含

在这里,因为我们没有使用到资源文件,所以资源包含弹出的窗口中,我们点确定就行。



6、新建类向导

查看(view)————类向导(class wizard)—————弹出窗口问是否创建,选是————弹出窗口,什么也不用填直接点OK————弹窗再直接点OK

类向导是我们用新建类做准备


7、设置项目

工程(project)————设置(setting)————使用MFC静态链接库————OK

4.jpg


静态链接库可以让程序在其他机子里也正常运行起来(程序包含MFC库),而选则共享DLL ,那么程序在其他机子里可能运行不起来(程序不包含MFC库,其他机子如果没有安装MFC库就可能运行不起来)



8、插入窗口类

插入(insert)————类(new class)——————类的类型MFC Class——自定义取名为gamewnd——————bass class(基类) 选择cframewnd————OK

5.jpg



cframewnd是主窗口的类。

这样,我们就生成了一个类,可以在目录中看到这个类


6.png 7.png


9、protect改为public

双击gamewnd这个类(或者打开gamewnd.h)——————把gamewnd()构造函数前面默认的protect改为public,因为我们之后要在其他类中调用到这个类。

8.png


10、再次创建一个类(普通类)

插入(insert)————类(new class)————类的类型generic class——取名为gameapp————derived from CWinApp————继承类型 共有————确定————弹窗是否————是

9.png



11、编译一下。发现有两条错误,修改。

错误一:'stdafx.h': No such file or directory

我们将这个#include"stdafx.h"去掉

错误二:'game.h': No such file or directory
把'game.h'变为game32.h   因为game.h是不存在的,只有game32.h


12、在gameapp.app中定义一个对象

双击gameapp.app    在构造函数前面定义一个这个类的对象。取名为myapp

10.png


13、增加gameapp类中一个BOOL函数

双击gameapp.h     在gameapp类public中增加一个BOOL函数。(构造函数前)

BOOL InitInstance() ;  //这是入口函数 函数名不可自定义

11.png

14、在gameapp.app中定义InitInstance() 函数

双击gameapp.app  在其中定义这个成员函数,用到的格式是类外定义成员的格式

这个函数是窗口的入口,定义具体内容就是初始化窗口,但为什么不在gameapp()这个构造函数中初始化呢?

因为winmain就是去调用InitInstance() 来进行初始化的。

BOOL gameapp::InitInstance()
{

m_pMainWnd = new gamewnd; // gamewnd就是我们从CFrameWnd中派生的自定义类。左边是指针。gameapp这个类是从CWinApp中派生出来的自定义类,CWinApp是从CWinThread中派生出来。总之这个指针就是gameapp继承下来的指针。

}


12.jpg

15、在gameapp.app中添加 #include "gamewnd.h"

因为我们在这个文件中使用了 gamewnd

16、定义gamewnd()构造函数的内容

打开gamewnd.app 找到构造函数,定义


gamewnd::gamewnd()
{

Create(NULL,"创建窗口") ;//创建一个窗口,第一个窗口是窗口类名,如果没有,则表示采用默认窗口类(默认风格),第二个是窗口的标题。这个函数只是建立窗口在内存中,并没有在显示器中显示出来。
}


17、让Create()函数建立的窗口在显示器上显示出来

打开gameapp.app  在BOOL gameapp::InitInstance() 函数中继续定义:

BOOL gameapp::InitInstance()
{
m_pMainWnd = new gamewnd;

m_pMainWnd ->ShowWindow(m_nCmdShow);// 调用gamewnd类中的成员ShowWindow函数,m_nCmdShow是窗口显示的方式,往往第一次传参数时用这个参数。当然这个参数还可以换成其他一些显示的参数。
}

18、增加更新窗口函数

因为我们要做一个人物移动的窗口,所以窗口随着人物移动在不断的改变,因此还需要一个能更新窗口的函数。

BOOL gameapp::InitInstance()
{
m_pMainWnd = new gamewnd;

m_pMainWnd ->ShowWindow(m_nCmdShow);// 调用gamewnd类中的成员ShowWindow函数,m_nCmdShow是窗口显示的方式,往往第一次传参数时用这个参数。当然这个参数还可以换成其他一些显示的参数。

m_pMainWnd ->UpdateWindow();//这个函数不断刷新窗体,如果值为false,则不进行更新

}



19、让BOOL gameapp::InitInstance() 返回一个值
BOOL gameapp::InitInstance()
{
m_pMainWnd = new gamewnd;

m_pMainWnd ->ShowWindow(m_nCmdShow);// 调用gamewnd类中的成员ShowWindow函数,m_nCmdShow是窗口显示的方式,往往第一次传参数时用这个参数。当然这个参数还可以换成其他一些显示的参数。

m_pMainWnd ->UpdateWindow();//这个函数不断刷新窗体,如果值为false,则不进行更新

return TRUE;//BOOL是判断真假,这里如果运行正常就返回TURE

}



13.jpg
运行一下,就弹出了窗口。

20、在gamewnd类定义中,再定义一个新的变量成员

我们可以打开gamewnd.h 然后在public中加入新成员。这里介绍一种新方式:

我们右击gamewnd.h类 选择 add member variable

14.jpg


15.jpg


我们要添加的是一个指向位图类的指针。CBitmap是一个库类。所以在变量类型中填入 CBitmap*     变量名自定义  权限是public


确定后,gamewnd.h中gamewnd类定义public 自动增加了 CBitmap*bitmap;

16.png 此时类的目录中,会自动增加一个变量的图标


当然,如果我们手动自己在h文件中增加一个新成员,类目录中也会自动增加一个变量的图标



21、在gamewnd()构造函数中建立位图类的对象,并用指针指向


打开gamewnd.cpp


gamewnd::gamewnd()
{
Create (NULL,"创建窗口") ;

bitmap = new CBitmap;  //  建立了一个位图类对象,并用指针指向。但这个对象还是空的,之后我们可以把图片放进去
}



22、用LoadImage()函数给位图类对象加载图片

LoadImage()函数有6个参数

第一个参数这里是 NULL  (如果资源是链接式的,就是写NULL,如果是嵌入式的那可能就是句柄,这个例子中是链接式)


第二个参数是访问路径字符串。如果说位图就在工程文件夹中,那么直接写文件名也可以。

第三个参数时加载图片的类型。这里是 IMAGE_BITMAP         当然图片类型不同这里的参数也不同

第四、五个参数:这是放置图片控件的长宽。(注意不是图片大小,是图片放置的控件空间大小,这里我们让他跟图片大小一样,都是 93,100 直接写数字)

第六个参数是:LR_LOADFROMFILE      是指载入的方式,这里就是链接式。还有黑白、缩放载入等

函数返回值:如果加载成功,函数会返回一个句柄,这个句柄是最后一次加载位图成功的句柄。



23、接受位图的句柄

什么是句柄:句柄就是保存数据新内存地址的不变地址(程序重启后当然会变,句柄近似是指向指针的指针)

bitmap->m_hObject  来接受句柄 它可以接受位图、字体、调色板、裁剪区、画笔、画刷等的句柄(m_hObject是CBitmap类的一个成员)

gamewnd::gamewnd()
{
Create (NULL,"创建窗口") ;

bitmap = new CBitmap;  //  建立了一个位图类对象,并用指针指向。但这个对象还是空的,之后我们可以把图片放进去

bitmap->m_hObject = LoadImage(NULL, "1.1.bmp", IMAGE_BITMAP ,93,100,LR_LOADFROMFILE);

}



24、把已经加载好的图片在窗口中显示出来

从图片加载到显示出来的步骤需要:


1、LoadImage把本地图片传入内存中,返回句柄(相当于返回资源地址)

2、用CBitmap类接收句柄(这步可以省略,但是之后要传句柄,如果没有接收的话,就需要把整个函数当参数,这个参数会很长)

3、创建客户区dc  (dc表示窗口空白的部分,图片自然是放到这个区域)

4、CreateCompatibleDC 创建一个兼容dc   (这个函数是CDC成员,这个函数创建了一个与客户区dc兼容的dc,因为图片不能直接读入dc,他需要先读入兼容的dc中)

5、SelectObject  把图片传入兼容dc中 (这个函数是CDC成员,这一步把图片传入了兼容dc中)

6、biblt  把图片传入客户区dc中 (传入后,在showwindow函数中就可显示出来)







gamewnd::gamewnd()
{
Create (NULL,"创建窗口") ;

bitmap = new CBitmap;  //  建立了一个位图类对象,并用指针指向。但这个对象还是空的,之后我们要把图片放进去

bitmap->m_hObject = LoadImage(NULL, "1.1.bmp", IMAGE_BITMAP ,93,100,LR_LOADFROMFILE);//这个位图类里面就有了图片

mdc = new CDC; // 这里CDC是一个库类,新建了一个对象,用来创建兼容dc,并存放位图,本来应该写成CDC *mdc = new CDC;但因为这个是写在构造函数里,是构造函数里的局部变量,而构造函数结束后,我们之后还要使用这个变量,所以这里定义成gamewnd的类成员。这里我们还需要在gamewnd.h中声明或者右击类目录添加这个成员。


CClientDC dc (this) ; //创建客户区,this是指这个类,相当于是在这个主窗体中创建了客户区

mdc->CreateCompatibleDC(&dc);//   该函数创建一个与指定设备(这里就是CClientDC dc)兼容的内存设备上下文环境(DC)。通过GetDc()获取的HDC直接与相关设备沟通,而本函数创建的DC,则是与内存中的一个表面相关联。因为图片不可以直接通过dc读入窗口,他要先放入一个与dc兼容的设备上下文中。这是为后面的SelectObject(bitmap);做准备

mdc->SelectObject(bitmap);//把位图传入前面一步所建立的兼容DC中,这一步不能提前,如果提前不会报错,但运行时会出错。
}

到这里,还剩最后一步biblt,只需要把兼容DC的内容读取到真正的dc中就行了,但是这一步需要使用WM_PAINT

系统会在很多的不同的机制下发送WM_PAINT消息,比如调用UpdateWindow函数,第一次创建窗口,改变了窗口的大小,最大化,最小化等等。这些动作的产生都是有系统来控制的,应用程序只是接收消息,并处理消息。

我们先创建了一个空白窗口,然后系统就会发生WM_PAINT消息(在这里,其实就是构造函数执行完后,就执行在这个类中,其自动生成的onpaint函数。这个消息不是立刻执行,而是等待执行)

所以,我们需要在这个类中,添加WM_PAINT消息,相当于是在这个类中增加onpaint函数。


我们把bc.BitBlt 放在一个 gamewnd::OnPaint()函数中 (需要我们自动添加WM_PAINT 它自动生成onpaint)

我们在类目录下对gamewnd类增加message handler



17.bmp

在gamewnd类目录中添加message handle ————WM_PAINT————add and edit

                               
登录/注册后可看大图



这个时候就会在类成员中增加onpaint函数

                               
登录/注册后可看大图


我们把dc.BitBlt (0,0,93,100,mdc,0,0,SRCCOPY);放入这个函数里面,运行即可。


前面0,0表示画布的左上起始位置,后面的0,0是指读入的图片,它放在窗口中左上的位置。
93,100是指读入图片的长宽。如果图片放置的位置不在画布上,那也是显示不出来的。

mdc,就是函数通过mdc来找到兼容的dc从中读取图片到真正的dc中。
最后一个SRCCOPY表示按照原样复制过来,不拉伸,不缩放等。


这里的画布就是CPaintDC dc 。但我们之前用的是CClientDC啊,其实CPaintDC跟CClientDC差不多。前面的兼容dc对于这两个都能用。

这里之所以要改为用CPaintDC dc   ,这是CPaintDC与CClientDC的一大区别,在onpaint函数中,CClientDC会不断发出WM_PAINT消息,导致不断的重绘。而CPaintDC则不会这样。


把程序运行后:


                               
登录/注册后可看大图



当我们放大缩小窗口,其图片是不变的。这是因为当我们改变大小,或窗体变无效区时,窗口会自动发送wm_paint消息,从而我们onpaint函数又会被执行。

如果我们在onpaint函数中用CClientDC,可以做一个实验,把onpaint函数里,让画布与画的坐标 +x ,+y  然后让x,y自增。如果是CClientDC,那么窗口运行后,画就一直在移动。而CPlientDC只有在更新窗口时图片才会移动。



游客,如果您要查看本帖隐藏内容请回复

1.jpg
2.jpg
6.jpg
7.jpg
8.jpg
9.jpg
10.jpg
11.jpg
16.jpg
19.jpg
20.jpg
001.1.1.jpg
001.1.1.jpg
001.1.jpg
1.jpg
1.png
2.png
3.jpg
4.jpg
5.jpg
6.png
7.png
8.png
9.png
10.png
11.png
12.jpg
13.jpg
14.jpg
15.jpg
16.png
19.jpg
20.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-9-23 12:52:00 | 显示全部楼层
发个图发的乱七八糟  真不知道怎么搞的,怎么后面多了这么多图?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-9-23 13:13:04 | 显示全部楼层
:sweat:那不就是范磊c++  显示图片的教程吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-9-23 13:20:36 | 显示全部楼层
这个好呀,学一下怎么做!!!!!!!!!!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-9-23 19:50:59 | 显示全部楼层
钻地鼠 发表于 2013-9-23 13:20
这个好呀,学一下怎么做!!!!!!!!!!!!

{:2_31:}哟哟哟
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-9-23 20:27:13 | 显示全部楼层
好资源啊,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-9-23 22:07:45 | 显示全部楼层
多谢分享,认真学习,不浪费
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-10-18 23:05:26 | 显示全部楼层
樓主,圖片文字都亂七八糟的,重新編輯一下吧!貌似還有幾幅圖挂了:

                               
登录/注册后可看大图
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-22 03:54

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表