generate the dang room

This commit is contained in:
Max Bradbury 2020-11-08 14:54:49 +00:00
parent 512f386c25
commit 8c92b05b74
5 changed files with 58 additions and 31 deletions

View File

@ -1,11 +1,8 @@
# todo # todo
* tests
* if image is exactly 128×128, *don't* crop * if image is exactly 128×128, *don't* crop
* tile reuse * tile reuse
* noise reduction (remove lonely pixels) * noise reduction (remove lonely pixels)
* implement Atkinson and Bayer dithering options * implement Atkinson and Bayer dithering options
* if "create new bitsy game", add new room as room 0
* actually create room
* stats for added room (number of tiles) * stats for added room (number of tiles)
* dedupe "palette from custom colours" functionality * dedupe "palette from custom colours" functionality

View File

@ -269,48 +269,57 @@ pub fn add_room() -> String {
}, },
}); });
let width = state.image.as_ref().unwrap().width(); let foreground = &game.palettes
let height = state.image.as_ref().unwrap().height(); .iter()
.find(|&palette| &palette.id == palette_id.as_ref().unwrap())
.unwrap().colours[1].clone();
let preview = render_preview(&state);
let width = 128;
let height = 128;
let columns = (width as f64 / SD as f64).floor() as u32; let columns = (width as f64 / SD as f64).floor() as u32;
let rows = (height as f64 / SD as f64).floor() as u32; let rows = (height as f64 / SD as f64).floor() as u32;
let mut tile_ids = Vec::new(); let mut tile_ids = Vec::new();
let mut new_tile_count: u32 = 0; let initial_tile_count = game.tiles.len();
for column in 0..columns { for row in 0..rows {
for row in 0..rows { for column in 0..columns {
let mut pixels = Vec::with_capacity(64); let mut pixels = Vec::with_capacity(64);
fn colour_match(a: &image::Rgb<u8>, b: &bitsy_parser::Colour) -> u8 {
if a[0] == b.red && a[1] == b.green && a[2] == b.blue { 1 } else { 0 }
};
for y in (row * SD)..((row + 1) * SD) { for y in (row * SD)..((row + 1) * SD) {
for x in (column * SD)..((column + 1) * SD) { for x in (column * SD)..((column + 1) * SD) {
let pixel = state.image.as_ref().unwrap().get_pixel(x, y).to_rgb(); let pixel = preview.get_pixel(x, y).to_rgb();
let total = pixel[0] as u32 + pixel[1] as u32 + pixel[2] as u32; pixels.push(colour_match(&pixel, foreground));
// is each channel brighter than 128/255 on average?
pixels.push(if total >= 384 {1} else {0});
} }
} }
let tile = Tile { let tile = Tile {
// "0" will get overwritten to a new, safe tile ID // "0" will get overwritten to a new, safe tile ID
id: "0".to_string(), id: "0".to_string(),
name: tile_name(&state.room_name, &new_tile_count), name: tile_name(&state.room_name, &(row * column)),
wall: None, wall: None,
animation_frames: vec![Image { pixels }], animation_frames: vec![Image { pixels }],
colour_id: None colour_id: None
}; };
tile_ids.push( let tile_id = if game.tiles.contains(&tile) {
if game.tiles.contains(&tile) { game.tiles.iter().find(|&t| t == &tile).unwrap().id.clone()
game.tiles.iter().find(|&t| t == &tile).unwrap().id.clone() } else {
} else { game.add_tile(tile)
new_tile_count += 1; };
game.add_tile(tile.clone())
} tile_ids.push(tile_id);
);
} }
} }
// todo if player selected "create new game", delete room 0 here // todo if player selected "create new game", delete room 0 here?
// that would probably break unless the avatar was also placed in the room
game.add_room(bitsy_parser::Room { game.add_room(bitsy_parser::Room {
id: "0".to_string(), id: "0".to_string(),
@ -325,12 +334,14 @@ pub fn add_room() -> String {
game.dedupe_tiles(); game.dedupe_tiles();
let new_tile_count = game.tiles.len();
state.game = Some(game.to_owned()); state.game = Some(game.to_owned());
format!( format!(
"Added room \"{}\" with {} new tiles", "Added room \"{}\" with {} new tiles",
&state.room_name.as_ref().unwrap_or(&"untitled".to_string()), &state.room_name.as_ref().unwrap_or(&"untitled".to_string()),
new_tile_count new_tile_count - initial_tile_count
) )
} }
@ -376,9 +387,9 @@ mod test {
#[test] #[test]
fn example() { fn example() {
load_default_game(); load_default_game();
load_image(include_str!("test-resources/test.png.base64").to_string()); load_image(include_str!("test-resources/test.png.base64").trim().to_string());
add_room(); println!("add_room(): {}", add_room());
// todo what? why are extraneous pixels appearing in the output tiles?
assert_eq!(output(), include_str!("test-resources/expected.bitsy")); assert_eq!( output(), include_str!("test-resources/expected.bitsy"));
} }
} }

View File

@ -30,6 +30,25 @@ ROOM 0
NAME example room NAME example room
PAL 0 PAL 0
ROOM 1
a,a,1,1,2,2,3,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
PAL 0
TIL a TIL a
11111111 11111111
10000001 10000001
@ -41,7 +60,7 @@ TIL a
11111111 11111111
NAME block NAME block
TIL 2 TIL 1
00011000 00011000
00111000 00111000
00011000 00011000
@ -51,7 +70,7 @@ TIL 2
00011000 00011000
00111100 00111100
TIL 3 TIL 2
00111100 00111100
01100110 01100110
01100110 01100110
@ -61,7 +80,7 @@ TIL 3
01100000 01100000
01111110 01111110
TIL 4 TIL 3
00111100 00111100
01100110 01100110
01100110 01100110

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 B

After

Width:  |  Height:  |  Size: 523 B

View File

@ -1 +1 @@
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAQCAYAAACm53kpAAAAvElEQVR4nO2QQQrDMBAD6/8/upVSBMqClab2IWAP2M1qtgmovcFrgNYa7i96lWdO8nKi7oz6HkcBvWUo3FgKXo7PQpmTvJzy2XNiWgGEM/HM6fmaz54TpwLwiBvhjVnPhDPxzLny5Gpn1FceVcCoJ7/sOKcCKlC4sRS8O87EMyf55Ejy1dU58YgCerm46+ucOArA79/oI/U1ykXy1QntXHlSd9wluHX+52LsAnB2ATjLsgvA2QXgLMvyBXwAjqzoAQg4VfAAAAAASUVORK5CYII= data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAABHNCSVQICAgIfAhkiAAAAcJJREFUeJzt19FqgzAAQFEz+v+/nD1t2NLWsQgW7jlP2ogVvUYdc865LRhj/C7/7Gr/29678cfDeNxmdZznbtv2vwu2H39cPtr26H/mnNuc8259ZZzXvs7a0dHJdjE+022/sjKFrzh6jKyO89ppM8AZrgqw7C6AMcbbk3s0vmL1BfLZewDHPmIGcOdfZ5z1GbjymfbqEI7u5nf7EMvfjG3bzJVhH/EI4DoCiBNAnADiBBAngDgBxAkgTgBxAogTQJwA4gQQJ4A4AcQJIE4AcQKIE0CcAOIEECeAOAHECSBOAHECiBNAnADiBBAngDgBxAkgTgBxAogTQJwA4gQQJ4A4AcQJIE4AcQKIE0CcAOIEECeAOAHECSBOAHECiBNAnADiBBAngDgBxAkgTgBxAogTQJwA4gQQJ4A4AcQJIE4AcQKIE0CcAOIEECeAOAHECSBOAHECiBNAnADiBBAngDgBxAkgTgBxAogTQJwA4gQQJ4A4AcQJIE4AcQKIE0CcAOIEECeAOAHECSBOAHECiBNAnADiBBAngDgBxAkgTgBxAogTQJwA4gQQJ4A4AcQJIE4AcQKIE0CcAOIEECeAOAHEfQM+SHkFb+/YEwAAAABJRU5ErkJggg==