现在的位置: 首页 > 综合 > 正文

[Cocos2d-X 案例]MoonWarriors战神传说 飞行游戏菜单场景(二)

2012年10月29日 ⁄ 综合 ⁄ 共 7623字 ⁄ 字号 评论关闭

菜单场景创建

这次我们先把菜单场景创建好,为了跟MoonWarriors html5进行匹配,我们跟html5的文件名尽量起一样的。
在Classes目录下先创建一个SysMenu的C++文件,这是程序的入口跟菜单选项

接下来就是编辑SysMenu.h文件了

这里需要说一下的就是静态方法scene(),肯定有同学想问了,cocos2d-x类的初始化不都是由create()来创建的吗?为什么这里需要一个静态方法呢?直接create()不就行了,呵呵,因为调用了预编译的方法,所以create()只能在类内部使用,如果想切换场景通过外部类来调用的话,这里就需要包装一下,通过scene()来让外部类调用。好了,看一下我们的SysMenu.cpp
#include "SysMenu.h"
#include "SimpleAudioEngine.h"

using namespace cocos2d;
using namespace CocosDenshion;

//静态方法,方便类外调用
CCScene* SysMenu::scene(){
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::create();

    // 'layer' is an autorelease object
    SysMenu *layer = SysMenu::create();
    
    // add layer as a child to scene
    scene->addChild(layer);
    
    // return the scene
    return scene;
}

bool SysMenu::init(){
    //初始化标记
    bool bRet = false;
    //场景大小
    winSize = CCDirector::sharedDirector()->getWinSize();
    
    //背景图
    CCSprite *sp = CCSprite::create("loading.png");
    //设置锚点(不清楚的同学可以单独查一下setPosition跟setAnchorPoint的区别,这个在cocos2d中还是比较重要的知识点)
    sp->setAnchorPoint(ccp(0, 0));
    this->addChild(sp, 0, 1);
    
    //logo图片
    CCSprite *logo = CCSprite::create("logo.png");
    logo->setAnchorPoint(ccp(0, 0));
    logo->setPosition(ccp(0, 250));
    this->addChild(logo, 10, 1);
    
    //新游戏 菜单
    CCSprite *newGameNormal = CCSprite::create("menu.png", CCRect(0, 0, 126, 33));
    CCSprite *newGameSelected = CCSprite::create("menu.png", CCRect(0, 33, 126, 33));
    CCSprite *newGameDisabled = CCSprite::create("menu.png", CCRect(0, 66, 126, 33));
    
    //设置 菜单
    CCSprite *gameSettingsNormal = CCSprite::create("menu.png", CCRect(126, 0, 126, 33));
    CCSprite *gameSettingsSelected = CCSprite::create("menu.png", CCRect(126, 33, 126, 33));
    CCSprite *gameSettingsDisabled = CCSprite::create("menu.png", CCRect(126, 66, 126, 33));
    
    //关于 菜单
    CCSprite *aboutNormal = CCSprite::create("menu.png", CCRect(252, 0, 126, 33));
    CCSprite *aboutSelected = CCSprite::create("menu.png", CCRect(252, 33, 126, 33));
    CCSprite *aboutDisable = CCSprite::create("menu.png", CCRect(252, 66, 126, 33));
    
    CCMenuItemSprite *newGame = CCMenuItemSprite::create(newGameNormal, newGameSelected, newGameDisabled,this, NULL);
    
    CCMenuItemSprite *gameSettings = CCMenuItemSprite::create(gameSettingsNormal, gameSettingsSelected, gameSettingsDisabled,this, NULL);
    
    CCMenuItemSprite *about = CCMenuItemSprite::create(aboutNormal, aboutSelected, aboutDisable, this, NULL);
    
    CCMenu *menu = CCMenu::create(newGame, gameSettings, about, NULL);
    //每个菜单间隔10px(不知道是像素还是其他单位)
    menu->alignItemsVerticallyWithPadding(10);
    //居中
    menu->setPosition(ccp(winSize.width/2, winSize.height/2-80));
    this->addChild(menu);
    
    bRet = true;
    return bRet;
}

这里面创建了很多精灵类,背景,logo,还有菜单都是精灵类,这里着重要说明的是菜单,CCMenu通过CCMenuItemSprite将CCSprinte一层层包装起来,
这样我们点击的时候就会调用不同的CCSprinte来显示,cocos2d将菜单包装得还是不错的,因为游戏除了界面就是菜单这几种元素。

