效果图1 640 * 960
效果图2 640 * 1136
准备工作
1,确定设计分辨率 640 * 1024(egret模拟器提供的宽高比在1.5-1.77之间,这里取1.6方便测试,实际开发建议640 * 1136 或者720 * 1280)2,准备一张与设计分辨率尺寸一致的图片用做背景(用于测试,直接采用创建项目时提供的默认背景,使用代码调整高度为640 * 1024)
1,创建egret项目
egretLauncher创建eui或者游戏项目,看自己喜好
2,修改代码
1,全局类AllGlobals.ts
module game {
export class AllGlobals {
public constructor() {
}
public static designWidth = 640;
public static designHeigh = 1024;
}
}
2,场景管理类 SceneManger.ts单例,用于切换场景
module scene
{
enum FIT_STATE{ FIT_NULL,FIT_W,FIT_H}
export class SceneManager{
private static gInstance:SceneManager;
public static get Instance()
{
if(SceneManager.gInstance == null)
{
SceneManager.gInstance = new SceneManager();
}
return SceneManager.gInstance;
}
private mStage:egret.Stage = null;
private mCurrentScene:egret.DisplayObjectContainer;
public setStage(stage:egret.Stage)
{
this.mStage = stage;
// 适配适配背景
let fitLayer = new layer.screenFitLayer();
this.mStage.addChild( fitLayer);
// 监听尺寸变更
this.mStage.addEventListener(egret.Event.RESIZE, this.resizeChange, this);
this.autoFit();
}
private fitScale:number = 1;
private fitState:FIT_STATE = FIT_STATE.FIT_NULL;// 1 适配宽,2 适配高
private autoFit()
{
if(this.mStage == null)
{
console.log('error ===== not found stage !!! ');
return;
}
this.mStage.scaleMode = egret.StageScaleMode.FIXED_WIDE;
this.mStage.setContentSize(game.AllGlobals.designWidth,game.AllGlobals.designHeigh);
this.checkFitState();
}
private checkFitState()
{
let designRate = game.AllGlobals.designHeigh/game.AllGlobals.designWidth;
let stageRate = this.mStage.stageHeight/this.mStage.stageWidth; // 设计分辨率宽高比
console.log('stage.width = ',this.mStage.stageWidth,'...heigh = ',this.mStage.stageHeight,'..staageRate = ',stageRate);
if(stageRate > designRate )
{
this.fitState = FIT_STATE.FIT_W;
}else
{
this.fitState =FIT_STATE.FIT_H;
}
console.log('checkFitState == ',this.fitState);
}
private resizeChange()
{
console.log('================resizeChange ================== ');
this.checkFitState();
this.changeFitScene();
}
private changeFitScene()
{
if(this.fitState == FIT_STATE.FIT_W)
{// x 超出,缩放x至屏幕大小,调整y坐标居中
this.fitScale = this.mStage.stageWidth/game.AllGlobals.designWidth;
console.log("=====1111==== ",this.fitScale);
if(this.mCurrentScene)
{
this.mCurrentScene.scaleX = this.fitScale;
this.mCurrentScene.scaleY = this.fitScale;
this.mCurrentScene.x = 0;
this.mCurrentScene.y = game.AllGlobals.designHeigh*(1-this.fitScale)/2;
}
}
else if(this.fitState == FIT_STATE.FIT_H)
{
this.fitScale = this.mStage.stageHeight/game.AllGlobals.designHeigh;
console.log("=====2222==== ",this.fitScale);
if(this.mCurrentScene)
{
this.mCurrentScene.scaleX = this.fitScale;
this.mCurrentScene.scaleY = this.fitScale;
this.mCurrentScene.x = game.AllGlobals.designWidth*(1-this.fitScale)/2;
this.mCurrentScene.y = 0;
}
}
}
public changeScene(s:egret.DisplayObjectContainer)
{
if(s ==null)
{
console.log('error ==== ',s);
return;
}
if(this.mCurrentScene != null && this.mCurrentScene.parent)
{
this.mStage.removeChild(this.mCurrentScene);
this.mCurrentScene = null;
}
this.mCurrentScene = s;
this.mStage.addChild(s);
this.changeFitScene();
}
}
}
核心方法
changeScene 切换场景
setStage 初始化时设置舞台,提供适配背景图 ,监听egret.Event.RESIZE,用于模拟器切换时动态适配
3,适配screenFitLayer.ts
这个layer默认放到最底层,其他层做缩放时,会显示此界面边框部分,代替黑边
这里简单使用矢量图做了个矩形框,实际项目中可以根据需求改为自己的背景图
module layer {
/*
1,fix_width
2,固定设计分辨率,UI按照固定分辨率设置
3,场景层固定添加适配layer,背景使用固定分辨率尺寸
4,非适配layer按比率缩放,调整坐标位于屏幕中心
*/
export class screenFitLayer extends egret.DisplayObjectContainer {
public constructor() {
super();
this.init();
}
private bgShape:egret.Shape = null;
private init()
{
this.bgShape = new egret.Shape();
this.bgShape.graphics.beginFill(0x82a805);
this.bgShape.graphics.drawRect(0,0,game.AllGlobals.designWidth,game.AllGlobals.designHeigh);
this.bgShape.graphics.endFill();
this.addChild(this.bgShape);
}
}
}
4,主场景LoginScene.ts
module scene {
export class LoginScene extends eui.UILayer {
public constructor() {
super();
this.init();
}
private init()
{
// 添加一张底图,默认为设计分辨率大小,表示真实屏幕
let bgTexture:egret.Texture = RES.getRes("bg_jpg")
let bg:egret.Bitmap = new egret.Bitmap(bgTexture);
bg.height = 1024;
this.addChild(bg);
// 在4角添加4个小方块,
let topSp:egret.Shape = new egret.Shape();
topSp.graphics.beginFill(0x0f0f0f);
topSp.graphics.drawRect(0,0,100,100);
topSp.graphics.endFill();
this.addChild(topSp);
let bottomSp:egret.Shape = new egret.Shape();
bottomSp.graphics.beginFill(0xff0f0f);
bottomSp.graphics.drawRect(0,0,100,100);
bottomSp.graphics.endFill();
this.addChild(bottomSp);
bottomSp.x = game.AllGlobals.designWidth - 100;
bottomSp.y = game.AllGlobals.designHeigh - 100;
let bottomSp2:egret.Shape = new egret.Shape();
bottomSp2.graphics.beginFill(0x0fff0f);
bottomSp2.graphics.drawRect(0,0,100,100);
bottomSp2.graphics.endFill();
this.addChild(bottomSp2);
bottomSp2.y = game.AllGlobals.designHeigh - 100;
let topSp2:egret.Shape = new egret.Shape();
topSp2.graphics.beginFill(0x0f0fff);
topSp2.graphics.drawRect(0,0,100,100);
topSp2.graphics.endFill();
this.addChild(topSp2);
topSp2.x = game.AllGlobals.designWidth - 100;
}
}
}
5,在Main.ts中修改createGameScene方法,切换场景
protected createGameScene(): void {
scene.SceneManager.Instance.setStage(this.stage);
scene.SceneManager.Instance.changeScene(new scene.LoginScene());
}
分析
适配的原理是提供一个适配层 平铺在底部,游戏层在上层,我们缩放游戏层,是游戏内容等比例全显在屏幕上,而黑边部分显示适配层内容
核心代码为SceneManger类autofit方法
首先设置适配方案,设置设计分辨率
this.mStage.scaleMode = egret.StageScaleMode.FIXED_WIDE;
this.mStage.setContentSize(game.AllGlobals.designWidth,game.AllGlobals.designHeigh);
这里采用fixed_width,这种模式下,游戏会保持原始宽高做缩放,保证水平和竖直方向都填满屏幕视图,但这样会导致较宽的方向超出屏幕,
所以我们需要以较宽的方向为基准,将游戏整体缩放,使较宽方向刚好铺满,此时较窄方向由于缩放导致无法铺满,产生黑边
这一步就需要一个适配层放到游戏层底部,来遮盖黑边了