前言
我们知道,cocos2dx 中屏幕适配的设置方法是
- Director::getInstance()->getOpenGLView()->setDesignResolutionSize(960,640,kResolutionShowAll);
为了保持我们的游戏不被拉伸,选择showAll方法。但是有一个问题,showAll会留黑边,那么我们只需要在openGL中渲染黑边即可。这样黑边就会被填充为我们自己设置的图片。话不多说,看看下面的代码。
MainScene.lua
调用示例如下,只需要在onEnter里面渲染即可
- function MainScene:onEnter()
- local function createSpriteWithPathPosScale(path,pos)
- local sprite = cc.Sprite:create(path)
- sprite : setAnchorPoint(cc.p(0.5,0.5))
- sprite : setPosition(pos)
- return sprite
- end
- local frameSize = cc.Director:getInstance() : getOpenGLView() : getFrameSize()
- local layer = cp.ScreenMatchLayer : create()
- layer:retain()
- local sprite = createSpriteWithPathPosScale("ui_img_left.jpg",cc.p(-44,320))
- layer : getChildByName("_node") : addChild(sprite)
- sprite = createSpriteWithPathPosScale("ui_img_right.jpg",cc.p(960 + 44,320))
- layer : getChildByName("_node") : addChild(sprite)
- sprite = createSpriteWithPathPosScale("ui_img_top.jpg",cc.p(480,640 + 32.5))
- layer : getChildByName("_node") : addChild(sprite)
- sprite = createSpriteWithPathPosScale("ui_img_down.jpg",-32.5))
- layer : getChildByName("_node") : addChild(sprite)
- end
AppDelegate.cpp
这里面对ScreenMatchLayer进行注册以便被lua调用
- bool AppDelegate::applicationDidFinishLaunching()
- {
- // set default FPS
- Director::getInstance()->setAnimationInterval(1.0 / 60.0f);
- // register lua module
- auto engine = LuaEngine::getInstance();
- ScriptEngineManager::getInstance()->setScriptEngine(engine);
- lua_State* L = engine->getLuaStack()->getLuaState();
- lua_module_register(L);
- ScreenMatchLayer::lua_bind_AllFunction(L);
- // If you want to use Quick-Cocos2d-X,please uncomment below code
- // register_all_quick_manual(L);
- LuaStack* stack = engine->getLuaStack();
- stack->setXXTEAKeyAndSign("2dxLua",strlen("2dxLua"),"XXTEA",strlen("XXTEA"));
- //register custom function
- //LuaStack* stack = engine->getLuaStack();
- //register_custom_function(stack->getLuaState());
- #if (COCOS2D_DEBUG > 0) && (CC_CODE_IDE_DEBUG_SUPPORT > 0)
- // NOTE:Please don't remove this call if you want to debug with Cocos Code IDE
- RuntimeEngine::getInstance()->start();
- cocos2d::log("iShow!");
- #else
- if (engine->executeScriptFile("src/main.lua"))
- {
- return false;
- }
- #endif
- return true;
- }
ScreenMatchLayer.h
- #ifndef __SCREENMATCHLAYER_H__
- #define __SCREENMATCHLAYER_H__
- #include "cocos2d.h"
- namespace cocos2d{
- class ScreenMatchLayer : public Layer
- {
- public:
- ScreenMatchLayer(void);
- ~ScreenMatchLayer(void);
- static ScreenMatchLayer* create();
- bool init();
- void visit(Renderer *renderer,const Mat4& parentTransform,uint32_t parentFlags);
- void onBeforeVisit();
- void onAfterVisit();
- static int lua_bind_AllFunction(lua_State* tolua_S);
- static const std::string classPrefix;
- static const std::string fullName;
- static const std::string className;
- private:
- Node* _node;
- CustomCommand _beforeVisit;
- CustomCommand _afterVisit;
- };
- }
- int lua_cocos2dx_ScreenMatchLayer_create(lua_State* tolua_S);
- #endif
ScreenMatchLayer.cpp
- #include "ScreenMatchLayer.h"
- #include "tolua_fix.h"
- #include "LuaBasicConversions.h"
- using namespace cocos2d;
- const std::string ScreenMatchLayer::classPrefix = "cp";
- const std::string ScreenMatchLayer::className = "ScreenMatchLayer";
- const std::string ScreenMatchLayer::fullName = classPrefix + "." + className;
- ScreenMatchLayer::ScreenMatchLayer(void)
- {
- }
- ScreenMatchLayer::~ScreenMatchLayer(void)
- {
- }
- bool ScreenMatchLayer::init()
- {
- if ( !Layer::init() ) {
- return false;
- }
- _node = Node::create();
- _node->setName("_node");
- _node->setAnchorPoint(ccp(0,0));
- addChild(_node);
- GLView* openGLView = this->_director->getOpenGLView();
- Size frameSize = openGLView->getFrameSize();
- Size designSize = Size(960,640);
- Size nodeSize = Size(0,0);
- bool frameSizeWidthLarger = (designSize.width / designSize.height) < (frameSize.width / frameSize.height );
- if(frameSizeWidthLarger)
- {
- nodeSize.height = designSize.height;
- nodeSize.width = nodeSize.height * (frameSize.width / frameSize.height);
- }
- else
- {
- nodeSize.width = designSize.width;
- nodeSize.height = nodeSize.width * (frameSize.height / frameSize.width);
- }
- _node->setPosition(ccp((nodeSize.width - designSize.width) / 2,(nodeSize.height - designSize.height) / 2));
- auto _afterDrawListener = EventListenerCustom::create(Director::EVENT_AFTER_VISIT,[this](EventCustom* event) {
- this->visit(this->_director->getRenderer(),Mat4::IDENTITY,0);
- });
- auto eventDispatcher = Director::getInstance()->getEventDispatcher();
- eventDispatcher->addEventListenerWithFixedPriority(_afterDrawListener,1);
- return true;
- }
- void ScreenMatchLayer::onBeforeVisit()
- {
- GLView* openGLView = this->_director->getOpenGLView();
- Size frameSize = openGLView->getFrameSize();
- glViewport((GLint)(0),(GLint)(0),(GLsizei)(frameSize.width),(GLsizei)(frameSize.height));
- }
- void ScreenMatchLayer::onAfterVisit()
- {
- GLView* openGLView = this->_director->getOpenGLView();
- Size designSize = openGLView->getDesignResolutionSize();
- openGLView->setViewPortInPoints(0,designSize.width,designSize.height);
- }
- void ScreenMatchLayer::visit(Renderer *renderer,uint32_t parentFlags)
- {
- if(!_visible)
- return;
- _beforeVisit.init(_globalZOrder);
- _beforeVisit.func = CC_CALLBACK_0(ScreenMatchLayer::onBeforeVisit,this);
- renderer->addCommand(&_beforeVisit);
- Node::visit(renderer,parentTransform,parentFlags);
- _afterVisit.init(_globalZOrder);
- _afterVisit.func = CC_CALLBACK_0(ScreenMatchLayer::onAfterVisit,this);
- renderer->addCommand(&_afterVisit);
- }
- ScreenMatchLayer * ScreenMatchLayer::create()
- {
- ScreenMatchLayer *pRet = new ScreenMatchLayer();
- if ( pRet && pRet->init() ) {
- pRet->autorelease();
- return pRet;
- }
- CC_SAFE_DELETE(pRet);
- return nullptr;
- }
- int ScreenMatchLayer::lua_bind_AllFunction(lua_State* tolua_S)
- {
- lua_getglobal(tolua_S,"_G");
- if (lua_istable(tolua_S,-1))//stack:...,_G,{
- tolua_open(tolua_S);
- tolua_module(tolua_S,classPrefix.c_str(),0);
- tolua_beginmodule(tolua_S,classPrefix.c_str());
- tolua_usertype(tolua_S,ScreenMatchLayer::fullName.c_str());
- tolua_cclass(tolua_S,className.c_str(),ScreenMatchLayer::fullName.c_str(),"cc.Layer",nullptr);
- tolua_beginmodule(tolua_S,className.c_str());
- tolua_function(tolua_S,"create",lua_cocos2dx_ScreenMatchLayer_create);
- tolua_endmodule(tolua_S);
- g_luaType[typeid(ScreenMatchLayer).name()] = ScreenMatchLayer::fullName;
- g_typeCast[className] = ScreenMatchLayer::fullName;
- tolua_endmodule(tolua_S);
- }
- lua_pop(tolua_S,1);
- return 1;
- }
- int lua_cocos2dx_ScreenMatchLayer_create(lua_State* tolua_S)
- {
- int argc = 0;
- ScreenMatchLayer* parentOfFunction = nullptr;
- const std::string &functionString = "'lua_cocos2dx_ScreenMatchLayer_create'";
- const std::string &luaFunctionString = ScreenMatchLayer::fullName + ":create";
- #if COCOS2D_DEBUG >= 1
- tolua_Error tolua_err;
- if (!tolua_isusertable(tolua_S,1,&tolua_err))
- {
- tolua_error(tolua_S,("#ferror in function " + functionString).c_str(),&tolua_err);
- return 0;
- }
- parentOfFunction = (ScreenMatchLayer*)tolua_tousertype(tolua_S,0);
- if (!parentOfFunction)
- {
- //tolua_error(tolua_S,("invalid 'cobj' in function " + functionString).c_str(),nullptr);
- //return 0;
- }
- #endif
- argc = lua_gettop(tolua_S) - 1;
- if (argc == 0)
- {
- ScreenMatchLayer* ret = ScreenMatchLayer::create();
- object_to_luaval<ScreenMatchLayer>(tolua_S,(ScreenMatchLayer*)ret);
- return 1;
- }
- else
- {luaL_error(tolua_S,"%s has wrong number of arguments: %d,was expecting %d \n",luaFunctionString.c_str(),argc,1);}
- return 0;
- }