声明:本文翻译自Box2D C++ tutorial-Setting up (iPhone),仅供学习参考。
简介
这篇文章针对在iOS上使用Box2D和OpenGL进行开发的环境设置问题。既然这跟环境设置话题中使用testbed框架不一样,那么我么也就让这个教程页单独分离出来,但是如果你现在的情况依然是我六个月前提到的情况,那么这篇文章依然对你有用:
- 想用Box2D基于iOS开发物理类游戏
- 比较熟悉C++,并且对于学习Obj-C没有顾虑
- 想在你的游戏中使用OpenGL
- 比起使用cocos2d来说,你更愿意使用自己的代码
- 你从来都没有用过XCode(甚至是Mac)
本篇文章可以作为’绝对的新手’导读,引导大家在XCode工具上使用Box2D创建一个基本的iPhone项目,假设用户对于XCode和Obj-C一无所知。本次将会创建一个正在掉落盒子的场景作为教程的简单例子。
项目仅使用OpenGL ES 1.1,基于XCode 3.2.4以及Box2D 2.1.2.
让项目支持Box2D
本项目创建了OpenGL基本的运行场景,动画方面使用了timer。
从这里下载Box2D源代码,解压到项目文件夹下面或者其它任何你认为方面的地方。
在项目的源代码目录下添加Box2D引擎。
明确一点,引擎的源代码应该包括带有Box2D.h文件的文件夹。
可以方便的创建包含子目录的目录。
添加完之后可以在项目文件中很容易的进行浏览。(cmake文件不是必须的,你可以移除这些。)
试着编译项目。你可能会得到一个找不到有效文件的错误提示,可以从苹果(Apple)的iOS开发者中心获取此文件,这里我们不打算帮你解决这个问题,你需要把编译类型改为模拟器(Simulator)然后再次编译。
呃…试着编译一下,结果可能会显示几千个Box2D的头文件找不到的错误。
对于项目的设置…
…双击’Header Search Paths’(设置search域的’header’为的是更容找到头文件)。
指定Box2D.h头文件的目录。这么做的原因是为了能够像下面这样把Box2D文件包含进来:
#include <Box2D/Box2d,h>
现在应该能够编译成功了。
为OpenGL视图添加Box2D世界
查看一下项目目录树中目录下的ViewContorller.m文件:
-
-(void) awakeFromNib
-
-(void) drawFrame
-
-(void) viewDidUnload
awakeFromNib
当视图加载的时候调用一次。任何只需要加载一次就可以完成的任务都可以放在这里。当前这里创建OpenGL上下文(context)和动画timer。
drawFrame
当程序运行的时候此方法会不停的重复调用以更新视图。帧速可以在startAnimation方法中进行调整。drawFrame方法作为运行循环的一部分,每次循环都会调用,所以不需要另起线程,你不用担心并行问题。
viewDidUnload
当视图关闭的时候此方法被调用,默认情况下项目永远都不会关闭。如果有一个需要加载和卸载场景的更复杂的应用,可以在这个方法中释放任何资源。目前,这个方法只是可怜巴巴的对OpenGL上下文(context)进行了释放。
现在看下目录下的ViewController.h文件
这个类包含OpenGL上下文和一些其它成员变量。具体包括了Box2D头文件并添加了Box2D 中的world指针作为类的成员变量:
这将再次引起大量的错误,因为我们试着把C++代码放到了Obj-C的文件中所以不会顺利的运行。不管怎么说吧,这些错误非常神奇的在乎起把文件的扩展名从.m
文件改为.mm
-如果你想在XCode完成这个操作,可以在Group&Files(??)面板上方便的更改硬盘上的文件名称。你还必须更改目录下的AppDelegate.m文件,因为它包含了viewController头文件。.mm
扩展名意味着可以让C/C++/Obj-C很容易的进行混合编译。
现在我们可以在awakeFromNib方法中添加Box2D世界:
在viewDidUnload进行删除:
使用debug draw 类渲染Box2D世界
既然我不打算使用OpenGL ES 2.0,在app中我也会尽量避免使用,这也不是本篇文章的目的。我经常在awakeFromNib方法的开始的地方进行修改,避免第一次就创建2.0上下文(context),创建1.1上下文很容易:
使用硬编码(bare-bones)来实现,代替drawFrame方法中原来的内容:
既然我们没有在世界中设置debug draw句柄(handler),那我们在这里调用DrawDebugData方法是无用的。如果你只要一个黑屏那正合适,但我想要再多做一点。为了让Box2D世界再OpenGL的视图进行展示,我们需要创建一个b2DebugDraw类的子类,然后用OpenGL ES的方式对其中的方法进行填充。
对于细节的部分可以看debug draw话题,不过,按说对于b2DebugDraw中的每个方法都应该像下面这样进行实现:
作为一个简单的例子而言,类中其它方法的实现就留给读者了。对于本话题中接下来的内容,请假设我们有了一个称为MyDebugDraw的类实现和头文件(既然类实现是用纯C++实现的,所以这里的扩展名可以为.cpp)。
扫尾
现在我们有了一个debug draw类使用,在viewController头文件中我们可以添加:
…在viewController实现文件(.mm)中随后我们可以创建b2World:
我擦依然是黑屏!呃,世界现在还是空的?让我们往里添加一些物体(这一步没什么特别的,添加任何你希望看到的东西进去):
我擦现在出现了一个绿屏!呃,这显示了世界的哪部分呢?你可以在调用DrawDebugData之前添加如下两行代码:
添加完之后你可以看到类似的屏幕…
源代码
你可以从这里下载针对于XCode项目的源代码。