3D遊戲現在玩起來門檻還是挺高的。不過如果在Cocos2d-x引擎加入3D擴充,實現2.5D遊戲效果又會怎麼樣?
1.概述先上大會現場示範圖:
Apk下載:http://pan.baidu.com/s/1ntM75bV
源碼下載:https://github.com/chukong/EarthWarrior3D.git,給個star不費電。。。
開發環境:Cocos2d-x v3.0 + Sprite3D擴充
適用平台:Mac/iOS/Android
2.Sprite3D擴充2.1. Sprite3Dsprite3D擴充目前可以支援載入靜態obj模型。
auto model = Sprite3D::create("3dmodel.obj", "texture.png");
2.2. Toon ShadingCocos2d-x精靈不能做光暈效果,而Sprite3D中加入了發光函數,指定outline width和color就行了。
model->setOutline(1.5, Color3B(0,0,0)); // 設定發光寬度1.5,黑色
2.3. 3D API
3D API是Cocos2d-x v3.0就具有的屬性,源碼可以到Node上看。
node->setPosition3D(Vertex3F(x,y,z));//設定位置Vertex3F pos = node->getPosition3D();node->setRotation3D(Vertex3F(x,y,z));//設定旋轉Vertex3F rot = node->getRotation3D();
其中Vertex3F當然就是指定了三維空間。而3D API同樣也移植到了一些動作中,比如:
node->runAction(RotateBy::create(Vertex3F(x,y,z)));
完全沒問題。
3.EarthWarriorClasses/3d檔案夾包含了Sprite3D。其餘檔案為遊戲邏輯控制,遊戲總共三個情境
3.1. 主菜單介面(MainMenuScene)包含:主菜單情境(MainMenuScene),飛機模型(Plane),License和Credits層(LicenseLayer)。
關鍵點:①主介面3D飛機的實現
//Plane.cpp_Model = Sprite3D::create("playerv002.obj", "playerv002_256.png");if(_Model){ _Model->setScale(55); ((Sprite3D*)_Model)->setOutline(0.035, Color3B::BLACK); _Model->setRotation3D(Vertex3F(originX,originY,originZ)); this->setRotation3D(Vertex3F(originX, originY, originZ)); this->addChild(_Model); this->scheduleUpdate();}
②對數學感興趣的可以研究一下scheduleUpdate怎樣讓飛機晃啊晃。。。粒子系統這裡就不再重複了。
void Plane::update(float dt){ pRate+=0.01; _Model->setRotation3D(Vertex3F(0-pXA*sin(pXW*pRate),0,0-pZA*sin(pZW*pRate)));}
3.2. 載入介面(LoadingScene)包含:載入情境(LoadingScene),粒子管理器(ParticleManager)
關鍵點:①Loading介面實現資源的預先載入,包括音樂,紋理,粒子效果,其中紋理使用非同步載入,粒子效果在ParticleManager(單例類)中載入。
②同時Loading介面也實現了遊戲元素的預建立並儲存在全域池中,避免遊戲過程中的卡頓現象和反覆create的低效,包括四類敵機和飛彈Missile,在update中實現每幀建立一個,避免LoadingScene的卡頓。
③cocos Logo的旋轉動畫
void LoadingScene::InitCoco(){ Size visibleSize = Director::getInstance()->getVisibleSize(); auto coco = Sprite3D::create("coconut.obj", "coco.png"); if(coco) { coco->setPosition(Point(visibleSize.width/2, visibleSize.height/2-150)); coco->setOutline(10,Color3B(0,0,0)); addChild(coco,1); coco->runAction(RepeatForever::create(RotateBy::create(0.8f,Vertex3F(0,360,0)))); }}
3.3. 遊戲介面(HelloWorldScene)包含:遊戲層(GameLayer),遊戲元素基類(GameEntity),飛機類(AirCraft),玩家類(Player),敵機類(Enemies,又包括Fodder,FodderLeader,BigDude,Boss四類敵機),子彈類(Bullet,又包括PlayerBullet,Missile兩類子彈),效果管理類(EffectManager),爆炸類(Explosion,又包括SmallExplosion,BigExplosion,BulletExplosion),遊戲控制層(GameController,又包括BulletController,EnemyController和GameController),遊戲結束層(GameOverLayer)
關鍵點:①玩家和敵機的子彈控制統一在BulletController::spawnBullet中處理。如上述遊戲元素儲存在全域池中,可回收利用,避免反覆建立,spawnBullet會先從這個池中取出,如果該池為空白才會建立對於的子彈。
②敵機的處理也是採用相同的方式,在EnemyController::spawnEnemy中處理,如果該池為空白才會建立對於的敵機。
③GameLayer::gameMaster管理敵機的出現的頻率。
④GameController::update管理遊戲的碰撞檢測。
除了一些數學上的計算比較羞澀意外,整個遊戲的邏輯還是比較簡單的。。。這裡就不細說了,大家直接看源碼吧。。。
支援原創,原帖地址:http://www.cocoachina.com/bbs/read.php?tid=194900