blend 5
我想与您分享一个长期存在于Microsoft内部的神秘内部秘密。 这是Microsoft为IE10和Windows Store Apps想象的CSS网格布局概念的真实故事。
你们中的大多数人可能认为该规范旨在为开发人员提供用于其网站和应用程序的更好的布局引擎。 但是最初的动机是完全不同的。 最初的目标是能够以简单的方式创建类似Tetris的游戏!
我确定您还没有说服。 这就是为什么我将使用Blend 5作为伴侣向您证明这一点的原因。 好了,走吧!
先决条件:要学习本教程,您首先需要:
- 在您的计算机上下载/购买并安装Windows 8 RTM : http : //msdn.microsoft.com/zh-CN/windows/apps/br229516.aspx
- 下载并安装Windows 8的Visual Studio 2012 Express RTM的免费版本: http : //msdn.microsoft.com/zh-cn/windows/apps/br229516.aspx ,其中包括适用于Visual Studio的Expression Blend 5或使用更高版本。
第1步:借助Blend 5,发现CSS网格布局背后的秘密
启动Expression Blend 5并创建一个空白应用程序类型的新HTML(Windows应用商店)项目。 将其命名为“ TheRealCSSGridStory ”:
更换:
< p > Content goes here </ p >
带有:
< div class ="mainGrid"> </ div >
让我们使用分数单位创建一个包含10列和20行的网格,无论屏幕的分辨率如何。 为此,请添加以下CSS规则:
.mainGrid { display : -ms-grid ; width : 100% ; height : 100% ; -ms-grid-columns : (1fr)[10] ; -ms-grid-rows : (1fr)[20] ; }
在实时DOM中选择<div> mainGrid元素,您将获得以下信息:
让我们在这个美丽的网格中绘制一个形状。 在主网格内添加以下HTML块:
< div class ="shape1"> </ div >
并插入与此关联CSS:
.shape1 { -ms-grid-column : 4 ; -ms-grid-row : 3 ; -ms-grid-column-span : 3 ; -ms-grid-row-span : 2 ; background-color : red ; }
您现在应该在Blend 5中看到这一点:
很酷,但是对俄罗斯方块游戏来说,看起来还没有什么。 让我们继续努力。 在shape1中添加以下两个DIV:
< div class ="line1shape1"></ div > < div class ="line2shape1"></ div >
并使用以下CSS块替换之前的.shape1规则:
.shape1 { -ms-grid-column : 4 ; -ms-grid-row : 3 ; -ms-grid-column-span : 3 ; -ms-grid-row-span : 2 ; display : -ms-grid ; -ms-grid-columns : 1fr 1fr 1fr ; -ms-grid-rows : 1fr 1fr ; width : 100% ; height : 100% ; } .line1shape1 { -ms-grid-column-span : 2 ; background-color : red ; } .line2shape1 { -ms-grid-column : 2 ; -ms-grid-row : 2 ; -ms-grid-column-span : 2 ; background-color : red ; }
shape1当前跨三列两行。 然后,我将在此区域内创建一个新的网格,该网格由三列和两行定义,以便使单元具有与主网格的单元完全相同的大小,而不管分辨率如何。
完成后,我将创建两条线以模仿俄罗斯方块游戏的Z形。 您现在应该得到以下结果:
免费学习PHP!
全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。
原价$ 11.95 您的完全免费
更好的是,使用“设备”选项卡中的各种视图进行操作,您会发现我们的游戏已经实现了自适应设计 ! 这真是太酷了,不是吗?
例如,以下是快照视图和纵向视图的输出:
现在让我们解决另一个问题。
俄罗斯方块网格游戏网格由正方形组成。 我们当前的响应式设计正在拉伸100%的宽度。 在大多数情况下,为Windows应用商店构建Windows 8应用程序将满足宽屏显示器的要求(当前的平板电脑为1366×768或1920×1080,大多数台式机的比例为16/9)。 然后,让我们假设针对宽屏比例可以解决几乎所有情况。 要计算适当的响应宽度,您需要执行:9/16 * 10/20(主游戏网格的比率),等于: 28.125%。
添加此规则以在全屏横向模式下定位主网格:
@media screen and (-ms-view-state: fullscreen-landscape) { .mainGrid { width : 28.125% ; } }
现在让我们再次使用CSS网格布局来居中游戏网格! (现在您应该开始相信它是真正为俄罗斯方块设计的!)
将body元素切换到由一列和一行组成的–ms-grid :
body { display : -ms-grid ; -ms-grid-columns : 1fr ; -ms-grid-rows : 1fr ; width : 100% ; height : 100% ; }
现在,只需将此属性添加到与主网格关联CSS中即可:
-ms-grid-column-align : center ;
网格现在居中:
在这个阶段,您可能已经感到震惊。 “ 我怎么会错过这个不可思议的秘密? ”您在想自己。
喘口气。
现在您已经知道了秘密,让我们一起继续本教程,以发现由CSS规范结合在一起提供的其他绝佳功能。
步骤2:移动或旋转形状
我的第一个想法是尝试通过使用尽可能多CSS来避免JS。 然后,我首先尝试使用CSS3动画在各个行/列上移动和设置形状的动画。 但坏消息是您无法通过CSS3动画更改–ms-grid-column或–ms-grid-row值。 然后,这将是一些JavaScript代码的工作。
然后,我开始考虑如何旋转形状。 CSS Transforms似乎非常适合于此。 让我们通过做一些实验来检查一下。 Blend 5真的很酷,因为您可以直接实时看到更改的结果。
通过将class添加到其DIV元素,在shape1上添加90度旋转:
.shape1rotated { transform : rotate(90deg) ; }
我确定您没有想到这一点:
问题:它与游戏网格的排列不正确。 为了使形状与网格对齐,我们需要进行一些小的调整:
.shape1rotated { transform-origin : 33% 50% ; transform : rotate(90deg) translateX(-33%) ; }
现在,我们具有与类似俄罗斯方块的游戏相同的旋转方式。 这是旋转前后的两个屏幕截图:
通过以下方式,我们甚至可以通过在shape1上使用过渡集来做进一步的工作:
transition : all 1s ease-out ;
现在,在shape1 DIV上删除/添加.shape1rotated类将触发平滑的旋转动画。
借助这段简短的视频,您可以在Blend 5中查看结果:
下载视频: VideoJS的MP4 , WebM , HTML5视频播放器
在这个阶段,我们可以认为这种方法是构建我们游戏的好方法。 不幸的是,事实并非如此。 这就是为什么。 尝试通过简单更改其–ms-grid-column属性来移动形状。 Blend 5将直接反映更改。 不旋转时,形状可以向上移动到第八列:
到目前为止,一切都很好。 但是,当您通过将.shape1rotated类添加到DIV来旋转它时:
您会看到右侧还有1行可用于形状移动。 如果您认为我们只需要将其移至第9行,那就错了! 确实,这是我们将在第9行获得的结果:
您可能忘记了我们当前正在移动一个DIV元素,该元素显示的网格布局完全与基础游戏网格匹配,三列两行。 在移动它时,我们确实感觉到这是我们要移动的主网格的一个块部分。 但是,要使此技巧起作用,我们至少需要三列可用于包含shape元素。 如果它包含在两列(或设置为第9列)中或更少,则将被“压缩”,如屏幕截图所示。
有两种解决方法。
1 –停止使用CSS变换,并使用另一个网格定义绘制旋转的形状。 例如,在形状内使用三个div而不是两个。 但是使用这种方法将阻止我们使用合适CSS动画。
2 –重新定义了主网格,使其可以处理12列而不是10列,并且我们将仅使用2到11列(如果需要,可以使用某种裁剪区域)。 这将解决我们的“溢出”问题。
让我们实现第二个解决方案。
使用以下方法重新定义主网格:
.mainGrid { display : -ms-grid ; -ms-grid-columns : (1fr)[12] ; -ms-grid-rows : (1fr)[20] ; -ms-grid-column-align : center ; width : 100% ; height : 100% ; }
为获得适当的比率,您需要更新关联的媒体查询:
@media screen and (-ms-view-state: fullscreen-landscape) { .mainGrid { width : 33.75% ; } }
33.75%= 9/16 * 12/20
让我们还添加一个“虚拟网格”来界定我们将能够移动形状的空间。 在主网格DIV中,插入以下内容:
< div class ="virtualGrid"> </ div >
与此CSS块相关联:
.virtualGrid { -ms-grid-column : 2 ; -ms-grid-column-span : 10 ; -ms-grid-row-span : 20 ; border-right-style : dashed ; border-left-style : dashed ; background-color : #505A5A ; }
这将有助于使用灰色背景和一些虚线边框来界定游戏区域。
现在,如果我在第9列第2行上移动Z形状,则结果如下:
如果使用CSS变换旋转它,则可以在第10列正确移动它:
奖励–处理人像模式:
如果您想支持纵向模式(这对于俄罗斯方块游戏来说更好),请添加以下CSS Media Query定义:
@media screen and (-ms-view-state: fullscreen-portrait) { .mainGrid { width : 106.66% ; } }
由于该比率需要计算为= 16/9 * 12/20 = 106.66%。
步骤3:添加一些代码来处理部分游戏逻辑
现在,我们仅使用一些纯CSS和HTML代码解决了游戏的图形部分,我们需要JavaScript的帮助才能在游戏区域中移动/旋转形状。 我们将通过WinJS.Class来定义一个JS对象,以重新实现CSS逻辑。
在Visual Studio 2012中打开“ TheRealCSSGridStory ”。
在JS目录中创建TetrisShapeZ.js文件,然后复制/粘贴以下代码:
( function () { "use strict" ; var ShapeZ = WinJS.Class.define( /// Constructor - columnIndex is optional. If provided, defines the column the shape starts in function (columnIndex) { // We're creating the equivalent of this HTML block : // <div class="shape1 "> // <div class="line1shape1"></div> // <div class="line2shape1"></div> // </div> this ._shape1 = document.createElement( "div" ); var line1 = document.createElement( "div" ); var line2 = document.createElement( "div" ); this ._shape1.className = "shape1" ; line1.className = "line1shape1" ; line2.className = "line2shape1" ; this ._shape1.appendChild(line1); this ._shape1.appendChild(line2); // Boolean to indicate if the shape is in its default orientation mode or not // True means not rotated, false means rotated this ._defaultOrientation = true ; // Setting the column position in the main grid if (columnIndex) { this ._currentColPos = columnIndex; this ._shape1.style.msGridColumn = this ._currentColPos; } else { this ._currentColPos = 1; } // We always start at line 1 this ._currentLinePos = 1; // Boolean to know if the shape can be move/rotate or not // If true, this means we've reached the last line possible this ._fixed = false ; }, { /// Specify in which HTML element displayed in CSS Grid you'd like to work with /// width is the number of columns of the grid & height is the number of lines insertIntoGrid: function (element, width, height) { element.appendChild( this ._shape1); this ._gridWidth = width; this ._gridHeight = height; // These are the left & bottom max limit for this shape // when displayed in default orientation mode this ._maxLeft = width - 3; this ._maxBottom = height - 1; }, /// Rotate the Z shape 90 degrees anti/clockwise using CSS Transforms /// by simply removing/adding the shape1rotated class rotate: function () { if (! this ._fixed && this ._defaultOrientation) { // rotating 90 degrees clockwise, it will trigger also the CSS Transition WinJS.Utilities.addClass( this ._shape1, "shape1rotated" ); this ._defaultOrientation = false ; // the left limit is now +1 vs the default orientation this ._maxLeft = this ._gridWidth - 2; } else { if (! this ._fixed && this ._currentColPos < this ._maxLeft) { // removing the shape1rotated will automatically reset the shape // to its initial matrix and again the CSS Transition will do the // animation for you WinJS.Utilities.removeClass( this ._shape1, "shape1rotated" ); this ._defaultOrientation = true ; this ._maxLeft = this ._gridWidth - 3; } } }, // Internal function called by public moveLeft/moveRight _moveHorizontally: function (direction) { if (! this ._fixed && ( this ._currentColPos < this ._maxLeft || direction === -1) && ( this ._currentColPos > 2 || direction === 1)) { this ._currentColPos = this ._currentColPos + direction; this ._shape1.style.msGridColumn = this ._currentColPos; } }, /// Move the shape on the immediate left column /// Test if you've reached the left limit or not moveLeft: function () { this ._moveHorizontally(-1); }, /// Move the shape on the immediate right column /// Test if you've reached the right limit or not moveRight: function () { this ._moveHorizontally(1); }, /// Move the shape down on the immediate below line /// Test if you've reached the bottom limit or not moveDown: function () { if (! this ._fixed) { this ._currentLinePos = this ._currentLinePos + 1; this ._shape1.style.msGridRow = this ._currentLinePos; if ( this ._currentLinePos === this ._maxBottom) { this ._fixed = true ; } } } } ); WinJS.Namespace.define( "CSSTetris" , { ShapeZ: ShapeZ }); } ());
只需阅读代码即可了解其功能。 它应该被评论得足够自明。
在default.html中添加对此脚本文件的引用,并在主体中仅保留以下HTML块:
< div class ="mainGrid"> < div class ="virtualGrid"> </ div > </ div >
跳到default.js 。
拥有完善文档的代码,最酷的部分是我们现在有了有趣的IntelliSense详细信息,例如构造函数 :
或旋转功能:
为了正确使用此代码,请在processAll调用之后添加此JS块:
document.addEventListener( "keydown" , OnKeyDown, false ); mainGrid = document.getElementsByClassName( "mainGrid" )[0]; myShape = new CSSTetris.ShapeZ(4); myShape.insertIntoGrid(mainGrid, 12, 20); init();
并添加以下两个功能:
function init() { setInterval( function () { myShape.moveDown(); }, 1000); } function OnKeyDown(event) { switch (event.keyCode) { case KEYCODE_X: myShape.rotate(); break ; case KEYCODE_LEFT: myShape.moveLeft(); break ; case KEYCODE_RIGHT: myShape.moveRight(); break ; case KEYCODE_DOWN: myShape.moveDown(); break ; } }
我们完成了! 现在,我们有一个非常基本的游戏,它使用CSS Grid Layout结合图形部分CSS Transforms&Animations和几行JS代码来开始类似Tetris的游戏基础。
这是演示最终结果的简短视频:
下载视频: VideoJS的MP4 , WebM , HTML5视频播放器
您可以在此处下载与本教程的三个步骤相对应的最终Visual Studio解决方案: http : //david.blob.core.windows.net/win8/TheRealCSSGridStory.zip
那么,您现在是否确信CSS网格布局是为了简化类似俄罗斯方块的游戏的创建而设计的?
翻译自: https://www.sitepoint.com/using-css-grid-layout-and-blend-5-to-build-a-game/
blend 5