2024MoonBit全球编程创新挑战赛参赛作品“飞翔的小鸟”游戏技术开发指南

本文章已经生成可运行项目,

在这里插入图片描述

一、前言

在CSDN分享技术文章的时候,偶然发现2024年MoonBit全球编程创新挑战赛正如火如荼地进行着,这场由粤港澳大湾区数字经济研究院(福田)基础软件中心主办的盛会,不仅吸引了全球各地的编程爱好者,更是成为了展示创新技术与独特创意的绝佳舞台。对前沿技术感兴趣的我,立即通过天池平台报名参加了本次比赛,游戏赛道的主题是:基于moonbit开发语言和wasm4游戏引擎开发出具有创新性和趣味性的游戏作品,在经过几天的官方文档摸索和示例教程学习,我也开发并提交了moonbit版本“飞翔的小鸟”的游戏作品。
在这里插入图片描述
MoonBit编程创新挑战赛,旨在通过编程竞赛推动计算机软件开发专业建设,助力人工智能云原生领域创新人才梯队培育,养编程语言这一基础软件领域的后备人才。它不仅仅是一场赛事,更是一个学习、交流、展示的平台。本次大赛分为游戏开发挑战赛和程序语言设计和实现赛两大赛道,吸引了众多来自高校、企业和独立开发者的热情参与。我们有机会与来自世界各地的优秀开发者同台竞技,共同探索编程的无限可能。

二、MoonBit介绍

MoonBit(月兔)是中国开发者团队创建的编程语言(类似 Rust,支持 GC),是基于WASM驱动的云计算智能开发平台和边缘计算平台:

1.全产品协同设计

  • 程序语言、编译器、构建系统和集成开发环境的协同设计保证整个系统的一致性,减少组件摩擦,大幅提升整体性能
  • 生成比任何现有解决方案体积都小的WebAssembly目标代码

2.程序语言

  • MoonBit语言专为WebAssembly设计,同时提供JavaScript,Native等多种后端,支持函数式和面向对象等多种编程范式
  • 实用的类型系统,面向数据的语言设计,让任何背景的开发者迅速上手

3.编译器与构建系统

  • 顶尖的编译时性能
  • 全代码优化提供良好的运行时性能
  • 支持增量化、并行化编译,极快的编译速度轻松面对超大规模编程场景

4.集成开发环境

  • 极快的响应速度,在云端获得本地开发体验,
  • 提供JavaScript实现的LSP,可在浏览器离线开发

三、游戏开发

3.1 MoonBit开发环境搭建

为了提供更佳的开发体验,你可以在 VS Code Marketplace 中安装 MoonBit 插件。通过插件来安装开发环境,此插件为 MoonBit 提供了丰富的开发环境,包括语法高亮、代码完成等功能

第 1 步:安装最新版本的 VS Code。

第 2 步:点击左侧的“扩展”,搜索“MoonBit”并安装 VS Code MoonBit 扩展
在这里插入图片描述

第 3 步:按下shift+cmd+p快捷键(mac快捷键,windows和linux快捷键是ctrl+shift+p)
输入 MoonBit:install latest moonbit toolchain,随后会出现提示框,点击“yes”,等待程序下载完成。
在这里插入图片描述

第 4 步: 下载完成后,点击terminal (cmd控制台),输入moon new hello ; code hello以创建并打开新项目。

第 5 步: 项目启动后,再次打开terminal(cmd控制台),输入moon run main命令,即可开始执行代码。

到这一步我们的moonbit环境就装好了,就可以使用vscode和 moonbit语言来开发各种应用了

3.2 如何在MoonBit项目中集成wasm-4框架

WASM-4 是一款使用 WebAssembly 实现的较底层的虚拟游戏机,主要用于构建小型、复古的游戏。 和其他一些可能可以编译到 WebAssembly 的语言不同,MoonBit 为 WASM 平台提供第一方支持,社区则提供了 WASM-4 的 binding。 使用 WASM-4 进行游戏开发,MoonBit 是有许多优势的

