问一个IMAGE声明顺序的问题
easyx吧
全部回复
仅看楼主
level 9
zhangjb90s 楼主
今天写程序的时候,发现了一个BUG,IMAGE对象输出的内容不是预期的,调试了4个小时发现竟然跟 IMAGE对象定义顺序和读取图片的顺序 有关。。。。
有问题的定义顺序,读取的IMAGE对象之间都混乱了,IMAGE对象定义顺序和读取图片的顺序不一致
1.IMAGE picture[N],PicSmall[N];
IMAGE block[2],welcome,bk,CutPic[16];
IMAGE temppic;
MOUSEMSG msg;
修改IMAGE的定义顺序,一切正常了
2.IMAGE picture[N],PicSmall[N];
IMAGE block[2],welcome,bk;
IMAGE temppic;
MOUSEMSG msg;
IMAGE CutPic[16];
看了一下IMAGE 内容
class IMAGE
{
public:int getwidth() const;// 获取对象的宽度int getheight() const;// 获取对象的高度
private:int width, height;// 对象的宽高HBITMAP m_hBmp;HDC m_hMemDC;int m_MemCurX;// 当前点X坐标int m_MemCurY;// 当前点Y坐标float m_data[6];COLORREFm_LineColor;// 当前线条颜色COLORREFm_TextColor;// 当前文字颜色COLORREFm_BkColor;// 当前背景颜色DWORD*m_pBuffer;// 绘图区的内存
struct{intlinestyle;WORDupattern;// 自定义画线样式intthickness;}m_LineType;// 画线样式
struct{int pattern;char upattern[8];// 自定义填充样式int color;}m_FillType;// 填充样式virtual void SetDefault();// 设置为默认状态
public:IMAGE(int _width = 0, int _height = 0);// 创建图像IMAGE(const IMAGE &img);// 拷贝构造函数IMAGE& operator = (const IMAGE &img);// 赋值运算符重载函数virtual ~IMAGE();virtual void Resize(int _width, int _height);// 调整尺寸
};
IMAGE对象定义顺序和读取图片的顺序有关系吗?@yangw80
2013年05月09日 08点05分 1
level 9
zhangjb90s 楼主
2013年05月09日 08点05分 2
level 9
zhangjb90s 楼主
标题打错了,应该是“问一个IMAGE定义顺序的问题”
2013年05月09日 08点05分 3
level 12
我确定,IMAGE 定义顺序无关。
是不是代码的问题?贴出来一起看看吧。
2013年05月15日 00点05分 4
出现的问题,我在cpp文件顶部说明了
2013年05月15日 05点05分
level 11
很复杂的样子
2013年05月15日 00点05分 5
level 12
代码已看,问题不复杂。
我说一个万能的调试办法,我记得以前我说过的,就是删掉无关代码。
2013年05月16日 02点05分 6
level 12
我稍微精简了一下,也不用太精简,至少让自己能找到问题就行。如下:
// 九宫格拼图.cpp : Defines the entry point for the application.
//在全局变量开头,有两个注释,一个是有问题的定义顺序,另一个是没问题的定义顺序,
//当用有问题的定义顺序时,选择4X4模式,会出现图片混乱现象
#include "stdafx.h"
#include <graphics.h>
#include <stdio.h>
#include <stdlib.h>
#define N 5 //图片总数
const int LENGTH = 60; //与边界距离
/////////////////////////全局变量//////////////////////////
//没有问题的定义
/*
IMAGE picture[N],PicSmall[N]; //存储图片 存储缩略图
IMAGE block[2],welcome,but3,but4,bk; //存储空格 欢迎界面背景 游戏开始后背景
IMAGE temppic; //输出步数位置的背景
MOUSEMSG msg;
IMAGE CutPic[16];//一张图片分成九份
*/
//有问题的定义顺序
IMAGE picture[N],PicSmall[N];
IMAGE block[2],welcome,but3,but4,bk;
IMAGE CutPic[16];
IMAGE temppic;
MOUSEMSG msg;
int status[16]; //九宫格的对应状态
int CurPicNum; //当前图片
char strtemp[16]; //存储临时字符串
int MousePosx,MousePosy; //鼠标单击位置
int GameMode=3; //模式 3x3 4x4
TCHAR tmpmp3[_MAX_PATH];
volatile int EDGE_LENGTH=160; //图片的边长
volatile int EDGE_NUM=3; //行列数
///////////////////////////////////////////////////////////
/////////////////////////函数声明//////////////////////////
void LoadRes(void); //初始化各种资源
void StartGame(int); //加载对应图片
void Move(void); //移动图片
///////////////////////////////////////////////////////////
// 提取指定模块中的资源文件
// 参数:
// strDstFile: 目标文件名。提取的资源将保存在这里;
// strResType: 资源类型;
// strResName: 资源名称;
// 返回值:
// true: 执行成功;
// false: 执行失败。
bool ExtractResource(LPCTSTR strDstFile, LPCTSTR strResType, LPCTSTR strResName)
{
// 创建文件
HANDLE hFile = ::CreateFile(strDstFile, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return false; // 查找资源文件中、加载资源到内存、得到资源大小
HRSRC hRes = ::FindResource(NULL, strResName, strResType);
HGLOBAL hMem = ::LoadResource(NULL, hRes);
DWORD dwSize = ::SizeofResource(NULL, hRes);
// 写入文件
DWORD dwWrite = 0; // 写入大小
::WriteFile(hFile, hMem, dwSize, &dwWrite, NULL);
::CloseHandle(hFile); return true;
}
//////////////////////////////////////////////////////////////
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
initgraph(740,600); EDGE_LENGTH=120;
EDGE_NUM=4; LoadRes();
StartGame(CurPicNum);
Sleep(1000); return 0;
}
//////////////////////////////////////////////////////////
void LoadRes(void) //初始化各种资源
{
loadimage(&bk,"IMAGE","bk");
putimage(0,0,&bk);
SetWorkingImage(&bk);
getimage(&temppic,590,335,120,40);
SetWorkingImage(NULL);
loadimage(&picture[0],"IMAGE","0.jpg");
loadimage(&PicSmall[0],"IMAGE","0_small.jpg");
loadimage(&block[1],"IMAGE","block4");
setlinestyle(PS_SOLID,NULL,2);
setbkmode(TRANSPARENT);
setfont(25,0,"宋体");
setcolor(LIGHTRED);
setlinecolor(BROWN);
rectangle(LENGTH-2,LENGTH-2,LENGTH+EDGE_NUM*EDGE_LENGTH+1,LENGTH+EDGE_NUM*EDGE_LENGTH+1);//边框
CurPicNum=0;
}
//////////////////////////////////////////////////////////
void StartGame(int curpicnum) //加载对应图片
{
int x,y,i;
SetWorkingImage(&picture[curpicnum]);
for(y=0;y<EDGE_NUM;y++)
for(x=0;x<EDGE_NUM;x++)
{
getimage(&CutPic[EDGE_NUM*y+x],EDGE_LENGTH*x,EDGE_LENGTH*y,EDGE_LENGTH,EDGE_LENGTH);
}
SetWorkingImage(NULL);
outtextxy(600,80,_T("缩略图"));
putimage(570,120,&PicSmall[CurPicNum]);
outtextxy(600,300,_T("步数"));
outtextxy(595,340,strtemp);
for(i=0;i<EDGE_NUM*EDGE_NUM;i++) //0-8或15表示正常的图片
{
status[i]=i;
}
status[EDGE_NUM*3
+3
]=EDGE_NUM*EDGE_NUM; //9或16表示空格
for(y=0;y<EDGE_NUM;y++) //输出随机后的图片
for(x=0;x<EDGE_NUM;x++)
{
if(EDGE_NUM*y+x==EDGE_NUM*3+3)
{
putimage (LENGTH+EDGE_LENGTH*3,LENGTH+EDGE_LENGTH*3,&block[1]);
}
putimage (LENGTH+EDGE_LENGTH*x,LENGTH+EDGE_LENGTH*y,&CutPic[status[EDGE_NUM*y+x]]);
rectangle(LENGTH+EDGE_LENGTH*x,LENGTH+EDGE_LENGTH*y,LENGTH+EDGE_LENGTH*(x+1)-1,LENGTH+EDGE_LENGTH*(y+1)-1);
}
}
2013年05月16日 02点05分 7
level 12
唉,调整恶心的百度格式真麻烦。。。
以上代码,就是包含问题的、最小的、可编译的代码。遇到奇怪的问题,需要抛开其他干扰因素找问题。
2013年05月16日 02点05分 8
level 12
其实提取资源部分也可以精简掉的,我懒得弄了。
2013年05月16日 02点05分 9
level 12
剩下的代码,没有任何用户控制部分,做单步调试毫无压力,很快就能找到问题所在:
最后一个循环内:
if(EDGE_NUM*y+x==EDGE_NUM*3+3)
{
putimage (LENGTH+EDGE_LENGTH*3,LENGTH+EDGE_LENGTH*3,&block[1]);
}
putimage (LENGTH+EDGE_LENGTH*x,LENGTH+EDGE_LENGTH*y,&CutPic[status[EDGE_NUM*y+x]]);
执行了 if 里面的内容后,再往下执行,就会执行 if 外面的部分,然后,就会发生你说的图片错位的现象。
那就很明显了,问题在最后一条 putimage 上。
2013年05月16日 02点05分 10
恩,却实越界了,输出block[1]后,还得继续往下执行,status[EDGE_NUM*y+x]必定等于16。 在if里面加了continue解决了。谢谢老大[Love] [Love]
2013年05月16日 04点05分
level 12
最后一个 putimage 只是输出而已,输出 CutPic[status[EDGE_NUM*y+x]]
加变量监视:
status[EDGE_NUM*y+x]
一看,等于 16。
于是 CutPic[16] 越界了。
越界后发生的事情你应该知道了吧,所以才会出现你说的变量定义顺序的问题。
2013年05月16日 02点05分 11
level 12
往前追溯代码,为什么 status[15] == 16?
只有这里有赋值:
for(i=0;i<EDGE_NUM*EDGE_NUM;i++) //0-8或15表示正常的图片
{
status[i]=i;
}
status[EDGE_NUM*3+3]=EDGE_NUM*EDGE_NUM; //9或16表示空格
于是,问题找到了吧。
2013年05月16日 02点05分 12
1