泡泡堂Tips

C++ fstream 使用相对路径存取文件失败

读取泡泡堂地图的时候发现 ifstream 无法打开文件,后来发现是因为不能使用相对路径名,但如果使用绝对路径,游戏的移植性又太差,解决方法:

TCHAR buf[MAX_PATH + 1];
CString strtemp, path;
//得到exe文件的路径名
GetModuleFileName(NULL,buf,sizeof(buf));
strtemp=buf;
//得到exe文件所在文件夹的路径
int s=strtemp.ReverseFind('\\');
if (s != -1)
	strtemp=strtemp.Left(s);
//最终路径
path = strtemp+"\\pic\\town2.mp";
ifstream fin(path);
if (fin.fail())
{
	::MessageBox(NULL, "read file failure", "Error", MB_OK ¦ MB_ICONERROR ¦ MB_APPLMODAL);
}

error C2601: 本地函数定义是非法的

问题原因:少了个大括号

关于HGE引擎设置bmp图片的ColorKey

HGE引擎原本无法对bmp图片设置透明色,但是现有的资源都是bmp的,转换太麻烦,只要对引擎稍加修改就可以达到目的.

原引擎接口:

HTEXTURE CALL HGE_Impl::Texture_Load(const char *filename, DWORD size, bool bMipmap)
{
	void *data;
	DWORD _size;
	D3DFORMAT fmt1, fmt2;
	LPDIRECT3DTEXTURE8 pTex;
	D3DXIMAGE_INFO info;
	CTextureList *texItem;

	if(size) { data=(void *)filename; _size=size; }
	else
	{
		data=pHGE->Resource_Load(filename, &_size);
		if(!data) return NULL;
	}

	if(*(DWORD*)data == 0x20534444) // Compressed DDS format magic number
	{
		fmt1=D3DFMT_UNKNOWN;
		fmt2=D3DFMT_A8R8G8B8;
	}
	else
	{
		fmt1=D3DFMT_A8R8G8B8;
		fmt2=D3DFMT_UNKNOWN;
	}

//	if( FAILED( D3DXCreateTextureFromFileInMemory( pD3DDevice, data, _size, &pTex ) ) ) pTex=NULL;
	if( FAILED( D3DXCreateTextureFromFileInMemoryEx( pD3DDevice, data, _size,
							D3DX_DEFAULT, D3DX_DEFAULT,
							bMipmap ? 0:1,		// Mip levels
							0,			// Usage
							fmt1,			// Format
							D3DPOOL_MANAGED,	// Memory pool
							D3DX_FILTER_NONE,	// Filter
							D3DX_DEFAULT,		// Mip filter
							0,			// Color key
							&info, NULL,
							&pTex ) ) )

	if( FAILED( D3DXCreateTextureFromFileInMemoryEx( pD3DDevice, data, _size,
							D3DX_DEFAULT, D3DX_DEFAULT,
							bMipmap ? 0:1,		// Mip levels
							0,			// Usage
							fmt2,			// Format
							D3DPOOL_MANAGED,	// Memory pool
							D3DX_FILTER_NONE,	// Filter
							D3DX_DEFAULT,		// Mip filter
							0,			// Color key
							&info, NULL,
							&pTex ) ) )

	{	
		_PostError("Can't create texture");
		if(!size) Resource_Free(data);
		return NULL;
	}

	if(!size) Resource_Free(data);

	texItem=new CTextureList;
	texItem->tex=(HTEXTURE)pTex;
	texItem->width=info.Width;
	texItem->height=info.Height;
	texItem->next=textures;
	textures=texItem;

	return (HTEXTURE)pTex;
}

理论上只要对该函数增加一个 ColorKey 的参数,然后在 D3DXCreateTextureFromFileInMemoryEx 调用里将 0 改成 ColorKey 就可以了,但由于HGE使用DX8,我的电脑没有安装,所以编译不成功,在网上找到一个改过的版本,不过是直接把RGB(255,0,255)设为了透明色,不能用别的透明色,凑合用着…

关于常量和全局变量

对于游戏里的各种常量,一开始是分别写在各个类里的,后来发现很多类都要用到相同的常量,要重复设置很多遍.

更佳方案:单独写一个头文件用来定义常量和宏

如果将全局变量写到头文件里就容易出现各种莫名其妙的错误,基本是因为重定义的问题,如果一个头文件被 include 多次就会出现这个问题,即使使用 ifdef 之类的宏只定义一次也难免会出问题,后来就导致我的程序无法编译,即使改回去也编译不成功,这个原因至今不明.

方案:目前的解决方法是把全局变量写在 main 函数前,在其它文件里使用 extern 声明. 不知道又没用更好的方案,有时间要把C++基础补补了.好多东西都忘了.

另外如果两个头文件相互 include 也会出现奇怪问题,设计时要把类的关系划分清楚,搞的很混乱就很容易出问题.

C++传递二维数组作为函数参数的语法:

比如一个二维数组:

int map[10][12];

函数定义方法

void fuc( int map[][12] )
{
    int (*interMap)[12] ; //这个定义太纠结了>___<
    interMap = map;
}

使用库时报错缺少 dll 文件

解决方法: 要将库里的 dll 文件放到 exe 文件的文件夹下.