القائمة الرئيسية

الصفحات

برمجة لعبة إطلاق نار باستخدام لغة Rust: دليل شامل للمبتدئين

Best-Guide-to-create-Shooting-Game-in-Rust-ggez،Best Guide of create Shooter Game in Rust ggez، Comprehensive Beginners، Programming a Shooter Game with Rust: A Comprehensive Beginner's Guide، Rust، ggez، لعبة إطلاق نار، Cargo، مشروع جديد، نافذة اللعبة، حركة اللاعب، تصادم، رصاصة، ذكاء اصطناعي، المؤثرات الصوتية، المؤثرات البصرية، نقاط اللعبة، نهاية اللعبة، الصوتيات، الصور، تطوير الألعاب، برمجة الألعاب، الأداء العالي، الأمان، Game Loop، MeshBuilder، ContextBuilder، EventHandler، KeyCode، Graphics، Timer، Update، Draw، تصميم الألعاب، الفيزياء، بيئة التطوير، برمجة الألعاب باستخدام لغة Rust ومكتبة ggez. كيفية برمجة لعبة إطلاق نار باستخدام لغة Rust ومكتبة ggez، دليل المبتدئين لتطوير الألعاب باستخدام Rust و ggez، Loop، MeshBuilder، ContextBuilder، EventHandler، كيفية برمجة لعبة إطلاق نار باستخدام لغة Rust، إنشاء لعبة ثنائية الأبعاد باستخدام ggez في Rust، شرح مكتبة ggez لتطوير الألعاب في Rust، دليل المبتدئين لتطوير الألعاب باستخدام Rust و ggez، خطوات إنشاء لعبة إطلاق نار ثنائية الأبعاد بلغة Rust، كيفية إضافة تصادم بين الرصاص والأعداء في لعبة Rust، أفضل مكتبات Rust لتطوير الألعاب ثنائية الأبعاد،  طريقة تحريك اللاعب والعدو في لعبة Rust باستخدام ggez، كيفية إنشاء نظام نقاط في لعبة إطلاق نار بلغة Rust، إضافة مؤثرات صوتية وبصرية إلى لعبة Rust باستخدام ggez، كيفية تحسين أداء الألعاب المطورة باستخدام Rust، تطوير لعبة فيديو بسيطة باستخدام Rust ومكتبة ggez، إضافة ذكاء اصطناعي للأعداء في لعبة Rust، كيفية إنشاء نظام إطلاق الرصاص في ألعاب Rust، تصميم واجهة لعبة بإستخدام مكتبة ggez في Rust، إعداد بيئة تطوير ألعاب باستخدام Rust و Cargo، كيفية برمجة حركة اللاعب باستخدام ggez في Rust، إضافة شاشة نهاية اللعبة في مشاريع الألعاب Rust، كيفية رسم العناصر في لعبة Rust باستخدام ggez، برمجة ألعاب ثلاثية الأبعاد باستخدام Rust، برمجة الألعاب باستخدام Rust وggez، Rust، ggez، لعبة إطلاق نار، برمجة ألعاب، تطوير ألعاب، ألعاب ثنائية الأبعاد، برمجة لعبة اطلاق نار باستخدام لغة Rust،



برمجة لعبة إطلاق نار باستخدام لغة Rust: دليل شامل للمبتدئين



لغة Rust هي #لغة_برمجة حديثة المعروفة بأدائها الفائق وميزاتها الأمنية القوية،
 تبرز كخيار مثالي لتطوير ألعاب إطلاق النار التي تتطلب دقة وسرعة. 
في هذا الدليل، سنأخذك في رحلة خطوة بخطوة لإنشاء لعبة إطلاق نار باستخدام #Rust،
 مستعرضين كيفية بناء العناصر الأساسية للعبة، من الحركة والتصويب إلى آليات إطلاق النار والتفاعل مع البيئة.
 سنقوم بإنشاء لعبة إطلاق نار باستخدام لغة Rust ومكتبة ggez، 
وسنغطي الخطوات الأساسية لإنشاء اللعبة، بدءًا من إعداد البيئة وحتى إضافة وظائف إطلاق النار والحركة.
#برمجة_الألعاب_باستخدام_Rustggez #لعبة_إطلاق_نار #برمجة_ألعاب
#ألعاب_ثنائية_الأبعاد

خطوات برمجة  لعبة إطلاق نار باستخدام لغة Rust



