1. 预备知识
1.1 屏幕分辨率 设计分辨率
屏幕分辨率:设备的实际屏幕显示分辨率
设计分辨率:制作场景使用的分辨率蓝本,通常设计分辨率会使用市场里使用率最高的设备的屏幕分辨率
1.2 各种适配方案
EXACT_FIT
拉伸变形,铺满屏幕
NO_BORDER
按比例伸缩,全屏展示无黑边(大图裁剪、小图无黑边)
SHOW_ALL
按比例伸缩,全屏展示(大图铺满屏幕,小图留有黑边)
FIXED_WIDTH
按照 窗体(手机)分辨率宽度/设计分辨率宽度 的比例,缩放设计分辨率画面。这种设计分辨率,适合于竖版游戏。美术出底图资源时,要保证高度足够,否则会穿帮。
FIXED_HEIGHT
按照 窗体(手机)分辨率高度/设计分辨率高度 的比例,缩放设计分辨率画面。这种设计分辨率,适合于横版游戏。美术出底图资源时,要保证宽度足够,否则会穿帮。
1.3 美术图片计算
图片高度 = 屏幕像素高度 / (屏幕像素宽度 / 图片像素宽度)
2. 深入代码
先获得openglView,如果为空就根据config.lua
里的设计分辨率创建
local glview = sharedDirector:getOpenGLView()
if nil == glview then
glview = cc.GLViewImpl:createWithRect("QuickCocos",
cc.rect(0, 0, CONFIG_SCREEN_WIDTH or 900, CONFIG_SCREEN_HEIGHT or 640))
sharedDirector:setOpenGLView(glview)
end
下面为config.lua
的部分代码,可以看出CONFIG_SCREEN_WIDTH
和CONFIG_SCREEN_HEIGHT
是设计分辨率
-- design resolution
CONFIG_SCREEN_WIDTH = 640
CONFIG_SCREEN_HEIGHT = 960
可以通过glView获得屏幕分辨率。下面的代码需要注意一个地方:当CONFIG_SCREEN_WIDTH
或高度为空的时候,会将屏幕分辨率赋值给它们。因为我们在config.lua
里已经配置了,所以现在我们的CONFIG_SCREEN_WIDTH
就是设计分辨率,当我们在使用player的时候,设计分辨率的宽和高会随着我们选择的机型的改变而改变
local size = glview:getFrameSize()
display.sizeInPixels = {width = size.width, height = size.height}
local w = display.sizeInPixels.width
local h = display.sizeInPixels.height
if CONFIG_SCREEN_WIDTH == nil or CONFIG_SCREEN_HEIGHT == nil then
CONFIG_SCREEN_WIDTH = w
CONFIG_SCREEN_HEIGHT = h
end
设置自动缩放值,如果当前屏幕的宽大于高,就设置为FIXED_HEIGHT
,即高度固定,这适用于横屏游戏。反之宽度固定,适用于竖屏游戏。
if not CONFIG_SCREEN_AUTOSCALE then
if w > h then
CONFIG_SCREEN_AUTOSCALE = "FIXED_HEIGHT"
else
CONFIG_SCREEN_AUTOSCALE = "FIXED_WIDTH"
end
else
CONFIG_SCREEN_AUTOSCALE = string.upper(CONFIG_SCREEN_AUTOSCALE)
end
FILL_ALL
保证了设计区域总有一个方向铺满屏幕,另一个方向可能超出屏幕或留有黑边。在没有触摸事件的时候cc.bPlugin_
为真,如果为真就使用NO_BORDER
,按比例伸缩,大图裁剪,小图留黑边。
if CONFIG_SCREEN_AUTOSCALE == "FILL_ALL" then
CONFIG_SCREEN_WIDTH = w
CONFIG_SCREEN_HEIGHT = h
scale = 1.0
if cc.bPlugin_ then
glview:setDesignResolutionSize(CONFIG_SCREEN_WIDTH, CONFIG_SCREEN_HEIGHT, cc.ResolutionPolicy.NO_BORDER)
else
glview:setDesignResolutionSize(CONFIG_SCREEN_WIDTH, CONFIG_SCREEN_HEIGHT, cc.ResolutionPolicy.FILL_ALL)
end
如果为FIXED_WIDTH
,就将X的缩放赋值给它,因为是宽度固定,高度适应,所以设计分辨率高度最终的值就是屏幕高度除以X的缩放值。FIXED_HEIGHT
同理
if not scaleX or not scaleY then
scaleX, scaleY = w / CONFIG_SCREEN_WIDTH, h / CONFIG_SCREEN_HEIGHT
end
if CONFIG_SCREEN_AUTOSCALE == "FIXED_WIDTH" then
scale = scaleX
CONFIG_SCREEN_HEIGHT = h / scale
elseif CONFIG_SCREEN_AUTOSCALE == "FIXED_HEIGHT" then
scale = scaleY
CONFIG_SCREEN_WIDTH = w / scale
else
scale = 1.0
printError(string.format("display - invalid CONFIG_SCREEN_AUTOSCALE \"%s\"", CONFIG_SCREEN_AUTOSCALE))
end
glview:setDesignResolutionSize(CONFIG_SCREEN_WIDTH, CONFIG_SCREEN_HEIGHT, cc.ResolutionPolicy.NO_BORDER)
3 IphoneX适配方案
下面是display为我们提供的各种属性,在引擎初始化的时候会计算好各种值,在游戏中可以用这些坐标值作为参考点来定位我们的内容
local x = display.right - 100 -- 图片中心在屏幕右边往左 100pt
local y = display.top - 100 -- 图片中心在屏幕顶部往下 100pt
local sprite = display.newSprite("Button.png") -- 创建 sprite 对象用于显示图片
sprite:setPosition(x, y) -- 设置这个 sprite 对象的坐标
X的最大的坑就是头上的铁刘海,所以我们需要做的就是以下两点:
- 屏幕中心点往上偏移37个像素
- 屏幕高度减去铁刘海的高度即95个像素
所以界面实际是640x1291
display.size = {width = winSize.width, height = (winSize.height - 95)}
display.cy = (display.height / 2) + 37
4 Ipad实际页面计算
前提:竖屏游戏,Ipad的屏幕大小为768x1024
,config.lua里的设计分辨率为640x960
注:现在我们的设计尺寸为640x853