适当缩放Javascript Canvas游戏

Tas*_*ons 5 javascript html5 canvas

我试图根据屏幕尺寸动态扩展我的画布游戏.我理解如何基于屏幕大小来调整画布大小,但我也希望调整内容的大小.基本上我希望游戏在每台设备上看起来都一样.我目前的问题是当有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); 
}
Run Code Online (Sandbox Code Playgroud)

如果我像这样缩放画布,则会产生不希望的结果.它偏离中心,而且太大了.如您所见,我已设置最大宽度和高度.基本上我试图让游戏在每个设备上看起来都像在具有该分辨率的机器上一样.

现场演示:www.vertix.io

更新:这是一张目前的图片: 在此输入图像描述

Bli*_*n67 10

你将面临一些问题.

如果不设置ctx.imageSmoothingEnabled = false,高分辨率显示将显示模糊,如果未设置,低分辨率显示将显示混叠效果ctx.imageSmoothingEnabled = true.

最好是不要超过最大分辨率.这是任意的,我的选择是使用大多数人使用的屏幕分辨率.屏幕统计信息的一个示例有许多站点提供此信息.选择最近的人报告您的人口统计目标.

对于大于此值的显示,不增加分辨率只会增加DOM元素的大小.

canvas.widthcanvas.height设置画布的大小.canvas.style.widthcanvas.style.height设置分辨率.

对于分辨率较低的显示,会降低画布分辨率以适合屏幕分辨率.没有必要为设备提供额外的像素来渲染不会被看到.我个人重新渲染所有图形,以便在加载图像时为较低分辨率的显示更正res.这又是为了阻止设备渲染比所需更多的像素(移动设备无法处理太多),并且因为平滑方法有很多不足之处(即完全错误)请参阅此视频解释为什么计算机颜色被破坏

小心降低分辨率.如果你有一个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;
Run Code Online (Sandbox Code Playgroud)

您有两个缩放选项.缩放以适合或缩放以填充.

// 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);
Run Code Online (Sandbox Code Playgroud)

将画布分辨率和大小设置为

canvas.style.width = deviceWidth + "px";
canvas.style.height = deviceHeight + "px";
canvas.width = deviceWidth;
canvas.height = deviceHeight;
Run Code Online (Sandbox Code Playgroud)

现在您需要设置渲染比例

// ctx is the canvas 2d context 
ctx.setTransform(
    scaleFitNative,0, // or use scaleFillNative 
    0,scaleFitNative,
    Math.floor(deviceWidth/2),
    Math.floor(deviceHeight/2)
);
Run Code Online (Sandbox Code Playgroud)

这已将屏幕的中心设置为原点.

UPDATE

我的原始答案出错了.

要获得原始res左上角的偏移量是

var offSetToNativeTop = -nativeHeight/2; // incorrect
var offSetToNativeleft = -nativeWidth/2; // incorrect
Run Code Online (Sandbox Code Playgroud)

应该...

var offSetToNativeTop = (-nativeHeight/2)*scaleFitNative; // correct
var offSetToNativeleft = (-nativeWidth/2)*scaleFitNative; // correct
Run Code Online (Sandbox Code Playgroud)

要么

var offSetToNativeTop = (-nativeHeight/2)*scaleFillNative; // correct
var offSetToNativeleft = (-nativeWidth/2)*scaleFillNative; // correct
Run Code Online (Sandbox Code Playgroud)

很抱歉给您带来不便.

要获得设备左上角的偏移量

var offsetDeviceTop = -(deviceHeight/scaleFitNative)/2;
var offsetDeviceLeft = -(deviceWidth/scaleFitNative)/2;
Run Code Online (Sandbox Code Playgroud)

获取设备的playfield显示大小

var deviceDisplayWidth = deviceWidth/scaleFitNative;
var deviceDisplayHeight = deviceHeight/scaleFitNative;
Run Code Online (Sandbox Code Playgroud)

不要忘记平滑.

if(scaleFitNative < 1){
    ctx.imageSmoothingEnabled = true; // turn it on for low res screens
}else{
    ctx.imageSmoothingEnabled = false; // turn it off for high res screens.
}
Run Code Online (Sandbox Code Playgroud)

你也可以在个别渲染项目上进行,具体取决于它的规模和个人偏好,看看它们看起来如何平滑,减少和平滑扩展或不平滑大小.

这应该为您提供了为所有设备渲染图形所需的一切