في هذا القسم، نركز على الجانب العملي لتطوير لعبة إطلاق نار باستخدام Rust. 
سنقوم بتفصيل الخطوات اللازمة لتحويل الأفكار والتصميمات إلى واقع برمجي،
 مع التركيز على استخدام ميزات Rust الفريدة لتحقيق أداء عالٍ وتجربة لعب سلسة. 
سنتناول كيفية إنشاء بيئة اللعب، وتطبيق آليات الحركة، وتنفيذ أنظمة إطلاق النار، وتطوير 
الذكاء الاصطناعي للأعداء، وإضافة المؤثرات البصرية والصوتية، اليك التفاصيل :

الخطوة 1: إعداد البيئة وتثبيت المكتبات
قبل البدء، تأكد من تثبيت Rust على جهازك، ثم قم بإنشاء 
مشروع جديد باستخدام Cargo :

        


cargo new shooting_game
cd shooting_game

* أضف مكتبة ggez إلى ملف Cargo.toml  :

Ini, TOML

[dependencies]
ggez = "0.8"
rand = "0.8"

--

الخطوة 2: إنشاء نافذة اللعبة
أولاً، سنقوم بإنشاء نافذة اللعبة باستخدام ggez. 
إليك الكود في ملف src/main.rs :

        


use ggez::{Context, ContextBuilder, GameResult, event, graphics, timer};
use ggez::event::{EventHandler, KeyCode, KeyMods};
use ggez::graphics::{Color, Mesh, MeshBuilder, DrawParam};
use ggez::nalgebra as na;
use rand::{thread_rng, Rng};

struct MainState {
    player_pos: na::Point2<f32>,
    enemy_pos: na::Point2<f32>,
    bullet_pos: na::Point2<f32>,
    bullet_state: BulletState,
    score: i32,
}

enum BulletState {
    Ready,
    Firing,
}

impl MainState {
    fn new(ctx: &mut Context) -> GameResult<MainState> {
        let s = MainState {
            player_pos: na::Point2::new(400.0, 550.0),
            enemy_pos: na::Point2::new(thread_rng().gen_range(50.0..750.0), 50.0),
            bullet_pos: na::Point2::new(0.0, 550.0),
            bullet_state: BulletState::Ready,
            score: 0,
        };
        Ok(s)
    }
}

