0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ゼロからEntityComponentSystemを書いてみる 8

Posted at

前回は、こんなコードを書きました。

main.rs
use std::collections::HashMap;

use rand;

#[derive(Debug)]
struct Position {
    x: i32,
    y: i32,
}

#[derive(Debug)]
struct Velocity {
    x: i32,
    y: i32,
}

fn main() {
    
    // idは配列の要素数を表す
    let mut id = 0;

    // ベクタをやめて、ハッシュマップで宣言する
    // Position構造体のハッシュマップ
    let mut pos_ary: HashMap<u32, Position> = HashMap::new();  

    // Velocity構造体のハッシュマップ
    let mut vel_ary: HashMap<u32, Velocity> = HashMap::new();
    
    // 効果を確かめるために、2回づつ create_entity を呼び出す
    // Positionコンポーネントのみ
    for i in 0..2 {
        let (x, y) = rand::random();
        let key = create_entity(&mut id);
        add_component(&key, &mut pos_ary, Position { x, y });
    }

    // Velocityコンポーネントのみ
    for i in 0..2 {
        let (x, y) = rand::random();
        let key = create_entity(&mut id);
        add_component(&key, &mut vel_ary, Velocity{ x, y });
    }

    // PositionとVelocityの両方
    for i in 0..2 {
        let (x ,y) = rand::random();
        let key = create_entity(&mut id);
        add_component(&key, &mut pos_ary, Position { x, y });
        add_component(&key, &mut vel_ary, Velocity { x, y })
    }


    // 各要素の値を出力する
    for i in 0..id  {
        let pos = pos_ary.get(&i);
        let vel = vel_ary.get(&i);
        
        println!("{}: {:?}", i, pos);
        println!("{}: {:?}", i, vel);
    }
}

// id に +1 して作成したエンティティを返す
fn create_entity (id: &mut u32) -> u32 {
    let key = *id;
    *id += 1;
    key
}

// ハッシュマップにコンポーネントを追加する
fn add_component <T> (id: &u32, v: &mut HashMap<u32, T>, data: T) {
    v.insert(*id, data);
}

// ジェネリックなデータ型を引数に取る set_data 関数
fn generic_set_data <T> (id: &usize, v: &mut Vec<T>, data: T) {
    v[*id] = data;
}

そろそろ id という変数名を変えたいです。

main.rs
    // 現時点で作られたエンティティの数を表す。
    // それと、次に作るエンティティのidも表す。
    let mut entity_count = 0;

変えました。

ついでに、Entity 構造体を定義します。

main.rs
#[derive(Debug)]
struct Entity {
    id: u32,
}

create_entity 関数が Entity 構造体のインスタンスを返すように変更します。

main.rs
// 現在のentity_countをidにしたエンティティを返す
fn create_entity (id: &mut u32) -> Entity {
    let entity = Entity { id: *id };
    *id += 1;
    entity
}

あと、set_dataは不要になったので消します。(add_componentするときに値を設定するので不要と判断)

for ループの i を _ に変更
_ を変数の前に付けると変数が未使用でもワーニングが出なくなる。 _ だけでも問題はない。

main.rs
    // 効果を確かめるために、2回づつ create_entity を呼び出す
    // Positionコンポーネントのみ
    for _ in 0..2 {
        let (x, y) = rand::random();
        let entity = create_entity(&mut entity_count);
        add_component(&entity, &mut pos_ary, Position { x, y });
    }

    // Velocityコンポーネントのみ
    for _ in 0..2 {
        let (x, y) = rand::random();
        let entity = create_entity(&mut entity_count);
        add_component(&entity, &mut vel_ary, Velocity{ x, y });
    }

    // PositionとVelocityの両方
    for _ in 0..2 {
        let (x ,y) = rand::random();
        let entity = create_entity(&mut entity_count);
        add_component(&entity, &mut pos_ary, Position { x, y });
        add_component(&entity, &mut vel_ary, Velocity { x, y })
    }

最後に、コードの全体を記載して終わります。

main.rs
use std::collections::HashMap;

use rand;

#[derive(Debug)]
struct Entity {
    id: u32,
}

#[derive(Debug)]
struct Position {
    x: i32,
    y: i32,
}

#[derive(Debug)]
struct Velocity {
    x: i32,
    y: i32,
}

fn main() {
    
    // 現時点で作られたエンティティの数を表す。
    // それと、次に作るエンティティのidも表す。
    let mut entity_count = 0;

    // ベクタをやめて、ハッシュマップで宣言する
    // Position構造体のハッシュマップ
    let mut pos_ary: HashMap<u32, Position> = HashMap::new();  

    // Velocity構造体のハッシュマップ
    let mut vel_ary: HashMap<u32, Velocity> = HashMap::new();
    
    // 効果を確かめるために、2回づつ create_entity を呼び出す
    // Positionコンポーネントのみ
    for _ in 0..2 {
        let (x, y) = rand::random();
        let entity = create_entity(&mut entity_count);
        add_component(&entity, &mut pos_ary, Position { x, y });
    }

    // Velocityコンポーネントのみ
    for _ in 0..2 {
        let (x, y) = rand::random();
        let entity = create_entity(&mut entity_count);
        add_component(&entity, &mut vel_ary, Velocity{ x, y });
    }

    // PositionとVelocityの両方
    for _ in 0..2 {
        let (x ,y) = rand::random();
        let entity = create_entity(&mut entity_count);
        add_component(&entity, &mut pos_ary, Position { x, y });
        add_component(&entity, &mut vel_ary, Velocity { x, y })
    }


    // 各要素の値を出力する
    for i in 0..entity_count  {
        let pos = pos_ary.get(&i);
        let vel = vel_ary.get(&i);
        
        println!("{}: {:?}", i, pos);
        println!("{}: {:?}", i, vel);
    }
}

// 現在のentity_countをidにしたエンティティを返す
fn create_entity (id: &mut u32) -> Entity {
    let entity = Entity { id: *id };
    *id += 1;
    entity
}

// ハッシュマップにコンポーネントを追加する
fn add_component <T> (entity: &Entity, v: &mut HashMap<u32, T>, data: T) {
    v.insert(entity.id, data);
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?