0Pricing
Learn Rust Coding · บทเรียน

แนวคิดแบบ ECS

เอนทิตี คอมโพเนนต์ และระบบ

แนวคิดแบบ ECS เป็นบทเรียน Learn Rust Coding ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Learn Rust Coding และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน

สิ่งที่ ECS แก้ปัญหา

Bevy สร้างขึ้นบนรูปแบบ Entity Component System (ECS) แทนที่จะใช้ลำดับชั้นการสืบทอดที่ซับซ้อน คุณประกอบพฤติกรรมจากส่วนข้อมูลขนาดเล็กที่เป็นอิสระต่อกัน

การออกแบบที่เน้นข้อมูลนี้ทำให้การจัดวางหน่วยความจำเหมาะกับแคช และเปิดให้เอนจินแบ่งงานทำงานขนานกันบนแกน CPU ได้แทบโดยไม่มีต้นทุนเพิ่ม

เอนทิตีเป็นเพียง ID

เอนทิตีไม่มีอะไรมากไปกว่าตัวระบุขนาดเล็ก — ดัชนีที่มีรุ่นกำกับ เอนทิตีไม่ครอบครองข้อมูลและไม่มีพฤติกรรมของตัวเอง

ลองนึกภาพว่าเป็นคีย์ในแถวฐานข้อมูล คอมโพเนนต์ที่แนบกับคีย์นั้นจะให้ความหมายแก่เอนทิตี เช่น "Player" หรือ "Bullet"

// An Entity is a tiny handle
struct Entity {
    index: u32,
    generation: u32,
}

คอมโพเนนต์คือข้อมูลล้วน

คอมโพเนนต์คือโครงสร้าง Rust ธรรมดาที่อนุพันธ์ Component โดยเก็บสถานะไว้แต่ไม่มีตรรกะ

ควรทำให้แต่ละคอมโพเนนต์มีขนาดเล็กและมุ่งเน้นหน้าที่เดียว ตำแหน่ง ความเร็ว และค่าพลังชีวิตควรเป็นคอมโพเนนต์สามตัวแยกกัน แทนที่จะรวมเป็นโครงสร้างขนาดใหญ่เพียงตัวเดียว

use bevy::prelude::*;

#[derive(Component)]
struct Position { x: f32, y: f32 }

#[derive(Component)]
struct Velocity { x: f32, y: f32 }

ระบบเก็บตรรกะ

ระบบคือฟังก์ชันธรรมดาที่ทำงานกับคอมโพเนนต์ ตรรกะเกมทั้งหมดของคุณจะอยู่ที่นี่

Bevy จะตรวจสอบพารามิเตอร์ของแต่ละระบบเพื่อดูว่าระบบเข้าถึงข้อมูลใด จากนั้นจัดตารางให้ระบบที่ไม่ขัดแย้งกันทำงานแบบขนาน

fn move_system(mut query: Query<(&mut Position, &Velocity)>) {
    for (mut pos, vel) in &mut query {
        pos.x += vel.x;
        pos.y += vel.y;
    }
}

คิวรี: การขอข้อมูล

Query ใช้ระบุคำขอเอนทิตีที่มีชุดคอมโพเนนต์เฉพาะอย่างประกาศไว้ Bevy จะคืนเฉพาะเอนทิตีที่ตรงเงื่อนไข

คุณขอการเข้าถึงร่วมกันได้ด้วย &T หรือการเข้าถึงแบบเฉพาะด้วย &mut T ข้อมูลการยืมนี้เป็นตัวขับเคลื่อนตัวจัดตารางแบบขนาน

// Entities with BOTH Position and Velocity
fn report(query: Query<(&Position, &Velocity)>) {
    for (pos, vel) in &query {
        info!("at {},{} moving {},{}", pos.x, pos.y, vel.x, vel.y);
    }
}

การกรองคิวรี

พารามิเตอร์ชนิดที่สองของ Query คือตัวกรอง ใช้ With และ Without เพื่อจำกัดผลลัพธ์โดยไม่ยืมข้อมูลของคอมโพเนนต์นั้น

วิธีนี้เหมาะอย่างยิ่งกับคอมโพเนนต์แท็ก ซึ่งเป็นโครงสร้างว่างที่ใช้ระบุบทบาทของเอนทิตี

#[derive(Component)]
struct Player;

fn player_only(query: Query<&Position, With<Player>>) {
    for pos in &query {
        info!("player at {},{}", pos.x, pos.y);
    }
}

ทรัพยากร: สถานะส่วนกลาง

