本系列文章由@二货梦想家张程 所写,转载请注明出处。

本文章链接:http://blog.csdn.net/terence1212/article/details/44208419

作者:ZeeCoder  微博链接:http://weibo.com/zc463717263

我的邮箱:michealfloyd@126.com   欢迎大家发邮件来和我交流编程心得

you are what you read!与大家共勉!

-------------------------------------------------------分割线:ZeeCoder-----------------------------------------------

上一个学习笔记中写了用定时器来实现简易动画,但是在实际游戏编程开发中,往往需要游戏画面在一秒之内更新至少25次以上,这一秒钟内程序还必须进行消息的处理和大量数学运算甚至音效的输出等操作。如此看来,定时器往往满足不了这一需求。所以提出了游戏循环的概念,其基本思想是:判断其中的内容是否有当前要处理的消息,如果有则处理,否则按照设定的时间间隔来重绘画面。其代码如下:

<span style="font-size:12px;">//gamecircle
GetMessage(&msg,NULL,NULL,NULL);//MSG初始化,如果没有初始化会报错
while ( msg.message != WM_QUIT)//如果窗口消息不是WM_QUIT,则继续运行循环
{
	//BOOL PeekMessage(		//函数原型
	//	LPMSG IpMsg,	//接受消息用的MSG指针
	//	HWND hWnd,	//某消息被检查的窗口句柄
	//	UINT wMSGfilterMin, //指定被检查的消息范围里的第一个消息
	//	UINT wMsgFilterMax,	//指定被检查的消息范围里的最后一个消息
	//	UINT wRemoveMsg		//确定消息如何被处理
	//	);
	if ( PeekMessage( &msg , NULL ,0 ,0 ,PM_REMOVE))//PM_REMOVE消息从队列里除掉
	{
		TranslateMessage( &msg);
		DispatchMessage(&msg);
	}
	else
	{
		tNow = GetTickCount();
		if (tNow - tPre >= 100)   //相差0.1秒时在进行重绘操作
			MyPaint(hdc);
	}
}</span>

上述代码理解后就可以进行游戏循环的编程了。来看具体代码

1、声明全局变量

// Global Variables:
HINSTANCE hInst;								// current instance
TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name
HBITMAP walker[16];
HDC hdc , mdc ;
HWND hwnd;
DWORD tPre , tNow ,tCheck; //tPre记录上一次的绘图时间,tNow记录此次准备绘图的时间,tCheck记录每秒开始的时间
int num ,frame ,fps;//num记录图号,frame用来累加每次画面更新的次数,fps记录每秒画面更新的次数

2、主函数

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO: Place code here.
	MSG msg;

	//HACCEL hAccelTable;

	// Initialize global strings
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_GAMECIRCLE, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}
	////gamecircle
	GetMessage(&msg,NULL,NULL,NULL);//MSG初始化,如果没有初始化会报错
	while ( msg.message != WM_QUIT)
	{
		//BOOL PeekMessage(
		//	LPMSG IpMsg,	//接受消息用的MSG指针
		//	HWND hWnd,		//某消息被检查的窗口句柄
		//	UINT wMSGfilterMin, //指定被检查的消息范围里的第一个消息
		//	UINT wMsgFilterMax,	//指定被检查的消息范围里的最后一个消息
		//	UINT wRemoveMsg		//确定消息如何被处理
		//	);
		if ( PeekMessage( &msg , NULL ,0 ,0 ,PM_REMOVE))//PM_REMOVE消息从队列里除掉
		{
			TranslateMessage( &msg);
			DispatchMessage(&msg);
		}
		else
		{
			tNow = GetTickCount();
			if (tNow - tPre >= 100)   //相差0.1秒时在进行重绘操作
				MyPaint(hdc);
		}
	}

3、自定义绘图函数

void MyPaint(HDC hdc)
{
	TCHAR str[40];

	if (num == 15)
		num =0;
	frame++;		//更新次数加1
	if (tNow - tCheck  >= 1000)
	{
		fps = frame;
		frame = 0 ;
		tCheck = tNow;
	}
	SelectObject(mdc , walker[num]);
	_stprintf_s(str , TEXT("每秒显示%d个画面") ,fps );
	TextOut(mdc , 0 ,0 , str , _tcslen(str));
	BitBlt(hdc , 0 ,0 ,600 ,450 , mdc , 0 , 0 ,SRCCOPY);
	tPre = GetTickCount(); //记录此次绘图时间
	num++;
}

4、初始化函数

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;
   TCHAR filename[20] ;
   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }
   MoveWindow(hWnd , 10 ,10 ,600 ,450 ,true);
   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   hdc = GetDC(hWnd);
   mdc = CreateCompatibleDC(hdc);
   int i;
   //载入各个人物位图
   for ( i = 0 ; i <= 15 ;i++)
   {
	   _stprintf_s(filename , TEXT("%d.bmp") , i);
	   walker[i] = (HBITMAP)LoadImage(NULL , filename , IMAGE_BITMAP , 121 ,129, LR_LOADFROMFILE);
   }
   num = 0 ;
   frame = 0 ;
   MyPaint(hdc);
   return TRUE;
}

