Cocos2d-x 2.0.1 运行在MFC中的一种方法

来源:互联网 发布:linux 打开22端口 编辑:程序博客网 时间:2024/05/16 19:40

需要Cocos2d-x运行在MFC中,可能是因为需要直接看配置的效果,也可能是因为打算制作工具。参考网上的一篇文章,实践出本文。

1.打开cocos2d-win32.vc2008.sln,右键新建项目;
2.选择MFC应用程序,工程名为Cocos2dXEdit,路径默认;
3.在下一步中选择“基于对话框”,其余默认;
4.按如下图步好局:

5.右键工程属性,开始如下设置:

1
2
3
4
5
6
7
General→Output Directory:$(SolutionDir)$(ConfigurationName).win32
Debugging→Working Directory:$(ProjectDir)\Resources
C/C++→General→Additional Include Directories:"$(SolutionDir)cocos2dx";"$(SolutionDir)cocos2dx\include";"$(SolutionDir)cocos2dx\kazmath\include";"$(SolutionDir)cocos2dx\platform\win32";"$(SolutionDir)cocos2dx\platform\third_party\win32";"$(SolutionDir)cocos2dx\platform\third_party\win32\OGLES";"$(SolutionDir)";"$(SolutionDir)chipmunk\include\chipmunk";"$(SolutionDir)CocosDenshion\include";
C/C++→Preprocessor→Preprocessor Definitions:WIN32;_DEBUG;_WINDOWS;_USE_MATH_DEFINES;GL_GLEXT_PROTOTYPES;COCOS2D_DEBUG=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS
(Release版)WIN32;NDEBUG;_WINDOWS;_USE_MATH_DEFINES;GL_GLEXT_PROTOTYPES;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS
Linker→General→Additional Library Directories:$(OutDir)
Linker→Input→Additional Dependencies:libcocos2d.lib libCocosDenshion.lib opengl32.lib glew32.lib libBox2d.lib libchipmunk.lib libcurl_imp.lib
6.拷贝HelloWorld示例里的“Classes”、“Resources”文件夹到当前工程目录下,把“Classes”里的文件加到工程中,对“HelloWorldScene.cpp”、“AppDelegate.cpp”文件增加头文件定义“#include "stdafx.h"”,或者去掉这两个文件的预编译选项;

7.在“AppDelegate.h”文件中,添加自定义函数:
1
int runMy();
在“AppDelegate.cpp”文件中,添加如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
static void PVRFrameEnableControlWindow(bool bEnable);

