我们已经创建了一个 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# 代码。