<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>iPhoneGeek 爱疯极客 &#187; 游戏</title>
	<atom:link href="http://www.iphone-geek.cn/category/%e7%bc%96%e7%a8%8b/%e6%b8%b8%e6%88%8f/feed" rel="self" type="application/rss+xml" />
	<link>http://www.iphone-geek.cn</link>
	<description>iPhone 新闻，编程，技巧与提示，代码，教程</description>
	<lastBuildDate>Thu, 08 Dec 2011 01:18:52 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Cocos2d实现简单动画</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/cocos2d%e5%ae%9e%e7%8e%b0%e7%ae%80%e5%8d%95%e5%8a%a8%e7%94%bb</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/cocos2d%e5%ae%9e%e7%8e%b0%e7%ae%80%e5%8d%95%e5%8a%a8%e7%94%bb#comments</comments>
		<pubDate>Fri, 15 Apr 2011 03:33:15 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[图形图像]]></category>
		<category><![CDATA[游戏]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[OpenGL ES]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=1158</guid>
		<description><![CDATA[最近实在很忙，没有时间写整篇文章，就分享一下一些简单的实例吧。
首先介绍一篇博客文章：cocos2d HOWTO系列之：如何创建帧动画。我初学cocos2d时就发现这篇文章，不过里面的一些内容已经过时了，所以自己又写了一个动画的例子。
我把要点说一下：

制作动画需要的一系列动画图片（比如png文件）。要制作动画png，可根据上面介绍的文章使用Adobe Flash将fla转换为png。也可以使用一些免费软件，将swf转换为png。这里有一些软件：SpriteSheetCreator，SWFSheet，SWFToPNG。大家可以网上搜索一下。
生成png动画系列后，要将其整合成一个png（也就是所谓的sprite sheet）。这里使用的软件就是Zwoptex。使用此软件生成一个png和一个plist，plist记录了每个sprite的x，y，高，宽数据。Cocos2d支持Zwoptex生成的plist格式。不过遗憾的是最近Zwoptex开始收费了。这里提供以前的一个版本，也可以满足我们的要求。Zwoptex-0.4b10.app下载 。
我的程序就是播放一个电扇的动画，按一下就进行动画，再按一下动画就停止。我是修改了HelloWorld程序，添加了一个Object类进行动画处理。唯一要说明的是addSpriteFramesWithFile中要使用的路径是相对路径，我开始一直遇到问题就是因为使用了绝对路径。

源代码下载
]]></description>
			<content:encoded><![CDATA[<p>最近实在很忙，没有时间写整篇文章，就分享一下一些简单的实例吧。</p>
<p>首先介绍一篇博客文章：<a href="http://dualface.qeeplay.com/index.php/archives/406">cocos2d HOWTO系列之：如何创建帧动画</a>。我初学cocos2d时就发现这篇文章，不过里面的一些内容已经过时了，所以自己又写了一个动画的例子。</p>
<p>我把要点说一下：</p>
<ol>
<li>制作动画需要的一系列动画图片（比如png文件）。要制作动画png，可根据上面介绍的文章使用Adobe Flash将fla转换为png。也可以使用一些免费软件，将swf转换为png。这里有一些软件：SpriteSheetCreator，SWFSheet，SWFToPNG。大家可以网上搜索一下。</li>
<li>生成png动画系列后，要将其整合成一个png（也就是所谓的sprite sheet）。这里使用的软件就是Zwoptex。使用此软件生成一个png和一个plist，plist记录了每个sprite的x，y，高，宽数据。Cocos2d支持Zwoptex生成的plist格式。不过遗憾的是最近Zwoptex开始收费了。这里提供以前的一个版本，也可以满足我们的要求。<a href="http://www.iphone-geek.cn/wp-content/uploads/2011/04/Zwoptex-0.4b10.app.zip">Zwoptex-0.4b10.app下载</a> 。</li>
<li>我的程序就是播放一个电扇的动画，按一下就进行动画，再按一下动画就停止。我是修改了HelloWorld程序，添加了一个Object类进行动画处理。唯一要说明的是addSpriteFramesWithFile中要使用的路径是相对路径，我开始一直遇到问题就是因为使用了绝对路径。</li>
</ol>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2011/04/animation.zip">源代码下载</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/cocos2d%e5%ae%9e%e7%8e%b0%e7%ae%80%e5%8d%95%e5%8a%a8%e7%94%bb/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>cocos2d-iphone 0.99.5 Xcode 静态库模板</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/cocos2d-iphone-0-99-5-xcode-%e9%9d%99%e6%80%81%e5%ba%93%e6%a8%a1%e6%9d%bf</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/cocos2d-iphone-0-99-5-xcode-%e9%9d%99%e6%80%81%e5%ba%93%e6%a8%a1%e6%9d%bf#comments</comments>
		<pubDate>Sun, 27 Feb 2011 03:29:19 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[图形图像]]></category>
		<category><![CDATA[游戏]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[OpenGL ES]]></category>
		<category><![CDATA[开源项目]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=1132</guid>
		<description><![CDATA[最近一个项目需要用到opengles，由于实在没有时间无法完成自己的引擎，因此开始对cocos2d-iphone引擎进行了研究。经过研究发现一个问题，其模板生成的项目每次都会把整个cocos2d的源代码拷贝进新项目中，这样每次cocos2d-iphone进行更新时都会带来麻烦，而且如果多个项目使用cocos2d-iphone，非常的不方便。我在网上搜索了一下，发现了了这个网站，介绍了怎样将cocos2d-iphone编译成静态库的方法，与我的想法不谋而合。不过该网站中的模板只适用于0.99.4，于是我修改了一下，让其可以运行于0.99.5。下面是主要步骤：
1. 下载cocos2d-iphone 0.99.5 template模板。
2. 解压到/$HOME/Library/Application Support/Developer/Shared/Xcode下
3. 下载cocos2d-iphone 0.99.5，解压到你想要的地方。
3. 在Xcode Preferences中找到Source Tree，输入新变量COCOS2D_SOURCE，让其指向cocos2d-iphone 0.99.5的源代码处。
这样，下次你打开Xcode，你就可以使用我的模板创建cocos2d项目了（注意不要安装随cocos2d-iphone下载的模板），以后每次cocos2d-iphone进行更新，你仅仅需要修改COCOS2D_SOURCE变量（当然前提是cocos2d-iphone的编程接口没有改变）。
]]></description>
			<content:encoded><![CDATA[<p>最近一个项目需要用到opengles，由于实在没有时间无法完成自己的引擎，因此开始对cocos2d-iphone引擎进行了研究。经过研究发现一个问题，其模板生成的项目每次都会把整个cocos2d的源代码拷贝进新项目中，这样每次cocos2d-iphone进行更新时都会带来麻烦，而且如果多个项目使用cocos2d-iphone，非常的不方便。我在网上搜索了一下，发现了了<a href="http://www.learn-cocos2d.com/">这个</a>网站，介绍了怎样将cocos2d-iphone编译成静态库的方法，与我的想法不谋而合。不过该网站中的模板只适用于0.99.4，于是我修改了一下，让其可以运行于0.99.5。下面是主要步骤：<br class="spacer_" /><br />
1. 下载<a href="http://www.iphone-geek.cn/wp-content/uploads/2011/02/cocos2d-iphone-0.99.5-template.zip">cocos2d-iphone 0.99.5 template</a>模板。</p>
<p>2. 解压到/$HOME/Library/Application Support/Developer/Shared/Xcode下</p>
<p>3. 下载cocos2d-iphone 0.99.5，解压到你想要的地方。</p>
<p>3. 在Xcode Preferences中找到Source Tree，输入新变量COCOS2D_SOURCE，让其指向cocos2d-iphone 0.99.5的源代码处。<br class="spacer_" /><br />
这样，下次你打开Xcode，你就可以使用我的模板创建cocos2d项目了（注意不要安装随cocos2d-iphone下载的模板），以后每次cocos2d-iphone进行更新，你仅仅需要修改COCOS2D_SOURCE变量（当然前提是cocos2d-iphone的编程接口没有改变）。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/cocos2d-iphone-0-99-5-xcode-%e9%9d%99%e6%80%81%e5%ba%93%e6%a8%a1%e6%9d%bf/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cocos 2d基本概念</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/cocos-2d%e5%9f%ba%e6%9c%ac%e6%a6%82%e5%bf%b5</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/cocos-2d%e5%9f%ba%e6%9c%ac%e6%a6%82%e5%bf%b5#comments</comments>
		<pubDate>Fri, 28 Jan 2011 08:10:26 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[图形图像]]></category>
		<category><![CDATA[游戏]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[OpenGL ES]]></category>
		<category><![CDATA[开源项目]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=1119</guid>
		<description><![CDATA[开发cocos2d程序前有必要对一些基本概念进行介绍：


场景（Scenes）
主控器（Director）
层（Layers）
精灵（Sprites）




场景

场景（通过 CCScene 对象实现）是程序的工作流程中相对独立的部分。有些人可能喜欢称呼其为“屏幕”或“舞台”。你的应用程序可能具有许多场景，但在某刻只能有一个活动的场景。
例如，你的游戏中可能有下列场景：介绍，菜单，第一关，过场一，第二关，过场二，胜利过场，失败过场，高分记录等等。
你可以将每个场景定义成一个独立的程序; 你可以通过某种逻辑将这些场景联系起来（比如当介绍中断或者完成后，就进入菜单场景，第一关成功将进入过场一，而失败则进入失败过场，等等）。



CCScene 是由一个或者多个层（通过 CCLayer 对象实现）组成。场景的外观和行为是通过层来实现的。
CCScene 类家族中还包括一组称为“过渡” （通过 CCTransitionScene 对象实现），它允许你在两个场景之间进行生成一些特殊的过渡效果（比如淡入淡出，滑入效果等等）。
由于场景是 CCNode 的子类，因此可以使用“动作”对场景进行变换。

主控器
CCDirector 是一个负责控制场景变化的元件。
CCDirector 是一个单例对象。它知道当前哪个场景是活动的，它负责处理场景的控制，并允许进行“场景调用”之类的操作（比如在进入另一个场景时，暂停当前场景，并在适当时候返回原始场景）。在CCLayer 要求替换当前场景后，实际上是 CCDirector 进行的场景切换。
另外， CCDirector 还负责OpenGL ES的初始化。

层
CCLayer 拥有整个可进行绘制的区域，并且知道怎样对自身进行绘制。它还可以是半透明的（还可以在某些地方部分或者完全透明），这样可以看到层后的部分。层是对外观和行为进行定义的元件，所以大部分时间我们都说针对 CCLayer 及子类进行编程的。

CCLayer 还是进行事件处理的地方。事件是通过层进行传递直到某些层捕捉并进行处理。
尽管许多程序要求你定义自定义 CCLayer 类，但 cocos2d 提供了一些有用的预定义的层（比如简单的菜单层： CCMenu，颜色层： CCColorLayer， 其他层之间 的多路器：CCMultiplexLayer，等等）。
层还可以包括 CCSprite 对象， CCLabel 对象以及甚至是 CCLayer 对象。
由于层是 CCNode的子类，因此可以使用“动作”对场景进行变换。

精灵
Cocos2d 的精灵与其他程序库描述的精灵一样，是一个可以进行移动，旋转，大小变化，动画等操作的2D图像。
精灵（通过 CCSprite 类实现）可以拥有其它精灵作为其子成员。当一个父成员进行变换时，其所有子成员也将同时进行变换。
由于精灵是 CCNode的子类，因此可以使用“动作”对场景进行变换。
]]></description>
			<content:encoded><![CDATA[<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">开发cocos2d程序前有必要对一些基本概念进行介绍：</p>
<p><br class="spacer_" /></p>
<ul>
<li>场景（Scenes）</li>
<li>主控器（Director）</li>
<li>层（Layers）</li>
<li>精灵（Sprites）</li>
</ul>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">
<p><br class="spacer_" /><br />
<span id="more-1119"></span></p>
<h2>场景</h2>
<p><br class="spacer_" /></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">场景（通过 <strong>CCScene </strong>对象实现）是程序的工作流程中相对独立的部分。有些人可能喜欢称呼其为“屏幕”或“舞台”。你的应用程序可能具有许多场景，但在某刻只能有一个活动的场景。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">例如，你的游戏中可能有下列场景：<strong>介绍，菜单，第一关，过场一，第二关，过场二，胜利过场，失败过场，高分记录</strong>等等。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">你可以将每个场景定义成一个独立的程序; 你可以通过某种逻辑将这些场景联系起来（比如当<strong>介绍</strong>中断或者完成后，就进入<strong>菜单</strong>场景，<strong>第一关</strong>成功将进入<strong>过场一</strong>，而失败则进入<strong>失败过场</strong>，等等）。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: center; "><a style="color: #0088cc; text-decoration: none; padding: 0px; margin: 0px;" title="prog_guide:scenes.png" href="http://www.cocos2d-iphone.org/wiki/lib/exe/detail.php/prog_guide:scenes.png?id=prog_guide%3Abasic_concepts"><img class="aligncenter" style="margin-top: 3px; margin-bottom: 3px; padding: 0px;" src="http://www.cocos2d-iphone.org/wiki/lib/exe/fetch.php/prog_guide:scenes.png" alt="" width="576" height="128" /></a></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;"><strong>CCScene </strong>是由一个或者多个层（通过 <strong>CCLayer</strong> 对象实现）组成。场景的外观和行为是通过层来实现的。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">CCScene 类家族中还包括一组称为“过渡” （通过 CCTransitionScene 对象实现），它允许你在两个场景之间进行生成一些特殊的过渡效果（比如淡入淡出，滑入效果等等）。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">由于场景是 CCNode 的子类，因此可以使用“动作”对场景进行变换。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">
<h2>主控器</h2>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">CCDirector 是一个负责控制场景变化的元件。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">CCDirector 是一个单例对象。它知道当前哪个场景是活动的，它负责处理场景的控制，并允许进行“场景调用”之类的操作（比如在进入另一个场景时，暂停当前场景，并在适当时候返回原始场景）。在CCLayer 要求替换当前场景后，实际上是 CCDirector 进行的场景切换。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">另外， CCDirector 还负责OpenGL ES的初始化。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">
<h2>层</h2>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">CCLayer 拥有整个可进行绘制的区域，并且知道怎样对自身进行绘制。它还可以是半透明的（还可以在某些地方部分或者完全透明），这样可以看到层后的部分。层是对外观和行为进行定义的元件，所以大部分时间我们都说针对 CCLayer 及子类进行编程的。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;"><a style="color: #0088cc; text-decoration: none; padding: 0px; margin: 0px;" title="prog_guide:layers.png" href="http://www.cocos2d-iphone.org/wiki/lib/exe/detail.php/prog_guide:layers.png?id=prog_guide%3Abasic_concepts"><img style="padding: 0px; margin: 3px; border: 0px initial initial;" src="http://www.cocos2d-iphone.org/wiki/lib/exe/fetch.php/prog_guide:layers.png" alt="" /></a></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">CCLayer 还是进行事件处理的地方。事件是通过层进行传递直到某些层捕捉并进行处理。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">尽管许多程序要求你定义自定义 <strong>CCLayer </strong>类，但 cocos2d 提供了一些有用的预定义的层（比如简单的菜单层： CCMenu，颜色层： CCColorLayer， 其他层之间 的多路器：CCMultiplexLayer，等等）。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">层还可以包括 CCSprite 对象， CCLabel 对象以及甚至是 <strong>CCLayer </strong>对象。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">由于层是 CCNode的子类，因此可以使用“动作”对场景进行变换。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">
<h2>精灵</h2>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">Cocos2d 的精灵与其他程序库描述的精灵一样，是一个可以进行移动，旋转，大小变化，动画等操作的2D图像。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">精灵（通过 CCSprite 类实现）可以拥有其它精灵作为其子成员。当一个父成员进行变换时，其所有子成员也将同时进行变换。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 1em; line-height: 1.5em; padding: 0px;">由于精灵是 CCNode的子类，因此可以使用“动作”对场景进行变换。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/cocos-2d%e5%9f%ba%e6%9c%ac%e6%a6%82%e5%bf%b5/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>跨平台游戏引擎开发实录之一 &#8211; 设计文档</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b7%a8%e5%b9%b3%e5%8f%b0%e6%b8%b8%e6%88%8f%e5%bc%95%e6%93%8e%e5%bc%80%e5%8f%91%e5%ae%9e%e5%bd%95%e4%b9%8b%e4%b8%80-%e8%ae%be%e8%ae%a1%e6%96%87%e6%a1%a3</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b7%a8%e5%b9%b3%e5%8f%b0%e6%b8%b8%e6%88%8f%e5%bc%95%e6%93%8e%e5%bc%80%e5%8f%91%e5%ae%9e%e5%bd%95%e4%b9%8b%e4%b8%80-%e8%ae%be%e8%ae%a1%e6%96%87%e6%a1%a3#comments</comments>
		<pubDate>Mon, 18 Jan 2010 06:03:09 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[游戏]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[开源项目]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=797</guid>
		<description><![CDATA[我目前正在开发一个跨平台游戏引擎，我准备将整个开发过程通过博客记录下来。欢迎各位朋友提出宝贵意见。

下面是我的设计文档初稿。

项目名称
 
Portable Game Engine （PGE ）

目标

跨平台，希望能支持Windows，Linux，Mac OSX，iPhone，WinCE, Android, Blackberry, Symbian phone 等
简单，尽量简化编程接口
2D和3D
组件可选，以减小目标代码
支持Unicode


组件

核心：游戏主循环，线程，垃圾收集，插件等
图形系统（采用OpenGL或OpenGL ES）：图像（纹理），动画，字体
声音系统（采用OpenAL）：音效，音乐，乐器
资源管理器：压缩/解压，加密/解密
输入：键盘，鼠标及触摸屏（重力感应）
网络：Tcp/ip，Http, UDP
GUI（用户接口）：菜单，文本，按钮，列表框，下拉框，选择框
游戏AI
游戏Physics


开发按阶段进行。第一阶段开发Windows下的OpenGL 2D引擎，然后移植到iPhone下。
]]></description>
			<content:encoded><![CDATA[<p>我目前正在开发一个跨平台游戏引擎，我准备将整个开发过程通过博客记录下来。欢迎各位朋友提出宝贵意见。</p>
<p><br class="spacer_" /></p>
<p>下面是我的设计文档初稿。</p>
<p><br class="spacer_" /></p>
<h3>项目名称</h3>
<p><strong> </strong></p>
<p><strong>Portable Game Engine （PGE ）</strong></p>
<p><br class="spacer_" /></p>
<h3>目标</h3>
<ul>
<li>跨平台，希望能支持Windows，Linux，Mac OSX，iPhone，WinCE, Android, Blackberry, Symbian phone 等</li>
<li>简单，尽量简化编程接口</li>
<li>2D和3D</li>
<li>组件可选，以减小目标代码</li>
<li>支持Unicode</li>
</ul>
<p><br class="spacer_" /></p>
<h3>组件</h3>
<ul>
<li>核心：游戏主循环，线程，垃圾收集，插件等</li>
<li>图形系统（采用OpenGL或OpenGL ES）：图像（纹理），动画，字体</li>
<li>声音系统（采用OpenAL）：音效，音乐，乐器</li>
<li>资源管理器：压缩/解压，加密/解密</li>
<li>输入：键盘，鼠标及触摸屏（重力感应）</li>
<li>网络：Tcp/ip，Http, UDP</li>
<li>GUI（用户接口）：菜单，文本，按钮，列表框，下拉框，选择框</li>
<li>游戏AI</li>
<li>游戏Physics</li>
</ul>
<p><br class="spacer_" /></p>
<p>开发按阶段进行。第一阶段开发Windows下的OpenGL 2D引擎，然后移植到iPhone下。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b7%a8%e5%b9%b3%e5%8f%b0%e6%b8%b8%e6%88%8f%e5%bc%95%e6%93%8e%e5%bc%80%e5%8f%91%e5%ae%9e%e5%bd%95%e4%b9%8b%e4%b8%80-%e8%ae%be%e8%ae%a1%e6%96%87%e6%a1%a3/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>iPhone游戏编程教程之四-游戏简单音频</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e6%b8%b8%e6%88%8f%e7%bc%96%e7%a8%8b%e6%95%99%e7%a8%8b%e4%b9%8b%e5%9b%9b-%e6%b8%b8%e6%88%8f%e7%ae%80%e5%8d%95%e9%9f%b3%e9%a2%91</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e6%b8%b8%e6%88%8f%e7%bc%96%e7%a8%8b%e6%95%99%e7%a8%8b%e4%b9%8b%e5%9b%9b-%e6%b8%b8%e6%88%8f%e7%ae%80%e5%8d%95%e9%9f%b3%e9%a2%91#comments</comments>
		<pubDate>Fri, 13 Nov 2009 10:42:33 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[游戏]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[音频]]></category>
		<category><![CDATA[教程]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=235</guid>
		<description><![CDATA[本教程系列的最后一讲将介绍怎样为你的游戏加上声音。由于这是针对初学者的教程，所以我不会讨论复杂的音频技术，如OpenGL和Audio Queue。今天的主题是播放一段短的声音（少于30秒）。如果你不要求任何背景音乐，这将是最容易的播放音频的方式了。这种方式的缺点是一次只能播放一个音频文件。好，我们开始吧&#8230;&#8230;先从上次教程的代码开始。我们今天将使用两种声音，一个是击打球的声音，另一个是得分的声音。

&#160;

下面是你需要下载的音频文件：

clapping-crowd-studio-01
tennis-volley-01

&#160;
注意文件的格式是.caf。你所有音频文件格式必须符合在iPhone上播放的要求。Apple提供了一个工具将音频转换成这种格式。这里是参考。很简单，打开终端输入：
&#160;
/usr/bin/afconvert -f caff -d LEI16 {INPUT} {OUTPUT}
&#160;
 {INPUT}是输入音频文件路径，{OUTPUT} 是你想要存放的.caf文件路径。
&#160;
将音频文件添加到项目中
&#160;
将下载好的音频文件拖放到项目下的Resources文件夹。如果你还希望 安排得更为有序些的话，你还可以建立一个Audio子文件夹。请确定在“copy the  files into your project’s directory”检查框上打勾。

&#160;
添加AudioToolbox.framework到项目
&#160;
由于我们要用到此框架的一些函数，所以我们必须将此框架加入项目中。右击项目中的Frameworks文件夹选择Add -&#62; Existing Frameworks。在搜索框内输入AudioToolbox.framework 然后选择搜索结果中的框架。（请确定点取了Computer 以搜索整个电脑）。

&#160;
找到所需框架后，按Add。现在我们已经准备好写代码了&#8230;&#8230;
&#160;
头文件声明
&#160;
打开 iTennisViewController.h 加入下列代码：

&#160;
首先我们看到代码引入AudioServices.h，我们需要使用其中一些函数来播放音频。接下来定义了两个SystemSoundID。它们都是Integers（整数型，也可以使用int，但会引起许多警告信息）。然后打开iTennishViewController.m加入下面代码：

&#160;
现在我们来初始化声音对象。找到viewDidLoad方法加入下列代码：

&#160;
很简单吧。第一行是获取音频文件路径。下一行是将路径转换为CFURLRef。最后，加载音频文件并与指定soundID联系起来。注意我们传递的&#38;clappingFileID参数，  这是通过参考地址传递的，因此它允许AudioServicesCreateSystemSoundID方法对其进行修改。我们用同样方法处理击球声。下面，我们可以开始播放了。
&#160;
声音播放
&#160;
播放加载好的声音实际上很简单。只需将需要播放文件的soundID传递给AudioServicesPlaySystemSound方法即可。所以播放得分时的鼓掌声只需在reset方法中加入下列代码：

&#160;
请注意，我们传递的clappingFileID说明我们是要播放鼓掌声。加在gameLoop中加入下列代码将播放球拍击球的声音：

&#160;
很容易吧？按“Build and Go”试玩我们的游戏吧。源代码下载 。
&#160;
原文见：iPhone Game Programming Tutorial Part 4 – Basic Game Audio  
]]></description>
			<content:encoded><![CDATA[<p>本教程系列的最后一讲将介绍怎样为你的游戏加上声音。由于这是针对初学者的教程，所以我不会讨论复杂的音频技术，如OpenGL和Audio Queue。今天的主题是播放一段短的声音（少于30秒）。如果你不要求任何背景音乐，这将是最容易的播放音频的方式了。这种方式的缺点是一次只能播放一个音频文件。好，我们开始吧&#8230;&#8230;先从上次教程的代码开始。我们今天将使用两种声音，一个是击打球的声音，另一个是得分的声音。
</p>
<p>&nbsp;</p>
<p><span id="more-235"></span></p>
<p>下面是你需要下载的音频文件：</p>
<ul>
<li><a href="http://icodeblog.com/wp-content/uploads/2009/05/clapping-crowd-studio-01.caf">clapping-crowd-studio-01</a></li>
<li><a href="http://icodeblog.com/wp-content/uploads/2009/05/tennis-volley-01.caf">tennis-volley-01</a></li>
</ul>
<p>&nbsp;</p>
<p>注意文件的格式是.caf。你所有音频文件格式必须符合在iPhone上播放的要求。Apple提供了一个工具将音频转换成这种格式。这里是<a href="CONVERT_AN_AUDIO_FILE_TO_THE_PREFERRED_FORMAT_FOR_IPHONE_OS">参考</a>。很简单，打开终端输入：</p>
<p>&nbsp;</p>
<p><strong>/usr/bin/afconvert -f caff -d LEI16 {INPUT} {OUTPUT}</strong></p>
<p>&nbsp;</p>
<p> {INPUT}是输入音频文件路径，{OUTPUT} 是你想要存放的.caf文件路径。</p>
<p>&nbsp;</p>
<h2>将音频文件添加到项目中</h2>
<p>&nbsp;</p>
<p>将下载好的音频文件拖放到项目下的Resources文件夹。如果你还希望 安排得更为有序些的话，你还可以建立一个Audio子文件夹。请确定在“copy the  files into your project’s directory”检查框上打勾。</p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/05/screenshot_01.png"><img title="screenshot_01" src="http://icodeblog.com/wp-content/uploads/2009/05/screenshot_01.png" alt="screenshot_01" width="232" height="240"></a></p>
<p>&nbsp;</p>
<h2>添加AudioToolbox.framework到项目</h2>
<p>&nbsp;</p>
<p>由于我们要用到此框架的一些函数，所以我们必须将此框架加入项目中。右击项目中的<strong>Frameworks</strong>文件夹选择<strong>Add -&gt; Existing Frameworks</strong>。在搜索框内输入<strong>AudioToolbox.framework </strong>然后选择搜索结果中的框架。（请确定点取了<strong>Computer</strong> 以搜索整个电脑）。</p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/05/screenshot_02.png"><img title="screenshot_02" src="http://icodeblog.com/wp-content/uploads/2009/05/screenshot_02.png" alt="screenshot_02" width="532" height="427"></a></p>
<p>&nbsp;</p>
<p>找到所需框架后，按<strong>Add</strong>。现在我们已经准备好写代码了&#8230;&#8230;</p>
<p>&nbsp;</p>
<h2>头文件声明</h2>
<p>&nbsp;</p>
<p>打开 <strong>iTennisViewController.h</strong> 加入下列代码：</p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/05/screenshot_11.png"><img title="screenshot_11" src="http://icodeblog.com/wp-content/uploads/2009/05/screenshot_11.png" alt="screenshot_11" width="325" height="356"></a></p>
<p>&nbsp;</p>
<p>首先我们看到代码引入AudioServices.h，我们需要使用其中一些函数来播放音频。接下来定义了两个SystemSoundID。它们都是Integers（整数型，也可以使用int，但会引起许多警告信息）。然后打开<strong>iTennishViewController.m</strong>加入下面代码：</p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/05/screenshot_09.png"><img title="screenshot_09" src="http://icodeblog.com/wp-content/uploads/2009/05/screenshot_09.png" alt="screenshot_09" width="258" height="27"></a></p>
<p>&nbsp;</p>
<p>现在我们来初始化声音对象。找到viewDidLoad方法加入下列代码：</p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/05/screenshot_12.png"><img title="screenshot_12" src="http://icodeblog.com/wp-content/uploads/2009/05/screenshot_12.png" alt="screenshot_12" width="709" height="223"></a></p>
<p>&nbsp;</p>
<p>很简单吧。第一行是获取音频文件路径。下一行是将路径转换为CFURLRef。最后，加载音频文件并与指定soundID联系起来。注意我们传递的&amp;clappingFileID参数，  这是通过参考地址传递的，因此它允许AudioServicesCreateSystemSoundID方法对其进行修改。我们用同样方法处理击球声。下面，我们可以开始播放了。</p>
<p>&nbsp;</p>
<h2>声音播放</h2>
<p>&nbsp;</p>
<p>播放加载好的声音实际上很简单。只需将需要播放文件的soundID传递给AudioServicesPlaySystemSound方法即可。所以播放得分时的鼓掌声只需在reset方法中加入下列代码：</p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/05/screenshot_14.png"><img title="screenshot_14" src="http://icodeblog.com/wp-content/uploads/2009/05/screenshot_14.png" alt="screenshot_14" width="322" height="52"></a></p>
<p>&nbsp;</p>
<p>请注意，我们传递的clappingFileID说明我们是要播放鼓掌声。加在gameLoop中加入下列代码将播放球拍击球的声音：</p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/05/screenshot_15.png"><img title="screenshot_15" src="http://icodeblog.com/wp-content/uploads/2009/05/screenshot_15.png" alt="screenshot_15" width="381" height="209"></a></p>
<p>&nbsp;</p>
<p>很容易吧？按“Build and Go”试玩我们的游戏吧。源代码<a href="http://icodeblog.com/wp-content/uploads/2009/05/itennis-4.zip">下载</a> 。</p>
<p>&nbsp;</p>
<h5>原文见：<a href="http://icodeblog.com/2009/05/04/iphone-game-programming-tutorial-part-4-basic-game-audio/" rel="bookmark" title="Permanent Link to iPhone Game Programming Tutorial Part 4 – Basic Game Audio">iPhone Game Programming Tutorial Part 4 – Basic Game Audio </a> </h5>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e6%b8%b8%e6%88%8f%e7%bc%96%e7%a8%8b%e6%95%99%e7%a8%8b%e4%b9%8b%e5%9b%9b-%e6%b8%b8%e6%88%8f%e7%ae%80%e5%8d%95%e9%9f%b3%e9%a2%91/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>OpenGL ES系列之0 &#8211; 建立Xcode项目</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone-opengl-es%e7%b3%bb%e5%88%97%e4%b9%8b0-%e5%bb%ba%e7%ab%8bxcode%e9%a1%b9%e7%9b%ae</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone-opengl-es%e7%b3%bb%e5%88%97%e4%b9%8b0-%e5%bb%ba%e7%ab%8bxcode%e9%a1%b9%e7%9b%ae#comments</comments>
		<pubDate>Wed, 11 Nov 2009 10:53:03 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[图形图像]]></category>
		<category><![CDATA[游戏]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[OpenGL ES]]></category>
		<category><![CDATA[教程]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=182</guid>
		<description><![CDATA[
为iPhone建立一个OpenGL ES的Xcode项目是很容易的事，特别是在苹果公司的SDK发布时引入了模板的概念后。我们所需要做的只是在适当的地方快速而简单的加入代码。这就是我们今天的主题。

&#160;
老实说，如果你只是想早点切入OpenGL 教程的主题，你尽可以忽略这一部分。而且这样做，你也不会错失什么，因为有关Xcode设定部分我并不准备过多涉猎。尽管进入教程的最后部分下载项目文件。
&#160;
启动Xcode并创建Xcode新项目。选择模板&#8220;OpenGL ES Application&#8221;（见图1），然后将项目存储在你认为方便的地方。&#160;
&#160;



&#160;&#160;
图1
&#160;
好，我们假定你肯能以前已经在哪看过这个模板或运行过用这个模板建立的项目。我们说要做的就是移除那个旋转的彩色正方形的有关代码并将其转换成使用深度缓冲的视图（即使其成为&#8220;真正的&#8221;3D）。
&#160;
3D空间的2D
  
&#160;
像Apple的模板一样，大部分OpenGL教程开始都忽略深度，通常都使用2维坐标系统（X,Y)而不是更复杂的3维坐标系统（X,Y,Z)。你可能已经注意到Apple模板中的正方形定点使用（X,Y)，这是因为他们没有使用深度。
&#160;
这叫做正交投影。本教程系列的目标是带你进入3D世界。所以我现在不会讨论正交投影；可能稍后的系列会有提及。现在我们直接向3D世界进发吧。
  
&#160;
允许Depth Buffer（深度缓存）
  
&#160;
我们要作的第一件事是允许深度缓存。Apple示例中的正方形只是一个2D物体，所以根本不需要深度缓存。由于我们需要深度，所以我们必须启用它。Apple已经提供了设定深度缓存的代码，我们正好可以使用。
  
&#160;
在编辑器中打开EAGLView.m找到下面代码:
  
1#define USE_DEPTH_BUFFER 0

不用多说，把0改为1。这将启用视图设定部分创建深度缓存的代码。代码在createFrameBuffer方法中。现在还不需要考虑太多这段代码。它是Apple写的，应该能正常工作。
  
&#160;
现在我们需要启用深度来测试OpenGL。我们要建立一个新方法，它只会被调用一次以使视图正常工作。首先，建立一个新方法setupView并将下面代码加入新方法中：  
1234567891011121314151617- &#40;void&#41;setupView &#123;
&#160; &#160; const GLfloat zNear = 0.1, zFar = 1000.0, fieldOfView = 60.0;
&#160; &#160; GLfloat size;
&#160; &#160; glEnable&#40;GL_DEPTH_TEST&#41;;

&#160; &#160; glMatrixMode&#40;GL_PROJECTION&#41;;

&#160; &#160; size = zNear * tanf&#40;DEGREES_TO_RADIANS&#40;fieldOfView&#41; / 2.0&#41;;

&#160; &#160; // This give [...]]]></description>
			<content:encoded><![CDATA[<div>
<p>为iPhone建立一个OpenGL ES的Xcode项目是很容易的事，特别是在苹果公司的SDK发布时引入了模板的概念后。我们所需要做的只是在适当的地方快速而简单的加入代码。这就是我们今天的主题。</p>
<p><span id="more-182"></span></p>
<p>&nbsp;</p>
<p>老实说，如果你只是想早点切入OpenGL 教程的主题，你尽可以忽略这一部分。而且这样做，你也不会错失什么，因为有关Xcode设定部分我并不准备过多涉猎。尽管进入教程的最后部分下载项目文件。</p>
<p>&nbsp;</p>
<p>启动Xcode并创建Xcode新项目。选择模板&ldquo;OpenGL ES Application&rdquo;（见图1），然后将项目存储在你认为方便的地方。&nbsp;</p>
<p>&nbsp;</p>
<div>
<div><img alt="" src="http://web.me.com/smaurice/AppleCoder/iPhone_OpenGL/Entries/2009/3/28_OpenGL_ES_00_-_Xcode_Project_Set_Up_files/figure01.png"></div>
</p></div>
<p>&nbsp;&nbsp;</p>
<h5>图1</h5>
<p>&nbsp;</p>
<p>好，我们假定你肯能以前已经在哪看过这个模板或运行过用这个模板建立的项目。我们说要做的就是移除那个旋转的彩色正方形的有关代码并将其转换成使用深度缓冲的视图（即使其成为&ldquo;真正的&rdquo;3D）。</p>
<p>&nbsp;</p>
<h2>3D空间的2D<br />
  </h2>
<p>&nbsp;</p>
<p>像Apple的模板一样，大部分OpenGL教程开始都忽略深度，通常都使用2维坐标系统（X,Y)而不是更复杂的3维坐标系统（X,Y,Z)。你可能已经注意到Apple模板中的正方形定点使用（X,Y)，这是因为他们没有使用深度。</p>
<p>&nbsp;</p>
<p>这叫做正交投影。本教程系列的目标是带你进入3D世界。所以我现在不会讨论正交投影；可能稍后的系列会有提及。现在我们直接向3D世界进发吧。
  </p>
<p>&nbsp;</p>
<p>允许Depth Buffer（深度缓存）
  </p>
<p>&nbsp;</p>
<p>我们要作的第一件事是允许深度缓存。Apple示例中的正方形只是一个2D物体，所以根本不需要深度缓存。由于我们需要深度，所以我们必须启用它。Apple已经提供了设定深度缓存的代码，我们正好可以使用。
  </p>
<p>&nbsp;</p>
<p>在编辑器中打开EAGLView.m找到下面代码:
  </p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #6e371a;">#define USE_DEPTH_BUFFER 0</span></div></td></tr></tbody></table></div>
</p>
<p>不用多说，把0改为1。这将启用视图设定部分创建深度缓存的代码。代码在createFrameBuffer方法中。现在还不需要考虑太多这段代码。它是Apple写的，应该能正常工作。
  </p>
<p>&nbsp;</p>
<p>现在我们需要启用深度来测试OpenGL。我们要建立一个新方法，它只会被调用一次以使视图正常工作。首先，建立一个新方法setupView并将下面代码加入新方法中：  </p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setupView <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #a61390;">const</span> GLfloat zNear <span style="color: #002200;">=</span> 0.1, zFar <span style="color: #002200;">=</span> 1000.0, fieldOfView <span style="color: #002200;">=</span> <span style="color: #2400d9;">60.0</span>;<br />
&nbsp; &nbsp; GLfloat size;<br />
&nbsp; &nbsp; glEnable<span style="color: #002200;">&#40;</span>GL_DEPTH_TEST<span style="color: #002200;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; glMatrixMode<span style="color: #002200;">&#40;</span>GL_PROJECTION<span style="color: #002200;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; size <span style="color: #002200;">=</span> zNear <span style="color: #002200;">*</span> tanf<span style="color: #002200;">&#40;</span>DEGREES_TO_RADIANS<span style="color: #002200;">&#40;</span>fieldOfView<span style="color: #002200;">&#41;</span> <span style="color: #002200;">/</span> 2.0<span style="color: #002200;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #11740a; font-style: italic;">// This give us the size of the iPhone display</span><br />
&nbsp; &nbsp; CGRect rect <span style="color: #002200;">=</span> self.bounds;<br />
<br />
&nbsp; &nbsp; glFrustumf<span style="color: #002200;">&#40;</span><span style="color: #002200;">-</span>size, size, <span style="color: #002200;">-</span>size <span style="color: #002200;">/</span> <span style="color: #002200;">&#40;</span>rect.size.width <span style="color: #002200;">/</span> rect.size.height<span style="color: #002200;">&#41;</span>, size <span style="color: #002200;">/</span> <span style="color: #002200;">&#40;</span>rect.size.width <span style="color: #002200;">/</span> rect.size.height<span style="color: #002200;">&#41;</span>, zNear, zFar<span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; glViewport<span style="color: #002200;">&#40;</span>0, 0, rect.size.width, rect.size.height<span style="color: #002200;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; glClearColor<span style="color: #002200;">&#40;</span>0.0f, 0.0f, 0.0f, 1.0f<span style="color: #002200;">&#41;</span>;<br />
<span style="color: #002200;">&#125;</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>上述代码通过建立一个映射到世界显示的视区设定了OpenGL操作的环境。我将稍后详细说明，现在注意下面代码：</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">glEnable<span style="color: #002200;">&#40;</span>GL_DEPTH_TEST<span style="color: #002200;">&#41;</span>;</div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>此代码启用了OpenGL中的深度测试。你需要记住在OpenGL中一旦你启用了什么，你一定要记住在你不需要时要关闭它。由于我们启用深度测试并没有关闭，所以在视图设定中仍然有效。</p>
<p><div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">glClearColor(0.0f, 0.0f, 0.0f, 1.0f);</div></td></tr></tbody></table></div>
</p>
<p>&nbsp;</p>
<p>我们在此定义了清屏时所用的颜色。OpenGLES中所有颜色都必须是RGBA值（即红，绿，蓝和alpha），而不能像OpenGL一样采用RGB值。由于OpenGLES已经知道清屏时采用的颜色，所以清屏时使用定义的黑色。此设定一直保持到我们改变它。</p>
<p>&nbsp;</p>
<p>当使用浮点时，颜色值为0-&gt;1，而使用无符号字节类型时，可为0-&gt;255。数值越大，所代表颜色的密度越高。
  </p>
<p>&nbsp;</p>
<p>好，回到文件最开始我们先前改变的#define处。我们要在这定义一个宏，在我们刚插入的setupView方法中需要用到。</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; <span style="color: #6e371a;">#define USE_DEPTH_BUFFER 1</span><br />
&nbsp; <br />
&nbsp; <span style="color: #6e371a;">#define DEGREES_TO_RADIANS(__ANGLE) ((__ANGLE) / 180.0 * M_PI)</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<h2>视图绘制 &#8211; 画图方法<br />
  </h2>
<p>&nbsp;</p>
<p>现在，找到drawView方法。这是本教程的重点。Apple已经提示我们这里是视图绘制的地方。</p>
<p>&nbsp;</p>
<p>首先，删除一切，加入下面代码：
  </p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>drawView <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #002200;">&#91;</span>EAGLContext setCurrentContext<span style="color: #002200;">:</span>context<span style="color: #002200;">&#93;</span>;<span style="color: #002200;">&amp;</span>nbsp;<span style="color: #002200;">&amp;</span>nbsp;<span style="color: #002200;">&amp;</span>nbsp; <br />
&nbsp; &nbsp; glBindFramebufferOES<span style="color: #002200;">&#40;</span>GL_FRAMEBUFFER_OES, viewFramebuffer<span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; glViewport<span style="color: #002200;">&#40;</span>0, 0, backingWidth, backingHeight<span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; glBindRenderbufferOES<span style="color: #002200;">&#40;</span>GL_RENDERBUFFER_OES, viewRenderbuffer<span style="color: #002200;">&#41;</span>;<br />
&nbsp; <br />
&nbsp; &nbsp; <span style="color: #002200;">&#91;</span>context presentRenderbuffer<span style="color: #002200;">:</span>GL_RENDERBUFFER_OES<span style="color: #002200;">&#93;</span>;<br />
<span style="color: #002200;">&#125;</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>上面代码的前三行是设定作图空间。后两行是将作图空间与当前屏幕可见空间进行交换。如果你以前进行过动画或游戏编程工作，那么你应该知道这叫做 &ldquo;double buffered（双重缓冲）&rdquo;。</p>
<p>&nbsp;</p>
<p>如果不知道，我们解释下：我们创建了两个完全相同的缓冲，一个用于显示给用户，另一个被清理掉然后在其上绘图。在绘制结束后，我们交换这两个视图以便用户看到新的视图。我们之所以不拍麻烦做了这么多事情是为了动画更为平滑。
  </p>
<p>&nbsp;</p>
<p>我们还要加入更多的代码。</p>
<p>&nbsp;</p>
<p>首先，在dealloc方法前插入以下代码：</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; <span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>checkGLError<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>visibleCheck <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; GLenum error <span style="color: #002200;">=</span> glGetError<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; <br />
&nbsp; &nbsp; <span style="color: #a61390;">switch</span> <span style="color: #002200;">&#40;</span>error<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span><br />
&nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">case</span> GL_INVALID_ENUM<span style="color: #002200;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;GL Error: Enum argument is out of range&quot;</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">break</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">case</span> GL_INVALID_VALUE<span style="color: #002200;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;GL Error: Numeric value is out of range&quot;</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">break</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">case</span> GL_INVALID_OPERATION<span style="color: #002200;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;GL Error: Operation illegal in current state&quot;</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">break</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">case</span> GL_STACK_OVERFLOW<span style="color: #002200;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;GL Error: Command would cause a stack overflow&quot;</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #a61390;">break</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">case</span> GL_STACK_UNDERFLOW<span style="color: #002200;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;GL Error: Command would cause a stack underflow&quot;</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">break</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">case</span> GL_OUT_OF_MEMORY<span style="color: #002200;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;GL Error: Not enough memory to execute command&quot;</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">break</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">case</span> GL_NO_ERROR<span style="color: #002200;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>visibleCheck<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;No GL Error&quot;</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #002200;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">break</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">default</span><span style="color: #002200;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Unknown GL Error&quot;</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">break</span>;<br />
<br />
<span style="color: #002200;">&#125;</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>OpenGL有一套错误检查的方法（glGetError())，但是需要将错误码转换成更容易读的格式。上面的代码就是完成这个工作的。</p>
<p>&nbsp;</p>
<p>布尔值&ldquo;visibleCheck&rdquo;只用于检查当没有错误时此方法是否已被调用。 </p>
<p>&nbsp;</p>
<p>最后，我们要做的只是在EAGLView.m中找到initWithCoder方法并调用&ldquo;setupView&rdquo;方法。在变量&ldquo;animationInterval&rdquo;设定之前，加入下面代码调用setupView：</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #002200;">&#91;</span>self setupView<span style="color: #002200;">&#93;</span>;</div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>应注意我们只是调用在initWithCoder中setupView方法而不是创建一个新方法，它只应该被调用一次。</p>
<p>下面，打开EAGLView.h！</p>
<p>&nbsp;</p>
<h3>EAGLView.h<br />
  </h3>
<p>&nbsp;</p>
<p>我们只需要在这里加入两个方法的原型：
  </p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setupView;<br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>checkGLError<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>visibleCheck;</div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>教程到此结束。</p>
<p>&nbsp;</p>
<h2>后续&#8230;<br />
  </h2>
<p>&nbsp;</p>
<p>如果你此时按&ldquo;build and run&rdquo;，那么在simulator（模拟器）上只是显示一个空白屏幕。在下一个教程中，我们将在屏幕上绘制一下基本图形，基本图形是指点，线和三角形之类的元素。</p>
<p>&nbsp;</p>
<p>
  代码下载：<a href="http://web.me.com/smaurice/AppleCoder/iPhone_OpenGL/Entries/2009/3/28_OpenGL_ES_00_-_Xcode_Project_Set_Up_files/AppleCoder-OpenGLES-00.zip" title="28_OpenGL_ES_00_-_Xcode_Project_Set_Up_files/AppleCoder-OpenGLES-00.zip">AppleCoder-OpenGLES-00.zip</a>
  </p>
<p>&nbsp;</p>
<h5>原文见： <a href="http://web.me.com/smaurice/AppleCoder/iPhone_OpenGL/Entries/2009/3/28_OpenGL_ES_00_-_Xcode_Project_Set_Up.html">OpenGL ES 00 &#8211; Xcode Project Set Up</a> 作者：Simon Maurice</h5>
<div>
<h5></h5>
</p></div>
</div>
<div> </div>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone-opengl-es%e7%b3%bb%e5%88%97%e4%b9%8b0-%e5%bb%ba%e7%ab%8bxcode%e9%a1%b9%e7%9b%ae/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>iPhone游戏编程教程之三- 启动画面</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e6%b8%b8%e6%88%8f%e7%bc%96%e7%a8%8b%e6%95%99%e7%a8%8b%e4%b9%8b%e4%b8%89-%e5%90%af%e5%8a%a8%e7%94%bb%e9%9d%a2</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e6%b8%b8%e6%88%8f%e7%bc%96%e7%a8%8b%e6%95%99%e7%a8%8b%e4%b9%8b%e4%b8%89-%e5%90%af%e5%8a%a8%e7%94%bb%e9%9d%a2#comments</comments>
		<pubDate>Wed, 18 Mar 2009 08:02:05 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[游戏]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[教程]]></category>

		<guid isPermaLink="false">http://iphonegeek.zuesitech.com/?p=165</guid>
		<description><![CDATA[今天，我将介绍怎样为你的程序加一些&#8220;铃和哨&#8221;（注：指一些附加的花哨的东西）是你的游戏显得更完整。首先，我们为游戏增加一个启动页面。

&#160;
创建启动页面
&#160;
我们加入的启动页面将淡出到游戏主屏幕。你可以下载此图像加入到项目的Resources（资源）文件夹中。 请选择复选框中&#8220;copy this image to the project&#8217;s directory（拷贝此 图像至项目目录）&#8221;选项。

&#160;

我们需要加入一个View Controller到我们的项目，它将负责处理启动画面视图。在你的项目中加入一个新的UIViewController的子类文件。取名为SplashViewController，同时选择建立.h文件。
&#160;


&#160;


然后，我们要改变AppDelegate以加载此View Controller而不是原来的Main View Controller。打开iTennisAppDelegate.h修改如下：
&#160;




&#160;


主要是将iTennisViewController替换为SplashViewController。接着，打开iTennisAppDelegate.m做如下修改：



&#160;


这里我们所作的也只是将iTennisViewController替换为SplashViewController。这是因为我们希望开始时加载启动页面而不是游戏主画面。这里需要注意的一个主要区别是我们分配了一个新的SplashViewController实例。我们不需要对iTennisViewController这样做是因为它是从nib文件中加载而由程序本身对它进行初始化的。由于我们是通过编程来建立SplashViewController(没有nib), 所以需要将其实例化。接着我们就要实现SplashView。打开SplashViewController.h加入以下代码：
&#160;



&#160;


我来解释一下我们到底做了什么。首先，我们看到一个NSTimer。它被用于在启动画面淡出到游戏主画面前启动画面保持显示的时间。接着，有一个UIImageView，它将提供启动画面的图像。

  


最后，我们看到iTennisViewController，这是被程序代理替换掉的视图控制器。我们将从启动视图中加载它。打开SplashViewController.m 加入下列代码：



&#160;


这只是用来合成所有的属性。在loadView方法中加入下面代码:
&#160;



&#160;
这里有很多新代码。首先，由于是通过编程而不是通过nib来加载视图，我们必须创建视图。我们使用运行程序的框架（frame）来建立一个新的视图。然后将SplashViewController的视图设定到这个刚建立的视图。我们必须建立一个框架来通知应用程序创建一个320&#215;480的视图。

&#160;

下面，我们用Splash.png图像创建splashImageView。我们还需要为这个图像创建一个框架。将此框架想象成一个空的容器，我们将把图像放在里面。接着，我们把imageview加入主视图。然后，我们通过将要加载的nib的文件传递给视图的主控制器而对其进行初始化。再把视图的alpha透明性设为0.0。这样，它就会完全不可见。最后，我们将其加到我们的视图中。请注意，此时它覆盖在splashImageView的上方，但由于alpha透明值为0.0，它仍然不可见。
&#160;
最后，启动定时器。这样，在调用&#8220;fadeScreen&#8221;方法前，启动屏幕将显示2秒钟。必须指出我是从这篇文章借用的fadescreen方法。

&#160;
加入下面代码:


此代码中包括很多动画。由于注解很详细，我就不过多涉猎了。在fadeScreen方法中视图淡出，然后调用finishedFading。finishFading方法使视图控制器的视图重新淡入。主视图将显示出来。记住从父视图中移除启动屏视图，否则你会看到奇怪的画面过度效果。

&#160;
今天就到这里。下次我将引入音频到游戏中。如果有什么问题与建议，write me on Twitter.

&#160;
源代码在这里下载。
&#160;
18 Mar 2009 原文见：iPhone Game Programming Tutorial Part 3 &#8211; Splash Screen 
]]></description>
			<content:encoded><![CDATA[<p>今天，我将介绍怎样为你的程序加一些&ldquo;铃和哨&rdquo;（注：指一些附加的花哨的东西）是你的游戏显得更完整。首先，我们为游戏增加一个启动页面。</p>
<p><span id="more-165"></span></p>
<p>&nbsp;</p>
<h3>创建启动页面</h4>
<p>&nbsp;</p>
<p>我们加入的启动页面将淡出到游戏主屏幕。你可以下载此图像加入到项目的<strong>Resources（资源）</strong>文件夹中。 请选择复选框中&ldquo;copy this image to the project&rsquo;s directory（拷贝此 图像至项目目录）&rdquo;选项。</p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/03/splash.png"><img title="splash" src="http://icodeblog.com/wp-content/uploads/2009/03/splash.png" alt="splash" width="320" height="480"></a></p>
<p>&nbsp;</p>
<p>
我们需要加入一个View Controller到我们的项目，它将负责处理启动画面视图。在你的项目中加入一个新的<strong>UIViewController</strong>的子类文件。取名为<strong>SplashViewController</strong>，同时选择建立.h文件。</p>
<p>&nbsp;</p>
<div>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/03/screenshot_01.png"><img title="screenshot_01" src="http://icodeblog.com/wp-content/uploads/2009/03/screenshot_01.png" alt="screenshot_01" width="600" height="442"></a></p>
<p>&nbsp;</p>
</div>
<div>
<p>然后，我们要改变AppDelegate以加载此View Controller而不是原来的Main View Controller。打开<strong>iTennisAppDelegate.h</strong>修改如下：</p>
<p>&nbsp;</p>
</div>
<p></p>
<div>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/03/screenshot_02.png"><img title="screenshot_02" src="http://icodeblog.com/wp-content/uploads/2009/03/screenshot_02.png" alt="screenshot_02" width="466" height="194"></a></p>
<p>&nbsp;</p>
</div>
<div>
<p>主要是将iTennisViewController替换为SplashViewController。接着，打开<strong>iTennisAppDelegate.m</strong>做如下修改：</p>
</div>
<div>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/03/screenshot_03.png"><img title="screenshot_03" src="http://icodeblog.com/wp-content/uploads/2009/03/screenshot_03.png" alt="screenshot_03" width="418" height="365"></a></p>
<p>&nbsp;</p>
</div>
<div>
<p>这里我们所作的也只是将iTennisViewController替换为SplashViewController。这是因为我们希望开始时加载启动页面而不是游戏主画面。这里需要注意的一个主要区别是我们分配了一个新的SplashViewController实例。我们不需要对iTennisViewController这样做是因为它是从nib文件中加载而由程序本身对它进行初始化的。由于我们是通过编程来建立SplashViewController(没有nib), 所以需要将其实例化。接着我们就要实现SplashView。打开<strong>SplashViewController.h</strong>加入以下代码：</p>
<p>&nbsp;</p>
</div>
<div>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/03/screenshot_04.png"><img title="screenshot_04" src="http://icodeblog.com/wp-content/uploads/2009/03/screenshot_04.png" alt="screenshot_04" width="406" height="231"></a></p>
<p>&nbsp;</p>
</div>
<div>
<p>我来解释一下我们到底做了什么。首先，我们看到一个NSTimer。它被用于在启动画面淡出到游戏主画面前启动画面保持显示的时间。接着，有一个UIImageView，它将提供启动画面的图像。</p>
<p>
  </p>
</div>
<div>
<p>最后，我们看到<strong>iTennisViewController</strong>，这是被程序代理替换掉的视图控制器。我们将从启动视图中加载它。打开<strong>SplashViewController.m</strong> 加入下列代码：</p>
</div>
<div>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/03/screenshot_05.png"><img title="screenshot_05" src="http://icodeblog.com/wp-content/uploads/2009/03/screenshot_05.png" alt="screenshot_05" width="301" height="25"></a></p>
<p>&nbsp;</p>
</div>
<div>
<p>这只是用来合成所有的属性。在<strong>l</strong><strong>oadView</strong>方法中加入下面代码:</p>
<p>&nbsp;</p>
</div>
<div><a href="http://icodeblog.com/wp-content/uploads/2009/03/screenshot_07.png"><img title="screenshot_07" src="http://icodeblog.com/wp-content/uploads/2009/03/screenshot_07.png" alt="screenshot_07" width="761" height="259"></a></div>
<div>
<p>&nbsp;</p>
<p>这里有很多新代码。首先，由于是通过编程而不是通过nib来加载视图，我们必须创建视图。我们使用运行程序的框架（frame）来建立一个新的视图。然后将SplashViewController的视图设定到这个刚建立的视图。我们必须建立一个框架来通知应用程序创建一个320&#215;480的视图。</p>
</div>
<p>&nbsp;</p>
<div>
下面，我们用Splash.png图像创建splashImageView。我们还需要为这个图像创建一个框架。将此框架想象成一个空的容器，我们将把图像放在里面。接着，我们把imageview加入主视图。然后，我们通过将要加载的nib的文件传递给视图的主控制器而对其进行初始化。再把视图的alpha透明性设为0.0。这样，它就会完全不可见。最后，我们将其加到我们的视图中。请注意，此时它覆盖在splashImageView的上方，但由于alpha透明值为0.0，它仍然不可见。</p>
<p>&nbsp;</p>
<p>最后，启动定时器。这样，在调用&ldquo;fadeScreen&rdquo;方法前，启动屏幕将显示2秒钟。必须指出我是从<a href="http://www.iphonedevsdk.com/forum/iphone-sdk-development/12998-how-fade-between-views-transitioning-through-black.html" onclick="pageTracker._trackPageview('/outgoing/www.iphonedevsdk.com/forum/iphone-sdk-development/12998-how-fade-between-views-transitioning-through-black.html?referer=http%3A%2F%2Ficodeblog.com%2Fcategory%2Fiphone-programming-tutorials%2F');">这篇文章</a>借用的fadescreen方法。
</div>
<p>&nbsp;</p>
<div>加入下面代码:</div>
<div><a href="http://icodeblog.com/wp-content/uploads/2009/03/screenshot_08.png"><img title="screenshot_08" src="http://icodeblog.com/wp-content/uploads/2009/03/screenshot_08.png" alt="screenshot_08" width="578" height="317"></a></div>
<div>
此代码中包括很多动画。由于注解很详细，我就不过多涉猎了。在fadeScreen方法中视图淡出，然后调用finishedFading。finishFading方法使视图控制器的视图重新淡入。主视图将显示出来。记住从父视图中移除启动屏视图，否则你会看到奇怪的画面过度效果。
</div>
<p>&nbsp;</p>
<p>今天就到这里。下次我将引入音频到游戏中。如果有什么问题与建议，<a href="http://twitter.com/brandontreb" onclick="pageTracker._trackPageview('/outgoing/twitter.com/brandontreb?referer=http%3A%2F%2Ficodeblog.com%2Fcategory%2Fiphone-programming-tutorials%2F');">write me on Twitter</a>.
</p>
<p>&nbsp;</p>
<p>源代码在<a href="http://icodeblog.com/wp-content/uploads/2009/03/itennis-3.zip">这里下载</a>。</p>
<p>&nbsp;</p>
<h5>18 Mar 2009 原文见：<a href="http://icodeblog.com/2009/03/18/iphone-game-programming-tutorial-part-3-splash-screen/" rel="bookmark" title="Permanent Link to iPhone Game Programming Tutorial Part 3 &ndash; Splash Screen">iPhone Game Programming Tutorial Part 3 &ndash; Splash Screen </a></h5>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e6%b8%b8%e6%88%8f%e7%bc%96%e7%a8%8b%e6%95%99%e7%a8%8b%e4%b9%8b%e4%b8%89-%e5%90%af%e5%8a%a8%e7%94%bb%e9%9d%a2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPhone游戏编程教程之二-用户互动，简单AI，游戏逻辑</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e6%b8%b8%e6%88%8f/iphone%e6%b8%b8%e6%88%8f%e7%bc%96%e7%a8%8b%e6%95%99%e7%a8%8b%e4%b9%8b%e4%ba%8c-%e7%94%a8%e6%88%b7%e4%ba%92%e5%8a%a8%ef%bc%8c%e7%ae%80%e5%8d%95ai%ef%bc%8c%e6%b8%b8%e6%88%8f%e9%80%bb%e8%be%91</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e6%b8%b8%e6%88%8f/iphone%e6%b8%b8%e6%88%8f%e7%bc%96%e7%a8%8b%e6%95%99%e7%a8%8b%e4%b9%8b%e4%ba%8c-%e7%94%a8%e6%88%b7%e4%ba%92%e5%8a%a8%ef%bc%8c%e7%ae%80%e5%8d%95ai%ef%bc%8c%e6%b8%b8%e6%88%8f%e9%80%bb%e8%be%91#comments</comments>
		<pubDate>Tue, 17 Feb 2009 16:29:00 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[游戏]]></category>
		<category><![CDATA[教程]]></category>

		<guid isPermaLink="false">http://iphonegeek.zuesitech.com/?p=126</guid>
		<description><![CDATA[今天，我将讨论玩家互动，简单的游戏AI即游戏逻辑。还将探讨一下简单的碰撞检测以便检测到什么时候球碰到球拍。根据大家要求，我还会在教程最后加入一些“挑战”以改进一些更高级的创意。首先打开第一部分的代码&#8230; 
 
&#160;
用户互动
&#160;
我们首先要实现的是用户互动。我们所需要做的只是将球拍的X位置移动到用户触摸的X位置。这是很简单的方法，我们还可以做得更好（我将这部分挑战放在教程的最后 ）。打开iTennisViewController.m加入下面代码：     
&#160;


&#160;
 就像上一篇教程一样，我们要重载touchesMoved方法。此方法在用户在屏幕上“拖动”手指时被触发。首先，我在touchesBegan中加入“else if”语句，当游戏处于运行状态时简单地将所有事件转发到touchesMoved中。touchesMoved中前两行是检测用户触屏的位置。接着，我们根据用户触屏X位置及黄色球拍（玩家球拍）Y位置创建 一个新的CGPoint。Objective-C不允许racquet_yellow.center.x = location.x。这可能是因为CGpiont不可改变（不可编辑）。最后，将玩家球拍的中点设置到新的位置。

&#160;
碰撞检测
&#160;
*更新, 有读者指出有更简单的碰撞检测方法。将下列代码加入到iTennisViewController.m 的gameLoop方法中：     
&#160;
    
&#160;
 苹果已经提供我们一个十分方便的方法检测对象frame是否碰撞。它就是CGRectIntersectsRect。我们只是简单地提交球和球拍的frame给此方法。当球与球拍碰撞时，我们将Y速度反向。下一个if语句也是必需的，因为有时球被向反向移动的球拍“截留”住了而不会移动。因此，我们应保证球速度只当球在球拍前方时反向。（注：NSLog仅用调试）。

&#160;
简单游戏AI
&#160;
下面 ，我们将讨论怎样加入简单的AI，让电脑选手与我们玩iTennis。你们可能知道一个不错的AI设计牵涉了多少工作。我可以不停地介绍数学，哲学，试探法等，但我不会这么做。我只是介绍一种超级菜鸟级的游戏AI。基本上说，电脑将“观察”球并向其方向移动，希望能击打到它。
&#160;
首先，我们需要定义一个常量，它决定了电脑的移动速度。 在iTennisViewController.m顶部加入如下定义：
&#160;
     
&#160;
你测试时，可以调整这个数值。它定义了电脑选手为到达球的位置能移动得多快。这个数值越大，电脑选手将越“强”。如果这个数值足够大的话，那么电脑将不可战胜。现在，在碰撞检测代码后加入以下代码： 
&#160;
     
&#160;
第一个“if”语句是为了给电脑增加点难度，检查球是否处于“它”的半场。如果球不在它的半场，电脑将不会有任何动作。你可以省略这条语句，那就成了另一个有趣的游戏了。下一条“if”语句检查球中心的X与球拍中心的X是否不同。如果球在电脑球拍的右方，电脑球拍的X坐标将增大kCompMoveSpeed。如果球在电脑球拍的左方，电脑球拍的X坐标将减小kCompMoveSpeed。
&#160;
现在应该很清楚kCompMoveSpeed变量是怎样影响电脑的表现了吧&#8230;&#8230;
&#160;
你可以按“Build and Go”来看看游戏的表现吧。你可以看到电脑会做出反应并在大部分时间内击打到球。但为了游戏更有趣，还剩下最后一部分：记分。
&#160;
游戏机制：记分 
&#160;
我们需要一种方式来保存分数。这实际上是一种更简单的碰撞检测。我们将检查球是否碰到后墙。 首先，我们定义几个变量和方法。打开iTennisViewController.h，添加下列高亮的代码：
&#160;
      
&#160;
 我们需要一个代表分数的整数，当电脑和玩家得分时，我们会把分数加上。 另外我们还需要一个“reset”函数，调用它会将球复位到屏幕的中心。我们还需要定义另一个变量。将下面各行加入到iTennisViewController.m的顶部：

&#160;
 
&#160;
这个变量的意思应该很清楚，它定义了需要获胜的分数。为了加快游戏进程，我只是将其赋值为5。下面，我们检查是电脑还是玩家得分。在AI代码后，加入下面代码： 
&#160;
 
&#160;
首先我们看到两条if语句。它们只是检查球是否碰到/超过屏幕的顶部或底部。如果球超过顶部，玩家将得分。如果球超出底部，电脑将得分。如果你是编程新手的话，下面一行可能有些奇怪。我们调用reset函数，但是我们传递的表达式是什么意思？
&#160;
如果你看一下reset的定义，你就会知道，它接受一个代表游戏是否结束的BOOL值。它可以为true或false。我们实际上只是传递true或false给函数。所以，当player_score_value变量小于5时，(player_score_value &#62;= [...]]]></description>
			<content:encoded><![CDATA[<p align="left">今天，我将讨论玩家互动，简单的游戏AI即游戏逻辑。还将探讨一下简单的碰撞检测以便检测到什么时候球碰到球拍。根据大家要求，我还会在教程最后加入一些“挑战”以改进一些更高级的创意。首先打开第一部分的代码&#8230; </p>
<p> <span id="more-126"></span>
<p>&#160;</p>
<h3 align="left"><strong>用户互动</strong></h3>
<p>&#160;</p>
<p align="left">我们首先要实现的是用户互动。我们所需要做的只是将球拍的X位置移动到用户触摸的X位置。这是很简单的方法，我们还可以做得更好（我将这部分挑战放在教程的最后 ）。打开<strong>iTennisViewController.m</strong>加入下面代码：     </p>
<p>&#160;</p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/02/screenshot_01.jpg"><img title="screenshot_01" alt="screenshot_01" src="http://icodeblog.com/wp-content/uploads/2009/02/screenshot_01.jpg" width="442" height="218" /></a></p>
<p align="left"></p>
<p>&#160;</p>
<p> 就像上一篇教程一样，我们要重载<strong>touchesMoved</strong>方法。此方法在用户在屏幕上“拖动”手指时被触发。首先，我在<strong>touchesBegan</strong>中加入“else if”语句，当游戏处于运行状态时简单地将所有事件转发到<strong>touchesMoved</strong>中。<strong>touchesMoved</strong>中前两行是检测用户触屏的位置。接着，我们根据用户触屏X位置及黄色球拍（玩家球拍）Y位置创建 一个新的CGPoint。Objective-C不允许racquet_yellow.center.x = location.x。这可能是因为CGpiont不可改变（不可编辑）。最后，将玩家球拍的中点设置到新的位置。
</p>
<p>&#160;</p>
<h3 align="left"><strong>碰撞检测</strong></h3>
<p>&#160;</p>
<p align="left">*更新, 有读者指出有更简单的碰撞检测方法。将下列代码加入到<strong>iTennisViewController.m</strong> 的gameLoop方法中：     </p>
<p>&#160;</p>
<p> <a href="http://icodeblog.com/wp-content/uploads/2009/02/screenshot_011.jpg"><img title="screenshot_011" alt="screenshot_011" src="http://icodeblog.com/wp-content/uploads/2009/02/screenshot_011.jpg" width="370" height="175" /></a>   </p>
<p>&#160;</p>
<p> 苹果已经提供我们一个十分方便的方法检测对象frame是否碰撞。它就是<strong>CGRectIntersectsRect</strong>。我们只是简单地提交球和球拍的frame给此方法。当球与球拍碰撞时，我们将Y速度反向。下一个if语句也是必需的，因为有时球被向反向移动的球拍“截留”住了而不会移动。因此，我们应保证球速度只当球在球拍前方时反向。（注：NSLog仅用调试）。
</p>
<p>&#160;</p>
<h3 align="left"><strong>简单游戏AI</strong></h3>
<p>&#160;</p>
<p align="left">下面 ，我们将讨论怎样加入简单的AI，让电脑选手与我们玩iTennis。你们可能知道一个不错的AI设计牵涉了多少工作。我可以不停地介绍数学，哲学，试探法等，但我不会这么做。我只是介绍一种超级菜鸟级的游戏AI。基本上说，电脑将“观察”球并向其方向移动，希望能击打到它。</p>
<p>&#160;</p>
<p align="left">首先，我们需要定义一个常量，它决定了电脑的移动速度。 在<strong>iTennisViewController.m</strong>顶部加入如下定义：</p>
<p>&#160;</p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/02/picture-2.png">     <img title="picture-2" alt="picture-2" src="http://icodeblog.com/wp-content/uploads/2009/02/picture-2.png" width="156" height="20" /></a></p>
<p>&#160;</p>
<p>你测试时，可以调整这个数值。它定义了电脑选手为到达球的位置能移动得多快。这个数值越大，电脑选手将越“强”。如果这个数值足够大的话，那么电脑将不可战胜。现在，在碰撞检测代码后加入以下代码： </p>
<p>&#160;</p>
<p><a href="http://www.weebly.com/uploads/3/1/2/4/3124527/iphonegameprogramming-3.jpg"><img alt="http://icodeblog.com/wp-content/uploads/2009/02/picture-3.png" src="http://www.weebly.com/uploads/3/1/2/4/3124527/iphonegameprogramming-3.jpg" /></a>     </p>
<p>&#160;</p>
<p>第一个“if”语句是为了给电脑增加点难度，检查球是否处于“它”的半场。如果球不在它的半场，电脑将不会有任何动作。你可以省略这条语句，那就成了另一个有趣的游戏了。下一条“if”语句检查球中心的X与球拍中心的X是否不同。如果球在电脑球拍的右方，电脑球拍的X坐标将增大<strong>kCompMoveSpeed</strong>。如果球在电脑球拍的左方，电脑球拍的X坐标将减小<strong>kCompMoveSpeed</strong>。</p>
<p>&#160;</p>
<p>现在应该很清楚kCompMoveSpeed变量是怎样影响电脑的表现了吧&#8230;&#8230;</p>
<p>&#160;</p>
<p>你可以按“Build and Go”来看看游戏的表现吧。你可以看到电脑会做出反应并在大部分时间内击打到球。但为了游戏更有趣，还剩下最后一部分：记分。</p>
<p>&#160;</p>
<h3><strong>游戏机制：记分</strong> </h3>
<p>&nbsp;</p>
<p>我们需要一种方式来保存分数。这实际上是一种更简单的碰撞检测。我们将检查球是否碰到后墙。 首先，我们定义几个变量和方法。打开<strong>iTennisViewController.h</strong>，添加下列高亮的代码：</p>
<p>&#160;</p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/02/picture-4.png">     <br /><img title="picture-4" alt="picture-4" src="http://icodeblog.com/wp-content/uploads/2009/02/picture-4.png" width="398" height="450" /></a> </p>
<p>&#160;</p>
<p> 我们需要一个代表分数的整数，当电脑和玩家得分时，我们会把分数加上。 另外我们还需要一个“reset”函数，调用它会将球复位到屏幕的中心。我们还需要定义另一个变量。将下面各行加入到<strong>iTennisViewController.m</strong>的顶部：
</p>
<p>&#160;</p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/02/picture-5.png"><img title="picture-5" alt="picture-5" src="http://icodeblog.com/wp-content/uploads/2009/02/picture-5.png" width="132" height="18" /></a> </p>
<p>&#160;</p>
<p>这个变量的意思应该很清楚，它定义了需要获胜的分数。为了加快游戏进程，我只是将其赋值为5。下面，我们检查是电脑还是玩家得分。在AI代码后，加入下面代码： </p>
<p>&#160;</p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/02/picture-6.png"><img title="picture-6" alt="picture-6" src="http://icodeblog.com/wp-content/uploads/2009/02/picture-6.png" width="346" height="150" /></a> </p>
<p>&#160;</p>
<p>首先我们看到两条if语句。它们只是检查球是否碰到/超过屏幕的顶部或底部。如果球超过顶部，玩家将得分。如果球超出底部，电脑将得分。如果你是编程新手的话，下面一行可能有些奇怪。我们调用reset函数，但是我们传递的表达式是什么意思？</p>
<p>&#160;</p>
<p>如果你看一下reset的定义，你就会知道，它接受一个代表游戏是否结束的BOOL值。它可以为true或false。我们实际上只是传递true或false给函数。所以，当player_score_value变量小于5时，(player_score_value &gt;= kScoreToWin)为false，而当此变量到5时，表达式为true。 </p>
<p>&#160;</p>
<p>我们为什么要这样做？因为这样可以节省好几行代码并降低程序复杂度 。所以我们现在不需要if(player_score_value &gt;= kScoreToWin) ) [self reset:YES]; }else{[self reset:NO];}。明白了吗？</p>
<p>&#160;</p>
<p>下面，我们定义reset函数 。在<strong>iTennisViewController.m</strong>中加入下列代码： </p>
<p>&#160;</p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/02/picture-7.png"><img title="picture-7" alt="picture-7" src="http://icodeblog.com/wp-content/uploads/2009/02/picture-7.png" width="496" height="272" /></a></p>
<p>&#160;</p>
<p>首先我们暂停游戏。暂停游戏使“Tap to Begin”信息显示在屏幕上。然后，我们将球定位到屏幕中心。如果被传递的参数newGame为YES/true，我们需要做几件事。首先，通过比较电脑和玩家分数，我们要检查谁是赢家。然后，更新“tapToBegin”（标签变量）通知用户谁获胜。你也可以加多另一个标签作此用，但我只是循环使用“tapToBegin”标签。最后，因为要开始新游戏，我们将玩家和电脑的分数清零。</p>
<p>&#160;</p>
<p>如果newGame为NO/false，我们只需要复位tapToBegin，显示“Tap to Begin”。这只是为了更改tapToBegin中的信息，以防其还显示着像“Player/Computer wins！”（“玩家/电脑获胜！”）之类的信息。</p>
<p>&#160;</p>
<p>按“Build and Go”与电脑进行一场“史诗般”的iTennis决战吧！源代码在<a href="http://icodeblog.com/wp-content/uploads/2009/02/itennis-21.zip">此</a>下载。</p>
<p>&#160;</p>
<h3><strong>如约，这里有一些挑战</strong></h3>
<p>&#160;</p>
<ul type="disc">
<li>改进用户互动 – 当用户触屏时，球拍并不直接移动到触屏的位置，而是向触屏的方向移动 </li>
<li>改进碰撞检测 – 当球碰到球拍时，使用一些简单的物理学原理使球拍的速度影响球的速度（和方向） </li>
<li>改进AI – 为AI增加一些随机性，使它能尽量“预测”球的运行轨迹 </li>
<li>改进记分系统 &#8211; 使用网球记分 15, 30 , 等&#8230;&#8230; </li>
<li>改进记分系统 &#8211; 你必须赢两分以上 </li>
</ul>
<p>&#160;</p>
<p align="left">请继续关注我们的教程，我将介绍游戏音频，启动画面，“关于&#8230;&#8230;”以及其他部分&#8230;&#8230;.</p>
<p>&#160;</p>
<h5 align="left"><strong>18/02/2009 </strong><strong>原文见：</strong><a title="Permanent Link to iPhone Game Programming Tutorial Part 2- User Interaction, Simple AI, Game Logic" href="http://icodeblog.com/2009/02/18/iphone-game-programming-tutorial-part-2-user-interaction-simple-ai-game-logic/"><strong>iPhone Game Programming Tutorial Part 2- User Interaction, Simple AI, Game Logic</strong></a><strong>&#160;&#160; 翻译：</strong>bagusflyer</h5>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e6%b8%b8%e6%88%8f/iphone%e6%b8%b8%e6%88%8f%e7%bc%96%e7%a8%8b%e6%95%99%e7%a8%8b%e4%b9%8b%e4%ba%8c-%e7%94%a8%e6%88%b7%e4%ba%92%e5%8a%a8%ef%bc%8c%e7%ae%80%e5%8d%95ai%ef%bc%8c%e6%b8%b8%e6%88%8f%e9%80%bb%e8%be%91/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>iPhone游戏编程教程之一</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e6%b8%b8%e6%88%8f/iphone%e6%b8%b8%e6%88%8f%e7%bc%96%e7%a8%8b%e6%95%99%e7%a8%8b%e4%b9%8b%e4%b8%80</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e6%b8%b8%e6%88%8f/iphone%e6%b8%b8%e6%88%8f%e7%bc%96%e7%a8%8b%e6%95%99%e7%a8%8b%e4%b9%8b%e4%b8%80#comments</comments>
		<pubDate>Wed, 14 Jan 2009 16:03:00 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[游戏]]></category>
		<category><![CDATA[教程]]></category>

		<guid isPermaLink="false">http://iphonegeek.zuesitech.com/?p=123</guid>
		<description><![CDATA[这是此系列教程的第一部分，我将从最基本开始教大家怎样编写一个iPhone游戏。众所周知，OpenGL和Quartz的学习不是那么简单的。本教程将简化开发的过程而不会使用这两种技术。我们将使用UIImageView作为图像部分。 


在此教程系列中，我将教大家有关iPhone游戏编程的方方面面。游戏包括图形，音效，游戏逻辑以及简单的电脑AI。 

这是此系列教程的第一部分，我将从最基本开始教大家怎样编写一个iPhone游戏。众所周知，OpenGL和Quartz的学习不是那么简单的。本教程将简化开发的过程而不会使用这两种技术。我们将使用UIImageView作为图像部分。 


在此教程系列中，我将教大家有关iPhone游戏编程的方方面面。游戏包括图形，音效，游戏逻辑以及简单的电脑AI。 

这是此系列教程的第一部分，我将从最基本开始教大家怎样编写一个iPhone游戏。众所周知，OpenGL和Quartz的学习不是那么简单的。本教程将简化开发的过程而不会使用这两种技术。我们将使用UIImageView作为图像部分。 


在此教程系列中，我将教大家有关iPhone游戏编程的方方面面。游戏包括图形，音效，游戏逻辑以及简单的电脑AI。 
这是此系列教程的第一部分，我将从最基本开始教大家怎样编写一个iPhone游戏。众所周知，OpenGL和Quartz的学习不是那么简单的。本教程将简化开发的过程而不会使用这两种技术。我们将使用UIImageView作为图像部分。 


在此教程系列中，我将教大家有关iPhone游戏编程的方方面面。游戏包括图形，音效，游戏逻辑以及简单的电脑AI。]]></description>
			<content:encoded><![CDATA[<p align="left">这是此系列教程的第一部分，我将从最基本开始教大家怎样编写一个iPhone游戏。众所周知，OpenGL和Quartz的学习不是那么简单的。本教程将简化开发的过程而不会使用这两种技术。我们将使用UIImageView作为图像部分。 </p>
<p>&nbsp;</p>
<p align="left">在此教程系列中，我将教大家有关iPhone游戏编程的方方面面。游戏包括图形，音效，游戏逻辑以及简单的电脑AI。 </p>
<p> <span id="more-123"></span>
<p>&nbsp;</p>
<p align="left">我们将编写的游戏叫iTennis。它实际上是一个以网球为主题的乒乓游戏。它将遵循乒乓游戏的所有规则和逻辑。我选择其作为第一个游戏教程是不需要任何特殊动画效果的。如果大家有兴趣，我将在以后的系列中更加深入，介绍一个更加复杂的游戏。下面是游戏的截图：    </p>
<p>&nbsp;</p>
<p align="left"><img border="0" alt="screenshot_011" src="http://icodeblog.com/wp-content/uploads/2009/01/screenshot_011.jpg" width="386" height="742" />    </p>
<p>&nbsp;</p>
<p>下面是项目需要的图像。按图标下载压缩的图像文件。    </p>
<p>&nbsp;</p>
<p align="left"><a href="http://icodeblog.com/wp-content/uploads/2009/01/itennis_images.zip"><img border="0" alt="iTennis_Images.zip" src="http://icodeblog.com/wp-content/uploads/2009/01/packageicon.png" width="123" height="113" /></a></p>
<p>&nbsp;</p>
<p align="left">打开Xcode建立一个View Based应用程序，取名为iTennis。 </p>
<p>&nbsp;</p>
<p align="left"><img border="0" alt="screenshot_01" src="http://icodeblog.com/wp-content/uploads/2009/01/screenshot_01.jpg" width="600" height="442" />    </p>
<p>&nbsp;</p>
<p align="left">加压下载的图像文件，将其拖放到项目下的Resources(资源)文件夹。完成后，资源文件夹应该像这样。 </p>
<p>&nbsp;</p>
<p align="left"><img border="0" alt="screenshot_02" src="http://icodeblog.com/wp-content/uploads/2009/01/screenshot_02.jpg" width="240" height="306" /></a></p>
<p>&nbsp;</p>
<p align="left">&#160;</p>
<p align="left">现在可以开始编写代码了。为了在代码中与我们的图像互动，我们首先需要建立一个IBOutlet链接。我们还需要加入一些游戏变量以便在可以在教程中使用。打开iTennisVeiwController.h加入以下代码： </p>
<p>&nbsp;</p>
<p align="left"><img border="0" alt="screenshot_05" src="http://icodeblog.com/wp-content/uploads/2009/01/screenshot_05.jpg" width="397" height="405" />     </p>
<p>&nbsp;</p>
<p align="left">如你所见，我们有好些IBOutlet。这是因为我们需要与许多对象互动。暂时先忽略ballVelocity和gameState变量。现在，我们可以开始建立我们的用户界面了。双击iTennisViewController.xib在Interface Builder中打开。下面是一个视频介绍怎样建立界面。 </p>
<p>&nbsp;</p>
<div style="text-align: left"> <script type="text/javascript" src="http://icodeblog.com/wp-includes/js/jquery/jquery.js?ver=1.3.2"></script><script type="text/javascript" src="http://icodeblog.com/wp-content/plugins/quicktime-embed/qtobject.js"></script> <script type="text/javascript">
<!--
	var myQTObject = new QTObject("http://icodeblog.com/wp-content/uploads/2009/01/Game_1.mov", "Game_1", "640", "432"); 
	myQTObject.addParam("autostart","false");
	myQTObject.addParam("targetcache","true");
	myQTObject.write();
//--></p>
<p></script><noscript></noscript></div>
</p>
<p>&nbsp;</p>
<p align="left">现在你已经做好了链接，关闭Interface Builder返回Xcode。我们需要设定一些常量。你可以硬编码这些数值，但是将它们定为常量是你在调整游戏架构时更易于改变。打开iTennisViewController.m，加入下列代码。 </p>
<p>&nbsp;</p>
<p align="left"><strong><img border="0" alt="screenshot_06" src="http://www.weebly.com/uploads/3/1/2/4/3124527/iphonegameprogramming-1.jpg" width="511" height="166" /></strong>     </p>
<p>&nbsp;</p>
<p align="left">我们来解释下这些常量的意义。前面两个是游戏的状态。我们用它们来确定屏幕上将显示什么。游戏是暂停？是在运行？还是处于标题画面？以后我们会加入更多的状态。下面两个变量是球运行的速度。由于游戏是2D的，只需要X和Y的速度作为它们的速度矢量。再下面一行（注：应该是@synthesize这一行）是用来自动产生getter和setter方法的变量。</p>
<p>&nbsp;</p>
<p align="left">现在，我们在viewDidLoad方法中加入下列代码： </p>
<p>&nbsp;</p>
<p align="left"><img border="0" alt="screenshot_07" align="textTop" src="http://www.weebly.com/uploads/3/1/2/4/3124527/iphonegameprogramming-2.jpg" width="570" height="126" /></p>
<p>&nbsp;</p>
<p align="left">首先，我们将游戏状态设定为暂停状态。这样在视图被加载后，游戏不会立即开始。接着，我们建立球速向量。调整前面定义的常量，可以使球运行更快或更慢些。最后，创建一个NSTimer的实例。第一个参数是时阶。在此，我们设置为0.05秒。调整此参数可以改变整个游戏的速度。下面一个参数是目标。此参数告诉定时器回调的位置。再下面的参数就是回调的名称了。简单地说，就是通知定时器每隔0.05秒调用一次self.gameLoop。在这里我们不用管userInfo参数。最后一个参数是告诉定时器重复执行。 </p>
<p>&nbsp;</p>
<p align="left">初始化后，我们来创建游戏循环。加入下面代码： </p>
<p>&nbsp;</p>
<p align="left"><img border="0" alt="screenshot_08" src="http://icodeblog.com/wp-content/uploads/2009/01/screenshot_08.jpg" width="609" height="263" />     </p>
<p>&nbsp;</p>
<p align="left">首先我们检查游戏是否处于运行状态（暂停状态时，不需要移动球）。如果游戏没有运行，tabToBegin标签将会被显示出来。我们先前定义的这个标签只是通知用户触动屏幕开始。如果游戏真正运行，我们会根据其速度向量来移动球。下面几行是边界检查。如果球到达屏幕边界，我们就会将其速度方向，这样球就会“来回弹跳”。没有这些代码，球就会飞出屏幕了。
<p>&nbsp;</p>
<p>最后我们还要加入的代码是touchesBegan方法。此方法是在游戏暂停时用来启动游戏的。加入下面代码： </p>
<p>&nbsp;</p>
<p align="left"><img border="0" alt="screenshot_09" src="http://icodeblog.com/wp-content/uploads/2009/01/screenshot_09.jpg" width="409" height="91" />     </p>
<p>&nbsp;</p>
<p align="left">这段代码首先检查游戏是否处于暂停状态。如果是，则隐藏tapToBegin标签并设定游戏为运行状态。游戏将启动。以后，我们将会在此函数中写入玩家球拍控制。 </p>
<p>&nbsp;</p>
<p align="left">最后，作为一个好的iPhone开发者，我们需要清除分配的资源。在dealloc方法中加入下面代码。 </p>
<p>&nbsp;</p>
<p align="left"><img border="0" alt="screenshot_10" src="http://icodeblog.com/wp-content/uploads/2009/01/screenshot_10.jpg" width="184" height="135" /></p>
<p>&nbsp;</p>
<p align="left">游戏开发教程系列第一部分到此结束。有什么问题，请留言。<u><a href="http://icodeblog.com/wp-content/uploads/2009/01/itennis.zip">这里</a></u>下载源码。 </p>
<p align="left">&#160;</p>
<p>&nbsp;</p>
<h5 align="left"><strong>原文出自：</strong><a title="Permanent Link to iPhone Game Programming Tutorial – Part 1" href="http://icodeblog.com/2009/01/15/iphone-game-programming-tutorial-part-1/"><strong>iPhone Game Programming Tutorial – Part 1 </strong></a></h5>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e6%b8%b8%e6%88%8f/iphone%e6%b8%b8%e6%88%8f%e7%bc%96%e7%a8%8b%e6%95%99%e7%a8%8b%e4%b9%8b%e4%b8%80/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
<enclosure url="http://icodeblog.com/wp-content/uploads/2009/01/Game_1.mov" length="14481335" type="video/quicktime" />
		</item>
	</channel>
</rss>