OK,这里我们就可以跑一下看一下效果了

对了,如果你的屏幕是横向显示的,这就需要你在rootViewController.mm里找到以下代码,将它们改成

意思就是只支持横屏,原来以为cocos2D-x会在程序里支持转屏,但看了一下代码,2.0以后就不支持了,所以建议游戏开发者一开始就设定好游戏是横屏还是竖屏的。
接下来就是创建不停飞行的飞机,这就需要程序不停地刷屏了。
这里在init()方法底部加入
 //创建贴图
    CCTexture2D *tmp = CCTextureCache::sharedTextureCache()->addImage("ship01.png");
    //创建飞船
    _ship = CCSprite::createWithTexture(tmp, CCRect(0, 45, 60, 38));
    //飞船贴图大小
    CCSize shipSize = _ship->getContentSize();
    //随机位置
    CCPoint pos = ccp(CCRANDOM_0_1()*winSize.width, 0);
    _ship->setPosition(pos);
    //运动轨迹,从当前位置向上移动到窗口外
    _ship->runAction(CCMoveTo::create(2.0, ccp(CCRANDOM_0_1()*winSize.width, pos.y + winSize.height + shipSize.height)));
    this->addChild(_ship, 0, 4);
    
    //这里只能调用一次运作,所以如果想让飞机不停地进入界面飞行的话就需要不停的刷新
    //刷新界面
    this->schedule(schedule_selector(SysMenu::update), 0.1);

通过调用update不停地刷新屏幕

void SysMenu::update(){
    //如果飞船飞出窗口,我们就重新定位飞船的位置,重新飞入界面
    if (_ship->getPosition().y > winSize.height) {
        CCPoint pos = ccp(CCRANDOM_0_1()*winSize.width, 10);
        _ship->setPosition(pos);
        _ship->runAction(CCMoveTo::create(floor(CCRANDOM_0_1()*5), ccp(CCRANDOM_0_1()*winSize.width, pos.y + winSize.height)));
    }
}

