使用Blazor Web Assembly 创建简单计数游戏详细方法

作者:微信公众号:【架构师老卢】
4-30 8:57
24

概述:我为我两岁的女儿创建了一个简单的猴子数数游戏:猴子计数 - juldhais.netmonkey.juldhais.net它是使用 Blazor Web 程序集开发的,并托管在 Azure 静态应用中。这是我通过实践经验学习 Blazor 的旅程的一部分。本文将是从头开始开发猴子计数游戏的详细指南。让我们开始吧。创建新的 Blazor Web 程序集项目打开 Visual Studio 2022,然后选择 Blazor Web Assembly 独立应用项目模板。将项目名称设置为 BlazorCountingGame 或你选择的任何其他名称。将框架设置为**“.NET 8.0**”,将身份验证

本文将是从头开始开发猴子计数游戏的详细指南。

它是使用 Blazor Web 程序集开发的,并托管在 Azure 静态应用中。这是我通过实践经验学习 Blazor 的旅程的一部分。

让我们开始吧。

创建新的 Blazor Web 程序集项目

打开 Visual Studio 2022,然后选择 Blazor Web Assembly 独立应用项目模板。

将项目名称设置为 BlazorCountingGame 或你选择的任何其他名称。

将框架设置为**“.NET 8.0**”,将身份验证类型设置为**“无**”,然后选择**“配置 HTTPS”**。

单击 [创建] 以初始化新的 Blazor Web Assembly 项目。项目结构将如下所示:

从 CDN 添加 Bootstrap CSS

我们将使用 Bootstrap 进行样式设置。打开 wwwroot 文件夹中的 index.html 文件,然后将指向以下引导 CSS 文件的链接添加到标签中:<head>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" 
      integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">

我还修改_了index.html的内容,使其更简单。这是index.html_文件的完整代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Monkey Count - juldhais.net</title>
    <base href="/" />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" 
          integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
    <link rel="stylesheet" href="css/app.css" />
</head>

<body>
    <div id="app">
        Loading...
    </div>

    <script src="_framework/blazor.webassembly.js"></script>
</body>

</html>

生成随机数量的猴子

现在转到 Pages 文件夹中的 Home.razor 文件。这是我们为游戏编写代码的地方。

@page "/"

<PageTitle>Monkey Count</PageTitle>

<div class="mx-4 my-4">
    <div class="display-3 text-center">How many monkeys are there?</div>

    <div>
        <div class="row row-cols-3">
            @for (int i = 0; i < count; i++)
            {
                <div class="col">🙉</div>
            }
        </div>
    </div>
</div>

@code {
  int count;

  protected override void OnInitialized()
  {
      NextQuestion();
  }

  void NextQuestion()
  {
      // generate random number of monkeys
      count = Random.Shared.Next(1, 10);
  }
}

@page指令

@page "/"
此指令使组件成为可通过根 URL (“/”) 访问的页面。它为应用程序定义路由终结点。

PageTitle 组件

<PageTitle>Monkey Count</PageTitle>
设置页面的标题,该标题显示在浏览器选项卡上。

HTML 内容

它充当主容器,其边距属性由 Bootstrap 类(水平边距和垂直边距)设置。<div class="mx-4 my-4">mx-4my-4

这些结构用于创建一个网格(使用 Bootstrap 的带类的网格系统),该网格将显示猴子表情符号。显示的表情符号数量是根据变量的值动态生成的。divrow row-cols-3count

@code块

该块包含处理页面交互性的 C# 代码:@code

  • count变量保存要显示的猴子表情符号的数量。
  • OnInitialized是重写以在初始化组件时调用该方法的生命周期方法。NextQuestion
  • NextQuestion方法生成一个介于 1 和 9 之间的随机数,并将其分配给变量。这决定了将在网格中显示的猴子表情符号 () 的数量。count🙉

创建和随机选择

玩家必须选择正确数量的猴子。给出了三个选项,其中只有一个是正确的。

我们必须修改代码部分,如下所示:

@code {
  int count;
  List<int> choices = [];

  protected override void OnInitialized()
  {
      NextQuestion();
  }
  
  void NextQuestion()
  {
      // generate random number
      count = Random.Shared.Next(1, 10);
  
      choices.Clear();
  
      // add count to choices
      choices.Add(count);
  
      // add 2 more unique random number to choices
      while (choices.Count < 3)
      {
          int choice = Random.Shared.Next(1, 9);
  
          if (!choices.Contains(choice))
          {
              choices.Add(choice);
          }
      }
  
      // shuffle the choices using Fisher-Yates algorithm
      var n = choices.Count;
      while (n > 1)
      {
          n--;
          int k = Random.Shared.Next(n + 1);
          int value = choices[k];
          choices[k] = choices[n];
          choices[n] = value;
      }
  }
}

变量是整数列表。它旨在存储正确答案 () 和两个额外的唯一随机数作为答案的可能选择。choicescount

方法的变化:NextQuestion

  • 从前面的问题中删除任何选项。choices.Clear()
  • 将(正确答案)添加到列表中。choices.Add(count)countchoices
  • 循环继续将 1 到 9 之间的随机数添加到列表中,直到总共有三个选项。它确保这些数字是唯一的。whilechoices
  • 最后,它实现了 Fisher-Yates 随机排序算法来随机化列表中元素的顺序。choices

