当前位置: 首页 > news >正文

2024年全球 MoonBit 编程创新赛-零基础早鸟教程-使用wasm4八小时开发井子棋小游戏

在这里插入图片描述

前言

  • 本篇文章主要分享 “2024年全球 MoonBit 编程创新赛 游戏赛道”参赛过程中九宫棋游戏的开发技巧和心得。以此抛砖引玉。首先介绍下 MoonBit。

  • 月兔语言 MoonBit 是一个用于云计算和边缘计算的 WebAssembly 端到端的编程语言工具链。 您可以访问 https://try.moonbitlang.cn 获得 IDE 环境,无需安装任何软件,也不依赖任何服务器。生成比现有解决方案明显体积更小的 WASM 文件。并有着更高的运行时性能和先进的编译时性能

  • 比赛会用到 WASM-4 引擎,此引擎是一个框架,可以开发有趣的复古游戏,最终的编译文件可在浏览器或单片机设备(如 ESP32)上直接运行。

话不多说,直入正题

开发环境准备

  • 拢共分为5步, 我们目标是以最快速度进入到游戏开发本身。因此略过目录,配置等说明,可通过官网了解更多细节。

1. 部署月兔环境

curl -fsSL https://cli.moonbitlang.cn/install/unix.sh | bash

2. 创建项目工作区

mkdir moonbit_wsam4_game
cd moonbit_wsam4_game
moon new --lib --path . --user spaceack --name mygame

3. 安装wasm4依赖

npm install -D wasm4 

4. 将 wasm4绑定增加到项目中

moon update && moon add moonbitlang/wasm4

在这里插入图片描述
此时的代码目录如下:
在这里插入图片描述

5. 更新项目配置

  1. 使用以下代码覆盖 moon.pkg.json文件
{// "is-main": true,"import": ["moonbitlang/wasm4"],"link": {"wasm-gc": {"exports": ["start", "update"],"import-memory": {"module": "env","name": "memory"}},"wasm": {"exports": ["start", "update"],"import-memory": {"module": "env","name": "memory"},"heap-start-address": 6590}}
}
  1. 使用以下代码覆盖top.mbt文件
pub fn update() -> Unit {}
pub fn start() -> Unit {}

编译及运行

  • 此时一个游戏代码已经写好了,我们编译并运行看看效果
# 编译
moon build --target wasm
# 运行npx wasm4 run target/wasm/release/build/mygame.wasm

在这里插入图片描述

  • 访问 http://localhost:4444 即可查看执行效果。可见绿油油的一片。 这是WASM-4 引擎的默认配色。
    在这里插入图片描述

游戏开发

小试牛刀

  • top.mbt文件是游戏的主程序的入口, 简单逻辑的游戏,所有逻辑仅在此文件内编写即可。

  • 依据惯例,首先我们尝试在终端打印“Hello, World”。在start()函数中调用wasm的trace方法即可。它可是我们调试程序的好帮手。😊

pub fn update() -> Unit {}
pub fn start() -> Unit {
@wasm4.trace("Hello world!");
}
  • 太好啦,经过再次编译运行,我们的代码起作用啦,在终端成功打印了Hello World.
    在这里插入图片描述

设置配色

  • wasm 单帧最多支持4种颜色,可以对调色板的4个颜色索引设置配色。这里我们要用到set_palette方法。 默认索引1为背景色。
pub fn start() -> Unit {@wasm4.trace("Hello world!");@wasm4.set_palette(1, @wasm4.rgb(0x282e30)) // 暗岩灰@wasm4.set_palette(2, @wasm4.rgb(0xaa337f)) // 陈玫红 Maximum Red Purple@wasm4.set_palette(3, @wasm4.rgb(0xd4392e)) // 茜红@wasm4.set_palette(4, @wasm4.rgb(0x898f92)) // 
}
  • 太好啦,经过再次编译运行,我们的代码起作用啦,背景色成功变为了暗岩灰。

