想一想,上一次编写win32可视化程序还是在大一刚开学的时候,我连面向对象是什么都不知道,熬夜照着书打代码想尽快做出自己的游戏,还拿着《游戏编程大师技巧》的书,问c++老师书里说的COM是什么。现在已经想不起来老师当时是怎么回答的,反正最后的我决定先放下这么“大师技巧”的话题,好好打基础。然而这一打就打了两年浮躁的php、网站前端和还不错的课内成绩。反省一下,感觉离我真正想做的事情,大一的我越来越远,变成了高速学习去完成项目的机器(3个月从不会ios到做成一个完整ios应用我挺佩服自己)。

终于,这一次,课内的windows编程综合训练任务迫使我(都这么windows了我还不写游戏,太对不起大一的我了)在五天内,学会用基础的DirectX、基础的Winsock制作了一个简单的飞机大战联机版。

初步设想的游戏是让一个局域网内的玩家可以开设游戏房间,一定数量的其它玩家可以随时加入、断线重连,玩家们用键盘控制自己的飞机移动和开火,消灭由主机生成各种各样的敌人。这里需要各个玩家向主机发送控制信息(主机自己玩自己的),主机向玩家广播游戏的内容,游戏实际上对延迟容忍较低,需要较高的同步算法复杂度。

基本的单机打飞机(控制、开火、生成敌机、爆炸)运用DirectX的体验还是很愉快的,看着游戏很流畅按照自己想像的样子运行,心理无比畅快。但是到了Winsock方面的编程,限时五天的训练时间似乎就不太足够了,熬夜无奈的我最终采取了最暴力的通信方式,还好在给老师检查时运行顺畅(毕竟局域网里通信环境还算安逸),怒得100分。

开始界面_compressed

界面同步_compressed

一点爆炸_compressed

参考资料

这次学习DirectX和windsock的过程中遇到了很多优秀的学习资源:
《游戏编程入门》 By Jonathan Harbour
《游戏编程大师技巧》 By Andre LaMothe
《秒杀多线程》
http://blog.csdn.net/morewindows/article/details/7421759
《socket阻塞与非阻塞,同步与异步、I/O模型》
http://blog.csdn.net/hguisu/article/details/7453390
《网游同步法则》以及博文作者其它关于游戏服务器优秀的文章
http://www.skywind.me/blog/archives/112

反省

游戏现在虽然可以在一个实验室的局域网下面勉强流畅运行了,但是和“初步设想”相差还是很大,好好反省的话这个游戏目前明显有且不限于以下缺点:

  1. 游戏内容少,只有不会开火的敌机慢慢加速过来送死,这方面需要研究一下如何给游戏更好地不断增设剧情
  2. 代码编写完全面向过程,特别是网络通信部分因为时间紧张封装很差,各种全局变量瞎了我狗眼。本应该在下手写代码前就构思好代码框架,运用各种设计模式的姿势,可是对待完全未知的知识,这样可能会导致我DirectX掌握时间拖后而达不到这次编程任务必须有Winsock的要求。
  3. 通信代码超级暴力,仅是无阻塞的socket,所有io都在主线程进行,辜负了上述博客优秀的多线程教学
  4. 游戏同步逻辑极其令人失望,在我看了《网游同步法则》博客中各种有趣的算法以后,我还写这样的同步,我好伤心,我一定要把那些算法都实现一次!
  5. 完全没有通信协议,请看如下代码
void BroadCastGame()
{

	ostringstream oss;
	// 子弹
	oss << "B " << friendlyBullets.size();
	for (auto it = friendlyBullets.begin(); it != friendlyBullets.end(); it++)
	{
		oss << " " << it->x << " " << it->y;
	}
	// 主机自己
	oss << " " << player.x << " " << player.y << " " << player.velx << " " << player.vely;

	// 敌机
	oss << " " << hostilePlanes.size();
	for (auto it = hostilePlanes.begin(); it != hostilePlanes.end(); it++)
	{
		oss << " " << it->x << " " << it->y << " " << it->velx << " " << it->vely << " " << it->scaling;
	}
	// 爆炸
	oss << " " << booms.size();
	for (auto it = booms.begin(); it != booms.end(); it++)
	{
		oss << " " << it->x << " " << it->y << " " << it->scaling << " " << it->frame;
 	}

	UDP_Host_Send(oss.str());
}

综上,老师打出100分的高分,大概是看在我纯手工打造,辛苦分50,态度分50。

预告

接下去的我为了在游戏编程的路上越走越远,及时总结学习到游戏方面的知识技巧,会在博客上正式开始更新游戏编程相关的自学笔记、各种算法题目的解题报告、C++重温和钻研以及反正是更认真的技术文章等。

所以说接下去两、三篇博文很可能是关于这次游戏编程过程中遇到的DirectX基础知识、C++编程技巧、Winsock和多线程编程。一下子学到好多,真是总结不过来。

细心的同学可能看到我博客两个月没更新,那是我三个月从零学起iOS赶着做项目,参加iOS比赛(我要举报这个比赛appcontest.com超级跳票行为,正当我们赶在截止之前做完准备提交,突然把提交窗口延后2个月,还我一口鲜血),这三个月学习量也十分巨大,来不及更新博客总结总结很遗憾。

「Unity Shaders」Surface Shaders and Texture Mapping

 本文内容参考《Unity 5.x Shaders and Effects Cookbook》 表面着色器和材质贴图 总的来说,一个表面着色器有两个关键的步骤。第一,必须确定材质的物理...

阅读全文

「Unity Shaders」Creating First Shader

创建第一个着色器 最近学习了一段时间Unity Shader相关知识,在进一步自顶向下学习计算机图形学之前,先将之前看《Unity 5.x Shaders and Effects Cookbook...

阅读全文

《Effective c++》、《Inside C++ Model》 小结(一)

最近瞻仰了一下Scott Meyers久负盛名的《effective c++》,特来总结一下,以加深一下印象与防止自己今后记忆力衰退。这本书里很多都是工程上很有意思的tips...

阅读全文

1 条评论

欢迎留言