zoukankan      html  css  js  c++  java
  • 解析cocos2d-lua项目中的Hello World

    创建完cocos2d-x的lua项目后。打开项目的Resources目录,找到hello.lua。cocos2d-x的lua项目的測试样例主要就是由这个脚本文件运行的。

    require "AudioEngine" --引入声音引擎文件
    
    -- for CCLuaEngine traceback
    function __G__TRACKBACK__(msg)
        print("----------------------------------------")
        print("LUA ERROR: " .. tostring(msg) .. "
    ")--打印错误信息
        print(debug.traceback())--输出当前运行的traceback信息
        print("----------------------------------------")
    end
    --主函数
    local function main()
        -- avoid memory leak
        -- 避免内存泄露
        --操作垃圾收集器
        collectgarbage("setpause", 100)
        collectgarbage("setstepmul", 5000)
        --定义日志输出函数
        local cclog = function(...)
            print(string.format(...))
        end
        --引入hello2脚本
        require "hello2"
        --调用hello2脚本中的myadd函数
        cclog("result is " .. myadd(3, 5))
    
        ---------------
        --获取屏幕的可视化大小
        local visibleSize = CCDirector:sharedDirector():getVisibleSize()
        --获取可视区域的起点坐标
        local origin = CCDirector:sharedDirector():getVisibleOrigin()
    
        -- add the moving dog
        --创建一个可移动的小狗
        local function creatDog()
            local frameWidth = 105
            local frameHeight = 95
    
            -- create dog animate
            --加入小狗的贴图到内存中
            local textureDog = CCTextureCache:sharedTextureCache():addImage("dog.png")
            --创建截取第一个小狗的精灵帧的矩形
            local rect = CCRectMake(0, 0, frameWidth, frameHeight)
            --创建一个小狗的精灵帧
            local frame0 = CCSpriteFrame:createWithTexture(textureDog, rect)
            --创建截取第二个小狗的精灵帧的矩形
            rect = CCRectMake(frameWidth, 0, frameWidth, frameHeight)
            --创建一个第二个小狗的精灵帧
            local frame1 = CCSpriteFrame:createWithTexture(textureDog, rect)
    
            --以小狗的第一个精灵帧创建一个小狗精灵
            local spriteDog = CCSprite:createWithSpriteFrame(frame0)
            --自己定义一个bool值的属性,标记为false
            spriteDog.isPaused = false
            --设置小狗的位置在 x:0, y:屏幕高度*0.75 处
            spriteDog:setPosition(origin.x, origin.y + visibleSize.height / 4 * 3)
            --创建一个用于存储精灵帧的数组
            local animFrames = CCArray:create()
            --把上面的两个精灵帧加入到数组中
            animFrames:addObject(frame0)
            animFrames:addObject(frame1)
            --以0.5秒的切换速度方式创建一个动画描写叙述
            local animation = CCAnimation:createWithSpriteFrames(animFrames, 0.5)
            --依据上面的动画描写叙述创建一个动画
            local animate = CCAnimate:create(animation);
            --运行该动画
            spriteDog:runAction(CCRepeatForever:create(animate))
    
            -- moving dog at every frame
            --小狗每帧都在移动
            local function tick()
                if spriteDog.isPaused then return end--假设暂停,则返回,不移动
                local x, y = spriteDog:getPosition()--获取小狗的当前位置
                if x > origin.x + visibleSize.width then--假设小狗的移到屏幕外面
                    x = origin.x--重置小狗的位置
                else
                    x = x + 1--每帧往右移动一个像素
                end
                --刷新小狗的最新位置
                spriteDog:setPositionX(x)
            end
            --运行定时器
            CCDirector:sharedDirector():getScheduler():scheduleScriptFunc(tick, 0, false)
            --返回创建的小狗
            return spriteDog
        end
    
        -- create farm
        --创建农田
        local function createLayerFarm()
            --创建一个农场层
            local layerFarm = CCLayer:create()
    
            -- add in farm background
            --创建一个背景精灵
            local bg = CCSprite:create("farm.jpg")
            --设置背景精灵的位置
            bg:setPosition(origin.x + visibleSize.width / 2 + 80, origin.y + visibleSize.height / 2)
            --把背景精灵加入到农场层中
            layerFarm:addChild(bg)
    
            -- add land sprite
            --创建农场精灵
            for i = 0, 3 do
                for j = 0, 1 do
                    local spriteLand = CCSprite:create("land.png")
                    spriteLand:setPosition(200 + j * 180 - i % 2 * 90, 10 + i * 95 / 2)
                    layerFarm:addChild(spriteLand)
                end
            end
    
            -- add crop
            --创建农作物
            local frameCrop = CCSpriteFrame:create("crop.png", CCRectMake(0, 0, 105, 95))
            for i = 0, 3 do
                for j = 0, 1 do
                    local spriteCrop = CCSprite:createWithSpriteFrame(frameCrop);
                    spriteCrop:setPosition(10 + 200 + j * 180 - i % 2 * 90, 30 + 10 + i * 95 / 2)
                    layerFarm:addChild(spriteCrop)
                end
            end
    
            -- add moving dog
            --创建一个会移动的小狗
            local spriteDog = creatDog()
            --将小狗加入到农场层中
            layerFarm:addChild(spriteDog)
    
            -- handing touch events
            --初始化触摸点
            local touchBeginPoint = nil
            --開始点击触摸屏
            local function onTouchBegan(x, y)
                --输出点击位置
                cclog("onTouchBegan: %0.2f, %0.2f", x, y)
                --将点击位置赋给触摸点
                touchBeginPoint = {x = x, y = y}
                --点击时小狗暂停移动
                spriteDog.isPaused = true
                -- CCTOUCHBEGAN event must return true
                return true
            end
            --滑动触摸屏
            local function onTouchMoved(x, y)
                --输出滑动位置
                cclog("onTouchMoved: %0.2f, %0.2f", x, y)
                --假设触摸点不为空
                if touchBeginPoint then
                    --获取农场层的当前位置
                    local cx, cy = layerFarm:getPosition()
                    --移动农场层
                    layerFarm:setPosition(cx + x - touchBeginPoint.x,
                                          cy + y - touchBeginPoint.y)
                    --将滑动的位置赋给触摸点
                    touchBeginPoint = {x = x, y = y}
                end
            end
            --离开触摸屏
            local function onTouchEnded(x, y)
                --输出离开屏幕时的位置
                cclog("onTouchEnded: %0.2f, %0.2f", x, y)
                --删除触摸点
                touchBeginPoint = nil
                --小狗又一次移动
                spriteDog.isPaused = false
            end
            --处理触摸状态
            local function onTouch(eventType, x, y)
                if eventType == "began" then   --点击屏幕状态
                    return onTouchBegan(x, y)
                elseif eventType == "moved" then --滑动屏幕状态
                    return onTouchMoved(x, y)
                else  --离开屏幕状态
                    return onTouchEnded(x, y) 
                end
            end
            --注冊触摸事件
            layerFarm:registerScriptTouchHandler(onTouch)
            --开启触摸
            layerFarm:setTouchEnabled(true)
            --返回农场层
            return layerFarm
        end
    
    
        -- create menu
        --创建菜单
        local function createLayerMenu()
            --创建一个菜单层
            local layerMenu = CCLayer:create()
            --定义三个变量
            local menuPopup, menuTools, effectID
            --运行菜单项的回调函数
            local function menuCallbackClosePopup()
                -- stop test sound effect
                --停止音效的播放
                AudioEngine.stopEffect(effectID)
                --隐藏菜单
                menuPopup:setVisible(false)
            end
            --运行菜单项的回调函数
            local function menuCallbackOpenPopup()
                -- loop test sound effect
                --获取播放音效的路径
                local effectPath = CCFileUtils:sharedFileUtils():fullPathForFilename("effect1.wav")
                --播放音效
                effectID = AudioEngine.playEffect(effectPath)
                --显示菜单
                menuPopup:setVisible(true)
            end
    
            -- add a popup menu
            --创建一个菜单项
            local menuPopupItem = CCMenuItemImage:create("menu2.png", "menu2.png")
            --设置菜单项位置
            menuPopupItem:setPosition(0, 0)
            --设置运行该菜单项所相应的回调函数
            menuPopupItem:registerScriptTapHandler(menuCallbackClosePopup)
            --创建一个菜单
            menuPopup = CCMenu:createWithItem(menuPopupItem)
            --设置菜单位置
            menuPopup:setPosition(origin.x + visibleSize.width / 2, origin.y + visibleSize.height / 2)
            --隐藏菜单
            menuPopup:setVisible(false)
            --将该菜单加入到菜单层
            layerMenu:addChild(menuPopup)
    
            -- add the left-bottom "tools" menu to invoke menuPopup
            --创建一个菜单项
            local menuToolsItem = CCMenuItemImage:create("menu1.png", "menu1.png")
            --设置菜单项位置
            menuToolsItem:setPosition(0, 0)
            --设置运行该菜单项所相应的回调函数
            menuToolsItem:registerScriptTapHandler(menuCallbackOpenPopup)
            --创建一个菜单
            menuTools = CCMenu:createWithItem(menuToolsItem)
            --设置菜单位置
            local itemWidth = menuToolsItem:getContentSize().width
            local itemHeight = menuToolsItem:getContentSize().height
            menuTools:setPosition(origin.x + itemWidth/2, origin.y + itemHeight/2)
            --将该菜单加入到菜单层
            layerMenu:addChild(menuTools)
            --返回菜单层
            return layerMenu
        end
    
        -- play background music, preload effect
    
        -- uncomment below for the BlackBerry version
        -- local bgMusicPath = CCFileUtils:sharedFileUtils():fullPathForFilename("background.ogg")
        --获取背景音乐的文件路径
        local bgMusicPath = CCFileUtils:sharedFileUtils():fullPathForFilename("background.mp3")
        --播放背景音乐
        AudioEngine.playMusic(bgMusicPath, true)
        --获取音效的文件路径
        local effectPath = CCFileUtils:sharedFileUtils():fullPathForFilename("effect1.wav")
        --将音效缓存到内存中
        AudioEngine.preloadEffect(effectPath)
    
        -- run
        --创建一个场景
        local sceneGame = CCScene:create()
        --将农村层加入到该场景中
        sceneGame:addChild(createLayerFarm())
        --将菜单层加入到该场景中
        sceneGame:addChild(createLayerMenu())
        --运行该场景
        CCDirector:sharedDirector():runWithScene(sceneGame)
    end
    --保护模式下调用主函数,并制定错误处理函数句柄__G__TRACKBACK__
    xpcall(main, __G__TRACKBACK__)
    

    而这个脚本是在AppDelegate.cpp中被运行的。里面初始化了cocos2d-x解析lua的引擎。

    bool AppDelegate::applicationDidFinishLaunching()
    {
        // initialize director
        CCDirector *pDirector = CCDirector::sharedDirector();
        pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
    
        // turn on display FPS
        pDirector->setDisplayStats(true);
    
        // set FPS. the default value is 1.0/60 if you don't call this
        pDirector->setAnimationInterval(1.0 / 60);
    
        // register lua engine
    	//初始化lua脚本引擎
        CCLuaEngine* pEngine = CCLuaEngine::defaultEngine();
    	//将lua脚本引擎加入到脚本引擎管理器中
        CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);
    	//取得lua的全局指针,全部的lua函数都须要使用这个指针来做为參数进行调用。  
        CCLuaStack *pStack = pEngine->getLuaStack();
    	//获取lua_State
        lua_State *tolua_s = pStack->getLuaState();
    	//开放扩展函数给lua调用
        tolua_extensions_ccb_open(tolua_s);
    	//假设是ios、android、win32平台则开放WebSocket类给lua调用
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
        pStack = pEngine->getLuaStack();
        tolua_s = pStack->getLuaState();
        tolua_web_socket_open(tolua_s);
    #endif
        
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_BLACKBERRY)//黑莓平台,不清楚
        CCFileUtils::sharedFileUtils()->addSearchPath("script");
    #endif
    	//获取待运行的脚本路径
        std::string path = CCFileUtils::sharedFileUtils()->fullPathForFilename("hello.lua");
    	//运行脚本
        pEngine->executeScriptFile(path.c_str());
    
        return true;
    }

    当中CCLuaEngine是继承自CCScriptEngineProtocl,这个协议定义了lua引擎的功能,当中CCScriptEngineManager用来管理当期的脚本文件(眼下没发现这个管理类有什么用)。

    void CCScriptEngineManager::setScriptEngine(CCScriptEngineProtocol *pScriptEngine)
    {
        removeScriptEngine();//移除上一个的脚本引擎
        m_pScriptEngine = pScriptEngine;//将当前的脚本引擎赋给m_pScriptEngine
    }
    
    void CCScriptEngineManager::removeScriptEngine(void)
    {
        if (m_pScriptEngine)//假设脚本引擎的实例存在,则delete掉
        {
            delete m_pScriptEngine;
            m_pScriptEngine = NULL;
        }
    }


  • 相关阅读:
    混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。
    SQL中获取自增长的最大ID
    (inline)内联函数在IOS开发中的使用
    MS SQL SERVER 2005 高可用性之日志传送
    19_toast通知和notify通知 onTouch事件响应
    20 按比例设置 子控件的宽度和高度
    18_SurfaceView 其他线程绘图
    使用Microsoft Media Service实现网络影音多媒体应用系列第三篇技术要点
    使用Microsoft Media Service实现网络影音多媒体应用系列第二篇开发须知
    MVC3WIN7下的IIS7.5部署MVC3应用程序
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/6859969.html
Copyright © 2011-2022 走看看