绘制图形

  • wasm 界面的长和宽是固定的 160*160像素
  • 以左上为坐标0点(第三象限)
  • wasm支持绘制矩形,椭圆, 线等基础图形。复杂的图形由基础图形构成,
    可练习实现如下效果图:
    在这里插入图片描述
    代码如下:
pub fn update() -> Unit {@wasm4.set_draw_colors(2) // 选用调色板索引为2的颜色,即茜红 @wasm4.rect(0, 0, 80, 80) // 用茜红绘制一个矩阵 四个参数分别为第三象限的 x, y, width, heigh@wasm4.set_draw_colors(4) @wasm4.line(0, 0, 80, 80)   //一条斜线 从左上到中间(叠加到矩形之上)@wasm4.line(0, 80, 160, 80) // 中间一条横线 (叠加到矩形之上)@wasm4.line(80, 0, 80, 160) // 中间一条竖	线 (叠加到矩形之上)@wasm4.set_draw_colors(3) @wasm4.oval(80, 80, 80,80 ) // 圆 第四象限
} 
pub fn start() -> Unit {@wasm4.trace("Hello world!");@wasm4.set_palette(1, @wasm4.rgb(0xaa337f)) // 陈玫红 Maximum Red Purple@wasm4.set_palette(2, @wasm4.rgb(0xd4392e)) // 茜红@wasm4.set_palette(3, @wasm4.rgb(0xffffff)) // 白@wasm4.set_palette(4, @wasm4.rgb(0x282e30)) // 暗岩灰
}

游戏状态

在这里插入图片描述

  • 一般游戏可以抽象为一个状态机,总共有开始游戏中结束三种基本状态。那么我们需要构建一个状态结构来描绘游戏的状态信息。
  • 以井子棋游戏为例。我们用枚举类型描绘三种状态。并定义一个状态结构来存储状态信息。
  • 这里我们能领略到 MoonBit 简单且实用数据导向语言设计的魅力。
enum GameState {GSInit // 初始状态GSGameStart // 游戏中GSGameEnd // 游戏结束
}struct GameStat {mut game_state : GameState mut score : UInt // 胜利得分mut times: UInt //游戏次数gamemap : FixedArray[FixedArray[Char]] //地图mut player_x : Int mut player_y : Intmut win: String mut step: Intrng : @random.Rand
}
  • 三子棋逻辑并不复杂,至多9个变量就可以描述整个状态!

  • 然后我们使用 let 声明一个名为 gs 的变量, 并将其初始化为 GameStat 类型的一个新实例。

let gs : GameStat = GameStat::new()
pub fn GameStat::new() -> GameStat {let gamemap : FixedArray[FixedArray[Char]] = [['0', '0', '0'],['0', '0', '0'],['0', '0', '0'],]{game_state: GSInit,score: 0,times: 1,gamemap,player_x: 1,player_y: 1,win: "",step: 0,rng: @random.new(),}
}

定义动作(玩家落子,玩家移动,AI落子策略)

  • 有了前面的状态定义,我们可以围绕这些状态参数定义一些动作。
举例1:玩家落子过程
  • 地图中地图使用0表示无棋子, 1代表玩家棋子,那么我们可以写一个函数描述落子过程。
pub fn put_point(self : GameStat) -> Unit {if self.gamemap[self.player_x][self.player_y] == '0' {self.gamemap[self.player_x][self.player_y] = '1'}
}
举例2:玩家移动过程
  • player_xplayer_y 代表玩家坐标。我们可以定义一个左移的过程。
pub fn moveLeft(self : GameStat) -> Unit {if self.player_x > 0 {self.player_x = self.player_x - 1}
}
举例3:AI落子策略
  • 为了降低游戏难度,并没有使用复杂的落子策略。而是利用随机数进行随机落子。
  • 需要注意,随机坐标可能会与玩家落子点坐标重合,避免坐标重合的方法由很多种,这里使用循环检测的方式生成唯一的坐标。首先随机生成两个坐标,如果坐标点位置不为空则再次调用生成坐标的函数,直到生成两个不同的坐标。
