<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[圣叹@游戏开发]]></title> 
<link>http://qizhi.me/index.php</link> 
<description><![CDATA[What your mother never told you about game development ]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[圣叹@游戏开发]]></copyright>
<item>
<link>http://qizhi.me/read.php?323</link>
<title><![CDATA[Xcode:当发现Archives成功，但是Organizer里看不见的时候]]></title> 
<author>Qizhi &lt;admin@yourname.com&gt;</author>
<category><![CDATA[Program]]></category>
<pubDate>Mon, 19 Sep 2011 02:01:16 +0000</pubDate> 
<guid>http://qizhi.me/read.php?323</guid> 
<description>
<![CDATA[ 
	昨天我们正式提交了我们公司的第一款iOS游戏到AppStore，目前正在审核中。也是我个人的第二款iOS游戏（第一款是一款个人产品：Turtle Reaction，<a href="http://itunes.apple.com/cn/app/turtle-reaction/id446570380?l=en&mt=8" target="_blank">http://itunes.apple.com/cn/app/turtle-reaction/id446570380?l=en&mt=8</a>）。<br/>在打包的时候，我发现我的XCode虽然Archive成功，但是在Organizer里看不见。后来发现，应该是Xcode写入默认路径权限不够。所以解决起来很简单：<br/>1. 点击Xcode的Preference。进入系统的设置界面。选择Locations选项卡。<br/>2. 修改Archives Location，设置路径由默认路径为自己的自定义路径。<br/>成功。<br/>Tags - <a href="http://qizhi.me/tag.php?tag=xcode" rel="tag">xcode</a> , <a href="http://qizhi.me/tag.php?tag=ios" rel="tag">ios</a> , <a href="http://qizhi.me/tag.php?tag=archive" rel="tag">archive</a> , <a href="http://qizhi.me/tag.php?tag=organizer" rel="tag">organizer</a> , <a href="http://qizhi.me/tag.php?tag=no" rel="tag">no</a> , <a href="http://qizhi.me/tag.php?tag=archives" rel="tag">archives</a>
]]>
</description>
</item><item>
<link>http://qizhi.me/read.php?322</link>
<title><![CDATA[MVC与Flash]]></title> 
<author>Qizhi &lt;admin@yourname.com&gt;</author>
<category><![CDATA[Program]]></category>
<pubDate>Thu, 14 Apr 2011 14:32:09 +0000</pubDate> 
<guid>http://qizhi.me/read.php?322</guid> 
<description>
<![CDATA[ 
	&nbsp;&nbsp;flashyiyi同学写了一篇关于MVC与Flash的文章，<a href="http://www.infoq.com/cn/news/2011/04/flash-pragmatism-4" target="_blank">http://www.infoq.com/cn/news/2011/04/flash-pragmatism-4</a>。里面的观点大部分我是赞同的。很久前我越来越意识到，网上热热闹闹的各种MVC框架是否真的有那么灵？在使用PureMVC的几年里，越来越倾向于抛弃这些框架，他们的束缚真得是很让我不爽，尤其作为一名游戏程序员，MVC如何能与游戏层完美的结合起来一直没有较优美的答案。<br/>&nbsp;&nbsp;首先，在我眼里MVC中的C，也就是Control，是我一直感觉存在争议的部分。在不采用Flex framework的情况下，大部分的游戏UI是由程序，或是美术在FLASH工具中创作的。这部分我们定义为View，只负责显示。那么PureMVC中的Mediator算做是什么呢？View，or Control？如果是Control，那么Command算做什么？我倾向于将Mediator直接归类为Control的一部分。极少采用Command的编写方式，原因为：<br/> 1. 采用Command来写，需要单独为每个控制行为定义对应的逻辑单元，而逻辑的控制需要有上下文（Context）。Mediator以中间人的身份正好是为协调多个单元而存在的，获得上下文是最简洁方便的，何必还要再发送一个通知，告诉那些不知道是大海里的哪一个的Command去做这些事？<br/> 2. 游戏是一种交互性很强、或着说，跑在flash里的应用绝大多数都是交互强交互的应用。这意味着会产生海量的交互逻辑，这些逻辑都要写成Command？太玩命了。这是因为这些行为一旦距离他的上下文数据远远的，维护工作只会变得更加复杂。何况他们的数量还很多。<br/> 3. 很多需要校验、存储的逻辑会交给server端去做，如果是单机应用，把server端相对独立、高度抽象的纯业务逻辑交给Command去完成比较恰当。<br/> 4. PureMVC中海一样的Notifications，包含的信息确缺乏强类型的支持。判断它的来源、携带的信息基本只能依赖调试器。这为团队的沟通反而带来了障碍。当然，这缺点即使换作Events机制也改善不了多少。<br/>&nbsp;&nbsp;没有了Command的PureMVC,还是pure的PureMVC么？同样，我也不支持采用依赖注入方式管理依赖的MVC框架。我并不怕任何MVC框架带来性能上的损失，这不是最重要的，作为UI层的解决方案，作为每隔1s以上才需要更新一次的小压力，如果因为MVC框架带来了性能损失，那绝对是因为你跑在了286机器上的缘故。然而，我要关心的是为什么要用依赖注入？依赖注入这玩意把接口与接口的耦合降级到了配置文件中去解决，主要解决编译型语言在大型应用程序中编译时间过长、每次改动都需要重新编译的问题。我想，大家的程序还没膨胀到每次编译都要喝杯咖啡打发时间的地步。接口与接口的耦合已经是我能接受的最好耦合关系了，我不在乎多编译几次，何况大部分产品、策划的配置都写到了配置文件中，通过专门的工具去修改。<br/>&nbsp;&nbsp;上面只是我对MVC框架有意见的地方。当然，它也是有积极的意义的。起码框架能告诉你代码应该怎么写，哪怕一开始你不知道怎么组织大中型应用程序；而且能告诉团队的成员，我们的代码基本是这么组织的，而且实际上大部分成熟的组织都是这么组织的，降低熟悉代码的成本。这一切的前提是，你有很多团队成员，你的代码很多或未来会变的很多。<br/>&nbsp;&nbsp;没有了MVC框架，这一些当然也能运行的很好。以上的林林总总，基本只是围绕这MVC大圈圈。那么，背后是否还有更深层次的原因？我的意见是，这与面向对象的编程思想的本质有关。OOP主张我们的项目应该被设计为一个系统，系统内的对象们是互相有关系的，这或许是耦合产生的根源之一，让整个系统或者被过度设计，或者设计不当。从这点说，OOP是一个反模块化的编程思想。当然这就扯远了。<br/>&nbsp;&nbsp;关于View，flex框架和flex编译器是一件优秀的工程。虽然我的游戏没用它，很多游戏估计都不会用它，但是通过xml配置界面排版、效果定义，让代码与视图干净的分离，是造福程序员的伟大工程。在这点上，包括Android的UI系统都走的是这条路线。这告诉我们，很多时候，我们是可以做的更好的（举例来说，让View更单纯，让代码更纯粹），比如Flex的编译器、比如Android的编译器...<br/>Tags - <a href="http://qizhi.me/tag.php?tag=flash" rel="tag">flash</a> , <a href="http://qizhi.me/tag.php?tag=mvc" rel="tag">mvc</a> , <a href="http://qizhi.me/tag.php?tag=puremvc" rel="tag">puremvc</a>
]]>
</description>
</item><item>
<link>http://qizhi.me/read.php?321</link>
<title><![CDATA[轻量级Android游戏引擎：libGDX-lite]]></title> 
<author>Qizhi &lt;admin@yourname.com&gt;</author>
<category><![CDATA[Program]]></category>
<pubDate>Thu, 14 Apr 2011 03:16:28 +0000</pubDate> 
<guid>http://qizhi.me/read.php?321</guid> 
<description>
<![CDATA[ 
	&nbsp;&nbsp;做android游戏我首选的游戏引擎是libGDX(http://code.google.com/p/libgdx/), 作者Badlogic Games是非常有爱的同学，写出了如此让人惊叹的高效渲染引擎。这个引擎让人惊叹的不只是他的性能，他干脆提供了PC上的backend支持，让你写得游戏不仅仅能跑在android上，还能跑在pc上。然而，有时我只想做一个简单的，能在android上卖钱的工具，所以这个引擎其它的模块对我而言，不是那么有吸引力。当然，我还想改改其中的一些代码，使之能更适合我的项目，那么，就有了这个简化版libGDX引擎，它只提供了以下几个核心的功能：<br/>1. open GL es渲染，2D sprite以及sprite batch支持。采用c优化过的高效的图形渲染能力。删去了原有的3D支持。<br/>2. 音乐、音效的播放、控制能力。删去了音乐采样、分析等功能。<br/>3. 高效的数学库。<br/>4. 针对android优化过的collection库以及其它一些帮助类。<br/>5. Ant支持。<br/>6. Box2D引擎被删除了。如果要做物理游戏，可以将相关的库在集成进来。<br/><br/>这样精简后的引擎紧紧占用600k出头，减少了一般以上的体积。项目的地址是：<br/><a href="http://code.google.com/p/libgdx-lite/" target="_blank">http://code.google.com/p/libgdx-lite/</a><br/><br/>另外推荐一款texture atlas工具Texture Packer（http://www.texturepacker.com/features/），提供贴图的打包、像素抖动、压缩、PVRs格式支持等功能。详细情况可以参考<a href="http://www.raywenderlich.com/2361/how-to-create-and-optimize-sprite-sheets-in-cocos2d-with-texture-packer-and-pixel-formats " target="_blank">How to Create and Optimize Sprite Sheets in Cocos2D with Texture Packer and Pixel Formats</a> 这篇文章。虽然介绍的是iOS环境下的开发，Texture Packer其实是支持libGDX贴图配置和Cocos2D等很多引擎的。<br/><a href="http://www.raywenderlich.com/wp-content/uploads/2010/11/TexturePackerSmall.png" target="_blank"><img src="http://www.raywenderlich.com/wp-content/uploads/2010/11/TexturePackerSmall.png" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/>Tags - <a href="http://qizhi.me/tag.php?tag=android" rel="tag">android</a> , <a href="http://qizhi.me/tag.php?tag=opengl" rel="tag">opengl</a> , <a href="http://qizhi.me/tag.php?tag=game" rel="tag">game</a> , <a href="http://qizhi.me/tag.php?tag=engine" rel="tag">engine</a> , <a href="http://qizhi.me/tag.php?tag=texture" rel="tag">texture</a> , <a href="http://qizhi.me/tag.php?tag=packer" rel="tag">packer</a>
]]>
</description>
</item><item>
<link>http://qizhi.me/read.php?320</link>
<title><![CDATA[利用Flash 3D API（Molehill）加速2D图形渲染]]></title> 
<author>Qizhi &lt;admin@yourname.com&gt;</author>
<category><![CDATA[Program]]></category>
<pubDate>Mon, 28 Feb 2011 04:00:03 +0000</pubDate> 
<guid>http://qizhi.me/read.php?320</guid> 
<description>
<![CDATA[ 
	Molehill API的发布使得利用硬件加速2d图形变为可能。写了一个比较粗糙的2D screen graph，放在了Google Code上：<br/><a href="https://code.google.com/p/molehill2d/" target="_blank">https://code.google.com/p/molehill2d/</a><br/><a href="http://farm6.static.flickr.com/5251/5484114025_96fe5919ed.jpg" target="_blank"><img src="http://farm6.static.flickr.com/5251/5484114025_96fe5919ed.jpg" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/>用法:<br/>首先创建一个stage 3d,这一步和创建普通的3d应用相同。<br/><div class="code"><br/>stage.stage3Ds&#91;0&#93;.viewPort=new Rectangle(0, 0, 1024, 1024);<br/>stage.stage3Ds&#91;0&#93;.addEventListener(Event.CONTEXT3D_CREATE, onContextCreation);<br/>stage.stage3Ds&#91;0&#93;.requestContext3D(Context3DRenderMode.AUTO);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>addEventListener(Event.ENTER_FRAME, onRender);<br/></div><br/>接下来就是直接使用我封装好的API即可：<br/><div class="code"><br/>scene=new DisplayContext3D(stage, stage.stage3Ds&#91;0&#93;);<br/>for(var i:int = 0; i &lt; 500; i ++)<br/>&#123;<br/>&nbsp;&nbsp;var mc:TexturedMovie = new TexturedMovie(schools, 30);<br/>&nbsp;&nbsp;mc.play();<br/>&nbsp;&nbsp;mc.position = new Vector3D(Math.random()*1000 - 500, Math.random()*1000-500);<br/>&nbsp;&nbsp;scene.addChild(mc);<br/>&#125;&nbsp;&nbsp;<br/></div><br/>鼠标事件也需要使用封装好的API来用：<br/><div class="code"><br/>royalcottage12 = new TexturedQuad(defaultTextureData, defaultTextureData.width, defaultTextureData.height);<br/>royalcottage12.addEventListener(Mouse2DEvent.ON_MOUSE_DOWN, onMouseDown);<br/>royalcottage12.addEventListener(Mouse2DEvent.ON_MOUSE_UP, onMouseUp);<br/>royalcottage12.addEventListener(Mouse2DEvent.ON_MOUSE_OUT, onMouseUp);<br/>royalcottage12.x = 32;<br/>royalcottage12.y = 144;<br/>scene.addChild(royalcottage12);<br/></div><br/><br/>注意3D编程和2D有很大不通，对3D api状态改变（贴图、顶点等）必须每帧尽可能的少，建议使用texture page等手段优化贴图资源。<br/>Tags - <a href="http://qizhi.me/tag.php?tag=molehill" rel="tag">molehill</a> , <a href="http://qizhi.me/tag.php?tag=3d" rel="tag">3d</a> , <a href="http://qizhi.me/tag.php?tag=render" rel="tag">render</a> , <a href="http://qizhi.me/tag.php?tag=2d" rel="tag">2d</a> , <a href="http://qizhi.me/tag.php?tag=screen" rel="tag">screen</a> , <a href="http://qizhi.me/tag.php?tag=graph" rel="tag">graph</a>
]]>
</description>
</item><item>
<link>http://qizhi.me/read.php?319</link>
<title><![CDATA[成为2011年Adobe Community Professional之一]]></title> 
<author>Qizhi &lt;admin@yourname.com&gt;</author>
<category><![CDATA[Program]]></category>
<pubDate>Fri, 28 Jan 2011 06:24:48 +0000</pubDate> 
<guid>http://qizhi.me/read.php?319</guid> 
<description>
<![CDATA[ 
	<a href="http://www.adobe.com/communities/professionals/images/acp_logo.gif" target="_blank"><img src="http://www.adobe.com/communities/professionals/images/acp_logo.gif" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a>很荣幸加入了2011年的<a href="http://www.adobe.com/communities/professionals/all.html" target="_blank">Adobe Community Professional</a>计划。籍此机会，我想说的是，我们公司还在招人，求贤若渴！期望走过路过的朋友不要错过，移步瞧瞧：<br/><a href="http://www.happyelements.com/index.php/category/jobs/beijing-office/engineer" target="_blank">http://www.happyelements.com/index.php/category/jobs/beijing-office/engineer</a><br/>Tags - <a href="http://qizhi.me/tag.php?tag=adobe" rel="tag">adobe</a> , <a href="http://qizhi.me/tag.php?tag=community" rel="tag">community</a> , <a href="http://qizhi.me/tag.php?tag=professional" rel="tag">professional</a> , <a href="http://qizhi.me/tag.php?tag=acp" rel="tag">acp</a>
]]>
</description>
</item><item>
<link>http://qizhi.me/read.php?318</link>
<title><![CDATA[令人生畏的Android]]></title> 
<author>Qizhi &lt;admin@yourname.com&gt;</author>
<category><![CDATA[Program]]></category>
<pubDate>Sat, 08 Jan 2011 16:29:40 +0000</pubDate> 
<guid>http://qizhi.me/read.php?318</guid> 
<description>
<![CDATA[ 
	太恐怖了。试了模拟器跑2.1，先测试了一款不知名的引擎：E3Roid，100个sprite平均FPS 5-6左右。E3Roid的screen graph是带有texture page的，所以性能应该不亚于其它底层引擎。<br/>后来换了一款知名的，偏底层的引擎，libgdx, 跑引擎自带的例子， 100个sprite仍然在5-6左右。<br/><div class="code"><br/>//libgdx自带的test，调整为100个sprite：<br/>spriteBatch = new SpriteBatch(1000); //batch size<br/><br/>Pixmap pixmap = Gdx.graphics.newPixmap(Gdx.files.getFileHandle(&quot;data/badlogicsmall.jpg&quot;, FileType.Internal));<br/>texture = Gdx.graphics.newUnmanagedTexture(32, 32, Format.RGB565, TextureFilter.Linear, TextureFilter.Linear,<br/>&nbsp;&nbsp;TextureWrap.ClampToEdge, TextureWrap.ClampToEdge);<br/>texture.draw(pixmap, 0, 0);<br/>pixmap.dispose();<br/><br/>pixmap = Gdx.graphics.newPixmap(32, 32, Format.RGBA8888);<br/>pixmap.setColor(1, 1, 0, 0.5f);<br/>pixmap.fill();<br/>texture2 = Gdx.graphics.newUnmanagedTexture(pixmap, TextureFilter.Nearest, TextureFilter.Nearest, TextureWrap.ClampToEdge,<br/>&nbsp;&nbsp;TextureWrap.ClampToEdge);<br/>pixmap.dispose();<br/><br/>for (int i = 0; i &lt; sprites.length; i += 6) &#123; // sprites.length = 100<br/>&nbsp;&nbsp;sprites&#91;i&#93; = (int)(Math.random() * (Gdx.graphics.getWidth() - 32));<br/>&nbsp;&nbsp;sprites&#91;i + 1&#93; = (int)(Math.random() * (Gdx.graphics.getHeight() - 32));<br/>&nbsp;&nbsp;sprites&#91;i + 2&#93; = 0;<br/>&nbsp;&nbsp;sprites&#91;i + 3&#93; = 0;<br/>&nbsp;&nbsp;sprites&#91;i + 4&#93; = 32;<br/>&nbsp;&nbsp;sprites&#91;i + 5&#93; = 32;<br/>&nbsp;&nbsp;sprites2&#91;i&#93; = (int)(Math.random() * (Gdx.graphics.getWidth() - 32));<br/>&nbsp;&nbsp;sprites2&#91;i + 1&#93; = (int)(Math.random() * (Gdx.graphics.getHeight() - 32));<br/>&nbsp;&nbsp;sprites2&#91;i + 2&#93; = 0;<br/>&nbsp;&nbsp;sprites2&#91;i + 3&#93; = 0;<br/>&nbsp;&nbsp;sprites2&#91;i + 4&#93; = 32;<br/>&nbsp;&nbsp;sprites2&#91;i + 5&#93; = 32;<br/>&#125;<br/><br/>for (int i = 0; i &lt; SPRITES * 2; i++) &#123;<br/>&nbsp;&nbsp;int x = (int)(Math.random() * (Gdx.graphics.getWidth() - 32));<br/>&nbsp;&nbsp;int y = (int)(Math.random() * (Gdx.graphics.getHeight() - 32));<br/><br/>&nbsp;&nbsp;if (i &gt;= SPRITES)<br/>&nbsp;&nbsp;&nbsp;&nbsp;sprites3&#91;i&#93; = new Sprite(texture2, 32, 32);<br/>&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;sprites3&#91;i&#93; = new Sprite(texture, 32, 32);<br/>&nbsp;&nbsp;sprites3&#91;i&#93;.setPosition(x, y);<br/>&nbsp;&nbsp;sprites3&#91;i&#93;.setOrigin(16, 16);<br/>&#125;<br/></div><br/><br/>--补<br/>以上测试均是模拟器的结果。用真机器调试取决于具体手机。后来试过milestone，hd2，libgdx在50-58fps左右。<br/>Tags - <a href="http://qizhi.me/tag.php?tag=gl" rel="tag">gl</a> , <a href="http://qizhi.me/tag.php?tag=android" rel="tag">android</a> , <a href="http://qizhi.me/tag.php?tag=sprite" rel="tag">sprite</a> , <a href="http://qizhi.me/tag.php?tag=engine" rel="tag">engine</a> , <a href="http://qizhi.me/tag.php?tag=game" rel="tag">game</a> , <a href="http://qizhi.me/tag.php?tag=libgdx" rel="tag">libgdx</a> , <a href="http://qizhi.me/tag.php?tag=e3roid" rel="tag">e3roid</a>
]]>
</description>
</item><item>
<link>http://qizhi.me/read.php?317</link>
<title><![CDATA[硬件加速2D图形的一些思考]]></title> 
<author>Qizhi &lt;admin@yourname.com&gt;</author>
<category><![CDATA[Program]]></category>
<pubDate>Wed, 29 Dec 2010 14:10:25 +0000</pubDate> 
<guid>http://qizhi.me/read.php?317</guid> 
<description>
<![CDATA[ 
	GPU加速2D图形常用的技术是Textured Quad，即用一个简单的平面（四个顶点，2个三角形，正交投影）+贴图完成（画法[GameDev真是个大宝库]：<a href="http://www.gamedev.net/reference/articles/article1972.asp" target="_blank">http://www.gamedev.net/reference/articles/article1972.asp</a>）。频繁更改GPU API的各状态、调用绘图接口会急剧降低显示性能，每次状态修改、接口调用都会消耗CPU，此时的性能瓶颈不在GPU而在CPU。具体的数据可参考Wloka, Matthias. 2003. "Batch, Batch, Batch: What Does It Really Mean?" Presentation at Game Developers Conference 2003. Available online at <a href="http://developer.nvidia.com/docs/IO/8230/BatchBatchBatch.pdf" target="_blank">http://developer.nvidia.com/docs/IO/8230/BatchBatchBatch.pdf</a> 。<br/>然而遗憾的是，2D游戏中我们不得不设置各式各样的贴图，每一个sprite都几乎要一张独立的（无法batch），往往还体积挺大（难以再用texture page之类技术优化），要命的是还有动画，导致贴图数数量巨大无比...崩溃的很──这么多年了，各大浏览器才嚷嚷着要提供硬件加速，现实是真的太难做了...换句话说，我们将整个屏幕要画的东西画到一个平面上不久OK了？问题在于这个大平面内要画很多元素，处理它们的遮挡、移动，这样的加速仍然有大量运算在CPU，加速效果怕还不如GDI来得快。<br/>这里的优化没有别的出路，Batch是最好的出路:<br/>1. If using triangle strips, use degenerate triangles to stitch together disjoint strips. This will enable you to send multiple strips, provided that they share material, in a single draw call.<br/>2. Use texture pages. Batches are frequently broken when different objects use different textures. By arranging many textures into a single 2D texture and setting your texture coordinates appropriately, you can send geometry that uses multiple textures in a single draw call. Note that this technique can have issues with mipmapping and antialiasing. One technique that sidesteps many of these issues is to pack individual 2D textures into each face of a cube map.<br/>3. Use the vertex shader constant memory as a lookup table of matrices. Often batches get broken when many small objects share all material properties but differ only in matrix state (for example, a forest of similar trees, or a particle system). In these cases, you can load n of the differing matrices into the vertex shader constant memory and store indices into the constant memory in the vertex format for each object. Then you would use this index to look up into the constant memory in the vertex shader and use the correct transformation matrix, thus rendering n objects at once.<br/>4. Defer decisions as far down in the pipeline as possible. It's faster to use the alpha channel of your texture as a gloss factor, rather than break the batch to set a pixel shader constant for glossiness. Similarly, putting shading data in your textures and vertices can allow for larger batch submissions.<br/>相关的文章：<br/><a href="http://http.developer.nvidia.com/GPUGems/gpugems_ch28.html" target="_blank">http://http.developer.nvidia.com/GPUGems/gpugems_ch28.html</a><br/>Tags - <a href="http://qizhi.me/tag.php?tag=gpu" rel="tag">gpu</a> , <a href="http://qizhi.me/tag.php?tag=textured" rel="tag">textured</a> , <a href="http://qizhi.me/tag.php?tag=quad" rel="tag">quad</a> , <a href="http://qizhi.me/tag.php?tag=sprite" rel="tag">sprite</a> , <a href="http://qizhi.me/tag.php?tag=batch" rel="tag">batch</a>
]]>
</description>
</item><item>
<link>http://qizhi.me/read.php?316</link>
<title><![CDATA[正交投影矩阵的推导]]></title> 
<author>Qizhi &lt;admin@yourname.com&gt;</author>
<category><![CDATA[Program]]></category>
<pubDate>Fri, 24 Dec 2010 07:20:10 +0000</pubDate> 
<guid>http://qizhi.me/read.php?316</guid> 
<description>
<![CDATA[ 
	投影线垂直投影面的投影称为正交投影，orthogonal projection。利用3D渲染2D图元时，需要用到这种投影。<br/>flash采用右手坐标系，CVV的z的范围为0到1。我们规定近剪裁平面为f，远剪裁平面为n，则有如下投影关系：<br/>P=[x,y,z,1], P'=[x',y',n,1] = [x,y,n,1];<br/>现在我们求n.由于z的范围为[0,1],设：<br/>1. 0 = az+b, z=n; <br/>2. 1 = az+b, z=f;<br/>解有1., 2.组成的方程组，得a = 1/(f-n); b = - n/(f-n):<br/>P'=[x',y'az+b,1] = [x, y, 1/(f-n) * z + (-n/f-n), 1];<br/>此时，我们要对x，y做线性插值到CVV空间，x属于[-1,1], y属于[-1,1], 设左右平面为l，r，上下面为t，b:<br/>(x-l)/(r-l) = (x'+1)/2, 解得 x' = 2/(r-l) -(r+l)/(r-l);由对称性得： y' = 2/(t-b) - (b+t)/(t-b); <br/>带入P'，得正交投影矩阵：<br/>&#124;2/(r-l)&nbsp;&nbsp; 0&nbsp;&nbsp; 0&nbsp;&nbsp; -(r+l)/(r-l)&nbsp;&nbsp;&nbsp;&nbsp;&#124;<br/>&#124;0&nbsp;&nbsp;&nbsp;&nbsp; 2/(t-b)&nbsp;&nbsp;0&nbsp;&nbsp;-(t+b)/(t-b) &#124;<br/>&#124;0&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1/(f-n)&nbsp;&nbsp; -n/(f-n)&nbsp;&nbsp; &#124;<br/>&#124;0&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br/>Tags - <a href="http://qizhi.me/tag.php?tag=orthogonal" rel="tag">orthogonal</a> , <a href="http://qizhi.me/tag.php?tag=projection" rel="tag">projection</a> , <a href="http://qizhi.me/tag.php?tag=3d" rel="tag">3d</a> , <a href="http://qizhi.me/tag.php?tag=flash" rel="tag">flash</a>
]]>
</description>
</item><item>
<link>http://qizhi.me/read.php?315</link>
<title><![CDATA[UI半自动化测试尝试]]></title> 
<author>Qizhi &lt;admin@yourname.com&gt;</author>
<category><![CDATA[Program]]></category>
<pubDate>Wed, 15 Dec 2010 13:26:46 +0000</pubDate> 
<guid>http://qizhi.me/read.php?315</guid> 
<description>
<![CDATA[ 
	&nbsp;&nbsp;Flash做自动化测试很难。针对UI代码写UnitTest是划不来的事情，一方面逻辑简单，没必要，一方面异步编程也加大了测试的难度。Flex框架提供了Agent给QTP等自动化工具，但是我们的游戏采用纯AS工程写就，这就意味这只好自己实现基本的半自动化测试技术，也即录制和回放。<br/>&nbsp;&nbsp;开始的设想是写一个FireFox扩展，通过修改mm.cfg的PreloadSWF设置，将所有SWF通过一个特殊的SWF：AutomationPreloader预加载，将自动控制权交给这个swf。<br/>&nbsp;&nbsp;录制只需要做简单的点击事件记录即可，由于是针对UI的测试，显示元件的事件是可以冒泡的，这样为录制提供了很大的方便。为了精确的记录所需要的回放的目标和事件，所有的UI控件都需要实现一个IAutomationAble接口，暴露其唯一ID等一些方便自动化的接口。<br/>&nbsp;&nbsp;回放的过程需要利用录制的元件所记录下的ID、坐标等信息，查找到所对应的元素。均是一些工程处理，代码逻辑没什么技术难度。假如这些事情由Adobe做了，无疑将是一件功在千秋的利好之事:)<br/>Tags - <a href="http://qizhi.me/tag.php?tag=ui" rel="tag">ui</a> , <a href="http://qizhi.me/tag.php?tag=automation" rel="tag">automation</a> , <a href="http://qizhi.me/tag.php?tag=tools" rel="tag">tools</a> , <a href="http://qizhi.me/tag.php?tag=flash" rel="tag">flash</a> , <a href="http://qizhi.me/tag.php?tag=test" rel="tag">test</a>
]]>
</description>
</item><item>
<link>http://qizhi.me/read.php?314</link>
<title><![CDATA[《Game Engine Architecture》by Jason Gregory]]></title> 
<author>Qizhi &lt;admin@yourname.com&gt;</author>
<category><![CDATA[Program]]></category>
<pubDate>Sat, 04 Dec 2010 16:39:59 +0000</pubDate> 
<guid>http://qizhi.me/read.php?314</guid> 
<description>
<![CDATA[ 
	<a href="http://ecx.images-amazon.com/images/I/51xMxRNbnvL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51xMxRNbnvL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0" align="left"/></a>原书<a href="http://www.amazon.com/Game-Engine-Architecture-Jason-Gregory/dp/1568814135" target="_blank">amazon</a>有售，我是淘宝代购的。《Game Engine Architecture》不是一本单纯的技术书。厚厚的800多页纸当板砖也能砸死人，包罗了创造一个现代游戏的方方面面。读第一章的时候，有些感觉Jason是在糊弄人，扯了些游戏发展史，C/C++入门，3D数学基础神马的。第二章开始渐入佳境，十分给力。<br/>讲游戏的技术书籍非常多，大多关注一些具体的领域知识，比如渲染、AI、网络等。但是这部书不同，Jason虽然是站在引擎开发的角度叙事，但涉及了语言、操作系统、硬件、工具、素材管理、图形、动画等方方面面。有时候这是很难做到的，我一直想总结在游戏开发中关于引擎、工具、素材管理等等的一些心得，可总是很琐碎且不成系统，似乎说不出什么来。Jason做到了这一点，当然大部分内容往往也是只言片语，同样遇到过问题的人读到后可能会心领神会，体会到作者字里行间中透露出的无奈的意味。比如讲素材的国际化时，说“这疙瘩玩意最好从开发的最开始做起”. --意译:)<br/><br/>《Game Engine Architecture》一共四大章，我目前只看完前两章。第一章中讲解内存的部分战力十足，虽说是基础技术细节，随着语言的发展，越来越多的高级语言将这些信息隐藏了起来，交由虚拟机自动管理。但是了解这些对理解语言的设计、程序的设计是有莫大的帮助的。第二章即从较高的视角阐述了一款游戏所需要的各个系统、子系统，以及引擎的分层结构。很多的代码实例来源于作者亲自参与的项目实例，或是Ogre、Unreal、ID等知名引擎的实现，详解了各自实现的优点，尤其是缺点。Resource一节中，感触较深的是关于美术素材的版本控制、开发工具、发布等问题。二进制文件的同步、多人编辑等问题在各大公司都是头痛的问题。Unreal的编辑器或是作者当时开发的工具都有着这样那样的问题。当然，我们用得最多的美术工具Flash CS系列也是问题多多，几乎包含了书中所提各大编辑器的通病。素材（资源管理）工具，这或将是一个巨大商机。<br/><br/>书仍在读ing，不吝赞美之词。<br/><br/>--最后，老婆拔牙了，祝福早日康复:)<br/>Tags - <a href="http://qizhi.me/tag.php?tag=%25E6%25B8%25B8%25E6%2588%258F" rel="tag">游戏</a> , <a href="http://qizhi.me/tag.php?tag=%25E4%25B9%25A6%25E8%25AF%2584" rel="tag">书评</a> , <a href="http://qizhi.me/tag.php?tag=engine" rel="tag">engine</a> , <a href="http://qizhi.me/tag.php?tag=architecture" rel="tag">architecture</a>
]]>
</description>
</item>
</channel>
</rss>
