首页 > 编程语言 >2024MoonBit全球编程创新挑战赛参赛作品“飞翔的小鸟”技术开发指南

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

时间:2024-11-11 10:19:28浏览次数:6  
标签:wasm4 2024MoonBit 游戏 编程 pipe width set 挑战赛 bird

本文转载自 CSDN:https://blog.csdn.net/m0_61243965/article/details/143510089作者:言程序plus

实战开发基于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)

    // 底部柱子
    // @wasm4.set_draw_colors(0x2U, index=1)
    @wasm4.set_draw_colors(3)
    @wasm4.rect(pipe.x, screen_size - pipe.bottom, pipe.width, pipe.bottom)
  }
}

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全球编程创新挑战赛的行列,让我们一起在编程的世界里翱翔,创造属于自己的辉煌!

标签:wasm4,2024MoonBit,游戏,编程,pipe,width,set,挑战赛,bird
From: https://blog.csdn.net/m0_74743788/article/details/143674430

相关文章

  • 【编程语言】理解C/C++当中的指针
    指针是C/C++语言中一个非常强大且重要的概念,也是编写高效程序的基础之一。对于没有编程背景的初学者来说,理解指针可能有些难度,但通过本篇文章的介绍,相信你会对指针有一个清晰的认识。本文将从指针的基本概念、作用、代码示例、注意事项等方面,带你一步步了解指针的世界。什......
  • 实验3 类和对象_基础编程2
    任务1:#pragmaonce#include<iostream>#include<string>usingstd::string;usingstd::cout;//按钮类classButton{public:Button(conststring&text);stringget_label()const;voidclick();private:stringlabel;};......
  • 实验3 类和对象 基础编程2
    实验任务1:源代码button.hpp:点击查看代码1#pragmaonce23#include<iostream>4#include<string>56usingstd::string;7usingstd::cout;89//按钮类10classButton{11public:12Button(conststring&text);13stringget_label(......
  • 实验3 类和对象_基础编程2
    任务1源程序:button.hpp1#pragmaonce23#include<iostream>4#include<string>56usingstd::string;7usingstd::cout;89//按钮类10classButton{11public:12Button(conststring&text);13stringget_label()cons......
  • 实验3 类和对象_基础编程2
    任务一task1.cppbutton.hpp#pragmaonce#include<iostream>#include<string>usingstd::string;usingstd::cout;//按钮类classButton{public:Button(conststring&text);stringget_label()const;voidclick();private:string......
  • 实验3 类和对象_基础编程2
    实验任务1button.cpp源码#pragmaonce#include<iostream>#include<string>usingstd::string;usingstd::cout;//按钮类classButton{public:Button(conststring&text);stringget_label()const;voidclick();private:string......
  • 鸿蒙网络编程系列 43- 仓颉版 HttpRequest 下载文件示例
    HttpRequest文件下载示例编写下面详细介绍创建该示例的步骤(确保DevEcoStudio已安装仓颉插件)。步骤1:创建[Cangjie]EmptyAbility项目。步骤2:在module.json5配置文件加上对权限的声明:"requestPermissions":[{"name":"ohos.permission.INTERNET"}]这里添加了访问......
  • 编程语言哪家强?对比C,C++,Java等语言的区别
    文章目录开始主题前的一些问题语言举例汇编语言C语言C语言比起汇编多了什么东西?编译器的作用是?C++语言C++语言比C语言多了什么?(推荐《深度探索C++对象模型》)C++有什么编程范式?C++语言特性分别是怎样实现?C++编译器的准则与virtual机制?C++的virtual机制如何实现的?跨平台......
  • Rust 在 Android 的编程实践——技术驱动的车云一体化解决方案探索
    Rust在Android的编程实践——技术驱动的车云一体化解决方案探索Greptime车云一体化解决方案颠覆了从前传统的车云协同模式,采用更加低成本、高效率的方案来满足当前的市场需求。其中GreptimeDBEdge作为核心组件,专为车机环境量身打造。本文旨在详尽探讨在Android平台利用......
  • 实验3 类和对象_基础编程2
    任务一:button.hpp:#pragmaonce#include<iostream>#include<string>usingstd::string;usingstd::cout;//按钮类classButton{public:Button(conststring&text);stringget_label()const;voidclick();private:string......