let mut flag = true
while flag {let limit = 3let x = self.rng.int(~limit)let y = self.rng.int(~limit)if self.gamemap[x][y] == '0' {self.gamemap[x][y] = '2'self.step = self.step + 1flag = false}
}

该篇程序涉及没有复杂的算法,仅使用简单的顺序判断循环 语句和一就可实现稍稍复杂的小游戏。

正所谓:大道至简 重剑无锋 大巧不工


如果此篇文章对您有所帮助,欢迎👏Star 仓库,为我投票,您的支持是我持续更新文章的动力💪,感谢感谢 。仓库链接:https://github.com/spaceack/MoonBit-Code-JAM-2024


竞赛地址:https://tianchi.aliyun.com/competition/entrance/532262

在线试玩链接:https://moonbitlang.github.io/MoonBit-Code-JAM-2024/CS%E8%B5%8F%E9%87%91%E7%8C%8E%E6%89%8B/index.html

相关文章:

2024年全球 MoonBit 编程创新赛-零基础早鸟教程-使用wasm4八小时开发井子棋小游戏

前言 本篇文章主要分享 “2024年全球 MoonBit 编程创新赛 游戏赛道”参赛过程中九宫棋游戏的开发技巧和心得。以此抛砖引玉。首先介绍下 MoonBit。 月兔语言 MoonBit 是一个用于云计算和边缘计算的 WebAssembly 端到端的编程语言工具链。 您可以访问 https://try.moonbitlang.…...

机器学习4

第3章 线性模型 3.1 线性模型的基本形式 3.1.1 线性模型的核心公式 线性模型通过属性的线性组合进行预测,其核心公式为: [ f(x) \omega_1 X_1 \omega_2 X_2 … \omega_d X_d b ] 其中: ω 1 , ω 2 , . . . , ω d \omega_1, \omega_…...

Python数值计算(33)——simpson 3/8积分公式

1. 背景知识 既然前的Simpson可以通过使用三个点构造二次曲线近似积分,那么,如果点数增加到了4个,然后不就可以构造三次多项式的曲线,实现对目标值的积分吗? 如果采用和上一节介绍的同样的方法,我们可以推…...

<项目代码>YOLOv8路面垃圾识别<目标检测>

YOLOv8是一种单阶段(one-stage)检测算法,它将目标检测问题转化为一个回归问题,能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法(如Faster R-CNN),YOLOv8具有更高的…...

Java中的注解(白金版)

Spring中常用注解 Springboot中@Validated注解的使用 Swagger中常用注解 @Validate...

actor模型

Actor模型(Actor Model)是一种用于并发计算的数学模型和编程概念,它最早由计算机科学家 Carl Hewitt 等人提出,用于简化对多线程或并发系统的设计和实现。Actor模型在并发编程、分布式系统、消息传递系统等领域具有广泛应用。 核…...

合约门合同全生命周期管理系统:企业智能合同管理的新时代

合约门合同全生命周期管理系统:企业智能合同管理的新时代 1. 引言 随着现代企业的快速发展,合同管理的复杂性日益增加。无论是采购合同、销售合同还是合作协议,合同管理已成为企业运营中至关重要的一环。传统的手工合同管理方式往往效率低下…...

vscode如何debug环境配置?torchrun与deepspeed库又该如何配置?

文章目录 前言一、vscode命令参数传递1、验证参数py文件2、第一种vscode调用方法(launch.json配置)3、第二种vscode调用方法(launch.json配置)二、deepspeed运行py文件代码(deepspeed_test.py)三、deepspeed命令调用(无法debug)四、deepspeed使用vscode进行调试(能debug)五、vs…...

Qt元对象系统 —— 信号与槽

信号与槽讨论的是Qt对象之间的连接与交互。我们就是使用这种方式实现了一个简单的异步调用。换而言之,信号与槽让我们可以不必考虑复杂的调用。只需要当我们需要在程序中表达:“希望在程序中通知一个事件而且按照我们设定的方式给出回应”的时候&#xf…...

