前言
我们知道,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; }