本文由BlueCoder编写   转载请说明出处:

http://blog.csdn.net/crocodile__/article/details/16887511

我的邮箱:bluecoder@yeah.net    欢迎大家和我交流编程心得

我的微博:BlueCoder_黎小华    欢迎光临^_^

注:

上次上传的关于如何创建适合游戏编程的MFC工程不能更改窗口的大小,是我疏漏了一步,按如下继续操作就行了:

int CSnowFlakeApp::ExitInstance()
{AfxOleTerm(FALSE);CleanState(L"WorkSpace");//清除工程状态return CWinAppEx::ExitInstance();
}

之后创建工程都加上这句代码就好了,另外感谢网友Enjoy__Coding的提醒

——By BlueCoder

2013/12/10

冬季来了,雪花是她最美的象征,象征着纯洁、美丽,同时也象征着美好的爱情……

呵呵,今天来实现一个浪漫唯美的场景——雪花漫天飞舞

一、效果演示

老规矩,上一个gif演示效果:

看着雪花漫天飘动的感觉,还是蛮爽的哈^_^

二、准备工作

在此之前,我想先声明一点:

最近,我发现VS2008有些让我苦恼了,由于它没有VS2010那样强大的代码规范性以及正确性的提示功能,加上写代码时难免出一些小错误,所以我发现开发大型点儿的程序,VS2008有点儿力不从心了。于是呢,我果断决定以后使用VS2010来写程序。

另外呢,对于写游戏而言,一般我们都只需要一个窗口就够了,而MFC封装了很多不必要的东西,为此,我精心准备了一个教程,专门教你精简MFC工程,以适合游戏编程(尽管这样,MFC还是不适合写大型的游戏,但一般而言是足够了的)

ps:此教程面向初学者,仅供借鉴、参考——教程为一个word文档,在后面的资源下载中提供

ok,继续……

(1). 抠图——准备一张图,利用ps或美图等美工软件将雪花提取出来,然后制作一个透明png:

提取之前                                         提取之后(前两个是抠的, 第三个是自带的)

                          

(2). 准备一首唯美动听的轻音乐

(3). 按照我所提供的MFC工程创建教程用VS2010来创建一个工程——SnowFlake

类视图

三、实现细节

从上面的gif效果演示图可以发现,程序中背景是静态的,雪花是动态的——并且,雪花是以向右倾斜、颤抖、匀速的状态"飘动着"。哪么,是如何实现的呢?Well,我做了一个示意图,请过目:

其中蓝色区域表示雪花png左上角点的飘动范围,红色边框表示窗口客户区

那么,只要给雪花png在水平x轴上设定一个速度分量、在垂直y轴上设定一个速度分量,就能达到雪花向右倾斜、匀速飘动的效果

至于,雪花颤抖,我们可以设定一个水平偏移分量offset,offset为正表示向右偏移;反之,向左偏移。那么只要不断的这样偏移,就能达到雪花颤抖的效果

当然,一张唯美浪漫的背景,加上漫天飞舞的雪花,貌似差点儿什么……

对,再加上一首动听的轻音乐——恩,浪漫的感觉似乎加分不少——呵呵,来一首林海的《星空》

四、代码剖析

(1). 定义一个枚举类型SNOWTYPE,表示三种不同雪花类型

//雪花类型      实心   空心    箭头
enum SNOWTYPE{SOLID, HOLLOW, ARROW};

(2). 定义一个雪花结构体

//雪花结构体
typedef struct s
{int x; //x坐标int y; //y坐标SNOWTYPE type;//雪花类型(两种不同的雪花形状)
}SNOW;

(3). CChildView类中的自定义

成员变量

private:CImage   m_bg;//背景CImage m_solid, m_hollow, m_arrow;//实心、空心、箭头雪花SNOW m_snow[MAX_SNOW];//雪花数组int      m_count;//雪花计数CSize m_sClient;//客户区大小CSize  m_sPng;//雪花大小

成员函数

public://初始化bool Initialize();//绘制雪花void PaintSnow(CDC*);

初始化代码

// 初始化
bool CChildView::Initialize()
{//加载图片m_bg.Load(_T("res\\bg.jpg"));m_solid.Load(_T("res\\0.png"));m_hollow.Load(_T("res\\1.png"));m_arrow.Load(_T("res\\2.png"));//判断图片是否加载成功if(m_bg.IsNull() ||m_solid.IsNull() ||m_hollow.IsNull() ||m_arrow.IsNull()){return false;}//计数为0m_count = 0;//获取客户区大小m_sClient.SetSize(640, 480);//获取雪花大小m_sPng.SetSize(30, 30);//设置时间种子srand(GetTickCount());//来一首唯美浪漫的背景音乐mciSendString(L"open res\\星空.mp3 alias bgm", NULL, 0, NULL);mciSendString(L"play bgm repeat", NULL, 0, NULL);return true;
}