第 1 步: 配置WASM-4环境 wasm-4 runtime,可通过 npm 安装
执行命令

npm install -D wasm4

第二步
新建一个 MoonBit 项目,将 wasm4 binding 作为依赖加入到项目中:

moon add moonbitlang/wasm4

第三步
修改 moon.pkg.json ,linking 配置中应当导出 start update 方法供 wasm-4 调用:

{
  "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
    }
  }
}

注意对于 wasm 后端,在 0x0000 ~ 0x19BE(6590,开区间)范围内的地址是分配给 wasm4 ABI 的,MoonBit 的堆在该区间之后。 若使用 wasm-gc 后端则不需配置。

根据 ABI 的规格,必须要导出 start update 方法
start 仅在游戏初始化时执行一次
update 会以游戏刷新率(60Hz)的频率执行
基本想法是,我们将任何静态代码(即那些不会改变游戏状态的代码)放在 start 方法中(例如初始化调色板); 除此之外的动态代码(即那些会更改游戏状态的),就需要放在 update 方法中。 游戏的主要逻辑和相关的函数调用都是在 update 中完成的。

在 MoonBit 中,函数是通过改变其可见性为 pub 来实现导出功能的。

确保环境配置一切无误之后,我们就可以开始编写游戏了。

3.3 实战开发基于moonbit和wasm4的飞翔的小鸟游戏

游戏中,玩家需要通过上下左右按键控制Bird,在不断移动的障碍pipe之间穿梭,通过点击上\下键控制小鸟的上升或者下降,成功避开障碍物可计1分,以此来挑战更高的分数.

1、定义游戏中的对象

这里以玩家控制的主角flybird和pipe 为例,使用moonbit的语法定义类型和实例化对象,语法简洁且实用.

struct BirdModel {    //bird 
  mut x : Int   //mut 标识之后表示 此属性可以修改
  mut y : Int
  width : Int
  height : Int
  mut birdVelocity : Int  //y轴向下方向速度
}
struct PipesItem {    // 障碍
  mut x : Int
  top : Int
  bottom : Int
  width : Int
}

let bird : BirdModel = { //bird初始化
  x: 10,
  y: 0,
  width: 15,
  height: 15,
  birdVelocity: 1 / 2,
}

let pipes : Array[PipesItem] = [{ x: 160, top: 60, bottom: 40, width: 15 }] // 障碍初始化

2、将定义的游戏角色bird和pipe绘制在画布上

绘制游戏角色到画布上,这里就我们用到了wasm4的语法,同样也和简单,这里是一个具体示例:

//绘制bird
pub fn drawBird() -> Unit {
  @wasm4.set_draw_colors(4)
  let blit_flag : @wasm4.BlitFlag = {
    one_bit_per_pixel: true,
    flip_x: false,
    flip_y:false,
    rotate:false,
  }
  @wasm4.blit(
    @wasm4.sprite(b"\xff\xff\x7f\x87\x3f\x00\x3f\x30\x0f\x33\x03\x03\x00\x03\x80\x03\x80\x07\x80\x07\x80\x0f\xc0\x1f\xe0\x3f\x00\x3f\x80\xff\xff\xff"),
    bird.x,
    bird.y,
    16,
    16,
    blit_flag,
  )
}

// 绘制障碍物
//这里我们用到了moonbit的循环语法,语法简洁且实际体验起来循环生成速度也很快
pub fn drawPipes() -> Unit {
  for pipe in pipes {
    @wasm4.set_draw_colors(3)
    @wasm4.rect(pipe.x, 0, pipe.width, pipe.top)
  }
}


3、为元素上色

在刚刚上一步绘制游戏角色的时候,我们用到了颜色,正常在前端开发中,元素的背景色可以随便设置,但在wasm-4 的调色板寄存器一次只能存储 4 种颜色, 但可以通过随时更改这一寄存器来引入新的颜色。我们使用 set_palette 来配置调色板,但在这个实现中就使用默认颜色配置。默认的配色看起来像 gameboy 的:

在这里插入图片描述

所以我们设计好游戏的主题颜色,初始化的时候,设置画布的四种颜色

