冠军

导航

Windows Phone 版 Cocos2d-x 程序的结构

我们已经创建了一个 MyGame 的初始应用,这个应用的结构是什么样的呢?

一、应用程序入口

在 cpp-tests 中,app.xaml.cs 是标准的应用程序入口。与普通的 Windows Phone 应用并没有什么不同。

MainPage.xaml 才是我们应用的第一个界面。这是在 Properties 文件中的 WMAppManifest.xml 中定义的。

如果你希望改变第一个界面,到这里将 Navigation Page: 修改为你的新页面就可以了。

MainPage.xaml.cs 中就包含了许多新的内容了。

主要就是一个与 Direct3D 互操作的类

// Direct3DInterop 与 Direct3D 互操作的类
private Direct3DInterop m_d3dInterop = null;

在 private void DrawingSurfaceBackground_Loaded(object sender, RoutedEventArgs e) 中创建了这个对象的实例。

private void DrawingSurfaceBackground_Loaded(object sender, RoutedEventArgs e)
{
    // 是否已经实例化 Direct3DInterop
    if (m_d3dInterop == null)
    {
        PageOrientation pageOrientation = (PageOrientation)GetValue(OrientationProperty);
        DisplayOrientations displayOrientation;

        switch (pageOrientation)
        {
            case PageOrientation.Portrait:
            case PageOrientation.PortraitUp:
                displayOrientation = DisplayOrientations.Portrait;
                break;
            case PageOrientation.PortraitDown:
                displayOrientation = DisplayOrientations.PortraitFlipped;
                break;
            case PageOrientation.Landscape:
            case PageOrientation.LandscapeLeft:
                displayOrientation = DisplayOrientations.Landscape;
                break;
            case PageOrientation.LandscapeRight:
                displayOrientation = DisplayOrientations.LandscapeFlipped;
                break;
            default:
                displayOrientation = DisplayOrientations.Landscape;
                break;
        }
        m_d3dInterop = new Direct3DInterop(displayOrientation);

        // Set WindowBounds to size of DrawingSurface
        m_d3dInterop.WindowBounds = new Windows.Foundation.Size(
            (float)Application.Current.Host.Content.ActualWidth,
            (float)Application.Current.Host.Content.ActualHeight
            );

        // Hook-up native component to DrawingSurfaceBackgroundGrid
        DrawingSurfaceBackground.SetBackgroundContentProvider(m_d3dInterop.CreateContentProvider());
        DrawingSurfaceBackground.SetBackgroundManipulationHandler(m_d3dInterop);

        // Hook-up Cocos2d-x delegates
        m_d3dInterop.SetCocos2dEventDelegate(OnCocos2dEvent);
        m_d3dInterop.SetCocos2dMessageBoxDelegate(OnCocos2dMessageBoxEvent);
        m_d3dInterop.SetCocos2dEditBoxDelegate(OpenEditBox);
    }
}

在这里,你看到 cocos2d 将本地代码与 C# 连接了起来。

在 Direct3DInterop.h 中,定义了一个私有变量 m_render;

private:
    Cocos2dRenderer^ m_renderer;

Direct3DInterop.cpp 中,你会看到如下代码来初始化 CocosdRender 的对象实例。

Direct3DInterop::Direct3DInterop(Windows::Graphics::Display::DisplayOrientations orientation) 
    : mCurrentOrientation(orientation), m_delegate(nullptr)
{
    m_renderer = ref new Cocos2dRenderer(mCurrentOrientation);
}

Cocos2dRender.cpp 也定义在 cpp-testsComponent 中。在这个类的构造函数中,我们可以看到熟悉的 AppDelegate 了。

Cocos2dRenderer::Cocos2dRenderer(Windows::Graphics::Display::DisplayOrientations orientation): mInitialized(false), m_loadingComplete(false), m_delegate(nullptr), m_messageBoxDelegate(nullptr)
{
    mApp = new AppDelegate();
    m_orientation = orientation;
}

而 AppDelegate.cpp 就是我们所熟悉的程序入口。

AppDelegate::AppDelegate() {

}

AppDelegate::~AppDelegate() 
{
}

// 应用开启入口
bool AppDelegate::applicationDidFinishLaunching() {
    // initialize director
    auto director = Director::getInstance();
    auto glview = director->getOpenGLView();
    if(!glview) {
        glview = GLView::create("My Game");
        director->setOpenGLView(glview);
    }

    // turn on display FPS
    director->setDisplayStats(true);

    // set FPS. the default value is 1.0/60 if you don't call this
    director->setAnimationInterval(1.0 / 60);

    // create a scene. it's an autorelease object
    auto scene = HelloWorld::createScene();

    // run
    director->runWithScene(scene);

    return true;
}

// 应用进入停机状态调用的函数
void AppDelegate::applicationDidEnterBackground() {
    Director::getInstance()->stopAnimation();

    // if you use SimpleAudioEngine, it must be pause
    // SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
}

// 当应用从待机恢复
void AppDelegate::applicationWillEnterForeground() {
    Director::getInstance()->startAnimation();

    // if you use SimpleAudioEngine, it must resume here
    // SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
}

在这里通过调用 HelloWorld:createScene() 创建了一个场景。这个方法定义在 HelloWorldScene.cpp 中。

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();
    
    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

在调用 HelloWorld::create 方法的时候,会自动调用类本身的 init 方法来初始化。这个方法是从 CCLayer.cpp 中继承过来的。

Layer *Layer::create()
{
    Layer *ret = new Layer();
    if (ret && ret->init())
    {
        ret->autorelease();
        return ret;
    }
    else
    {
        CC_SAFE_DELETE(ret);
        return nullptr;
    }
}

在 init() 方法中,定义了我们所看到的实际内容。

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    /////////////////////////////
    // 2. add a menu item with "X" image, which is clicked to quit the program
    //    you may modify it.

    // add a "close" icon to exit the progress. it's an autorelease object
    auto closeItem = MenuItemImage::create(
                                           "CloseNormal.png",
                                           "CloseSelected.png",
                                           CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
    
    closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
                                origin.y + closeItem->getContentSize().height/2));

    // create menu, it's an autorelease object
    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Vec2::ZERO);
    this->addChild(menu, 1);

    /////////////////////////////
    // 3. add your codes below...

    // add a label shows "Hello World"
    // create and initialize a label
    
    auto label = LabelTTF::create("Hello World", "Arial", 24);
    
    // position the label on the center of the screen
    label->setPosition(Vec2(origin.x + visibleSize.width/2,
                            origin.y + visibleSize.height - label->getContentSize().height));

    // add the label as a child to this layer
    this->addChild(label, 1);

    // add "HelloWorld" splash screen"
    auto sprite = Sprite::create("HelloWorld.png");

    // position the sprite on the center of the screen
    sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

    // add the sprite as a child to this layer
    this->addChild(sprite, 0);
    
    return true;
}

 最后,让我们加一行代码,将这个图片在 5s 内,放大两倍。

auto action = ScaleTo::create(5.0f, 2.0f);
sprite->runAction(action);

再次运行程序,就会看到,程序启动之后,cocos2d-x 的图片慢慢放大了 2 倍。

调试

如果需要调试的话,需要在 Windows Phone 项目的属性中,配置调试的模式

Native Only 表示可以调试本地代码,也就是 C++ 代码。

Managed Only 表示调试托管代码,也就是我们的 C# 代码。

 

posted on 2014-06-12 23:27  冠军  阅读(1345)  评论(0编辑  收藏  举报