我试图根据屏幕尺寸动态缩放画布游戏。我了解如何根据屏幕尺寸调整画布的大小,但是我也想调整内容的大小。基本上,我希望游戏在所有设备上看起来都一样。我目前遇到的问题是,当屏幕为4k的人玩游戏时,他们可以轻松看到整个地图。当某人的屏幕非常小时,他们几乎看不到任何东西。有一种简单有效的方法吗?我尝试执行以下操作:
var maxWidth = 1920;
var maxHeight = 1080;
...
function resize() {
c.width = screenWidth = window.innerWidth;
c.height = screenHeight = window.innerHeight;
widthToHeight = screenWidth / screenHeight; // ASPECT RATIO
var scalerAmnt = (maxWidth + maxHeight )
/ (screenWidth + screenHeight);
context.scale(scalerAmnt, scalerAmnt);
}
如果我像这样缩放画布,则会产生不良结果。它偏离中心,并且太大。如您所见,我已经设置了最大宽度和高度。基本上,我试图使游戏在每个设备上的外观都与具有该分辨率的计算机上的外观相同。
现场演示:www.vertix.io
您将面临一些问题。
如果未设置ctx.imageSmoothingEnabled = false
,高分辨率显示将显示模糊,如果未设置,则高分辨率显示将显示锯齿效果ctx.imageSmoothingEnabled = true
。
最好不要超过最大分辨率。这是任意的,我的选择是使用大多数人使用的屏幕分辨率。屏幕统计信息的示例有很多提供此信息的站点。选择一个最能报告您的人口统计目标的人。
对于更大的显示器,不增加分辨率,只需增加DOM元素的大小即可。
canvas.width
并canvas.height
设置画布的大小。canvas.style.width
并canvas.style.height
设置分辨率。
对于分辨率较低的显示器,请降低画布分辨率以适合屏幕分辨率。给设备额外的像素渲染毫无意义。我个人重新渲染所有图形,以在加载图像时将分辨率降低为较低分辨率的显示。再次,这是为了阻止设备渲染超出所需数量的像素(移动设备无法处理太多像素),并且由于平滑方法还有很多不足(即完全错误),请观看此视频以解释为什么计算机颜色损坏了
降低分辨率时要小心。如果您有一个100by100像素的图像,并且需要将其缩小到93by93,则看起来效果不佳。仔细选择每个渲染元素的图形大小,以最大可能地减少将要显示的最常见分辨率集。
还可以在运动场的大小中留出一些摆动的空间,它们的大小不必完全相同。
更好的方法是将图形存储为基于矢量的图像(例如SVG或直接用于画布的矢量渲染的自定义格式),然后在加载时以正确的分辨率在设备上渲染图像。
因此,您只剩下了方面。您无能为力,有些屏幕比其他屏幕显示更多的游戏场地。您将必须确定在宽度和高度上都可以播放的最小尺寸的运动场,并确保它不会超出该范围。
但是说了这么多,大部分工作都完成了,您将无法返回并重做所有工作,因此这是简单的解决方案。
var nativeWidth = 1024; // the resolution the games is designed to look best in
var nativeHeight = 768;
// the resolution of the device that is being used to play
var deviceWidth = window.innerWidth; // please check for browser compatibility
var deviceHeight = window.innerHeight;
您有两个缩放选项。缩放以适合或缩放以填充。
// A: This will ensure that the scale fills the device but will crop
// some of the top and bottom, or left and right of the play field.
// use the max scale.
var scaleFillNative = Math.max(deviceWidth / nativeWidth, deviceHeight / nativeHeight);
// B: this will ensure that all screens will see all of the native playscreen size
// but some displays will have extra playfield on the sides or top and bottom.
// use the min scale
var scaleFitNative = Math.min(deviceWidth / nativeWidth, deviceHeight / nativeHeight);
将画布分辨率和大小设置为
canvas.style.width = deviceWidth + "px";
canvas.style.height = deviceHeight + "px";
canvas.width = deviceWidth;
canvas.height = deviceHeight;
现在您需要设置渲染比例
// ctx is the canvas 2d context
ctx.setTransform(
scaleFitNative,0, // or use scaleFillNative
0,scaleFitNative,
Math.floor(deviceWidth/2),
Math.floor(deviceHeight/2)
);
这样就将屏幕的中心设置为原点。
更新
我的原始答案有误。
要获得与本机分辨率的偏移量,请左上角是
var offSetToNativeTop = -nativeHeight/2; // incorrect
var offSetToNativeleft = -nativeWidth/2; // incorrect
应该...
var offSetToNativeTop = (-nativeHeight/2)*scaleFitNative; // correct
var offSetToNativeleft = (-nativeWidth/2)*scaleFitNative; // correct
或者
var offSetToNativeTop = (-nativeHeight/2)*scaleFillNative; // correct
var offSetToNativeleft = (-nativeWidth/2)*scaleFillNative; // correct
不便之处,敬请原谅。
要获得设备左上角的偏移量
var offsetDeviceTop = -(deviceHeight/scaleFitNative)/2;
var offsetDeviceLeft = -(deviceWidth/scaleFitNative)/2;
获取设备运动场显示尺寸
var deviceDisplayWidth = deviceWidth/scaleFitNative;
var deviceDisplayHeight = deviceHeight/scaleFitNative;
不要忘记平滑。
if(scaleFitNative < 1){
ctx.imageSmoothingEnabled = true; // turn it on for low res screens
}else{
ctx.imageSmoothingEnabled = false; // turn it off for high res screens.
}
您还可以在单个渲染项目上执行此操作,具体取决于该区域的缩放比例以及您对它们的平滑和缩小以及平滑的扩大或不平滑大小的偏爱。
那应该为您提供所有设备渲染图形所需的一切
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句