(译)使用cocos2d和box2d制作滚动背景
原文链接地址:http://www.uchidacoonga.com/2011/01/side-scrolling-the-background-in-box2d/
前言:这次我要翻译的两篇教程,其实和大家比较关心的“超级玛利”有关,就是如何使用cocos2d和box2d制作一个带有滚动背景的platform游戏。但是,这两篇教程并没有教大家如何制作超级玛利。但是,一些关键技术点还是有涉及到。相信看完这两篇文章,应该能对大家有所启发。如果哪位朋友有空,能利用本教程制作一个超级玛利游戏,并且分享出来的话,那就太好了。如果能再写一篇教程,那就再好不过了。我在此再给出一些超级玛利的图片资源链接。希望有兴趣的朋友可以尝试一下,有问题大家可以一起探讨一下。
译文:
因为我实在是找不到一个这样的教程,它教您如何使用box2d来制作一个滚动背景,同时把视角固定在玩家身上。所以,我自己来写一个这样的教程。在游戏画面中,玩家几乎总是固定在屏幕的某个地方,但是,背景在移动。所以,你看起来好像就是玩家在游戏世界里面以第一视角在走一样。
如果您对box2d的一些基础知识还不了解的话,建议您先看我翻译的box2d基础教程。
对于这个简单的教程,我将使用Tile Map编辑器来做(因为超级玛利的关卡也是使用TileMap制作的)。如果你对于如何下载和使用TiledMap编辑器不熟悉的话,建议你先看我翻译的关于TiledMap的教程。上图中可以看出,我要制作的地图有2个层。一个是地图层,另外一个是对象层,对象层里面定义了一些对象,用来处理碰撞检测。在这个教程中,我只是简单地画了两个矩形盒子。而本游戏中的地图层完全是空的,没有任何地图信息,大家可以用我提供的超级玛利的图片资源来画一关。然后,在代码里面,我将把对象层里面的对象的位置信息读出来,然后创建相应的box2d对象。下面是添加tiledMap的代码:
- (void) addScrollingBackgroundWithTileMap {tileMapNode = [CCTMXTiledMap tiledMapWithTMXFile:@"scroller.tmx"];tileMapNode.anchorPoint = ccp(0, 0);[self addChild:tileMapNode];}
上面的代码加载“scroller.tmx”,然后把它加载到当前层中,注意要把“scroller.tmx”添加到resource目录下去。如果你去查看CCTMXTiledMap的源码的话,你会看到,那些tiles实际上都被创建成了CCSprite对象。但是,话说回来,我在这个例子中没有使用任何tileset来画地图层,所以你在屏幕上看不到任何东西。接下来的代码是根据对象层中的对象来创建box2d的对象。
- (void) drawCollisionTiles {CCTMXObjectGroup *objects = [tileMapNode objectGroupNamed:@"Collision"];NSMutableDictionary * objPoint; float x, y, w, h; for (objPoint in [objects objects]) {x = [[objPoint valueForKey:@"x"] floatValue];y = [[objPoint valueForKey:@"y"] floatValue];w = [[objPoint valueForKey:@"width"] floatValue];h = [[objPoint valueForKey:@"height"] floatValue]; CGPoint _point=ccp(x+w/2.0f,y+h/2.0f);CGPoint _size=ccp(w,h); [self makeBox2dObjAt:_point withSize:_size dynamic:false rotation:0 friction:0.0f density:0.0f restitution:0 boxId:-1];}}
这里的drawCollisionTiles方法把tileMap中的碰撞矩形读出来,然后位置和长宽信息创建相应的box2d对象。这里需要注意的是,读取坐标点使用的数据类型一定要是float型,否则会出现你在tileMap编辑器中画出来的矩形区域与你程序生成的矩形区域大小不一致的问题!!!大家一定要记住!还有,这里我把friction设置成了0。这会使我们的主角(其它就是个圆)沿着平台滑动。如果你把这个值设置成非0值,比如0.4,那么球会在平台上面滚动。
下面我们看看makeBox2dObjAt方法:
- (void) makeBox2dObjAt:(CGPoint)p withSize:(CGPoint)size dynamic:(BOOL)d rotation:(long)r friction:(long)f density:(long)dens restitution:(long)rest boxId:(int)boxId { // Define the dynamic body.//Set up a 1m squared box in the physics worldb2BodyDef bodyDef;// bodyDef.angle = r; bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO);bodyDef.userData = NULL;//bodyDef.userData = sprite; b2Body *body = world->CreateBody(&bodyDef); // Define another box shape for our dynamic body.b2PolygonShape dynamicBox;dynamicBox.SetAsBox(size.x/2/PTM_RATIO, size.y/2/PTM_RATIO); // Define the dynamic body fixture.b2FixtureDef fixtureDef;fixtureDef.shape = &dynamicBox; fixtureDef.density = dens;fixtureDef.friction = f;fixtureDef.restitution = rest;body->CreateFixture(&fixtureDef);}
上面这个方法负责创建box2d的对象。这是标准的创建box2d对象的方式。
Let’s Continue…
现在,把所有的代码都拿出来吧。。。
-(id) init {if( (self=[super init])) {b2Vec2 gravity = b2Vec2(0.0f, -9.8f);bool doSleep = true;world = new b2World(gravity, doSleep); m_debugDraw = new GLESDebugDraw(PTM_RATIO);world->SetDebugDraw(m_debugDraw);uint32 flags = 0;flags += b2DebugDraw::e_shapeBit;m_debugDraw->SetFlags(flags); [self addScrollingBackgroundWithTileMap];[self drawCollisionTiles]; CCSprite *sprite = [CCSprite spriteWithFile:@"Icon-Small.png"];sprite.position = ccp(100.0f, 180.0f); [self addChild:sprite]; b2BodyDef playerBodyDef;playerBodyDef.type = b2_dynamicBody;playerBodyDef.position.Set(sprite.position.x/PTM_RATIO, sprite.position.y/PTM_RATIO);playerBodyDef.userData = sprite; playerBody = world->CreateBody(&playerBodyDef); b2CircleShape circleShape;circleShape.m_radius = 1.0f; b2FixtureDef fixtureDef;fixtureDef.shape = &circleShape;fixtureDef.density = 1.0f;fixtureDef.friction = 0.0f;fixtureDef.restitution = 0.0f;playerBody->CreateFixture(&fixtureDef); b2Vec2 impulse = b2Vec2(10, 0);playerBody->ApplyLinearImpulse(impulse, playerBody->GetWorldCenter()); [self scheduleUpdate];}return self;}
首先,在上面的代码中,创建了一个box2d world,然后设置了debug draw。为什么要设置debug draw?因为我们的游戏世界里面什么都没有,如果不设置debug draw,你将什么都看不见!而且debug draw可以帮助我们更好地调试box2d。然后调用addScrollingBackgroundWithTileMap和drawCollisionTiles,用来加载tiledMap及创建相应的box2d对象。我们使用cocos2d的log来作为我们的主角精灵。前面已经提到了,它只是一个圆形的body。接下来,我们给它一个冲力。你可以把这个力改大一点,那么主角就会走得更快。
- (void) update:(ccTime)dt {//It is recommended that a fixed time step is used with Box2D for stability//of the simulation, however, we are using a variable time step here.//You need to make an informed choice, the following URL is useful//http://gafferongames.com/game-physics/fix-your-timestep/ int32 velocityIterations = 8;int32 positionIterations = 1; // Instruct the world to perform a single step of simulation. It is// generally best to keep the time step and iterations fixed.world->Step(dt, velocityIterations, positionIterations); //Iterate over the bodies in the physics worldfor (b2Body* b = world->GetBodyList(); b; b = b->GetNext()) {if (b->GetUserData() != NULL) {//Synchronize the AtlasSprites position and rotation with the corresponding bodyCCSprite *myActor = (CCSprite*)b->GetUserData();myActor.position = CGPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO);myActor.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());} } b2Vec2 pos = playerBody->GetPosition();CGPoint newPos = ccp(-1 * pos.x * PTM_RATIO + 50, self.position.y * PTM_RATIO); [self setPosition:newPos];}
接下来,上面的代码是标准的box2d代码,它负责处理box2d世界的仿真。根据body的位置来更新sprite的位置。实际给背景添加滚动的代码,只有最后3行。(说实话,本教程基本上都是知识的回顾。只有这3句话是新的,呵呵)
首先,我们获得玩家在box2d世界中的位置,然后我们需要把它转换成cocos2d的像素值,通过乘以PRM_RATIO。y值还是不变,因为,我们只想让背景在x轴方向变化,就是水平滚动。而屏幕是从右边滚动到左边,所以要乘以-1.而50在这里只是让玩家每次都远离屏幕左边一些。如果你不添加这个50的话,那么玩家每次都会在屏幕的左边。而且是只有半边球会露出来。
Sample Code
这里有本教程的完整源代码。
Happy coding!
转载于:https://www.cnblogs.com/pengyingh/articles/2388852.html
(译)使用cocos2d和box2d制作滚动背景相关推荐
- 按例学construct2_滚动背景制作 (一)
这次有改动的学习一下官方自带的例子. 上图是游戏的截图,后面背景是从右向左滚动的背景,这是这次要实现的第一步. 一.滚动的背景实现原理 1.制作一个无缝的长度是窗口大小一倍的背景图,坐标x=0,y=0 ...
- (译)如何使用box2d来做碰撞检测(且仅用来做碰撞检测)
原文链接地址:http://www.raywenderlich.com/606/how-to-use-box2d-for-just-collision-detection-with-cocos2d-i ...
- DelphiX教程系列 4 - 滚动背景 part 1
用到的组件: (TDXDraw, TDXImageList, TDXSpriteEngine, TDXTimer, TDXInput) 原文链接:http://www.delphigamedev.co ...
- box2d 碰撞检测_(译)如何使用box2d来做碰撞检测(且仅用来做碰撞检测)
免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之人无任何关系.谢谢合作 ...
- html 字幕飘动效果,html 滚动字幕 制作滚动字幕效果 参数
制作滚动字幕效果:marquee标签 如下:<MARQUEE direction=up height=146 οnmοuseοut=start() οnmοuseοver=stop() scro ...
- Expression Design与Blend制作滚动的小球动画教程
原文:Expression Design与Blend制作滚动的小球动画教程 一,开发工具 Microsoft Expression Design & Blend 4.0 (3.0亦可). 这两 ...
- php中如何滚动文字,HTML_网页HTML代码:滚动文字的制作,制作滚动文字
通过本章前面 - phpStudy...
制作滚动文字 通过本章前面的学习,读者已经能够很好地控制各种段落文字的显示方式,不过无论怎么设置,文字都是静态的.本节笔者讲述HTML代码中比较特殊的标签,它能使网页中的文字滚动,并且可以控制其滚动的 ...
- python 滚动字幕_Python pygame绘制文字制作滚动文字过程解析
这篇文章主要介绍了Python pygame绘制文字制作滚动文字过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 字体常用的不是很多,在pyg ...
- html滚动图片代码加文字,HTML代码制作滚动文字
这篇文章主要介绍了关于HTML代码制作滚动文字,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 本节笔者讲述HTML代码中比较特殊的标签,它能使网页中的文字滚动,并且可以控制其滚动的属性 ...
- XNA游戏开发之滚动背景
摘要: 在很多游戏开发中角色的运动都是相对游戏背景而言的,也就是说我们通过移动游戏场景来给游戏角色带来一种运动效果,毕竟我们的游戏视窗是有限的,如果无止境的让角色运动肯定是不可行的,下面我们就一块看一 ...
最新文章
- jQuery学习- 内容选择器
- matlab中ode45如何设置,matlab 中ode45的源代码如何看懂
- spring+hibernate+struts整合(1)
- A-Z排序控件的实现
- php中多选提交如何获取,php中checkbox值获取,显示,多选值获取
- MicroNets:更小更快更好的MicroNet,三大CV任务都秒杀MobileNetV3
- react笔记-设计复合式控件(三)
- 数值分析 python_数值分析python代码
- 蓝桥杯 AGLO-152 算法训练 8-2求完数
- Codeforces Round #334 (Div. 2) A. Uncowed Forces 水题
- Spring boot 2.x+oauth2实现单点登录:基础准备之Spring Security
- 机器学习(8):朴素贝叶斯
- Charles青花瓷安装使用及断点设置
- 解析云产品SLA的价值
- html制作简历供人填写,求职简历制作个人定制代写
- 4-17 定义一个长方形类,定义 求周长和面积的方法,然后定义一个测试类,进行测试。
- install Wine + 迅雷 in Fedora 31
- 家校在线app 页面
- android listview网络图片,Android ListView从网络获取图片及文字显示
- 美国人初学编程代码之三
热门文章
- 各种浏览器开启JavaScript脚本方法
- macos 10.15.2 iso镜像网盘下载
- 一年多开源没进展,我也放弃了
- github库fork后,将更新提交到源库
- JAVA反射性能约慢三个量级
- 现在连U盘都不兼容性了?
- 新版FireFox使用NPAPI插件的办法
- Python安装cv2库出错及解决:Could not find a version that satisfies the requirement cv2
- docker 中文目录及文件乱码_解决docker容器中文乱码,修改docker容器编码格式
- python 密码安全_python密码安全程序