ข้อมูลบางอย่างมีเพียงชุดเดียวสำหรับทั้งเกม เช่น คะแนน เวลาที่ผ่านไป หรือการตั้งค่าเกม ข้อมูลเหล่านี้จะอยู่ในรูปทรัพยากรแทนคอมโพเนนต์

เข้าถึงทรัพยากรในระบบด้วย Res<T> สำหรับการอ่าน หรือ ResMut<T> สำหรับการเขียน

#[derive(Resource)]
struct Score(u32);

fn show_score(score: Res<Score>) {
    info!("Score: {}", score.0);
}

ตัวสร้างแอป

ทุกอย่างเชื่อมต่อกันภายใน App คุณเพิ่มปลั๊กอิน แทรกทรัพยากร และลงทะเบียนระบบเข้ากับกำหนดการ

DefaultPlugins จัดเตรียมระบบหน้าต่าง การเรนเดอร์ อินพุต และเวลาไว้ให้ คุณจึงมุ่งเน้นกับการเล่นเกมได้

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .insert_resource(Score(0))
        .add_systems(Update, show_score)
        .run();
}

กำหนดการ: Startup กับ Update

ระบบทำงานอยู่ภายในกำหนดการ Startup ทำงานครั้งเดียวเมื่อแอปเริ่มต้น เหมาะสำหรับสร้างโลก

Update ทำงานทุกเฟรม และเป็นที่สำหรับการเคลื่อนที่ อินพุต และตรรกะต่าง ๆ Bevy ยังมี FixedUpdate สำหรับขั้นตอนฟิสิกส์ที่ให้ผลแน่นอน

App::new()
    .add_plugins(DefaultPlugins)
    .add_systems(Startup, setup)
    .add_systems(Update, move_system)
    .run();

เหตุใดการประกอบจึงชนะ

ต้องการศัตรูบินได้ที่ติดพิษใช่ไหม เพียงแนบคอมโพเนนต์ Flying และ Poisoned ไม่ต้องสร้างคลาสใหม่หรือสายการสืบทอด

พฤติกรรมเกิดขึ้นจากการที่ระบบต่าง ๆ ตรงกับชุดคอมโพเนนต์ใดบ้าง วิธีนี้ทำให้เพิ่มฟีเจอร์ได้ง่ายและปรับโครงสร้างได้โดยมีต้นทุนต่ำ

// Same systems, new combinations
commands.spawn((Position{x:0.0,y:0.0}, Velocity{x:1.0,y:0.0}, Flying, Poisoned));

การทำงานขนานโดยไม่ต้องเสียค่าใช้จ่ายเพิ่ม

เนื่องจากแต่ละระบบประกาศการเข้าถึงข้อมูลของตน ตัวจัดตารางของ Bevy จึงทราบว่าระบบใดขัดแย้งกัน ระบบที่ไม่ขัดแย้งจะทำงานบนเธรดต่างกันโดยอัตโนมัติ

คุณเขียนโค้ดที่ดูเหมือนทำงานในเธรดเดียว แล้วเอนจินจะดึงการทำงานขนานจากประกาศการยืมของคุณ ไม่ต้องใช้ล็อกหรือจัดการเธรดเอง

ตรวจสอบความเข้าใจ

ทดสอบความเข้าใจของคุณเกี่ยวกับบทบาทของ ECS

สรุป: แนวคิด ECS

เอนทิตีคือ ID คอมโพเนนต์คือข้อมูล ระบบคือตรรกะ และทรัพยากรคือสถานะส่วนกลาง App เชื่อมโยงทั้งหมดเข้าด้วยกันผ่านกำหนดการ

เมื่อประกอบคอมโพเนนต์ขนาดเล็กและปล่อยให้ระบบค้นหาคอมโพเนนต์ที่ตรงกัน คุณจะได้เกมที่ยืดหยุ่น ทำงานขนาน และใช้แคชได้ดี ต่อไปเราจะสร้างเอนทิตีและทำให้เอนทิตีเคลื่อนที่

คำถามที่พบบ่อย

บทเรียน “แนวคิดแบบ ECS” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “แนวคิดแบบ ECS” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Learn Rust Coding ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “แนวคิดแบบ ECS”

เอนทิตี คอมโพเนนต์ และระบบ คุณปฏิบัติ Learn Rust Coding ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Learn Rust Coding หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Learn Rust Coding บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “แนวคิดแบบ ECS” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Learn Rust Coding นี้ได้ไหม

ได้ บทเรียน Learn Rust Coding ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. แนวคิดแบบ ECS
  2. สร้างและเคลื่อนย้ายเอนทิตี
  3. จัดการข้อมูลนำเข้าและเวลา
  4. การชนและสถานะเกม
← กลับไปที่ Learn Rust Coding