用cocos2d-x 自制flappy bird
最近学习了一些cocos2d-x的知识,虽说只是的初学者,但还是忍不住开始实践一下,在网上找了点制作flappybird的资料,就照猫画虎的做了起来,不幸的是我找的资料已经太旧了,都是3.0以前的版本,虽说都是一个cocos2d-x的引擎,但对于像我这样又蠢又呆的人来说,就跟没找到资料一样,我现在用的是3.8的版本,因为我并没有找到早先的版本,所以索性就下一个当前最新的版本,cocos2d-x是我接触的第一个引擎,之前从没有弄过这东西,冷不丁的还真有些不适应呢。 好了,说了一大堆的废话,主要是为了多写点字数,不要骂我哈,我在这方面是有强迫症的,嘻嘻。下面我们开始进入主题吧。 步骤一准备工作 在开始打代码之前,我需要整理一些图片资源,用TexturePackers或其他的工具做成纹理集,主要为了节约内存,这一点如果不懂,请自行百度,其实还应该准备一点音效的,但是我很懒,没有下载音效,so.........,大家都懂。 步骤二打!代!码! 岁月如歌,时光匆匆,时间过的很快,做完了第一步,我们就开始搞游戏制作中核心的步骤吧,首先我们要数清楚flappybird里需要的精灵数,来,让我们回忆一下玩flappybird的时光,那一年我18她17,我未取她未嫁。。。。,不好意思,思路又跑偏了, 现在正式回想一下,这款游戏中有一个鸟一块地,还有若干的水管,因为水管都长得一 样,只有方向不同,所以我姑且把他算两个(上水管和下水管),有了这些概念,我们接 下来的编程会顺畅很多,flappybird是一个一物理引擎为主的游戏,我们要给予这个世 界一个塑造物理的能力,我们要自定义一个initPhysics()函数,在里面初始化物理 世界 voidHelloWorld::initPhysics() { b2Vec2gravity; gravity.Set(0.0f,-10.0f);//设置x,y方向的重力 world=newb2World(gravity); world->SetAllowSleeping(true); world->SetContinuousPhysics(true); world->SetContactListener(this);//设置监听碰撞事件 } 接下来我们要先给这个物理世一个可也任人踩踏的大地,我们将此函数叫addground() HelloWorld::addground() { autoground=Sprite::createWithSpriteFrameName("ground.png"); Sizesize=ground->getContentSize(); ground->setPosition(size.width/2,size.height/2); b2BodyDefbodydef; bodydef.type=b2_staticBody; bodydef.position=b2Vec2(size.width/2/RATIO,size.height/2/RATIO); b2PolygonShapeshape; shape.SetAsBox(size.width/2/b2FixtureDeffixdef; fixdef.shape=&shape; autobody=world->CreateBody(&bodydef); body->CreateFixture(&fixdef); ground->setUserData(body); this->addChild(ground,100); } 有了大地之后,我就可以让鸟随意的踩踏他了,所以我要往上边加一个鸟儿了函数名为addbird HelloWorld::addbird() { H_bird="bird.png"); H_bird->setPosition(visibleSize.width/2,visibleSize.height/2); this->addChild(H_bird); Sizesize=H_bird->getContentSize(); b2_dynamicBody; bodydef.position=b2Vec2(visibleSize.width/2/RATIO); body=world->CreateBody(&bodydef); b2FixtureDefbirdfixturedef; birdfixturedef.shape=&shape; body->CreateFixture(&birdfixturedef); body->SetUserData(H_bird); } 现在虽然把鸟加上去了,但是我的鸟儿还不能适应这个物理世界,只能傻傻的呆在原地不动, 要想让他动起来,我就得时时刻刻的刷新他的body位置,body在哪他就得在哪,不能像丢了魂一样。最好的方法就是在update()里做了 上代码 HelloWorld::update(floatdt) { world->Step(dt,8,1); for(b2Body*b=world->GetBodyList();b!=nullptr;b=b->GetNext()) { if(b->GetUserData()!=nullptr){ Sprite*sprite=(Sprite*)b->GetUserData(); sprite->setPosition(Vec2(b->GetPosition().x* RATIO)); sprite->setRotation(-1*CC_RADIANS_TO_DEGREES(b->GetAngle())); } } } 好了,现在鸟就可像真实的鸟一样的飞了,接下来就该往上边放破水管了,水管是横向运动的,所以他在横向上是有在速度的,并且他是成对出现的,并并且他们是有时间间隔成对出现的,所以 可定要用到schedule函数了, HelloWorld::addbar(t) { floatoffset=-rand()%5; //down autodown="down_bar.png"); down->setPosition(Vec2(visibleSize.width+2*RATIO)); Sizesize=down->getContentSize(); b2_kinematicBody; bodydef.position=b2Vec2(visibleSize.width/RATIO+2,size.height/RATIO/2+offset); b2Vec2a; a.Set(-5.0f,0.0f); bodydef.linearVelocity=a; b2Body*downbody=world->CreateBody(&bodydef); RATIO); b2FixtureDeffixtexdef; fixtexdef.shape=&shape; downbody->CreateFixture(&fixtexdef); downbody->SetUserData(down); this->addChild(down,2); //up autoup="up_bar.png"); up->setPosition(RATIO+2*Sizeupsize=up->getContentSize(); b2BodyDefupbodydef; upbodydef.type=b2_kinematicBody; upbodydef.position=RATIO + upsize.height/2/RATIO + 2 + offset/RATIO ); upbodydef.linearVelocity=a; b2Body*upbody=world->CreateBody(&upbodydef); b2PolygonShapeupshape; upshape.SetAsBox(size.width/2/b2FixtureDefupfixtexdef; upfixtexdef.shape=&upshape; upbody->CreateFixture(&upfixtexdef); upbody->SetUserData(up); this->addChild(up,2); score++; charchara[10]; charendc[20]="score:"; sprintf(chara,"%d",score-1); strcat(endc,chara); scorelabel->setString(endc); } 好了,该放的都放了,接下来就开始执行游戏法规了,不允许小鸟碰到任何精灵,那自然就得用到检测碰撞的东西了,让我们的类在继承一个b2ContactListener类,这样我们的类就有自己的检测事件了,好了上代码
HelloWorld::BeginContact(b2Contact*contact) { autoSpriteA=contact->GetFixtureA()->GetBody()->GetUserData();; autoSpriteB=contact->GetFixtureB()->GetBody()->GetUserData(); if(SpriteA==H_bird||SpriteB==H_bird) { stop(); } } 写到这,这款游戏基本上就已经接近成功了,后期的完善与优化,就看个人发挥喽。 完整代码请参照http://download.csdn.net/detail/w1143408997/9158581 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |