实现 HTML5 Canvas 游戏硬件缩放和CSS3的现代化

分享于 

14分钟阅读

Web开发

  繁體

在10天内开发 Windows 8应用程序。

Modern和 file的现代浏览器实现一些有趣的HTML5特性,包括离线应用程序编程接口( API ) drag拖放 file file和文件 API 这些特性使我们进入了一个新的网络应用时代,新的。快速出现的游戏场景。

我将展示我如何使用这些新特性来现代化我最后的HTML5游戏 modernize HTML5 Platformer。 希望你能为自己的游戏提供一些新的想法 !

  • 部分:硬件缩放和 CSS3 ( 这篇文章)
  • 部分:脱机,文件和 drag-and-drop API ( 下一篇文章)

注意:演示在本文末尾。 尽情发挥你喜欢的浏览器吧,看看IE10的游戏视频。 源代码将在第 2部分下载。

跨设备扩展

如果你构建一个HTML5游戏,你可能对这种标准编程语言的跨平台特性感兴趣。 但与广泛的设备相兼容意味着你必须考虑大量的解决方案。 SVG相比,canvas最初似乎已经准备好处理这个问题。

然而,在基于精灵的休闲游戏中,有一个简单的解决方案来实现。 在他的博客中,David Catuhe做了一个很好的描述,释放了 HTML 5画布的强大功能,第 1部分使用硬件缩放功能"关于细节)。

的想法就简单得多。 使用固定的可以预测分辨率来工作,并使用属性将它拉伸到当前显示的分辨率。

步骤 1: 拉伸

我的小型HTML5游戏游戏中,资产和级别逻辑已经被设置为 800 x480. 因此,如果我想填充一个屏幕或者一块1024x768的平板电脑,我需要建立更高分辨率的资产,以满足那些规格。

在构建所有这些资产之前,我可以尝试一个扩展操作,以及适当的anti-aliasing-to。 让 我们 试 一 试 !

缩放操作只需要以下代码:


window.addEventListener("resize", OnResizeCalled, false);



function OnResizeCalled() {


 canvas.style.width = window.innerWidth + 'px';


 canvas.style.height = window.innerHeight + 'px';


}



就是这样 !

使用硬件加速浏览器,这里操作将由你的GPU实现,无需任何成本。 甚至可以启用反走样。 that Catuhe在他的画布性能文章中值得 mentioning。

这个技巧并不是HTML5特有的。 大多数现代控制台游戏不在 720p 或者 1080年内计算;几乎所有的( 如 1024 x600 ) 都在低分辨率处理。 在大多数情况下,这里描述的方法可以帮助你提高每秒( FPS )的帧数。

但是这个行动本身引发了一个比率问题。 实际上,当画布的大小为 800 x480时,该比例被控制。 现在,在调整浏览器窗口的大小时,我得到了这个奇怪的结果:

游戏仍然可以玩,但还可以明显地远离最优。

步骤 2: 控制你的比率

这里的想法是控制当浏览器窗口被调整时屏幕是如何被填充的。 如果窗口太大,或者窗口太高,我将在右边添加一些空的空格。 下面是代码:


var gameWidth = window.innerWidth;


var gameHeight = window.innerHeight;


var scaleToFitX = gameWidth/800;


var scaleToFitY = gameHeight/480;



var currentScreenRatio = gameWidth/gameHeight;


var optimalRatio = Math.min(scaleToFitX, scaleToFitY);



if (currentScreenRatio >= 1.77 && currentScreenRatio <= 1.79) {


 canvas.style.width = gameWidth + "px";


 canvas.style.height = gameHeight + "px";


}


else {


 canvas.style.width = 800 * optimalRatio + "px";


 canvas.style.height = 480 * optimalRatio + "px";


}



"中频"语句创建一个异常: 如果你在浏览器中点击 switch 到,你就得到了 16: 9 屏幕( 就像我的1920 x1080索尼VAIO屏幕或者 1366三星三星版平板电脑),游戏将完全拉伸。 这个体验非常棒。

如果没有这里异常,下面是你将看到的输出类型:

注意 black 区域 below 和右边的游戏,控制比例。

如果游戏是居中的,那就更好了,给它一个宽屏电影效果,对吧? 让我们来吧。

步骤 3: 将游戏置于CSS3网格布局中

使HTML元素居中有时很痛苦。 有几种方法可以做到这一点,而且网络上有大量的资源可以帮助。

我喜欢使用名为的新规范 CSS,这是我们的地铁风格布局在 Windows 8中的基础。

用CSS网格布局来居中元素很简单
  • switch 将容器显示到 display:grid。
  • 定义 1列和 1行。
  • 将内部元素与列对齐和行对齐特性居中对齐。

下面是我的案例中使用的CSS:





.canvasHolder {


 width: 100%;


 height: 100%;


 display: -ms-grid;


 -ms-grid-columns: 1fr;


 -ms-grid-rows: 1fr;


}



#platformerCanvas {


 -ms-grid-column: 1;


 -ms-grid-row: 1;


 -ms-grid-column-align: center;


 -ms-grid-row-align: center;


}</</



你将注意到前缀是IE10的"-ms"。 最近还支持 annonced,他们还将在2010年为 Firefox 支持CSS网格布局规范,这是一个非常好的消息。 同时,这个定心技巧只适用于 IE10. 以下是它的外观:

IE10 Windows 将显示垂直或者水平 black 条,类似于你在电视屏幕上看到的。 在其他浏览器中,由于CSS3网格布局规范将被忽略,因此结果将在第1 步中。

使用平滑动画

现在,我们处理多个分辨率,使用一个简单的操作,当用户调整窗口的大小时很好。 它还可以在每个级别加载时播放一个很酷的动画。 为此,我们将使用CSS3转换和 CSS3 3D 转换工具。 在大多数平台上,硬件加速是由GPU提供的。