雪花绘制函数

// 绘制雪花
void CChildView::PaintSnow(CDC *pDC)
{//-------------------绘制----------------------CDC bufferDC;CBitmap bufferBmp;//创建兼容内存DC和BmpbufferDC.CreateCompatibleDC(NULL);bufferBmp.CreateCompatibleBitmap(pDC, m_sClient.cx, m_sClient.cy);bufferDC.SelectObject(bufferBmp);//绘制背景bufferDC.SetStretchBltMode(COLORONCOLOR);m_bg.StretchBlt(bufferDC, 0, 0, m_sClient.cx, m_sClient.cy, SRCCOPY);//现在内存中绘制雪花以及背景for(int i=0; i<m_count; i++){//以x轴移动3像素、y轴移动7像素匀速移动m_snow[i].y += 7;m_snow[i].x += 3;//如果雪花出了下边界, 返回起始位置并重新分配雪花类型if(m_snow[i].y > m_sClient.cy ||m_snow[i].x > (m_sClient.cx - m_sPng.cx)){m_snow[i].x = rand()%(m_sClient.cx + 100) - m_sPng.cx - 100;m_snow[i].y = 0;m_snow[i].type = static_cast<SNOWTYPE>(rand()%3);continue;}//水平x坐标的偏移量, 以达到雪花颤抖的效果int offset;//1为向右偏移if(rand()%2){offset = rand()%3;}//0为向左偏移else{offset = -rand()%3;}//根据雪花类型绘制对应形状的雪花switch(m_snow[i].type){case SOLID:m_solid.TransparentBlt(bufferDC, m_snow[i].x + offset, m_snow[i].y,m_sPng.cx, m_sPng.cy, RGB(0, 0, 0));break;case HOLLOW:m_hollow.TransparentBlt(bufferDC, m_snow[i].x + offset, m_snow[i].y,m_sPng.cx, m_sPng.cy, RGB(0, 0, 0));break;case ARROW:m_arrow.TransparentBlt(bufferDC, m_snow[i].x + offset, m_snow[i].y,m_sPng.cx, m_sPng.cy, RGB(0, 0, 0));}}//最后将内存中绘制的雪花一次性绘制到客户区中pDC->BitBlt(0, 0, m_sClient.cx, m_sClient.cy, &bufferDC, 0, 0, SRCCOPY);//释放内存兼容DC和BmpbufferBmp.DeleteObject();bufferDC.DeleteDC();
}

(4). 在WM_CREATE消息中进行一系列的初始化操作

int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{if (CWnd::OnCreate(lpCreateStruct) == -1)return -1;//如果加载失败, 直接退出程序if(!Initialize()){AfxMessageBox(L"图片加载失败");exit(0);}//设置计时器SetTimer(ID_TIMER, 80, NULL);return 0;
}

(5). 在WM_TIMER消息中添加雪花、重绘客户区

void CChildView::OnTimer(UINT_PTR nIDEvent)
{//如果小于指定的雪花最大个数, 继续添加if(m_count < MAX_SNOW){m_snow[m_count].x = rand()%(m_sClient.cx + 100) - m_sPng.cx - 100;m_snow[m_count].y = 0;m_snow[m_count].type = static_cast<SNOWTYPE>(rand()%3);m_count++;}//重绘客户区InvalidateRect(NULL, false);CWnd::OnTimer(nIDEvent);
}

(6). 在WM_PAINT消息中绘制整个场景

void CChildView::OnPaint()
{CPaintDC dc(this); // 用于绘制的设备上下文//用双缓冲绘制雪花PaintSnow(&dc);
}

(7). 别忘了回收内存资源

void CChildView::OnDestroy()
{CWnd::OnDestroy();//关闭音乐、计时器、释放资源mciSendString(L"close bgm", NULL, 0, NULL);KillTimer(ID_TIMER);m_bg.Destroy();m_solid.Destroy();m_hollow.Destroy();
}

五、零积分资源下载

点击下载源码以及MFC工程创建教程

OK,你可以自己添加一点儿创意,然后送给你的那个她,相信她会很喜欢的,O(∩_∩)O哈哈~

