首页 > 解决方案 > 锈活塞矩形功能在循环内不起作用

问题描述

我想在锈活塞库中基于二维数组绘制很多单元格。我尝试编辑 hello world 示例并具有如下功能:

fn render(&mut self, args: &RenderArgs) {
    const GREEN: [f32; 4] = [0.0f32, 1.0f32, 0.0f32, 1.0f32];
    const RED: [f32; 4] = [1.0f32, 0.0f32, 0.0f32, 1.0f32];

    let square = rectangle::square(0.0, 0.0, 10.0);
    let field = &mut self.field;

    self.gl.draw(args.viewport(), |c, gl| -> () {
        clear(GREEN, gl);

        for x_y_item in field {
            let item = x_y_item.2;

            if item == 7 {
                let x = x_y_item.0;
                let y = x_y_item.1;

                rectangle(
                    RED,
                    square,
                    c.transform.trans(x as f64 * 10.0, y as f64 * 10.0),
                    gl,
                );
            }
        }

        rectangle(
            RED,
            square,
            c.transform.trans(0 as f64 * 10.0, 0 as f64 * 10.0),
            gl,
        );
    })
}


可悲的是,它在循环中不起作用。因为如果我调试打印变量并在循环之外但在内部对它们一一硬编码,它工作正常 - 它只是不绘制任何东西,但不会崩溃。

更新: 我被要求提供代码以阐明什么是字段,以便可以运行它,所以这里是:

场地:



pub struct Grid {
    cursor: i32,
    body: Vec<Vec<i32>>,
    height: i32,
    width: i32,
}

impl Grid {

    pub fn new(width: i32, height: i32) -> Self {



        let mut body: Vec<Vec<i32>> = Vec::with_capacity(height as usize);
        let mut temp: Vec<i32> = Vec::with_capacity(width as usize);

        for i in 0..width {
            temp.push(0);
        }



        for i in 0..height {
            body.push(temp.clone());
        }

        println!("W: {}, TW:{}, H:{}, TH: {}",width,body[0].len() ,height, body.len());

        return Self {cursor: 1 ,width : width, height : height, body : body};
    }

    pub fn fill(&mut self, value: i32) {
        for y in 0..self.height-1 {
            for x in 0..self.width - 1 {
                self.body[y as usize][x as usize] = value;
            }
        }
    }

    pub fn inject(&mut self, pos: (i32,i32), arg: i32) {
        self.body[(pos.1 - 1) as usize][(pos.0 - 1) as usize] = arg;
    }

    pub fn extract(&mut self, pos: (i32,i32)) -> i32 {
        return self.body[(pos.1 - 1) as usize][(pos.0 - 1) as usize];
    }

    pub fn pinpoint(&mut self, val: i32) -> Vec<[i32;2]> {
        let mut ret: Vec<[i32;2]> = Vec::new();

        for y in 0..self.height  {
            for x in 0..self.width {
                if self.body[y as usize][x as usize] == val {
                    ret.push([x as i32 + 1,y as i32 + 1]);
                }
            }
        }

        return ret;
    }

    pub fn d_show(&mut self) {
        let mut counter: i32 = 1;
        for row in self.body.iter() {
            println!("{}. {:?}",counter,*row);
            counter += 1;
        }
    }




}

impl Iterator for Grid {

    type Item = (i32,i32,i32);



    fn next(&mut self) -> Option<Self::Item> {
        if self.cursor == self.width * self.height {

            return None;
        } else {

            let x: i32 = self.cursor - (self.cursor/self.width)*self.width;
            let y: i32 = self.cursor/self.width;


            let val: i32 = 0;
            self.cursor += 1;

            return Some((x,y,self.body[y as usize][x as usize]));

        }
    }
}

主要的:


extern crate glutin_window;
extern crate graphics;
extern crate opengl_graphics;
extern crate piston;

use glutin_window::GlutinWindow as Window;
use opengl_graphics::{GlGraphics, OpenGL};
use piston::event_loop::{EventSettings, Events};
use piston::input::{RenderArgs, RenderEvent, UpdateArgs, UpdateEvent};
use piston::window::WindowSettings;
use graphics::*;  