对画布样式属性所做的每个更改进行动画处理

CSS3转换易于使用,并且产生平滑。高效的动画。 to我们在 IE 测试驱动站点上,或者在测试驱动站点上玩,可以了解一下如何使用它们,: 转换。

我已经为所有画布属性设置了全局转换,这归功于以下规则:





#platformerCanvas {


 -ms-grid-column: 1;


 -ms-grid-row: 1;


 -ms-grid-column-align: center;


 -ms-grid-row-align: center;



 -ms-transition-property: all;


 -ms-transition-duration: 1s;


 -ms-transition-timing-function: ease;


}</</



带有" platformerCanvas"ID的画布将自动反映由缓动函数生成的第二个动画中的样式属性所做的任何更改。

感谢这里新规则,调整浏览器窗口的大小将减小/增加画布的平滑动画大小。 我喜欢它产生的效果,只有 3行 CSS。

注意:我还添加了不同的前缀( Mozilla,webkit 和 Opera的-moz,webkit 和 -o ) 来兼容。 你要记住做同样的事情。

在每个级别之间构建一个很酷的动画

现在我想使用 CSS3 3D 转换暂时使画布消失。 这将在Y 轴上使用动画 90-degree 旋转完成。 当动画旋转 90度并返回到初始位置( 旋转零度) 时,我将加载下一个级别。 要更好地了解效果,你可以使用我们的手: 3D 在 IE 测试驱动器站点上转换:

我们还将使用比例和rotateY属性来构建一个有趣的动画。 为此,我添加了两个CSS规则并针对两个类:





.moveRotation


{


 -ms-transform: perspective(500px) rotateY(-90deg) scale(0.1);


 -webkit-transform: perspective(500px) scale(0);


 -moz-transform: perspective(500px) rotateY(-90deg) scale(0.1);


}



.initialRotation


{


 -ms-transform: perspective(500px) rotateY(0deg) scale(1);


 -webkit-transform: perspective(500px) scale(1);


 -moz-transform: perspective(500px) rotateY(0deg) scale(1);


}</</



首先,我的画布具有 initialRotation 类集:


<canvas id="platformerCanvas" width="800"



height="480" class="initialRotation"></canvas>



现在的想法是等到玩家打败当前的水平。 完成之后,我们将把画布的类从 initialRotation 改为 moveRotation。 这将自动触发我们之前设置的CSS3转换来生成动画。

为了了解动画完成的时间,将引发一个事件。 在每个浏览器中名称不同。 下面是注册事件和定位 IE10,Firefox,webkit 和 Opera 所用的代码:


// Registering to the various browsers vendors transition end event


PlatformerGame.prototype.registerTransitionEndEvents = function () {


 // IE10, Firefox, Chrome & Safari, Opera


 this.platformerGameStage.canvas.addEventListener("MSTransitionEnd", onTransitionEnd(this));


 this.platformerGameStage.canvas.addEventListener("transitionend", onTransitionEnd(this));


 this.platformerGameStage.canvas.addEventListener("webkitTransitionEnd", onTransitionEnd(this));


 this.platformerGameStage.canvas.addEventListener("OTransitionEnd", onTransitionEnd(this));


};



下面是将被调用的代码:


// Function called when the transition has ended


// We're then loading the next level


function onTransitionEnd(instance) {


 return function () {


 if (instance.loadNextLevel === true) {


 instance.LoadNextLevel();


 }


 }


};



最后,在画布上设置 moveRotation类的代码:


// Perform the appropriate action to advance the game and


// to get the player back to playing.


PlatformerGame.prototype.HandleInput = function () {


 if (!this.wasContinuePressed && this.continuePressed) {


 if (!this.level.Hero.IsAlive) {


 this.level.StartNewLife();


 }


 else if (this.level.TimeRemaining == 0) {


 if (this.level.ReachedExit) {


 // If CSS3 Transitions is supported


 // We're using smooth & nice effects between each levels


 if (Modernizr.csstransitions) {


 this.loadNextLevel = true;


 // Setting the moveRotation class will trigger the css transition


 this.platformerGameStage.canvas.className = "moveRotation";


 }


 // If CSS3 Transition is not supported, we're jumping directly


 // to the next level


 else {


 this.LoadNextLevel();


 }


 }


 else


 this.ReloadCurrentLevel();


 }


 this.platformerGameStage.removeChild(statusBitmap);


 overlayDisplayed = false;


 }



 this.wasContinuePressed = this.continuePressed;


};



注意我使用插件来对CSS转换进行特性检测。 我们最后将在 LoadNextLevel 函数中设置initialRotation类:


// Loading the next level 


PlatformerGame.prototype.LoadNextLevel = function () {


 this.loadNextLevel = false;


 // Setting back the initialRotation class will trigger the transition


 this.platformerGameStage.canvas.className = "initialRotation";


 //.. . loadNextLevel logic stuff...


};



注意:你可能注意到我在以前的CSS版本中没有为IE10和 Firefox 设置相同的转换( 例如和)。 这是因为,在我的例子中,Chrome的行为不同于IE10和 Firefox 11. 我已经在jsFiddle上建立了一个简单的复制案例: http://jsfiddle.net/5H8wg/2/

演示视频和 URL

下面是演示本文所介绍的IE10特性的简短视频:

你还可以在IE10或者你喜爱的浏览器中使用这里演示文稿: 现代 HTML5

在本文的接下来部分,我将展示如何实现离线 API,使我的游戏工作没有网络连接,以及 drag-and-drop API如何创建另一个很酷的功能。


模式  GAM  Html5  CAN  HAR  Canvas  
相关文章