iT邦幫忙

2023 iThome 鐵人賽

DAY 13
0

Bevy Plugins 學習

以昨天的學習來看,想要製作遊戲應該是先從製作Plugins開始,有點像是模組化從每個模組開始,今天來看一下官方的Plugins範例

//! Renders an animated sprite by loading all animation frames from a single image (a sprite sheet)
//! into a texture atlas, and changing the displayed image periodically.

use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) // prevents blurry sprites
        .add_systems(Startup, setup)
        .add_systems(Update, animate_sprite)
        .run();
}

#[derive(Component)]
struct AnimationIndices {
    first: usize, // 動畫的起始幀
    last: usize, // 動畫的結束幀
}

#[derive(Component, Deref, DerefMut)]
struct AnimationTimer(Timer);

fn animate_sprite(
    time: Res<Time>, // 時間資源
    mut query: Query<( // 對所有具有 AnimationIndices、AnimationTimer 和 TextureAtlasSprite 組件的實體進行查詢
        &AnimationIndices,
        &mut AnimationTimer,
        &mut TextureAtlasSprite,
    )>,
) {
    for (indices, mut timer, mut sprite) in &mut query { // 遍歷所有查詢到的實體
        timer.tick(time.delta()); // 更新 AnimationTimer
        if timer.just_finished() { // 如果 AnimationTimer 結束
            sprite.index = if sprite.index == indices.last { // 如果當前的 sprite 索引等於動畫的結束幀
                indices.first // 將 sprite 索引設定為動畫的起始幀
            } else { // 否則
                sprite.index + 1 // 將 sprite 索引增加 1
            };
        }
    }
}

fn setup(
    mut commands: Commands, 
    asset_server: Res<AssetServer>, 
    mut texture_atlases: ResMut<Assets<TextureAtlas>>, 
) {
    let texture_handle = asset_server.load("textures/rpg/chars/gabe/gabe-idle-run.png"); // 載入 sprite sheet 圖片
    let texture_atlas =
        TextureAtlas::from_grid(texture_handle, Vec2::new(24.0, 24.0), 7, 1, None, None); // 根據 sprite sheet 圖片建立 TextureAtlas 
    let texture_atlas_handle = texture_atlases.add(texture_atlas); // 將 TextureAtlas 添加到AssetServer中

    // 使用 sprite sheet 圖片中構成跑步動作的所有 sprite
    let animation_indices = AnimationIndices { first: 1, last: 6 };

    // 建立相機實體
    commands.spawn(Camera2dBundle::default());

    // 建立 sprite 實體
    commands.spawn((
        SpriteSheetBundle {
            texture_atlas: texture_atlas_handle, // 設定 sprite sheet 
            sprite: TextureAtlasSprite::new(animation_indices.first), // 設定 sprite 的起始幀
            transform: Transform::from_scale(Vec3::splat(6.0)), // 設定 sprite 的縮放
            ..default()
        },
        animation_indices, // 設定 sprite 的動畫索引
        AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)), // 設定 sprite 的動畫計時器
    ));
}

而使用到的圖片素材是
https://ithelp.ithome.com.tw/upload/images/20230927/20140358sB2doh7vFR.png
執行後就可以看到人物再往前跑
https://ithelp.ithome.com.tw/upload/images/20230927/20140358jxoqMOcGRP.png
https://ithelp.ithome.com.tw/upload/images/20230927/20140358eFFfM4CAlJ.png
開始有點感覺了,如果要顯示角色上下左右的移動應該是要有對應四組的動作圖片然後讀取按鍵輸入在顯示對應的幀,明天也再來繼續探索Bevy範例。


上一篇
[Day 12] Bevy Plugins
下一篇
[Day 14] Bevy Plugins 學習 - 用鍵盤控制人物移動
系列文
三十歲時在做什麼?有沒有空?可以來做遊戲嗎?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言