write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
讨论新闻组及文件
虽然很早就想用做一个完整游戏来完成此教程,但是在做什么游戏的问题上很纠结,太大太好的游戏太费精力,太小的游戏又不足以展示Orx的特点,选来选去也没有自己感觉最合适的,最后还是选择打砖块吧,此游戏虽然不能展示Orx的全部特点,但是很好的展示了其内嵌物理引擎的特点。因为Orx内嵌Box2D物理引擎,所以在游戏中使用物理,从来没有这么方便过,也许,哪天我该写一篇用Cocos2D+Box2D的类似文章来做比较。
Orx 中的Object概述
在Orx中一个Object到底表示什么?简单的说,表示一切。一切有形的无形的,可见的不可见的东西。在Orx中,所有所有的概念全部归结于 Object。所有其他的东西,都是Object的属性。包括通常概念里面的sprite,animation等等,在Orx中还包括特效(fx),物理属性等。在几乎所有的2D游戏引擎中,几乎都是是Sprite为基础的,而在Orx中,是以Object为基础的。
显示一个 Object
在几乎所有的2D游戏引擎中,几乎都是是Sprite为基础的,所以最基本的操作都是显示一个Sprite,那么,换到Orx中,最基础的那就是显示一个 Object了。
其实,在原来《站在巨人的肩膀上开发游戏(2) -- Orx入门引导及Hello World》中,我们已经显示过一个 Object了,没错,那个Hello World的文字就是一个Object.........只不过其图形是显示文字而已。所以,我们创建Hello World的时候,调用的接口是orxObject_CreateFromConfig。
要将其换成显示图形,只需要改配置,将其显示成一个图形即可,因为是做打砖块游戏,这里,我显示一个球。(这里的资源全部来自于《How To Create A Breakout Game with Box2D and Cocos2D Tutorial》)顺面可以将Orx版本的程序与Cocos2D + Box2D(另外一个我非常喜欢的组合)做比较。
原代码的改动仅出于代码可读性考虑,将HelloWorld改为Ball,Orx的特点之一,不改代码,你甚至可以使用原来编译好的Hello World程序(必须是教程1老的那个,教程2新的那个我做了特殊处理),只需要将新的配置中的Ball改为HelloWorld即可。当然,出于可读性,这样做不自然,但是我还是提及这样做的可能性。
新添加配置如下:
[Ball]
Graphic =BallGraphic
Position =(0.0, 0.0, 0.0) ;球所在的位置
[BallGraphic]
Texture =data/ball.png ;球图形的png文件的位置
Pivot =center
原来的代码如下:
// Init game function
orxSTATUS GameApp::InitGame()
{
orxSTATUS result = orxSTATUS_SUCCESS;
// Creates viewport
if( orxViewport_CreateFromConfig("Viewport") == NULL) {
result = orxSTATUS_FAILURE;
}
if(orxObject_CreateFromConfig("Ball") == NULL) {
result = orxSTATUS_FAILURE;
}
// Done!
returnresult;
}
然后,就能显示出个球了。(显示个球-_-!)
就这么一个Object显示出来以后,就可以继续自由发挥了,很多的想象空间。
比如Scale = XXX调整球的大小。
比如Speed = (xxx, xxx, xxx) 给球初始速度,
(上面的属性都添加到 [Ball]段)
按照上面的方法,按打砖块游戏的特点,添加砖块及paddle。
配置:
[Ball]
Graphic =BallGraphic
Position =(0.0, 180.0, 0.0)
[BallGraphic]
Texture =data/ball.png
Pivot =center
[Paddle]
Graphic =PaddleGraphic
Position =(0.0, 230.0, 0.0)
[PaddleGraphic]
Texture =data/paddle.png
Pivot =center
[Blocks]
ChildList =Block1 # Block2 # Block3 # Block4
[Block1]
Graphic =BlockGraphic
Position =(-50.0, -30.0, 0.0)
[Block2]
Graphic =BlockGraphic
Position =(50.0, -30.0, 0.0)
[Block3]
Graphic =BlockGraphic
Position =(-50.0, 30.0, 0.0)
[Block4]
Graphic =BlockGraphic
Position =(50.0, 30.0, 0.0)
[BlockGraphic]
Texture =data/block.png
Pivot =center
代码:
// Init game function
orxSTATUS GameApp::InitGame()
{
orxSTATUS result = orxSTATUS_SUCCESS;
// Creates viewport
if( orxViewport_CreateFromConfig("Viewport") == NULL) {
result = orxSTATUS_FAILURE;
}
if(orxObject_CreateFromConfig("Ball") == NULL) {
result = orxSTATUS_FAILURE;
}
if(orxObject_CreateFromConfig("Paddle") == NULL) {
result = orxSTATUS_FAILURE;
}
if(orxObject_CreateFromConfig("Blocks") == NULL) {
result = orxSTATUS_FAILURE;
}
// Done!
returnresult;
}
代码实在就是没有太多好说的了,在Orx中,永远是配置复杂,代码简单。说说配置中的新东西,我在这里用
[Blocks]
ChildList =Block1 # Block2 # Block3 # Block4
的形式+一行创建Blocks的代码,来完成了4个砖块的创建。这是Orx中使用子列表的一种方式。
效果如下:(我把窗口大小也改了)
是不是有那么一点意思了?
到目前为止,我们学到什么了?4行配置。。。。。。。。。。且只有Graphic加Texture算是新内容。只要这些,你通过position就可以完成你想要的任何图形布局了。
当然,其实远远不止这些,请参考Orx的WIKI获取更多的信息:
物理的加入
好了,现在是添加真的游戏内容的时候了。光是静态图形可做不了游戏。
在打砖块的游戏中,很重要的就是球的碰撞,反弹,以及碰撞的检测了。由于Orx中内嵌了Box2D引擎,我们能够很方便的使用,我多次提到是内嵌,而不是外挂,不是如Cocos2D那种仅仅包含一个Box2D,然后需要你调用Box2D的API去完成的那种,事实上,你可以根本不知道Box2D是啥。(其实个人感觉,了解Box2D的相关概念是必要的,不然怎么知道各个属性应该怎么配置啊)
首先,物理世界的加入:
[Physics]
DimensionRatio =0.1
WorldLowerBound =(-300.0, -300.0, 0.0)
WorldUpperBound =(300.0, 300.0, 0.0)
这是必须的,似乎属于Box2D为了优化而添加的,Orx为了灵活,没有自动的去配置这些属性,一般而言,将其设为包含整个游戏屏幕即可。(稍微大一点点)配置的是一个矩形的左上角和右下角。(注意Orx的坐标系啊)
然后,为各个物体添加物理属性,最主要的是Body段的属性:
[Ball]
Graphic =BallGraphic
Body =BallBody
Speed =(0, -40, 0)
Position =(0.0, 180.0, 0.0)
[BallGraphic]
Texture =data/ball.png
Pivot =center
[BallBody]
Dynamic =true
PartList =BallPartTemplate
[BallPartTemplate]
Type =sphere;
Friction =0.0;
Restitution =1.0;
Density =1.0;
SelfFlags =0x0001;
CheckMask =0x0001;
Solid =true;
注意Ball的中添加了一个Body =BallBody,然后所有的物理部分都写在了BallBody和BallPartTemplate中。先说明一下,之所以我把part叫template,而且Orx的作者添加了这样一个新的段来表示物理部分,包括命名为part,是因为Orx允许一个body有多个part组合成一个object的物理。这在某些时候也极为有用。比如希望有个组合图形,一个part无法表示的时候。
至于各个物理的属性的含义,推荐先去了解一下Box2D 的各个定义。要图省事,看看Orx的说明也行。
然后,如法炮制,基本的意思就有了。
[Paddle]
Graphic =PaddleGraphic
Body =PaddleBody
Position =(0.0, 230.0, 0.0)
[PaddleGraphic]
Texture =data/paddle.png
Pivot =center
[PaddleBody]
Dynamic =false
PartList =PaddlePartTemplate
[PaddlePartTemplate]
Type =box;
Friction =0.0;
Restitution =1.0;
Density =1.0;
SelfFlags =0x0001;
CheckMask =0x0001;
Solid =true;
[Blocks]
ChildList =Block1 # Block2 # Block3 # Block4
[Block1]
Graphic =BlockGraphic
Body =BlockBody
Position =(-50.0, -30.0, 0.0)
[Block2]
Graphic =BlockGraphic
Body =BlockBody
Position =(50.0, -30.0, 0.0)
[Block3]
Graphic =BlockGraphic
Body =BlockBody
Position =(-50.0, 30.0, 0.0)
[Block4]
Graphic =BlockGraphic
Body =BlockBody
Position =(50.0, 30.0, 0.0)
[BlockGraphic]
Texture =data/block.png
Pivot =center
[BlockBody]
Dynamic =false
PartList =BlockPartTemplate
[BlockPartTemplate]
Type =box;
Friction =0.0;
Restitution =1.0;
Density =1.0;
SelfFlags =0x0001;
CheckMask =0x0001;
Solid =true;
特别需要注意的是,Orx的设计上常常会让人感觉很多时候一个段的东西拆了几个段,写起来很麻烦,但是每个段都是可以复用的,比如此例中,所有的Block都共用一个Body。所以作者从长远考虑才这样做。
然后,再给Ball 一个速度。你就能够看到物理的作用了。球从paddle反弹到block再反弹到paddle。带角度。。。。。。。。。
碰撞检测
打砖块的游戏要求球碰到砖块时砖块消失的,这个需要做碰撞检测,这在Orx中也是很简单的,需要进行物理的Event响应,这是个新内容。
首先,初始化的时候,添加关注的事件。
orxEvent_AddHandler(orxEVENT_TYPE_PHYSICS, GameApp::EventHandler);
这个没有什么好说的,别忘了就行。
然后,就是在注册函数中物理的响应了,此例中是GameApp::EventHandler。
// Event handler
orxSTATUS orxFASTCALL GameApp::EventHandler(constorxEVENT *_pstEvent)
{
orxSTATUS eResult = orxSTATUS_SUCCESS;
if(_pstEvent->eType == orxEVENT_TYPE_PHYSICS) {
if( _pstEvent->eID == orxPHYSICS_EVENT_CONTACT_ADD ) {
/*Gets colliding objects */
orxOBJECT *object_recipient = orxOBJECT(_pstEvent->hRecipient);
orxOBJECT *object_sender = orxOBJECT(_pstEvent->hSender);
string recipient_name(orxObject_GetName(object_recipient));
string sender_name(orxObject_GetName(object_sender));
if(recipient_name == "Ball"&& sender_name != "Paddle") {
orxObject_Delete(object_sender);
}
}
}
// Done!
returnorxSTATUS_SUCCESS;
}
有了代码后,其实基本上意思都很明显了,先判断事件的类型,然后判断事件的ID(其实相当于某类型事件中的子类型),这里判断的是物理的contact_add,表示有碰撞(外国人喜欢说有接触?)产生的时候。然后通过名字去判断两个物体是什么。这里没有考虑效率,直接用名字来判断了(事实上可以通过设定 userdate,然后通过ID判断),再进一步,为了方面直接用std::string而没有通过strcmp了。
判断被推开的物体是球,而且还不是paddle推开的,那么就肯定是block了,此时用orxObject_Delete将其删除,实现打砖块的消除效果。
需要完善的部分
游戏其实基本成型了,剩下的,就是给游戏加个边框,(这个都不需要我额外讲方法了)不然球飞出去了,然后就是操作部分了,下一节再讲。
原创文章作者保留版权 转载请注明原作者 并给出链接
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
分享到:
相关推荐
- 卓越商企服务定位于中高端市场,其管理的大部分商务物业位于核心城市的中心地带,这使得其出租率保持在一个较高的水平。 - 公司采用大客户业务模式,约60%的第三方外拓项目都基于大客户,这些大客户主要是科技型...
本教程资源"ios-站在巨人的肩膀上-scrollView联动.zip"可能包含了一个名为"XYSlideMenu"的示例项目,旨在帮助开发者理解并实现ScrollView的联动效果。 ScrollView联动的核心是通过监听ScrollView的滚动事件,将滚动...
八年级物理全册1.3站在巨人的肩膀上我国的四大发明素材新版沪科.doc
《奔跑吧巨人》是一款基于Cocos游戏引擎开发的小游戏,其源码的公开为我们提供了一个深入了解小游戏开发的宝贵机会。Cocos是一个广泛应用于2D游戏开发的开源框架,以其高效、易用和跨平台的特性受到开发者们的青睐。...
Cocos Creator 3作为Cocos系列的最新版本,不仅在2D游戏开发上表现出色,还扩展了对3D游戏的支持,使其成为开发跨平台游戏的强大工具。 1. **Cocos Creator 3引擎**: Cocos Creator 3是Cocos Studio的进化版,它...
标题中的"9巨人的花园----第二课时.ppt"似乎是指一个教育材料或者课程,可能是一堂关于文学、故事分析或是情感理解的课。这个标题是《巨人的花园》的第二部分,通常这类课程会深入探讨故事的细节,包括角色的发展、...
本项目“站在巨人肩膀上制作的异步非阻塞IM”是一个基于Java语言实现的高效通信平台,它巧妙地利用了现有的开源技术和工具,以解决大规模并发下的高性能通信问题。以下将详细阐述这个项目中的关键知识点。 首先,...
本项目“站在巨人肩膀上制作了异步非阻塞的IM”充分利用了Java的优势,构建了一个高效、灵活的多协议通讯解决方案。 首先,异步非阻塞编程模型是现代高性能网络应用的核心。传统的同步阻塞模型在处理高并发时容易...
本报告聚焦于保险行业的“御繁归简”系列,特别关注再保险领域,将其比喻为站在直保市场背后的巨人。随着保险行业向保障型业务转型,再保险的需求逐渐显现。报告指出,人身险销售模式从单一产品转向“1+N”组合,...
绿洲APP产品分析报告:站在巨人肩膀上能否看得更远?.pdf
站在巨人的肩膀上:分层设计在 Nervos 生态系统中的 layer 2区块链上的实际应用-SACC2021年中国系统架构师大会
这篇报告的标题“小米集团,站在“巨人们”的肩膀上看世界-家用电器行业-20180507-国盛证券-59页”揭示了报告的主要内容,即小米集团在2018年5月7日时在家用电器行业的战略定位和发展情况。报告由国盛证券发布,通常...
站在巨人的肩膀上,_迁移学习_Transfer_Learning
【标题】中的“站在巨人的肩膀上的项目,感谢zhile大佬的Pandora-Next项目”表明这是一个基于他人开源项目进行开发或改进的项目。这里的“Pandora-Next”可能是一个由用户“zhile”创建的开源项目,它很可能在Python...
报告指出,传统的α策略通常以宽基指数作为基准进行指数增强,但这里提出了一种新的方法,即以组合收益在主动股票投资基金中的排名作为业绩目标。 报告作者吴先兴和缪铃凯通过研究发现,普通股票型基金指数(885000...
【构建公有云平台上的容器服务】的主题由俞圆圆(Y3)提出,她是UCloud基础云产品中心的总监,有着丰富的实践经验,曾在Microsoft Windows Azure和Amazon AWS EC2任职,专注于大规模分布式系统、面向服务架构、TCP/IP...
在C++编程中,错误处理是一项至关重要的任务,因为它们能帮助我们发现并修复程序中的问题,从而提高软件的质量和稳定性。...记住,每一次错误都是学习的机会,站在前人的经验上,我们可以走得更远。
资源描述让你站在HTML巨人的肩膀上,制作非常酷炫的HTML前端web幻灯片。通过使用资源描述,你可以轻松地添加各种动画效果,使你的网页更加生动有趣。无论是淡入淡出、滑动、旋转还是缩放,你都可以通过资源描述实现...