int AppDelegate::runMy()
{
    PVRFrameEnableControlWindow(false);

    // Main message loop:
    MSG msg;
    LARGE_INTEGER nFreq;
    LARGE_INTEGER nLast;
    LARGE_INTEGER nNow;

    QueryPerformanceFrequency(&nFreq);
    QueryPerformanceCounter(&nLast);

    // Initialize instance and cocos2d.
    if (!applicationDidFinishLaunching())
    {
        return 0;
    }

    CCEGLView& mainWnd = CCEGLView::sharedOpenGLView();
    //mainWnd.centerWindow();   // 为了把这句给屏蔽掉
    ShowWindow(mainWnd.getHWnd(), SW_SHOW);

    while (1)
    {
        if (! PeekMessage(&msg, NULL00, PM_REMOVE))
        {
            // Get current time tick.
            QueryPerformanceCounter(&nNow);

            // If it's the time to draw next frame, draw it, else sleep a while.
            if (nNow.QuadPart - nLast.QuadPart > m_nAnimationInterval.QuadPart)
            {
                nLast.QuadPart = nNow.QuadPart;
                CCDirector::sharedDirector()->mainLoop();
            }
            else
            {
                Sleep(0);
            }
            continue;
        }

        if (WM_QUIT == msg.message)
        {
            // Quit message loop.
            break;
        }

        // Deal with windows message.
        if (! m_hAccelTable || ! TranslateAccelerator(msg.hwnd, m_hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}
static void PVRFrameEnableControlWindow(bool bEnable)
{
    HKEY hKey = 0;

    // Open PVRFrame control key, if not exist create it.
    if(ERROR_SUCCESS != RegCreateKeyExW(HKEY_CURRENT_USER,
        L"Software\\Imagination Technologies\\PVRVFRame\\STARTUP\\",
        0,
        0,
        REG_OPTION_NON_VOLATILE,
        KEY_ALL_ACCESS,
        0,
        &hKey,
        NULL))
    {
        return;
    }

    const WCHAR* wszValue = L"hide_gui";
    const WCHAR* wszNewData = (bEnable) ? L"NO" : L"YES";
    WCHAR wszOldData[256] = {0};
    DWORD   dwSize = sizeof(wszOldData);
    LSTATUS status = RegQueryValueExW(hKey, wszValue, 0NULL, (LPBYTE)wszOldData, &dwSize);
    if (ERROR_FILE_NOT_FOUND == status              // the key not exist
        || (ERROR_SUCCESS == status                 // or the hide_gui value is exist
        && 0 != wcscmp(wszNewData, wszOldData)))    // but new data and old data not equal
    {
        dwSize = sizeof(WCHAR) * (wcslen(wszNewData) + 1);
        RegSetValueEx(hKey, wszValue, 0, REG_SZ, (const BYTE *)wszNewData, dwSize);
    }

    RegCloseKey(hKey);
}
8.在“HelloWorldScene.h”文件添加如下:
1
2
3
enum ChildTag{
    kTagMainLayer,
};
在“HelloWorldScene.cpp”文件修改为如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CCScene* HelloWorld::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::create();
    
    // 'layer' is an autorelease object
    HelloWorld *layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer, 0, kTagMainLayer);   //在这里修改

    // return the scene
    return scene;
}
9.从“...\tests\Resources\Images”文件夹中,拷贝“grossini.png”图片到工程的“Resources”文件夹;
10.在“Cocos2dXEditDlg.cpp”文件中,添加如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include "Classes/AppDelegate.h"
#include "Classes/HelloWorldScene.h"
#include "CCEGLView.h"
USING_NS_CC;

// “Open Cocos2d-x”按钮事件
void CCocos2dXEditDlg::OnBnClickedButton1()
{
    GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
    AppDelegate app;
    CCEGLView& eglView = CCEGLView::sharedOpenGLView();
    eglView.setViewName("Hello World");
    eglView.setFrameSize(480320);

    ::SetParent(eglView.getHWnd(), this->GetSafeHwnd());
    SetWindowLong(eglView.getHWnd(), GWL_STYLE, GetWindowLong(eglView.getHWnd(), GWL_STYLE) & ~WS_CAPTION);

    // IDC_STATIC_X为图片控件ID
    CRect rc;
    GetDlgItem(IDC_STATIC_X)->GetWindowRect(&rc);
    ScreenToClient(&rc);
    ::SetWindowPos(eglView.getHWnd(), HWND_TOP, rc.left, rc.top, rc.Width(), rc.Height(), SWP_NOCOPYBITS | SWP_HIDEWINDOW);
    app.runMy();
    // 之后的阻塞
}

// “Create Sprite”按钮事件
void CCocos2dXEditDlg::OnBnClickedButton2()
{
    CCScene* pScene = CCDirector::sharedDirector()->getRunningScene();
    HelloWorld* pLayer = (HelloWorld*)pScene->getChildByTag(kTagMainLayer);
    if (!pLayer)
    {
        return;
    }
    CCSize sz = CCDirector::sharedDirector()->getWinSize();
    CCSprite* pSprite = CCSprite::create("grossini.png");
    pSprite->setPosition(ccp(rand() % (int)sz.width, rand() % (int)sz.height));
    pLayer->addChild(pSprite);
}

// “Exit”按钮事件
void CCocos2dXEditDlg::OnBnClickedCancel()
{
    if (!GetDlgItem(IDC_BUTTON1)->IsWindowEnabled())
    {
        CCDirector::sharedDirector()->end();
        CCDirector::sharedDirector()->mainLoop();
    }
    OnCancel();
}
11.编译运行,如下图所示:




注意:使用本文方法,在关闭MFC窗体后,会出现内存泄露,但也只在关闭的时候才出现,暂时未找到解决的方法。参考文章为《Cocos2d-X 2.0嵌入MFC的子窗体的方法(1.0姐妹篇)》,但是方法有点不同,本文不改动源码,直接把运行Cocos2d-x的窗体附加在对话框上,缺点是不能跟随对话框一起创建。



原创地址:http://blog.csdn.net/akof1314/article/details/8133800