rust 如何在SDL中更新屏幕而不 Flink 对象

xdyibdwo  于 2023-04-30  发布在  Flink
关注(0)|答案(1)|浏览(179)

我正在使用SDL2库在Rust中开发一个物理引擎。我有一个自定义Rectangle类型的方法fill。该方法只是在屏幕上绘制正确的像素:

use sdl::*;

pub fn fill(&self, canvas: &mut Canvas<Window>, color: Color) {
        let minx = self.x - self.w as i32 / 2;
        let miny = self.y - self.h as i32 / 2;
        
        let maxx = self.x + self.w as i32 / 2;
        let maxy = self.y + self.h as i32 / 2;

        canvas.set_draw_color(color);
        for x in minx..maxx {
            for y in miny..maxy {
                canvas.draw_point(Point::new(x, y)).unwrap();
            }
        }
    }

主循环调用此方法,canvas.present() s屏幕上的矩形:

fn main() {
    let sdl_context = sdl2::init()?;
    let video_subsystem = sdl_context.video()?;

    let window = video_subsystem
        .window("rust-sdl2 demo: Video", 800, 600)
        .position_centered()
        .opengl()
        .build()
        .map_err(|e| e.to_string())?;

    let mut canvas = window.into_canvas().build().map_err(|e| e.to_string())?;

    let mut rect1 = shapes::Rectangle {
        x: 400,
        y: 300,
        w: 200,
        h: 200
    };

    canvas.set_draw_color(Color::BLACK); 
    canvas.clear();
    canvas.present();

    let mut event_pump = sdl_context.event_pump().unwrap();
    'running: loop {
        for event in event_pump.poll_iter() {
            match event {
                Event::Quit {..} |
                Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                break 'running
                },
                _ => {}
            }
            canvas.set_draw_color(Color::BLACK); 
            canvas.clear();
            canvas.present();
        
            // I'm calling the method here
            rect1.fill(&mut canvas, Color::RGB(128, 128, 128));
            canvas.present();
        
            ::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 30));
        }
    }
}

矩形在屏幕上绘制得很好。但是,由于canvas.clear()方法,它似乎 Flink 。如何在不 Flink 对象的情况下更新屏幕?

axzmvihb

axzmvihb1#

解决的办法其实很简单。@SafelyFast提到我每帧对屏幕present()两次。解决方案是canvas.present()只在'running: loop的末尾。游戏循环中的代码如下所示:

'running: loop {
        for event in event_pump.poll_iter() {
            match event {
                Event::Quit {..} |
                Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                break 'running
                },
                _ => {}
            }
            canvas.set_draw_color(Color::BLACK); 
            canvas.clear();
            // canvas.present(); #Removed
        
            // I'm calling the method here
            rect1.fill(&mut canvas, Color::RGB(128, 128, 128));
            
            canvas.present(); // This is the only one needed
        
            ::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 30));
        }
    }

相关问题