Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Snake game: 最終的なアセンブリ

src/main.rs ファイル内のコードは、これまで説明してきた仕組みをすべてまとめて、最終的なゲームを作り上げます。

#![no_main]
#![no_std]

mod controls;
mod display;
pub mod game;

use controls::{get_turn, init_buttons};
use display::{clear_display, display_image, init_display};
use game::{Game, GameStatus};

use cortex_m_rt::entry;
use embedded_hal::delay::DelayNs;
use microbit::{
    display::nonblocking::{BitImage, GreyscaleImage},
    hal::{Rng, Timer},
    Board,
};
use panic_rtt_target as _;
use rtt_target::rtt_init_print;

#[entry]
fn main() -> ! {
    rtt_init_print!();
    let board = Board::take().unwrap();
    let mut timer = Timer::new(board.TIMER0).into_periodic();
    let mut rng = Rng::new(board.RNG);
    let mut game = Game::new(&mut rng);

    init_buttons(board.GPIOTE, board.buttons);
    init_display(board.TIMER1, board.display_pins);

    loop {
        loop {
            // Game loop
            let image = GreyscaleImage::new(&game.game_matrix(6, 3, 9));
            display_image(&image);
            timer.delay_ms(game.step_len_ms());
            match game.status {
                GameStatus::Ongoing => game.step(get_turn(true)),
                _ => {
                    for _ in 0..3 {
                        clear_display();
                        timer.delay_ms(200u32);
                        display_image(&image);
                        timer.delay_ms(200u32);
                    }
                    clear_display();
                    display_image(&BitImage::new(&game.score_matrix()));
                    timer.delay_ms(2000u32);
                    break;
                }
            }
        }
        game.reset();
    }
}

ボード、そのタイマー、および RNG ペリフェラルを初期化した後、Game 構造体と microbit::display::blocking モジュールの Display を初期化します。

「ゲームループ」(main 関数内に配置した「メインループ」の中で実行されます)では、次の手順を繰り返し実行します。

  1. グリッドを表す 5×5 のバイト配列を取得します。Game::get_matrix メソッドは 3 つの整数引数(いずれも 0 から 9 までの範囲である必要があります)を受け取り、これらは最終的に頭、尾、食べ物をどの程度明るく表示するかを表します。

  2. Game::step_len_ms メソッドで決まる時間だけ、行列を表示します。現在の実装では、このメソッドは基本的に各ステップの間に 1 秒を確保し、プレイヤーが 5 点獲得するたびに 200ms 短くなります(食べ物 1 個を食べる = 1 点)。ただし、下限は 200ms です。

  3. ゲームの状態を確認します。これが Ongoing(初期値)であれば、ゲームを 1 ステップ進めてゲームの状態(status プロパティを含む)を更新します。そうでなければゲームは終了しているため、現在の画像を 3 回点滅させ、その後プレイヤーのスコア(スコアに対応する数の LED を点灯させたものとして表現されます)を表示して、ゲームループを終了します。

メインループでは、各反復の後にゲームの状態をリセットしながら、ゲームループを繰り返し実行するだけです。