pub fn start() -> Unit {
  @wasm4.set_palette(1, @wasm4.rgb(0x6FC5CC)) //背景   天空色
  @wasm4.set_palette(2, @wasm4.rgb(0xffc000)) // 小鸟  
  @wasm4.set_palette(3, @wasm4.rgb(0x64B625)) // 柱子  绿色
  @wasm4.set_palette(4, @wasm4.rgb(0xE0F8CF)) //默认背景色

}


然后游戏角色或者障碍物需要上色的时候,直接调用即可,示例

  @wasm4.set_draw_colors(4)
  @wasm4.rect(bird.x, bird.y, 20, 20)  // 绘制一个正方形

4、获取用户输入,移动bird
wasm4可以获取到玩家输入可以有多种设备,如键盘,鼠标,游戏手柄等。用到的是@wasm4.get_gamepad()方法,我们点进源码里面是这样封装的

/// Gets the state of the gamepads.
/// @param index the index of the gamepad to get, from 1 to 4 (inclusive)  
/// @return the state of the gamepads

pub fn get_gamepad(~index : UInt = 1) -> GamePad {
  if index.reinterpret_as_int() > 4 {
    trace("Gamepad index out of range")
    panic()
  }
  let state = load_byte(address_GAMEPADS + index.reinterpret_as_int() - 1).to_int()
  GamePad::{
    button_1: (state & 1) == 1,
    button_2: (state & 2) == 2,
    button_left: (state & 16) == 16,
    button_right: (state & 32) == 32,
    button_up: (state & 64) == 64,
    button_down: (state & 128) == 128,
  }
}

所以我们控制游戏角色运动的方法如下:

//控制bird,如果是用户按了键盘右键,bird的x轴坐标加1
 if @wasm4.get_gamepad(index=1).button_right  {
         bird.x += 1
 }

5 游戏碰撞逻辑处理

在上面的文章中博主已经实现了各种游戏角色绘制到画布上,同时也可以控制bird进行运动,下面给大家分享一下,游戏的碰撞逻辑:bird的坐标区域和游戏中全部障碍物的坐标区域发生了重合,即通过坐标之间的对比,来判断是否发生了碰撞和游戏失败.

体现到编码中即为:

// 检查碰撞
pub fn checkCollisions() -> Unit {
  for pipe in pipes {
    // Check if the bird is within the horizontal bounds of the pipe  
    if bird.x < pipe.x + pipe.width && bird.x + bird.width > pipe.x {
      // Check if the bird is within the vertical bounds of the top or bottom part of the pipe  
      if bird.y < pipe.top || bird.y + bird.width > screen_size - pipe.bottom {
            gameState.gameTitle = "gameover"
            gameState.isGameOver = true
            @wasm4.set_draw_colors(0x4U, index=4)
            @wasm4.text("Game Over!", 80, 80)
      }
    }
  }
}

当然为了使游戏更丰富一些,我们还可以使用wasm4中的tone方法,给碰撞之后的判断里面加一些提示音

 源码:
 fn tone(
  frequency : (UInt, UInt),
  duration : ADSR,
  volume : ADSRVolume,
  flags : ToneFlag
)
- frequency:频率,即用频率度量的音调
- Duration:时长,是用 envelope 记录的。 envelope 用于记录一个声音随着时间的变化, 此处的 ADSR 指定了 envelope 的四个参数 attack, decay, sustain and release。
- volume:字面义,音量大小
- flags:包括 channel, duty cycle 和 panning。 对于我们的游戏来说,使用默认值即可。

示例:

pub fn checkCollisions() -> Unit {
  for pipe in pipes {
    // Check if the bird is within the horizontal bounds of the pipe  
    if bird.x < pipe.x + pipe.width && bird.x + bird.width > pipe.x {
      // Check if the bird is within the vertical bounds of the top or bottom part of the pipe  
      if bird.y < pipe.top || bird.y + bird.width > screen_size - pipe.bottom {
             @wasm4.tone(
                (2000, 0),
                @wasm4.ADSR::new(5),
                @wasm4.ADSRVolume::new(100),
                @wasm4.ToneFlag::new(),
            )
            gameState.gameTitle = "gameover"
            gameState.isGameOver = true
            @wasm4.set_draw_colors(0x4U, index=4)
            @wasm4.text("Game Over!", 80, 80)
      }
    }
  }
}