5、实现效果:

我们设定的画面更新时间是0.1秒,那么每秒中最多更新10次。

笔记三就写到这里了,还是那句话,欢迎大家发邮件和我交流学习~也请继续关注我的学习笔记~

学习游戏编程的路还很长,我还没有入门,望继续坚持下去,自我勉励~

end~

												

【Visual C++】游戏编程学习笔记之三:游戏循环的使用的更多相关文章

  1. 【Visual C++】游戏编程学习笔记之四:透明动画实现

    本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44224963 作者:ZeeCod ...

  2. 【Visual C++】游戏编程学习笔记之八:鼠标输入消息(小demo)

     本系列文章由@二货梦想家张程 所写,转载请注明出处. 作者:ZeeCoder  微博链接:http://weibo.com/zc463717263 我的邮箱:michealfloyd@126.c ...

  3. 【Visual C++】游戏编程学习笔记之七:键盘输入消息

     本系列文章由@二货梦想家张程 所写,转载请注明出处. 作者:ZeeCoder  微博链接:http://weibo.com/zc463717263 我的邮箱:michealfloyd@126.c ...

  4. 【Visual C++】游戏编程学习笔记之六:多背景循环动画

    本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44264153 作者:ZeeCod ...

  5. DirectX 11游戏编程学习笔记之8: 第6章Drawing in Direct3D(在Direct3D中绘制)(习题解答)

            本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com         注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...

  6. DirectX 11游戏编程学习笔记之6: 第5章The Rendering Pipeline(渲染管线)

            本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com         注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...

  7. Bash脚本编程学习笔记07:循环结构体

    本篇中涉及到算术运算,使用了$[]这种我未在官方手册中见到的用法,但是确实可用的,在此前的博文<Bash脚本编程学习笔记03:算术运算>中我有说明不要使用,不过自己忘记了.大家还是尽量使用 ...

  8. 【Visual C++】游戏编程学习笔记之五:单一背景滚动

    本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44224963 作者:ZeeCod ...

  9. 【Visual C++】游戏编程学习笔记之九:回合制游戏demo(剑侠客VS巡游天神)

    本系列文章由@二货梦想家张程 所写,转载请注明出处. 作者:ZeeCoder  微博链接:http://weibo.com/zc463717263 我的邮箱:michealfloyd@126.com ...

随机推荐

  1. solr多集合配置

    1.1 多SolrCore配置 一个solr工程中可以配置多个SolrCore实例. 分享牛原创(尊重原创 转载对的时候第一行请注明,转载出处来自分享牛http://blog.csdn.net/qq_ ...

  2. Scala:数据类型和变量

    http://blog.csdn.net/pipisorry/article/details/52902158 Scala数据类型 Scala 与 Java有着相同的数据类型,下表列出了 Scala ...

  3. Android对话框Dialog深度剖析

    对话框 对话框是提示用户作出决定或输入额外信息的小窗口. 对话框不会填充屏幕,通常用于需要用户采取行动才能继续执行的模式事件. 对话框设计 Dialog 类是对话框的基类,但您应该避免直接实例化 Di ...

  4. 剑指Offer——如何做好自我介绍

    剑指Offer--如何做好自我介绍 前言 自我特点+经历梳理   各位老师好,我叫某某某,XX人.研究生三年级,就读于某某大学信息科学与工程学院软件工程专业.主要使用的开发语言是Java,熟悉基本数据 ...

  5. 剑指Offer——好未来视频面知识点储备+面后总结

    剑指Offer--好未来视频面知识点储备+面后总结 情景介绍 时间:2016.10.12 13:00- 地点:宿舍 事件:好未来视频面 知识点储备 数据结构 单链表反转 public class Li ...

  6. tomcat生命周期的管理——生命周期统一接口Lifecycle

    我们知道Tomcat的架构设计是清晰的.模块化的,其拥有很多组件,假如我们要启动Tomcat,可以一个一个启动组件,但这样启动有很多缺点,不仅麻烦,而且容易漏了组件启动,还会对后面动态组件扩展带来麻烦 ...

  7. Android判断当前系统语言

    Android获取当前系统语言 getResources().getConfiguration().locale.getCountry() 国际化常用语言 中文: getResources().get ...

  8. Android View框架总结(七)View事件分发机制

    请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52282833 View布局告一段落,从本篇开始View事件相关分析, ...

  9. Android简易实战教程--第九话《短信备份~二》

    这一篇,承接地八话.使用高效的方式备份短信--xml序列化器. 存储短信,要以对象的方式存储.首先创建javabean: package com.itydl.createxml.domain; pub ...

  10. Android触摸屏幕时间-android学习之旅(三)

    android的多点触摸是经常遇到的编程技巧,这一篇可以将详细的介绍这个问题. 简单实例 android的触摸需要实现OnTouchListener接口,继承里面方法. 布局代码: <?xml ...