use image::{GenericImageView, ImageBuffer, Rgba}; const TILE_PX: u32 = 16; const ROWS: &[(&str, u8)] = &[ ("assets/sky.png", 0), // air (transparent) ("assets/grass_floor.png", 1), // grass ("assets/dirt_floor.png", 2), // dirt ("assets/rock_floor.png", 3), // rock ("assets/bedrock_floor.png", 4), // bedrock ("assets/sky.png", 5), // sky (transparent) ("assets/dirt_wall.png", 6), // dirt_wall fixture ("assets/rock_wall.png", 7), // rock_wall fixture ("assets/bedrock_wall.png", 8), // bedrock_wall fixture ("assets/log.png", 9), // log fixture ("assets/leaves.png", 10), // leaves fixture ]; fn main() { let rows = ROWS.len() as u32; let mut combined: ImageBuffer, Vec> = ImageBuffer::from_pixel(TILE_PX, TILE_PX * rows, Rgba([0, 0, 0, 0])); for (i, (path, _id)) in ROWS.iter().enumerate() { let y = i as u32 * TILE_PX; match image::open(path) { Ok(img) => { image::imageops::overlay(&mut combined, &img, 0, y as i64); println!("cargo:rerun-if-changed={}", path); } Err(e) => { eprintln!( "Warning: could not open {} — leaving row {} blank ({})", path, i, e ); let mut row_pixels = combined.rows_mut(); if let Some(row) = row_pixels.nth(i) { for px in row { *px = Rgba([255, 0, 255, 255]); } } } } } combined .save("assets/tileset.png") .expect("Failed to write assets/tileset.png"); println!("cargo:rerun-if-changed=build.rs"); }