cocos2d-x是一款众所周知的跨平台的游戏开发引擎。因为其跨平台的特性。多分辨率支持也自然就有其需求。

因此。在某一次更新中(抱歉,笔者已经忘了是哪次更新了),cocos2d-x加入了一个新的方法。能够很简便地让cocos2d依据屏幕尺寸的大小做自适配。

方法名:

    virtual void setDesignResolutionSize(float width, float height, ResolutionPolicy resolutionPolicy);

该方法所传的參数中,前两个參数width、height,指的是开发人员在设计界面时默认设计的尺寸。比如:开发人员在设计界面时以iphone5为准,则width和height就是568*320;若是以iphone4为准。则width和height就是480*320;以此类推。

第三个參数resolutionPolicy指的是cocos2d在缩放时须要遵守的规则。ResolutionPolicy这个自己定义结构例如以下:

enum ResolutionPolicy
{
// The entire application is visible in the specified area without trying to preserve the original aspect ratio.
// Distortion can occur, and the application may appear stretched or compressed.
kResolutionExactFit,
// The entire application fills the specified area, without distortion but possibly with some cropping,
// while maintaining the original aspect ratio of the application.
kResolutionNoBorder,
// The entire application is visible in the specified area without distortion while maintaining the original
// aspect ratio of the application. Borders can appear on two sides of the application.
kResolutionShowAll, kResolutionUnKnown,
};

通过凝视能够看出:

kResolutionExactFit是指cocos2d缩放的时候不考虑画面失真,直接用画面填充满整个屏幕

kResolutionNoBorder是指cocos2d缩放的时候尽量顶满画面,假设因此有超出画面的部分,就会把超出的部分切除掉(举例来说:假设设计大小是568*320,在480*320大小的屏幕上自适配的时候,就会把宽度超出的部分切除)

kResolutionShowAll是指cocos2d缩放的时候显示全部的画面,假设有填不满屏幕的地方就会显示黑条。

这三种规则各有优缺点,详细使用哪种规则须要考量项目的须要进行合理的选择。

然而。须要特别注意的一点是:setDesignResolutionSize和enableRetina这两个方法是不能够同一时候使用的。

这即意味着使用自适配的时候是不能够做高清版的。

假设查看cocos2d-x源码。能够看到在setDesignResolutionSize方法中有一句代码:

    CCAssert(m_bIsRetinaEnabled == false, "can not enable retina while set design resolution size!");

在下觉得这是由于高清模式下图片资源都是进行了缩小的,全部的坐标都是定义的point,而不是pixel。因此高清模式和自适配可能有某些冲突存在。

(以上仅仅是笔者的推測,不靠谱勿怪)

总之,假设想要使用自适配。就必须在项目一開始就放弃高清。假设要做高清版,眼下看来就仅仅能自己依据屏幕尺寸的比例变化设置setContentScaleFactor,这一部分的设置方法这里就不展开了。

另外,笔者在刚開始使用自适配功能时,误以为开发时要把UI元素的位置坐标和大小都写成相对于屏幕大小的一定比例。比如:

    CCSprite* avatarSprite = CCSprite::create("avatar.png");
avatarSprite->setPosition(ccp(winSize.width * 0.000878, winSize.height * 0.653125));
addChild(avatarSprite);

但实际上这是没有必要的。

自适配功能是直接调整整个CCDirector的画布大小,因此不论什么加入到CCDirector中的元素都会被缩放对应的比例。没有必要再特意将坐标写成相对屏幕比例的模式。

以下笔者将分享一下在使用自适配功能的时候遇到的一个问题,即CCListView在多分辨率模式下可能出现的被过多地切除一部分内容的问题。

首先先介绍下笔者发现问题时的背景:当时笔者是在实现一款跨平台的游戏的当中一个界面,该游戏的画面是依照iphone5的低清版设计。DesignResolutionSize设置的是568*320。在安装到iphone5上时一切正常。可是随后,在安装到iphone4机器上进行调试时,发现画面上全部的CCListView都被切除了左边的一部分内容。

因为在iphone5上一切正常。在iphone4上画面被切除了一部分。因此笔者马上怀疑是CCListView与setDesignResolutionSize之间有某些冲突。

通过debug和log。最后将问题锁定到了CCListView类的visit方法。

方法的源码例如以下:

void CCListView::visit(void)
{
if (!m_pListViewParent)
{
CCRect rectSelf;
float factor = CC_CONTENT_SCALE_FACTOR();
rectSelf.origin = convertToWorldSpace(CCPoint(0,0));
rectSelf.origin.x *= factor;
rectSelf.origin.y *= factor;
rectSelf.size = this->getContentSize();
rectSelf.size.width *= factor;
rectSelf.size.height *= factor;
glScissor((GLsizei)rectSelf.origin.x, (GLsizei)rectSelf.origin.y, (GLsizei)rectSelf.size.width , (GLsizei)rectSelf.size.height);
glEnable(GL_SCISSOR_TEST);
}
CCLayerColor::visit();
if (!m_pListViewParent)
{
glDisable(GL_SCISSOR_TEST);
}
}

这段代码中调用了一个方法:glScissor。这种方法是框定了CCListView将会显示在屏幕上的范围。

而因为在使用自适配模式。对CC_CONTENT_SCALE_FACTOR没有做不论什么改动,因此这个框出来的范围是相应于DesignResolutionSize设定的原始设计画面大小的。而在屏幕尺寸发生了变化。整个CCDirector被缩放的情况下。这个rectSelf却没有做不论什么改变,所以就导致了上述的被切除一部分的问题。

随后,笔者通过搜索。发现已经有人遇到了同一个问题。并且还提供了修复的方法:http://www.cocos2d-x.org/boards/18/topics/14464

