怎样做小游戏挖金子(VC,源码4)

这篇博客介绍了如何使用Windows API实现小游戏挖金子中叉子的旋转和伸缩效果。作者通过讲解图形旋转的原理,展示了不使用PlgBlt函数而是自行设计的方法。叉子的状态机设计包括摆动、伸出和拉回三种状态,通过调整坐标和角度实现运动效果。此外,还讨论了按键检测和即将面临的核心问题——碰撞检测。源码可供下载参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 有人下载我的工程文件,“我很欣慰”,名字是“挖金子VC版源码”,大家多讨论。

上回讲哪了?地图加载了,物品能显示了。该显示画面上方摆动的叉子了。计算机图形学的“图形旋转”,当然,有一个WINDOWS API函数PlgBlt,可我没有用。网上有很多介绍图形旋转的文章,我还是讲解一下我这个函数:

void  GAMECATCH::TcDrawAngleOff(HDC hdc, int   * pv, float  a, int  num, int  x0, int  y0)
{
    
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);
拉回的时候,也用相同的偏移值,只要再乘以一个系数,就实现了拉回的快慢不同。

按键检测

用户按“下”,叉子伸出。用按键消息来检测,代码为:

         case  WM_KEYDOWN:
            
switch (iGameState)
            {
            
case  GAME_STATE_MAIN:
                gamecatch.KeyProc(wParam);
void  GAMECATCH::KeyProc( int  iKey)
{
    
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版源码”(在CSDN下载频道)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值