这样就实现了飞船不停地进行界面飞行的效果。可是有没有感觉坏坏的味道?init()这个方法是不是太大了?我们可以将它进行分解,还有就是图片,我们可以初始的时候一次性加载图片放入贴图缓存,这样就不需要重复加载图片了,还有就是先加载大图,再加载小图(为什么?看这边http://article.ityran.com/archives/2310)因此我们进行重构

新代码如下:
#include "cocos2d.h"

using namespace cocos2d;

class SysMenu:CCLayer {
private:
    //场景大小
    CCSize winSize;
    //飞船精灵,因为菜单中需要飞船运动,所以将飞船设定为全局变量
    CCSprite* _ship;
    CCTexture2D *_texture[10];
    
public:
    //初始化
    virtual bool init();
    //场景
    static CCScene* scene();
    //更新场景
    virtual void update();
    //加入背景
    void addBackground();
    //加入logo
    void addLogo();
    //加入菜单
    void addMenu();
    //加入飞船
    void addShipWithAction();
    //加入背景音乐
    void addMusic();
    
    //调用预编译方法创建create()方法
    CREATE_FUNC(SysMenu);
};

SysMenu.cpp

#include "SysMenu.h"
#include "SimpleAudioEngine.h"

using namespace cocos2d;
using namespace CocosDenshion;

//静态方法,方便类外调用
CCScene* SysMenu::scene(){
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::create();

    // 'layer' is an autorelease object
    SysMenu *layer = SysMenu::create();
    
    // add layer as a child to scene
    scene->addChild(layer);
    
    // return the scene
    return scene;
}

bool SysMenu::init(){
    //初始化标记
    bool bRet = false;
    //场景大小
    winSize = CCDirector::sharedDirector()->getWinSize();
    
    CCTextureCache *textureCache = CCTextureCache::sharedTextureCache();
    _texture[0] = textureCache->addImage("loading.png");
    _texture[1] = textureCache->addImage("logo.png");
    _texture[2] = textureCache->addImage("menu.png");
    _texture[3] = textureCache->addImage("ship01.png");
    
    this->addBackground();
    
    this->addLogo();
    
    this->addMenu();
    
    this->addShipWithAction();
    
    this->addMusic();
    
    //这里只能调用一次运作,所以如果想让飞机不停地进入界面飞行的话就需要不停的刷新
    //刷新界面
    this->schedule(schedule_selector(SysMenu::update), 0.1);
    
    bRet = true;
    return bRet;
}

void SysMenu::update(){
    //如果飞船飞出窗口,我们就重新定位飞船的位置,重新飞入界面
    if (_ship->getPosition().y > winSize.height) {
        CCPoint pos = ccp(CCRANDOM_0_1()*winSize.width, 10);
        _ship->setPosition(pos);
        _ship->runAction(CCMoveTo::create(floor(CCRANDOM_0_1()*5), ccp(CCRANDOM_0_1()*winSize.width, pos.y + winSize.height)));
    }
}

void SysMenu::addBackground(){
    //背景图
    CCSprite *sp = CCSprite::createWithTexture(_texture[0]);
    //设置锚点(不清楚的同学可以单独查一下setPosition跟setAnchorPoint的区别,这个在cocos2d中还是比较重要的知识点)
    sp->setAnchorPoint(ccp(0, 0));
    this->addChild(sp, 0, 1);
}

void SysMenu::addLogo(){
    //logo图片
    CCSprite *logo = CCSprite::createWithTexture(_texture[1]);
    logo->setAnchorPoint(ccp(0, 0));
    logo->setPosition(ccp(0, 250));
    this->addChild(logo, 10, 1);
}

void SysMenu::addMenu(){
    //新游戏 菜单
    CCSprite *newGameNormal = CCSprite::createWithTexture(_texture[2], CCRect(0, 0, 126, 33));
    CCSprite *newGameSelected = CCSprite::createWithTexture(_texture[2], CCRect(0, 33, 126, 33));
    CCSprite *newGameDisabled = CCSprite::createWithTexture(_texture[2], CCRect(0, 66, 126, 33));
    
    //设置 菜单
    CCSprite *gameSettingsNormal = CCSprite::createWithTexture(_texture[2], CCRect(126, 0, 126, 33));
    CCSprite *gameSettingsSelected = CCSprite::createWithTexture(_texture[2], CCRect(126, 33, 126, 33));
    CCSprite *gameSettingsDisabled = CCSprite::createWithTexture(_texture[2], CCRect(126, 66, 126, 33));
    
    //关于 菜单
    CCSprite *aboutNormal = CCSprite::createWithTexture(_texture[2], CCRect(252, 0, 126, 33));
    CCSprite *aboutSelected = CCSprite::createWithTexture(_texture[2], CCRect(252, 33, 126, 33));
    CCSprite *aboutDisable = CCSprite::createWithTexture(_texture[2], CCRect(252, 66, 126, 33));
    
    CCMenuItemSprite *newGame = CCMenuItemSprite::create(newGameNormal, newGameSelected, newGameDisabled,this, NULL);
    
    CCMenuItemSprite *gameSettings = CCMenuItemSprite::create(gameSettingsNormal, gameSettingsSelected, gameSettingsDisabled,this, NULL);
    
    CCMenuItemSprite *about = CCMenuItemSprite::create(aboutNormal, aboutSelected, aboutDisable, this, NULL);
    
    CCMenu *menu = CCMenu::create(newGame, gameSettings, about, NULL);
    //每个菜单间隔10px(不知道是像素还是其他单位)
    menu->alignItemsVerticallyWithPadding(10);
    //居中
    menu->setPosition(ccp(winSize.width/2, winSize.height/2-80));
    this->addChild(menu);
}

void SysMenu::addShipWithAction(){
    //创建飞船
    _ship = CCSprite::createWithTexture(_texture[3], CCRect(0, 45, 60, 38));
    //飞船贴图大小
    CCSize shipSize = _ship->getContentSize();
    //随机位置
    CCPoint pos = ccp(CCRANDOM_0_1()*winSize.width, 0);
    _ship->setPosition(pos);
    //运动轨迹,从当前位置向上移动到窗口外
    _ship->runAction(CCMoveTo::create(2.0, ccp(CCRANDOM_0_1()*winSize.width, pos.y + winSize.height + shipSize.height)));
    this->addChild(_ship, 0, 4);
}

void SysMenu::addMusic(){
    SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(0.7);
    SimpleAudioEngine::sharedEngine()->playBackgroundMusic("mainMainMusic.mp3", true);
}

代码下载


抱歉!评论已关闭.