**
介绍
**
cocos官方提供四种适配方案 Fit Height ,Fit Width ,NO_BORDER ,ExactFit 。这些在官方文档里有详细赘述,这里我们就不做过多介绍。
这里我们就ExactFit(同时勾选Fit Height ,Fit Width)模式进行扩展。
这种模式没有黑边,也不会裁剪设计分辨率范围内的图像。但是代价是场景图像的 x 和 y 方向的缩放倍率不同,图像会产生形变拉伸。有没有办法既没有黑边又没有拉伸呢。有就是麻烦一点。
同时解决各个浏览器全屏的适配问题(高版本safari地址栏,安卓浏览器全屏)
**
适用范围
**
- 游戏区域相对固定
- 游戏区域和UI区域可以很好的分离
- 对背景没有严格的要求
**
准备
**
- 我们首先要设计两套简单的UI方式,因为我们有时候横板的设计直接到竖版,或者竖版直接发横板都是有问题的
- 游戏区域看游戏而定有的一套就行
- 设计分辨率为最小的ui分辨率,可以往大了拉伸不可以再小了。
**
代码部分
**
-
首先建立对Canvas操作的脚本
const {ccclass,property} =cc._decorator;
@ccclass
@ccclass
export default class ScreenAdaptation extends cc.Component {
//横板设计分辨率
@property(cc.Size)
private designSiveH: cc.Size = cc.size(1440, 1080);
private clientSize: cc.Size = cc.size(0, 0);
/竖版设计分辨率
@property(cc.Size)
private designSiveV: cc.Size = cc.size(1080, 1920);
/**
* H 横板 V 竖版 记录当前
*/
private _screenOrientation: string = “”;
public start() {
this.changeDesignResolution();
}
public update(){
//检测分辨率 某些环境下对尺寸改变添加回调函数会有严重延时所以放在update检测
this.changeDesignResolution();
}
//对分辨率进行检测
public changeDesignResolution(){
let size: cc.Size = cc.view.getFrameSize();
//未检测到尺寸变化则跳出函数
if (size.width == this.clientSize.width && size.height == this.clientSize.height) {
return;
}
this.clientSize = cc.size(size.width, size.height);
//计算当前屏幕比
let proportion: number = (size.width / size.height);
//屏占比切换条件 当宽>高 设定为横屏,当然你可以根据实际调整
if (proportion >= 1) {
//屏幕和横板设计相比比较宽
if (proportion >= this.designSiveH.width / this.designSiveH.height) {
//重新设定canvas设计分辨率
this.node.getComponent(cc.Canvas).designResolution = cc.size(size.width * (this.designSiveH.height / size.height), this.designSiveH.height);
} else {
//重新设定canvas设计分辨率
this.node.getComponent(cc.Canvas).designResolution = cc.size(this.designSiveH.width, size.height * (this.designSiveH.width / size.width));
}
if (this._screenOrientation != “H” ) {
this._screenOrientation = “H”;
//通知所有需要改变场景变成横屏
}
}else{//竖屏处理
if (proportion >= this.designSiveV.width / this.designSiveV.height) { //屏幕比较宽
this.node.getComponent(cc.Canvas).designResolution = cc.size(size.width * (this.designSiveV.height / size.height), this.designSiveV.height);
} else {
this.node.getComponent(cc.Canvas).designResolution = cc.size(this.designSiveV.width, size.height * (this.designSiveV.width / size.width));
}
if (this._screenOrientation != “V” ) {
this._screenOrientation = “V”;
}
}
}
}
**
全屏处理
**
safar浏览器中只有一个Creator网页,横屏后会自动全屏, 但是如果有多个网页,Creator网页横屏后safar浏览器无法全屏.所以添加遮罩层进行引导玩家上滑全屏
对于某些安卓手机则需要玩家触摸遮罩层,才会给你全屏。所以综合处理方案如下
一、将项目打包,找到打包出的index.html文件,在html文件里,添加一个div标签和一个文本提示,代码如下:
<div id="mask">
<h1 id="tip">请向上滑动全屏显示</h1>
</div>
二、 在style-mobile.css中为这个div和字体添加css样式:
#mask {
position:absolute;
z-index:9999;
background-color:#C0C0C0;
left: 0;
top: 0;
height:1080px;
width:100%;
display :none;
opacity:0.5;
}
#tip{
color:red;
text-align:center;
float:center;
line-height:250px;
}
三、重点构建代码
public start() {
//尝试用cc自带方法进行全屏实验
if (!CC_DEBUG && cc.sys.isMobile) {
if (cc.screen["fullScreen"]) {
cc.screen["fullScreen"]()
}
if (cc.screen["autoFullScreen"]) {
cc.screen["autoFullScreen"]();
}
}
//注册SAFARI全屏事件
if (cc.sys.isMobile && cc.sys.browserType == cc.sys.BROWSER_TYPE_SAFARI) {
window.addEventListener("scroll", () => {
if (window.orientation == 90 || window.orientation == -90) {
if (window.innerHeight == document.documentElement.clientHeight) {
let docClientHeight = document.documentElement.clientHeight;
let mask = document.getElementById('mask');
mask.style.height = document.getElementById('Cocos2dGameContainer').style.height = docClientHeight + 'px';
mask.style.display="none";
//document.addEventListener('touchmove',function(e){e.preventDefault();},false)
}
} else {
document.body.scrollTop = -1;
window.scrollTo(0,1)
}
})
}
}
public mobileFullscreen(){
//唯一性检测 保证此函数仅运行一次 因为有些就是不给你全屏你也没办法 就不要为难用户了
if(window['mobileFullscreen']){
this.mobileFullscreen=()=>{};
return
}
//检测如果存在全屏函数则执行
if(document.documentElement.requestFullscreen||document.documentElement['mozRequestFullscreen']||document.documentElement['webkitRequestFullscreen']||document.documentElement['msRequestFullscreen']){
document.getElementById('mask').addEventListener('touchmove',function(e){e.preventDefault();},false)
//显示点击遮罩
document.getElementById('mask').style.display = 'block';
//对遮罩添加点击事件
document.getElementById('mask').ontouchend=()=>{
if(document.documentElement.requestFullscreen){
document.documentElement.requestFullscreen()
}else if(document.documentElement['mozRequestFullscreen']){
document.documentElement['mozRequestFullscreen']()
}else if(document.documentElement['webkitRequestFullscreen']){
document.documentElement['webkitRequestFullscreen']()
}else if(document.documentElement['msRequestFullscreen']){
document.documentElement['msRequestFullscreen']()
}
document.getElementById('mask').ontouchend=()=>{}
//关闭遮罩
document.getElementById('mask').style.display = 'none';
}
}
window['mobileFullscreen']=true;
}
public update(){
//检测SAFARI是否全屏
if (cc.sys.isMobile && cc.sys.browserType == cc.sys.BROWSER_TYPE_SAFARI) {
//console.log(window.innerHeight,document.documentElement.clientHeight,window.innerWidth,document.documentElement.clientWidth);
let display=document.getElementById('mask').style.display;
if (window.innerHeight == document.documentElement.clientHeight && display!='none' ) {
document.getElementById('mask').style.display = 'none';
}
else if(window.innerHeight != document.documentElement.clientHeight && display!='block'){
//如果检测到没有全屏显示出mask并且设置遮罩层大于屏幕显示区域进而玩家可以滑动屏幕 ,进而引导用户滑动
document.getElementById('mask').style.height=(document.documentElement.clientHeight+100)+"px";
document.getElementById('mask').style.display = 'block';
}
}else if(cc.sys.isMobile && !window['mobileFullscreen']){//检测安卓设备
this.mobileFullscreen();
}
}
个人原创整理且看且珍惜