简单讲就是,用CCEGLView::sharedOpenGLView()->setScissorInPoints方法替换glScissor方法。其他不论什么地方都不用变。

改动好以后在iphone4和5上调试都没问题,因此这个bug本身能够算是修复了。

PS:因为对这种方法可以奏效感到好奇,笔者查看了setScissorInPoints方法的源文件。代码例如以下:

void CCEGLViewProtocol::setScissorInPoints(float x , float y , float w , float h)
{
glScissor((GLint)(x * m_fScaleX + m_obViewPortRect.origin.x),
(GLint)(y * m_fScaleY + m_obViewPortRect.origin.y),
(GLsizei)(w * m_fScaleX),
(GLsizei)(h * m_fScaleY));
}

能够看出这种方法内部仍然是调用了glScissor方法,可是传递的參数则考考虑到在屏幕尺寸的变化,因此,为了确保这种方法不切割过多CCListView内容。

其他,在project搜索glScissor发现CCScrollView这个方法也被称为,假定的使用CCScrollView建议同时更换的源代码glScissor方法。

cocos2d-x多分辨率和随后的自适应CCListView的bug修复的更多相关文章

  1. 常用样式制作思路 自定义按钮~自适应布局~常见bug seajs简记 初学者必知的HTML规范 不容忽略的——CSS规范

    常用样式制作思路   学习常用样式总结参考来自这里 带点文字链接列表利用:before实现 1 <!DOCTYPE html> 2 <html lang="en" ...

  2. 【原】文本图片自适应高度小bug以及解决办法

    自定义cell的文本图片自适应高度代码,如果存在自定义的cell赋值封装,就必须将自适应高度代码写在这个方法中

  3. 文本图片自适应高度小bug以及解决办法

    自定义cell的文本图片自适应高度代码,如果存在自定义的cell赋值封装,就必须将自适应高度代码写在这个方法中 点击效果: 注:- (void)layoutSubviews 方法不能同时操作,否则会出 ...

  4. 自定义按钮~自适应布局~常见bug

    一.元件 自定义按钮可用button或a   display为 inline-block 方便设置格式,通过 padding,height,line-height,font-size设置按钮的大小 & ...

  5. Cocos2d-x项目移植到WP8小记

    Cocos2d-x项目移植到WP8小记 作者: K.C. 日期: 10/24/2013 Date: 2013-10-24 00:33 Title: Cocos2d-x项目移植到WP8小记 Tags: ...

  6. margin设置为负数

    1.为负margin“平反” 我们在CSS中都会使用margin,但将margin设置成负数,那可能就不大好处理了.在网页设计中,人们对负margin用法的态度大相径庭,有的人非常喜欢,而有的人则认为 ...

  7. 我的Android进阶之旅------>经典的大牛博客推荐(排名不分先后)!!

    本文来自:http://blog.csdn.net/ouyang_peng/article/details/11358405 今天看到一篇文章,收藏了很多大牛的博客,在这里分享一下 谦虚的天下 柳志超 ...

  8. [PHP] 2018年终总结

    去掉敏感信息后的不完整版 ==========================================================================2018年12月29日 记 ...

  9. 集显也能硬件编码:Intel SDK && 各种音视频编解码学习详解

    http://blog.sina.com.cn/s/blog_4155bb1d0100soq9.html INTEL MEDIA SDK是INTEL推出的基于其内建显示核心的编解码技术,我们在播放高清 ...

随机推荐

  1. GUI (图形界面)知识点

    一:组件知识点 JTextField:    作用:  定义文本域,只支持单行输入.                使用:  定义文本域:  JTextField jtf=new JTextField ...

  2. Java设计模式菜鸟系列(十四)代理模式建模与实现

    转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/39856435 代理模式(Proxy):代理模式事实上就是多一个代理类出来,替原对象进行一些 ...

  3. php 二维数组传递给 js 问题解决记录

    需求: php从数据库中读取到二维数组.传递到js中 实现步骤: php:json_encode  →   json  →  js:eval 即在php中使用json_encode()将php的二维数 ...

  4. SQL -- 是否或推断线相交以在其内部的平面

    SQL如下面: update mapping_nj_roads set municipality='227' from mapping_geodata_boundary a where a.suppo ...

  5. Java 信号 Semaphore 简介

    Semaphore当前在多线程环境下被扩放使用.操作系统的信号量是个非常重要的概念,在进程控制方面都有应用. Java 并发库 的Semaphore 能够非常轻松完毕信号量控制,Semaphore能够 ...

  6. 【翻译】Ext JS最新技巧——2014-10-30

    原文:Top Support Tips Greg Barry:Ext JS 5的ExtraParams Ext JS 4同意用户直接将extraParams加入到一个链接,相似例如以下代码: Ext. ...

  7. Visual Studio 2015使用EF6的DBFirst模式操作Sqlite数据库

    什么是DBFirst 1:到官方下载并安装32位驱动(如果你是旧版的驱动,卸载掉,然后下载最新版的,否则操作数据时会出现异常) 2:通过Nuget获取System.Data.SQLite(会默认把下面 ...

  8. 第五十九届冠军(使用C++设计一个类不能被继承)

    称号:使用C++设计一个类不能被继承. 分析:这是Adobe 公司2007 的笔试题最新校园招聘. 应聘者的C++基本功底外,还能考察反应能力,是一道非常好的题目. 分析:C++中父类的构造函数会调用 ...

  9. iOS coreData

    static int row=0; static const NSString *kStoryboardName = @"LRCoreDataViewController"; st ...

  10. CCFadeOut ,CCFadeIn 不能使用的原因

    CCFadeOut *action = CCFadeOut::create(0.5f);  image->runAction(action); 截取部分代码.以上是我写游戏时候遇到的问题代码, ...