接下来,我们必须显示变量的内容:choices

<div class="mx-4 my-4">
  
    ...

    <div class="row">
        @foreach (var choice in choices)
        {
            <div class="col-4 text-center border py-3">
                @choice
            </div>
        }
    </div>
</div>

添加选择事件

我们必须添加方法,以便在用户做出选择时处理事件。如果答案正确,请继续下一个问题。CheckAnswer

@code {  
    
    ...  
    
    void CheckAnswer(int choice)  
    {  
        if (choice == count)  
        {  
            NextQuestion();  
        }  
    }  
}

我们需要设置事件回调,以便在单击时调用该方法:@onclickCheckAnswer

<div class="row">
    @foreach (var choice in choices)
    {
        <div class="col-4 text-center border py-3" @onclick="(() => CheckAnswer(choice))">
            @choice
        </div>
    }
</div>

添加自定义 CSS 和动画

我们将添加自定义CSS,使我们的猴子和选择看起来更大,并在玩家选择正确或错误答案时添加一些动画。

自定义 CSS

打开 wwwroot/css 文件夹中的_app.css_文件,然后将其内容替换为以下代码:

.monkey {
    font-size: 60px;
    text-align: center;
}

.choice {
    font-size: 60px;
    cursor: pointer;
}

@keyframes shake {

    0%, 100% {
        transform: translateX(0);
    }

    10%, 30%, 50%, 70%, 90% {
        transform: translateX(-10px);
    }

    20%, 40%, 60%, 80% {
        transform: translateX(10px);
    }
}

.shake {
    animation: shake 0.82s cubic-bezier(.36, .07, .19, .97) both;
    color: darkred;
}

@keyframes jump {

    0%, 100% {
        transform: translateY(0);
    }

    10%, 30%, 50%, 70%, 90% {
        transform: translateY(-10px);
    }

    20%, 40%, 60%, 80% {
        transform: translateY(0);
    }
}

.jump {
    animation: jump 1s ease;
    color: green;
}

ChatGPT 帮助我创建了摇晃跳跃动画 😄

现在回到 Home.razor 文件,将 和 CSS 类添加到相应的元素中:.monkey.choice

<div style="height:330px">
    <div class="row row-cols-3">
        @for (int i = 0; i < count; i++)
        {
            <div class="col monkey">🙉</div>
        }
    </div>
</div>

<div class="row">
    @foreach (var choice in choices)
    {
        <div class="col-4 text-center border py-3 choice" @onclick="(() => CheckAnswer(choice))">
            @choice
        </div>
    }
</div>

动画

当玩家选择正确答案时,将执行跳跃动画。如果答案不正确,它将改为执行_摇晃_动画。

为此,我们必须根据答案动态添加 or 类。在 JavaScript 中,我们可以通过使用 和 方法的组合来轻松实现这一点。.shake.jumpgetElementByIdclassList.add

但是,在 Blazor 中,按 ID 直接操作 DOM 元素并不是标准方法。Blazor 鼓励基于组件的体系结构,通过组件状态和属性来控制 UI 元素,而不是直接操作 DOM 操作。

为了启用动画,我们必须再添加两个变量,并且:animationClassselectedChoice

@code {  
    ...  
    string animationClass = "";  
    int? selectedChoice = null;  
    
    ...  
  
}

我们还必须添加 和 方法:TriggerAnimationGetAnimationClass

@code {  
    
    ...  
    
    async Task TriggerAnimation(int choice)  
    {  
        // prevent overlapping animation  
        if (selectedChoice != null) return;  
      
        selectedChoice = choice;  
      
        animationClass = selectedChoice == count ? "jump" : "shake";  
      
        await Task.Delay(1500);  
      
        animationClass = "";  
      
        selectedChoice = null;  
    }  
      
    string GetAnimationClass(int choice)  
    {  
        return selectedChoice == choice ? animationClass : "";  
    }  
}

我们需要修改 to 调用该方法并调用 to 通知组件其状态已更改:CheckAnswerTriggerAnimationStateHasChanged

async void CheckAnswer(int choice)  
{  
    await TriggerAnimation(choice);  
  
    if (choice == count)  
    {  
        NextQuestion();  
    }  
  
    StateHasChanged();  
}

为了仅将动画类应用于选定的选项,我们在循环中使用渲染选项的方法:GetAnimationClass(choice)@foreach

<div class="row">
    @foreach (var choice in choices)
    {
        <div class="col-4 text-center border py-3 choice" @onclick="(() => CheckAnswer(choice))">
            <div class="@GetAnimationClass(choice)">
                @choice
            </div>
        </div>
    }
</div>

我们还可以通过将 添加到猴子表情符号中来为猴子执行动画:@animationClass

<div style="height:330px">
    <div class="row row-cols-3">
        @for (int i = 0; i < count; i++)
        {
            <div class="col monkey @animationClass">🙉</div>
        }
    </div>
</div>

源代码获取:公众号回复消息【code:85131

相关代码下载地址
重要提示!:取消关注公众号后将无法再启用回复功能,不支持解封!
第一步:微信扫码关键公众号“架构师老卢”
第二步:在公众号聊天框发送code:85131,如:code:85131 获取下载地址
第三步:恭喜你,快去下载你想要的资源吧
相关留言评论
昵称:
邮箱:
阅读排行