impl EventHandler<ggez::GameError> for MainState {
    fn update(&mut self, ctx: &mut Context) -> GameResult {
        // تحديث منطق اللعبة
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult {
        graphics::clear(ctx, Color::BLACK);

        // رسم اللاعب والعدو والرصاصة
        let player_mesh = MeshBuilder::new().circle(graphics::DrawMode::fill(), self.player_pos, 25.0, 0.1, Color::GREEN)?.build(ctx)?;
        graphics::draw(ctx, &player_mesh, DrawParam::default())?;

        let enemy_mesh = MeshBuilder::new().circle(graphics::DrawMode::fill(), self.enemy_pos, 25.0, 0.1, Color::RED)?.build(ctx)?;
        graphics::draw(ctx, &enemy_mesh, DrawParam::default())?;

        if let BulletState::Firing = self.bullet_state {
            let bullet_mesh = MeshBuilder::new().circle(graphics::DrawMode::fill(), self.bullet_pos, 10.0, 0.1, Color::YELLOW)?.build(ctx)?;
            graphics::draw(ctx, &bullet_mesh, DrawParam::default())?;
        }

        graphics::present(ctx)?;
        timer::yield_now();
        Ok(())
    }

    fn key_down_event(&mut self, ctx: &mut Context, keycode: KeyCode, _keymods: KeyMods, _repeat: bool) {
        match keycode {
            KeyCode::Space => {
                if let BulletState::Ready = self.bullet_state {
                    self.bullet_pos = self.player_pos;
                    self.bullet_state = BulletState::Firing;
                }
            }
            _ => {}
        }
    }
}

fn main() -> GameResult {
    let (mut ctx, event_loop) = ContextBuilder::new("shooting_game", "Your Name")
        .build()?;
    let state = MainState::new(&mut ctx)?;
    event::run(ctx, event_loop, state)
}




* شرح الكود :

- ggez::init(): تهيئة ggez.
- ContextBuilder::new(): إنشاء نافذة اللعبة وتحديد أبعادها.
- MainState: هيكل لتخزين حالة اللعبة.
- EventHandler: معالجة الأحداث التي وقعت.
- graphics::clear(): مسح الشاشة.
- graphics::draw(): رسم العناصر على الشاشة.
- graphics::present(): تحديث الشاشة.
- timer::yield_now(): إعطاء وقت للمعالج.
- KeyCode::Space: التحقق من الضغط على مفتاح المسافة.

الخطوة 3: إضافة اللاعب والعدو
تم بالفعل إضافة اللاعب والعدو في الكود السابق.


** مقالات ذات صلة :

الخطوة 4: إضافة حركة اللاعب والعدو
قم بتعديل دالة update في impl EventHandler لإضافة حركة اللاعب والعدو :

        


fn update(&mut self, ctx: &mut Context) -> GameResult {
    let dt = timer::delta(ctx).as_secs_f32();

    // حركة اللاعب
    let keys = event::pressed_keys(ctx);
    if keys.contains(&KeyCode::Left) {
        self.player_pos.x -= 300.0 * dt;
    }
    if keys.contains(&KeyCode::Right) {
        self.player_pos.x += 300.0 * dt;
    }

    // حركة العدو
    self.enemy_pos.x += 150.0 * dt;
    if self.enemy_pos.x < 50.0 || self.enemy_pos.x > 750.0 {
        self.enemy_pos.x = self.enemy_pos.x.clamp(50.0, 750.0);
        self.enemy_pos.y += 50.0;
    }

    // حركة الرصاصة
    if let BulletState::Firing = self.bullet_state {
        self.bullet_pos.y -= 500.0 * dt;
        if self.bullet_pos.y < 0.0 {
            self.bullet_state = BulletState::Ready;
        }
    }

    Ok(())
}







الخطوة 5: إضافة الرصاصة
تم بالفعل إضافة الرصاصة في الكود السابق.

الخطوة 6: إضافة التصادم
قم بتعديل دالة update لإضافة وظيفة التصادم :

        


fn update(&mut self, ctx: &mut Context) -> GameResult {
    // ... (الكود السابق)

    // التحقق من التصادم
    if let BulletState::Firing = self.bullet_state {
        let distance = na::distance(&self.bullet_pos, &self.enemy_pos);
        if distance < 35.0 {
            self.bullet_state = BulletState::Ready;
            self.enemy_pos = na::Point2::new(thread_rng().gen_range(50.0..750.0), 50.0);
            self.score += 1;
        }
    }

    Ok(())
}

الخطوة 7: إضافة نقاط اللعبة
قم بتعديل دالة draw لعرض النقاط :

        


fn draw(&mut self, ctx: &mut Context) -> GameResult {
    // ... (الكود السابق)

    let score_text = graphics::Text::new(format!("Score: {}", self.score));
    graphics::draw(ctx, &score_text, DrawParam::new().dest(na::Point2::new(10.0, 10.0)))?;

    graphics::present(ctx)?;
    timer::yield_now();
    Ok(())
}


الخطوة 8: إضافة التصادم
قم بتعديل دالة update لإضافة وظيفة التصادم :

       
 

fn update(&mut self, ctx: &mut Context) -> GameResult {
    // ... (الكود السابق)

    // التحقق من التصادم
    if let BulletState::Firing = self.bullet_state {
        let distance = na::distance(&self.bullet_pos, &self.enemy_pos);
        if distance < 35.0 {
            self.bullet_state = BulletState::Ready;
            self.enemy_pos = na::Point2::new(thread_rng().gen_range(50.0..750.0), 50.0);
            self.score += 1;
        }
    }

    Ok(())
}

* شرح الكود :
- na::distance(&self.bullet_pos, &self.enemy_pos): 
حساب المسافة بين الرصاصة والعدو باستخدام مكتبة nalgebra.




- distance < 35.0: التحقق من أن المسافة بين الرصاصة والعدو أقل من 35 بكسل.
- في حالة التصادم، يتم إعادة تهيئة موقع العدو، وزيادة النقاط، وتغيير حالة الرصاصة إلى "جاهز".

الخطوة 9: إضافة نقاط اللعبة
قم بتعديل دالة draw لعرض النقاط :

        

fn draw(&mut self, ctx: &mut Context) -> GameResult {
    // ... (الكود السابق)

    let score_text = graphics::Text::new(format!("Score: {}", self.score));
    graphics::draw(ctx, &score_text, DrawParam::new().dest(na::Point2::new(10.0, 10.0)))?;

    graphics::present(ctx)?;
    timer::yield_now();
    Ok(())
}


* شرح الكود :
- graphics::Text::new(format!("Score: {}", self.score)):
 إنشاء نص لعرض النقاط.
- graphics::draw(ctx, &score_text, DrawParam::new().dest(na::Point2::new(10.0, 10.0))):
 رسم النص على الشاشة.

الخطوة 10: إضافة نهاية اللعبة
قم بتعديل دالة update لإضافة شاشة نهاية اللعبة عند خسارة اللاعب :

        

fn update(&mut self, ctx: &mut Context) -> GameResult {
    // ... (الكود السابق)

    // التحقق من نهاية اللعبة
    if self.enemy_pos.y > 550.0 {
        // شاشة نهاية اللعبة
        self.player_pos = na::Point2::new(400.0, 550.0);
        self.enemy_pos = na::Point2::new(thread_rng().gen_range(50.0..750.0), 50.0);
        self.bullet_pos = na::Point2::new(0.0, 550.0);
        self.bullet_state = BulletState::Ready;
        self.score = 0;
    }

    Ok(())
}


في حالة تجاوز العدو لحدود الشاشة، يتم إعادة تهيئة مواقع اللاعب و
العدو والرصاصة، وإعادة تعيين النقاط إلى الصفر.

الخطوة 11: إضافة مؤثرات صوتية (اختياري)
يمكنك إضافة مؤثرات صوتية لجعل اللعبة أكثر جاذبية. لتنفيذ ذلك، ستحتاج إلى
 إضافة مكتبة ggez::audio وتضمين ملفات صوتية في مشروعك.

* أضف مكتبة ggez::audio إلى ملف Cargo.toml :

Ini, TOML

[dependencies]
ggez = { version = "0.8", features = ["audio"] }
rand = "0.8"

--

* قم بإنشاء مجلد resources في جذر مشروعك وضع فيه ملفات الصوت.
* قم بتحميل وتشغيل الأصوات في الكود :

        


use ggez::audio::{Source, SoundData};

// ... (في هيكل MainState)
struct MainState {
    // ...
    shoot_sound: Source,
    hit_sound: Source,
}

impl MainState {
    fn new(ctx: &mut Context) -> GameResult<MainState> {
        let shoot_sound_data = SoundData::from_path(ctx, "/shoot.wav")?;
        let shoot_sound = Source::from_data(ctx, shoot_sound_data)?;

        let hit_sound_data = SoundData::from_path(ctx, "/hit.wav")?;
        let hit_sound = Source::from_data(ctx, hit_sound_data)?;

        let s = MainState {
            // ...
            shoot_sound,
            hit_sound,
        };
        Ok(s)
    }
}

// ... (في دالة key_down_event)
KeyCode::Space => {
    if let BulletState::Ready = self.bullet_state {
        self.bullet_pos = self.player_pos;
        self.bullet_state = BulletState::Firing;
        self.shoot_sound.play(ctx)?;
    }
}

// ... (في دالة update، داخل شرط التصادم)
if distance < 35.0 {
    // ...
    self.hit_sound.play(ctx)?;
}

الخطوة 12: إضافة صور (اختياري)
يمكنك إضافة صور لشخصيات اللعبة والخلفية لجعلها أكثر جاذبية.
قم بإنشاء مجلد resources في جذر مشروعك وضع فيه ملفات الصور.
* قم بتحميل ورسم الصور في الكود :

        


use ggez::graphics::{Image, ImageGeneric};

// ... (في هيكل MainState)
struct MainState {
    // ...
    player_image: Image,
    enemy_image: Image,
    bullet_image: Image,
}

impl MainState {
    fn new(ctx: &mut Context) -> GameResult<MainState> {
        let player_image = Image::from_path(ctx, "/player.png")?;
        let enemy_image = Image::from_path(ctx, "/enemy.png")?;
        let bullet_image = Image::from_path(ctx, "/bullet.png")?;

        let s = MainState {
            // ...
            player_image,
            enemy_image,
            bullet_image,
        };
        Ok(s)
    }
}

// ... (في دالة draw، استبدل رسم الدوائر برسم الصور)
graphics::draw(ctx, &self.player_image, DrawParam::new().dest(self.player_pos))?;
graphics::draw(ctx, &self.enemy_image, DrawParam::new().dest(self.enemy_pos))?;
if let BulletState::Firing = self.bullet_state {
    graphics::draw(ctx, &self.bullet_image, DrawParam::new().dest(self.bullet_pos))?;
}


      


* الخاتمة :
في هذا المقال، قمنا بإنشاء لعبة إطلاق نار بسيطة باستخدام لغة Rust ومكتبة ggez. 
يمكنك استخدام هذا التطبيق كنقطة بداية لإنشاء ألعاب أكثر تعقيدًا. 
يمكنك إضافة المزيد من الميزات إلى اللعبة، مثل أنواع مختلفة من الأعداء، ومستويات
 صعوبة مختلفة، والمزيد من المؤثرات الصوتية والبصرية.