单细胞配色效果模拟器 | 简陋版(已有颜色数组)

目的:假设你有一组颜色了,怎么模拟查看它们在单细胞DimPlot中的美学效果呢?要足够快,还要尽可能有模拟效果。 1. 尝试1: 随机矩阵,真的UMAP降维后绘图(失败) 造一个随机矩阵,使用S…...

面向对象编程中类与类之间的关系(一)

目录 1.引言 2."有一个"关系 3."是一个"关系(继承) 4.“有一个”与“是一个”的区别 5.not-a关系 6.层次结构 7.多重继承 8.混入类 1.引言 作为程序员,必然会遇到这样的情况:不同的类具有共同的特征,至少看起来彼…...

streamlit 实现 flink SQL运行界面

实现效果 streamlit flink-playground.py 文件如下: import streamlit as st import io import contextlib import sys import os import uuid import subprocess from jinja2 import Templatest.set_page_config(layout"wide")# 设置页面标题 st.title…...

鲸鱼优化算法(Whale Optimization Algorithm, WOA)原理与MATLAB例程

鲸鱼优化算法(Whale Optimization Algorithm, WOA)是一种基于鲸鱼捕食行为的智能优化算法。它模拟了座头鲸在狩猎时的“气泡网”捕食策略。 文章目录 1.适应度函数2. 更新公式2.1 突袭行为2.2 螺旋更新3.线性递减参数4. 边界处理 MATLAB 实现示例代码说明…...

MFC七段码显示实例

在MFC中添加iSenvenSegmentAnalogX控件,添加编辑框和按钮实现在编辑框中输入数字点击按钮后数字用七段码显示 1、在对话框中点击右键如下图添加控件和变量 2、在sevenDlg.h中添加代码 public: void ShowInd(int,double);3、在sevenDlg.cpp中添加代码 void CSe…...

【日常知识点】到底推不推荐用JWT?

👉博主介绍: 博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,WEB架构师,阿里云专家博主,华为云云享专家,51CTO 专家博主 ⛪️ 个人社区:个人社区 💞 个人主页:个人主页 🙉 专栏地址: ✅ Java 中级 🙉八股文专题:剑指大厂,手撕 J…...

网络编程项目之FTP服务器

项目介绍 模拟FTP核心原理:客户端连接服务器后,向服务器发送一个文件。文件名可以通过参数指定,服务器端接收客户端传来的文件(文件名随意),如果文件不存在自动创建文件,如果文件存在&#xff0…...

SpringBoot02:第一个springboot程序

3、第一个springboot程序 3.1、准备工作 我们将学习如何快速的创建一个Spring Boot应用,并且实现一个简单的Http请求处理。通过这个例子对Spring Boot有一个初步的了解,并体验其结构简单、开发快速的特性。 我的环境准备: java version "…...

快速入门HTML

欢迎关注个人主页:逸狼 创造不易,可以点点赞吗 如有错误,欢迎指出~ 目录 第一个html文件 标签 h1~h6 p >段落标签 br > 换行标签 img >图片标签 a >超链接标签 表格标签 表单标签 表单控件 form表单 ⽆语义标签:div&span 综…...

RabbitMQ是一个开源的消息代理和队列服务器

RabbitMQ是一个开源的消息代理和队列服务器,它基于AMQP(Advanced Message Queuing Protocol,高级消息队列协议)协议实现,同时也支持其他消息协议如STOMP、MQTT等。作为一个可靠的消息传递服务,RabbitMQ在分…...

经典算法思想--并查集

前言 (最近在学习Java,所有函数都是用Java语言来书写的)前言部分是一些前提储备知识 在并查集(Union-Find)数据结构中,rank(中文称为“秩”)是用来表示树的高度或深度的一种辅助信息…...

python打卡day49

知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

微服务通信安全:深入解析mTLS的原理与实践

🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践

在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...

【Linux】Linux安装并配置RabbitMQ

目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁

赛门铁克威胁猎手团队最新报告披露,数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据,严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能,但SEMR…...