mod arr2d;
use crate::arr2d::Grid;

pub struct State {

    field: arr2d::Grid,
    gl: GlGraphics,

}



impl State {

    fn render(&mut self, args: &RenderArgs) {

        const GREEN: [f32;4] = [0.0f32,1.0f32,0.0f32,1.0f32];
        const RED: [f32;4] = [1.0f32,0.0f32,0.0f32,1.0f32];

        let square = rectangle::square(0.0,0.0,10.0);
        let field = &mut self.field;


        self.gl.draw(args.viewport(), |c, gl| -> () {

            clear(GREEN,gl);

            for x_y_item in field {


                let item = x_y_item.2;   



                if item == 7 {

                    let x = x_y_item.0;
                    let y = x_y_item.1;

                    rectangle(RED, square, c.transform.trans(x as f64 * 10.0, y as f64 * 10.0), gl);
                }


            }

            rectangle(RED, square,  c.transform.trans(0 as f64 *10.0,0 as f64 *10.0), gl);



        })
    }

    fn update(&mut self, args: &UpdateArgs) {


    }

    fn new(gl: OpenGL ,w: i32,h: i32) -> Self {
        let mut body = Grid::new(w,h);
        body.inject((4,4),7);
        body.inject((4,5),7);
        body.inject((4,6),7);
        return Self{gl: GlGraphics::new(gl), field: body};
    }
}

fn main() {

    let open_gl = OpenGL::V3_2;

    let mut window : Window = WindowSettings::new("Spinning Square",[200,200])
        .opengl(open_gl)
        .exit_on_esc(true)
        .build()
        .unwrap();

    let mut app = State::new(open_gl,20,20);


    let mut events = Events::new(EventSettings::new());
    while let Some(e) = events.next(&mut window) {
        if let Some(args) = e.render_args() {
            app.render(&args);
        }
        if let Some(args) = e.update_args() {
            app.update(&args);
        }
    }

}

更新#2:

我做了更多的研究 - 并根据其他教程和示例创建了更简单的代码版本,但这个问题似乎仍然存在:

extern crate piston;
use piston_window::*;
use std::ffi::OsString;
use std::path::Path;

mod tileSet;
mod arr2d;

fn main() {

    let mut window: PistonWindow = WindowSettings::new("Hello Piston!", [640, 480]).exit_on_esc(true)
        .build()
        .unwrap();

    let mut tilez: tileSet::Textures = tileSet::Textures::from_directory(OsString::from("C:\\Users\\grass\\Desktop\\codes\\Rust\\ghandalf\\assets"),
                                                                     window.create_texture_context(),
                                                                     |x: &Path| -> bool {
                                                                         return x.to_str().unwrap().ends_with(".png");
                                                                     }
    );

    let mut field: arr2d::Grid = arr2d::Grid::new(40,40);
    field.fill(0);



    let mut image: Image = Image::new();


    while let Some(event) = window.next() {

        window.draw_2d(&event, |context, graphics, _device| {
            clear([1.0; 4], graphics);


            for (x,y,item) in &mut field {
                let tile: String = match item {
                    0 => "tile0.png".to_string(),
                    _ => "tile1.png".to_string()
                };
                image.draw(tilez.get(tile).unwrap(), &DrawState::default(), context.transform.trans(40.0,40.0), graphics); //empty screen here
            }
            image.draw(tilez.get(tile).unwrap(), &DrawState::default(), context.transform.trans(40.0,40.0), graphics); //works fine here

        });
    }
}

我尝试使用硬编码变量,调试循环是否迭代,检查是否有任何变量超出范围,但似乎没有给出答案。我认为这与一些开放的 gl 概念有关,比如每次迭代清除屏幕?

编译器不抛出错误无济于事。

标签: rustrust-piston

解决方案


是的,我很迟钝-我忘记重置为 arr2d -_- 隐含的迭代器,所以它正在绘制但在 1 帧内结束。


推荐阅读