到这里我们的游戏就完成了.
在这里插入图片描述

四、总结

在开发过程中,我充分学习了Moonbit编程语法中的判断、循环、逻辑运算 、数据类型、函数对象 等知识点,不仅新学习了一门编程语言,也深深感受到Moonbit编程语言简单且实用的数据导向语言设计理解。在后续会持续关注Moonbit技术生态的发展,也争取能为Moonbit技术生态的发展壮大贡献自己的一点力量.

同时我也参加了本次比赛,为了能让这款游戏更好地呈现给玩家,我按照MoonBit大赛的作品规范,在GitHub上创建了公开可见的仓库,提供了游戏描述、玩法介绍和运行视频链接,让更多的人能够了解并体验这款游戏。MoonBit编程创新挑战赛不仅让我有机会展示自己的作品,更让我在与其他开发者的交流中收获颇丰。分享经验、探讨技术,共同推动着编程技术的发展和创新。我相信,通过这场赛事,我不仅提升了自己的编程能力,也结识了一群志同道合的朋友。

如果你也热爱编程,渴望挑战自我,不妨加入MoonBit全球编程创新挑战赛的行列,让我们一起在编程的世界里翱翔,创造属于自己的辉煌!

[ MoonBit编程创新挑战赛官方地址][https://www.moonbitlang.cn/2024-mgpic]
MoonBit编程创新挑战赛官方地址
[我的参赛作品github地址]https://github.com/hyhstyle/MoonBit-Code-JAM-2024
我的参赛作品github地址
欢迎大家来体验和参赛,也为我的作品点上宝贵的star~~

本文章已经生成可运行项目
### 关于“互联网+”大赛参赛指南与规则 “互联网+”大赛是一项旨在促进技术创新和应用实践的比赛活动。根据已知的信息,以下是关于该比赛的关键要点: #### 时间安排 报名截止时间为8月31日,初赛/复赛将在9月30日前完成,而全国总决赛预计在2021年10月下旬举行[^1]。 #### 赛事主题 本次大赛特别设置了华为云赛道,并围绕物联网(IoT)技术展开命题设计。参赛者可以通过结合自身的创意与IoT技术,实现场景智能化的设计方案。 #### 报名方式 有兴趣参与的团队或个人可以点击进入赛事页面获取详细的报名流程及相关资料。 #### 学习资源 为了帮助参赛选手更好地准备比赛,“互联网+”大赛还提供了丰富的学习材料供下载和研究。 --- ### 作品示例参考 虽然上述信息主要针对的是“互联网+”大赛的具体情况,但从其他类似的编程比赛中也可以找到一些灵感。例如,在2024 MoonBit全球编程创新挑战赛中,有一款名为“飞翔小鸟”的游戏作为参赛作品被提及。该游戏技术开发文档、源码以及演示视频均托管在一个公开的GitHub仓库中,可供开发者查阅和借鉴[^2]。 以下是一个简单的代码片段展示了如何初始化一个基于Pygame的游戏框架,这可能适用于像“飞翔小鸟”这样的项目: ```python import pygame pygame.init() screen = pygame.display.set_mode((800, 600)) running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False screen.fill((0, 0, 0)) # 清屏操作 pygame.display.flip() # 更新屏幕显示内容 pygame.quit() ``` 此代码仅为示意用途,实际游戏中还需要加入更多功能模块来完善用户体验。 --- ### 总结 综上所述,“互联网+”大赛提供了一个良好的平台让参与者探索前沿科技领域的同时锻炼自身技能水平;与此同时,通过分析过往成功案例如MoonBit中的优秀成果也能为我们带来不少启发价值。
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

言程序plus

你的鼓励将是我最大的创作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值