虫虫教学

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 459|回复: 0

幸运转盘

[复制链接]

4449

主题

4659

帖子

4万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
41710

最佳新人发帖达人推广达人热心会员突出贡献优秀讲师

发表于 2021-10-15 18:36:34 | 显示全部楼层 |阅读模式
                   幸运转盘


    幸运转盘是一款转盘抽奖游戏,实例就是实现这样一款游戏,单击转盘中央的“开始”按钮后,转盘开始转动,转盘停止后,指针会指向不同的奖品,效果如图1所示。



关键技术
程序可以使用多个图片来完成,最底层为背景图,中间层转盘图,最上边为指针图;只要实现转盘图按照中心点旋转就可以实现最终的效果。图片可以使用PNG格式的图片,然后使用GDI+库来实现图片的旋转。
程序的难点体现在如何使用GDI+库来实现图片的旋转。PNG图片可以先转化为流,然后通过GDI+库的Image类打开,绘制的时候需要使用Graphics类的DrawImage函数,旋转需要使用矩阵Matrix类来实现,GDI+中有两个旋转函数Rotate和RotateAt,两者的区别是后者可以指定旋转点,用Matrix类来实现旋转其实质就是进行坐标的转换。
坐标的转换的过程是首先定义单位矩阵,将原点设置为(0,0),然后在单位矩阵上运行旋转函数,旋转函数通过旋转角度可以改变单位矩阵的值,最后通过坐标变换函数,就可以实现将指定点转换为旋转后的点
注意:GDI+库的有独立的头文件以及链接库,使用时应设置Visual C++的搜索路径(Tools/Options/Directories)使编译器能够找到头文件及链接库。
设计过程
(1)创建对话框应用程序,
(2)将PNG图片添加到工程内,并建立PNG资源组,将背景图的ID设置为IDR_BK,将转盘图的ID设置为IDR_DISK,将开始按钮图片的ID属性设置为IDR_START,将按下开始按钮后的图片ID属性设置为DR_STOP。
(3)在StdAfx.h文件中添加gdiplus.h头文件和gdiplus.lib库文件的引用
(4)方法OnInitDialog是对话框初始化的实现,首先从动态链接库User32中获取UpdateLayeredWindow函数,然后调用ImageFromIDResource函数创建PNG图片的Image指针,最后通过DrawDisk函数将图片绘制出来。
BOOL CDiskDlg::OnInitDialog()
{
      CDialog::OnInitDialog();
//代码省略

      this->MoveWindow(0,0,700,700);                             //设置窗体宽和高
       GdiplusStartup(&m_pGdiToken,&m_Gdiplus,NULL);  //创建GDI+句柄
      m_hInstance = LoadLibrary("User32.DLL");                     //加载User32.DLL动态链接库
      if(m_hInstance) //使指针指向链接库中UpdateLayeredWindow函数
            UpdateLayeredWindow=(MYFUNC)GetProcAddress(m_hInstance,
                  "UpdateLayeredWindow");
      else
      {
            MessageBox("连接库加载失败","提示",MB_OK);
            exit(0);

      }
      time_t t;                                                           //声明时间结构变量
      m_iRand = time(&t);                                                //获取时间,用于随机种子
      m_Blend.BlendOp=0;                                        //设置操作系统
      m_Blend.BlendFlags=0;                                     //属性标识设置
      m_Blend.AlphaFormat=1;                                         //设置Alpha格式
      m_Blend.SourceConstantAlpha=255;                                 //设置Alpha颜色
      ImageFromIDResource(IDR_DISK,"PNG",m_pImageDisk);      //创建转盘图片流
      ImageFromIDResource(IDR_BK,"PNG",m_pImageBk);             //创建背景图片流
       ImageFromIDResource(IDR_START,"PNG",m_pImageStart);   //创建开始按钮图片流
      ImageFromIDResource(IDR_STOP,"PNG",m_pImageStop);      //创建按下的开始按钮图片流
      m_StartWidth  =m_pImageStart->GetWidth();                  //获取开始按钮图片的宽度
      m_StartHeight =m_pImageStart->GetHeight();                   //获取开始按钮图片的高度
      DrawDisk();                                                     //绘制图片
      return TRUE;
}

(5)方法DrawDisk是绘制图片的实现。首先创建一个兼容的设备上下文,并加载一个内存位图,然后将Graphics对象绑定到设备上下文上,定义绘制图片所使用的三个点的坐标,然后通过DrawImage将图片绘制出来,需要旋转的图片需要定义一个单位矩阵,单位矩阵需要三个点的坐标,分别是左上、右下、中心点,使用RotateAt函数旋转完矩阵后,就可以通过TransformPoints来改变指定的坐标。最后仍然通过DrawImage函数将图片绘制出来。使用GDI+来显示PNG图片需要使用窗体的特殊层,通过函数UpdateLayeredWindow可以使用特殊层,并通过GetWindowLong函数修改窗体原有属性。
(6)自定义方法ImageFromIDResource实现将资源内的图片转换为流。首先使用FindResource找到资源,然后将资源的内容读取到由GlobalAlloc分配的缓存中,最后根据HGLOBAL对象来生成流。
秘笈心法
心法领悟598:矩阵的变换实现旋转

Matrix类的RotateAt方法实现图像绕自身的某个点进行旋转,如果想要实现图像绕指定点旋转就需要使用Rotate方法,这两个方法都对单位矩阵进行旋转变换,最后通过TransformPoints方法将单位矩阵应用到图像所在矩阵。

本帖子中包含更多资源

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

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

本版积分规则

QQ|Archiver|手机版|小黑屋|虫虫教学--虫虫联盟官网

GMT+8, 2025-4-28 23:32 , Processed in 0.093209 second(s), 25 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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