【VC++游戏开发#六】2D篇 —— 粒子系统(一):浪漫唯美的场景之雪花飞舞相关推荐

  1. 微信小游戏开发教程-2D游戏原理讲解

    微信小游戏开发教程-2D游戏原理讲解 原理 为了更加形象的描述,这里先上一张图: 背景 a. 首先,我们看到背景好像是一张无限长的图片在向下移动.实际则不然,这是一张顶部和底部刚好重叠的图片.这是一种 ...

  2. OCulus Rift 游戏开发六原则

    本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/46685477 作者:car ...

  3. CutJS – 用于 HTML5 游戏开发的 2D 渲染引擎

    CutJS 是轻量级的,快速的,基于 Canvas 开发的 HTML5  2D 渲染引擎,可以用于游戏开发.它是开源的,跨平台的,与现代的浏览器和移动设备兼容.CutJS 提供了一个类似 DOM 树的 ...

  4. Spine 游戏开发的 2D

    Spine 是一款针对游戏开发的 2D 骨骼动画编辑工具. Spine 旨在提供更高效和简洁 的工作流程,以创建游戏所需的动画 在 Spine 中通过将图片绑定到骨骼上,然后再控制骨骼实现动画. 2D ...

  5. 游戏开发心得——书籍篇——《游戏引擎框架》-导论

    游戏开发心得--书籍篇--<游戏引擎框架>-导论 FOR THE SIGMA FOR THE GTINDER FOR THE ROBOMASTER 简介: 学习<游戏引擎框架> ...

  6. 游戏开发面试答案篇(一)-- C++篇​

    游戏开发程序岗面试题答案版C++篇,后续继续更新游戏逻辑篇.unity篇.图形学篇,并整理成文档,可在公号[游戏君五尘]获取 原文链接 游戏开发面试答案篇(一)-- C++篇​ 目录 一.基础语法 二 ...

  7. 游戏开发心得——书籍篇——《游戏引擎框架》-专业工具

    游戏开发心得--书籍篇--<游戏引擎框架>-专业工具 FOR THE SIGMA FOR THE GTINDER FOR THE ROBOMASTER 简介: 学习<游戏引擎框架&g ...

  8. Cocos2D手机游戏开发之优化篇

    Cocos2D手机游戏开发之优化篇 在这个手机游戏盛行已久的年代,一款产品想要博得更多用户的喜爱就要在细节上做得更加到位.而游戏的优化在这里面起到了非常关键的作用.试想下,一款画面和玩法都深受用户喜欢 ...

  9. 游戏开发总结-java篇

    游戏开发总结-java篇 前言 网络通信 数据存储 逻辑开发 逻辑开发一般遇到的问题有: Java游戏服务器方面的开发要掌握的技术: java服务器目前主流框架技术 前言 Java语言,由于学习成本低 ...

最新文章

  1. im即时通讯源码_IM消息ID技术专题(六):深度解密滴滴的高性能ID生成器(Tinyid)
  2. OpenCV图像形态 image morphology的实例(附完整代码)
  3. gulp 安装时一直提示缺少模块( Cannot find module 'gulp-load-plugins')
  4. php性能优化 --- laravel 性能优化
  5. css样式float造成的浮动“塌陷”问题的解决办法
  6. 小程序 报request:fail invalid url 不校验合法域名已勾选
  7. MongoDBTool - 测试版【GUI美化完毕】 源代码发布 --MongoDB爱好者,Winform爱好者 请进...
  8. java web 登录demo_JavaWeb之Servlet登录demo
  9. 小灰的算法之旅python篇pdf_漫画算法 小灰的算法之旅 Python篇
  10. amos调节变量怎么画_AMOS结构方程教程,调节效应分析操作与结果的详细解读 ——【杏花开生物医药统计】...
  11. 4款超好用的时间轴制作软件
  12. 电路自学2-储能元件(电容+电感+储能元件的串并联)
  13. 【独家】这两个人的对决,决定了万科股权大战的走向
  14. 计算机一级最强大脑,计算机入侵人类 《最强大脑》选手完败?
  15. deflate php,gzip和deflate的几点区别
  16. OK1028A-C实现路由器功能
  17. 量子BB84,B92协议简单介绍
  18. 如何将Scratch作品转换成HTML或者应用程序
  19. average and standard deviation-平均数和标准差
  20. 图像基本处理——图像阈值和平滑

热门文章

  1. python运行代码不成功_【Python】程序在运行失败时,一声不吭继续运行pass
  2. elementui去掉表格所有边框
  3. 修改计算机桌面壁纸影响计算机考试吗,计算机考试
  4. andorid 问题集合
  5. excel计算二元线性回归_用人话讲明白梯度下降Gradient Descent(以求解多元线性回归参数为例)...
  6. RC电路(积分电路,微分电路)
  7. Kotlin 非对称加密RSA
  8. 跨境电商细分领域的探索-扬帆际海
  9. 运用ARCGIS制作行政区划数据图表
  10. OP27运放在同相比例放大器中的应用