egret适配方案,FIXED_WIDTH

效果图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,这种模式下,游戏会保持原始宽高做缩放,保证水平和竖直方向都填满屏幕视图,但这样会导致较宽的方向超出屏幕,
所以我们需要以较宽的方向为基准,将游戏整体缩放,使较宽方向刚好铺满,此时较窄方向由于缩放导致无法铺满,产生黑边
这一步就需要一个适配层放到游戏层底部,来遮盖黑边了

其他

发布了18 篇原创文章 · 获赞 2 · 访问量 1761

猜你喜欢

转载自blog.csdn.net/karaa/article/details/102211493
今日推荐