练习 - Blazor
在本练习中,我们将创建一个 Blazor 项目,并在该模块中开始构建“四子棋”游戏应用。
创建新的 Blazor 项目
首先,让我们使用 Visual Studio 2022 为我们的游戏创建一个新项目。
在 Visual Studio 2022 中依次选择“文件”>“新建”>“项目”菜单,创建新的 Blazor 应用。
从模板列表中选择“Blazor Web 应用”并将其命名为“四子棋”。 选择下一步。
选择 .NET 8 框架版本。 身份验证类型应设置为“无”,交互呈现模式应设置为“服务器”,交互位置应设置为“每页/组件”。 将所有其他选项保留为默认值。
此操作应创建包含我们应用的“四子棋”目录。
在 Visual Studio 2022 中按 F5 运行应用。
现在,应该会看到该 Blazor 应用在浏览器中运行:
祝贺你! 你已创建首个 Blazor 应用!
创建棋盘组件
接下来,让我们创建一个游戏棋盘组件,供玩家在游戏中使用。 组件是使用 Razor 语法定义的,该语法是 HTML 和 C# 的结合体。
右键单击 Visual Studio 解决方案资源管理器中的“组件”文件夹。 从上下文菜单中选择“添加”>“Razor 组件”,并将文件命名为“Board.razor”。
我们使用此组件来保存游戏棋盘布局所需的全部内容,并管理与其之间的交互操作。 此新组件的初始内容是一个
h3
标记和一个@code
代码块,指示应在何处编写 C# 代码:<h3>Board</h3> @code { }
使用“PageTitle”标记打开 Components/Pages/Home.razor 文件并清除第三行后的所有内容,从而准备好
Home
页面。@page "/" <PageTitle>Home</PageTitle>
通过添加与我们新组件的文件名匹配的
<Board />
标记,将Board
组件添加到Home
页面。@page "/" <PageTitle>Index</PageTitle> <Board />
要查看更改,请使用 F5 运行该应用。 如果应用已运行,请点击“运行/继续”按钮旁边的“热重载”按钮,将更改应用到正在运行的应用。
提示
在“热重载”菜单中选择“保存文件时进行热重载”选项,以在更改文件时将更改应用到正在运行的应用。
祝贺你! 你已生成第一个组件,并在 Blazor 页面上使用它。
向游戏棋盘添加内容和样式
让我们开始定义一个包含七列和六行的游戏棋盘。 随后,增添一些样式,让棋盘更加生动。
在 Board.razor 文件中,移除顶部的 HTML 并添加以下内容来定义包含 42 个游戏棋子放置位置的棋盘。
我们可以使用 C#
for
循环生成 42 个棋盘置。 我们选取并重复容器span
标记的内容 42 次以表示我们的棋盘。<div> <div class="board"> @for (var i = 0; i < 42; i++) { <span class="container"> <span></span> </span> } </div> </div>
保存棋盘组件时,我们的应用会刷新并显示为空页面,这是因为“热重载”功能会重新生成并启动更新后的应用。
注意
在文件发生更改时,Visual Studio 可能会提示你重启应用。 确认应在编辑代码后重新生成该应用,且该应用将在添加功能时自动重启并刷新浏览器。
设置组件的样式
让我们通过在 Board.razor 文件的第一个 div
标记上方定义棋盘边框和玩家的颜色,为 Board
组件添加一些样式:
<HeadContent>
<style>
:root {
--board-bg: yellow; /** the color of the board **/
--player1: red; /** Player 1's piece color **/
--player2: blue; /** Player 2's piece color **/
}
</style>
</HeadContent>
这样便会选取 CSS 变量 --board-bg
、--player1: red
、--player2: blue
并将其用于此组件的样式表的其余部分。
接下来,我们将游戏的已完成样式表添加到 Board
组件。
右键单击“组件”文件夹上的解决方案资源管理器,并创建一个名为“Board.razor.css”的新 CSS 文件。
将以下内容复制到新的 Board.razor.css 文件中:
div{position:relative}nav{top:4em;width:30em;display:inline-flex;flex-direction:row;margin-left:10px}nav span{width:4em;text-align:center;cursor:pointer;font-size:1em}div.board{margin-top:1em;flex-wrap:wrap;width:30em;height:24em;overflow:hidden;display:inline-flex;flex-direction:row;flex-wrap:wrap;z-index:-5;row-gap:0;pointer-events:none;border-left:10px solid var(--board-bg)}span.container{width:4em;height:4em;margin:0;padding:4px;overflow:hidden;background-color:transparent;position:relative;z-index:-2;pointer-events:none}.container span{width:3.5em;height:3.5em;border-radius:50%;box-shadow:0 0 0 3em var(--board-bg);left:0;position:absolute;display:block;z-index:5;pointer-events:none}.player1,.player2{width:3.5em;height:3.5em;border-radius:50%;left:0;top:0;position:absolute;display:block;z-index:-8}.player1{background-color:var(--player1);animation-timing-function:cubic-bezier(.5,.05,1,.5);animation-iteration-count:1;animation-fill-mode:forwards;box-shadow:0 0 0 4px var(--player1)}.player2{background-color:var(--player2);animation-timing-function:cubic-bezier(.5,.05,1,.5);animation-iteration-count:1;animation-fill-mode:forwards;box-shadow:0 0 0 4px var(--player2)}.col0{left:calc(0em + 9px)}.col1{left:calc(4em + 9px)}.col2{left:calc(8em + 9px)}.col3{left:calc(12em + 9px)}.col4{left:calc(16em + 9px)}.col5{left:calc(20em + 9px)}.col6{left:calc(24em + 9px)}.drop1{animation-duration:1s;animation-name:drop1}.drop2{animation-duration:1.5s;animation-name:drop2}.drop3{animation-duration:1.6s;animation-name:drop3}.drop4{animation-duration:1.7s;animation-name:drop4}.drop5{animation-duration:1.8s;animation-name:drop5}.drop6{animation-duration:1.9s;animation-name:drop6}@keyframes drop1{100%,75%,90%,97%{transform:translateY(1.27em)}80%{transform:translateY(.4em)}95%{transform:translateY(.8em)}99%{transform:translateY(1em)}}@keyframes drop2{100%,75%,90%,97%{transform:translateY(5.27em)}80%{transform:translateY(3.8em)}95%{transform:translateY(4.6em)}99%{transform:translateY(4.9em)}}@keyframes drop3{100%,75%,90%,97%{transform:translateY(9.27em)}80%{transform:translateY(7.2em)}95%{transform:translateY(8.3em)}99%{transform:translateY(8.8em)}}@keyframes drop4{100%,75%,90%,97%{transform:translateY(13.27em)}80%{transform:translateY(10.6em)}95%{transform:translateY(12em)}99%{transform:translateY(12.7em)}}@keyframes drop5{100%,75%,90%,97%{transform:translateY(17.27em)}80%{transform:translateY(14em)}95%{transform:translateY(15.7em)}99%{transform:translateY(16.5em)}}@keyframes drop6{100%,75%,90%,97%{transform:translateY(21.27em)}80%{transform:translateY(17.4em)}95%{transform:translateY(19.4em)}99%{transform:translateY(20.4em)}}
下面是选取的该 CSS 文件中的部分内容,用于设置棋盘格式并为每个空间“打孔”。 该 CSS 文件中还提供了更多内容来设置屏幕上的棋子及其动画效果。
div.board { margin-top: 1em; flex-wrap: wrap; width: 30em; height: 24em; overflow: hidden; display: inline-flex; flex-direction: row; flex-wrap: wrap; z-index: -5; row-gap: 0; pointer-events: none; border-left: 10px solid var(--board-bg); } span.container { width: 4em; height: 4em; margin: 0; padding: 4px; overflow: hidden; background-color: transparent; position: relative; z-index: -2; pointer-events: none; } .container span { width: 3.5em; height: 3.5em; border-radius: 50%; box-shadow: 0 0 0 3em var(--board-bg); left: 0px; position: absolute; display: block; z-index: 5; pointer-events: none; }
浏览器应该为你更新内容(如果没有,可以使用 F5 手动刷新浏览器),你应该会看到相应的黄色四子棋棋盘:
恭喜,你现在已初步创建了游戏。 在后面的单元中,我们将向其添加游戏逻辑。