有人下载我的工程文件,“我很欣慰”,名字是“挖金子VC版源码”,大家多讨论。
上回讲哪了?地图加载了,物品能显示了。该显示画面上方摆动的叉子了。计算机图形学的“图形旋转”,当然,有一个WINDOWS API函数PlgBlt,可我没有用。网上有很多介绍图形旋转的文章,我还是讲解一下我这个函数:
{
int pvdest[20]={0};
// int x0,y0;
int i;
int tempx,tempy;
memcpy(pvdest,pv,sizeof(int)*num);
/*
x0=pv[0];
y0=pv[1];
//move
for(i=0;i<num;i+=2)
{
pvdest[i]-=x0;
pvdest[i+1]-=y0;
}
*/
//rotate
for(i=0;i<num;i+=2)
{
tempx=pvdest[i];
tempy=pvdest[i+1];
pvdest[i]=tempx*cos(a)-tempy*sin(a);
pvdest[i+1]=tempx*sin(a)+tempy*cos(a);
}
//move,中心点坐标是320 58
for(i=0;i<num;i+=2)
{
pvdest[i]+=x0;
pvdest[i+1]+=y0;
}
//绘制图形
Draw(hdc,pvdest);
}
为什么我没有删除注释掉的代码?有原因。一个图形绕(x0,y0)旋转,总共分三步(耳熟):图形移动到坐标原点,旋转,再移动回原有位置。而我这个叉子的图形在哪里?就在原点。所以省略了第一步。叉子的图形,是画了几个线段,各端点坐标如下(x1,y1,x2,y2,...):
//设置爪子各顶点坐标
int temp[12]={
0,32,20,32,
40,0,64,0,
64,64,40,64
};
再解释一下公式:
pvdest[i]=tempx*cos(a)-tempy*sin(a);
pvdest[i+1]=tempx*sin(a)+tempy*cos(a);
屏幕坐标轴x向右,y向下,这个公式将逆时针旋转图形。
有一个问题,为什么不用一个位图?位图的显示效果虽然好,但是计算cos,sin时,会产生误差。这将使图像有一些变形,所以没有用位图。
绘制、摆动的问题解决了。下面是伸缩。
叉子的伸缩
关键是使用“状态机”。三种状态:摆动,伸出,拉回。我没有定义宏,应该批评。用0 1 2 表示的。
再次声明软件的“可维护性”,这种状态设置,也许琐碎,但有好处。
摆动状态:修改当前角度,当前摆动方向;
伸出状态:改变坐标,如果达到伸出的最大长度,则状态迁移:拉回;
拉回状态:改变坐标,如果“伸出长度”降为0,则状态迁移:摆动。
为了消除坐标计算的误差,伸出时,直接将坐标偏移值转为整型存储,如下:
xoff=10*cos(iAngle*10*1.57/90);
yoff=10*sin(iAngle*10*1.57/90);
拉回的时候,也用相同的偏移值,只要再乘以一个系数,就实现了拉回的快慢不同。
按键检测
用户按“下”,叉子伸出。用按键消息来检测,代码为:
switch(iGameState)
{
case GAME_STATE_MAIN:
gamecatch.KeyProc(wParam);
{
switch(iKey)
{
case VK_DOWN:
if(0==iState)
{
//摆动状态下才能变成伸出状态
iState=1;
xoff=10*cos(iAngle*10*1.57/90);
yoff=10*sin(iAngle*10*1.57/90);
}
break;
目前,叉子能正常摆动,用户按“下”,叉子伸出,然后拉回。紧接着就是核心问题“抓到物品”,即“检测碰撞”,下回接着说。欢迎参考原工程“挖金子VC版源码”(在优快云下载频道)。
Windows API实现小游戏挖金子:叉子的旋转与伸缩
这篇博客介绍了如何使用Windows API实现小游戏挖金子中叉子的旋转和伸缩效果。作者通过讲解图形旋转的原理,展示了不使用PlgBlt函数而是自行设计的方法。叉子的状态机设计包括摆动、伸出和拉回三种状态,通过调整坐标和角度实现运动效果。此外,还讨论了按键检测和即将面临的核心问题——碰撞检测。源码可供下载参考。
3541

被折叠的 条评论
为什么被折叠?



