allow public uses of structs; add sample program

This commit is contained in:
Max Bradbury 2020-04-12 17:13:08 +01:00
parent fd4a682ade
commit bef39f9b8b
15 changed files with 132 additions and 61 deletions

View File

@ -4,6 +4,51 @@ a library for parsing Bitsy game data.
the version number follows Bitsy itself, so version 0.65.* targets Bitsy 6.5.
## how to use
this sample program converts the player avatar to a smiley face.
```rust
extern crate bitsy_parser;
use std::{env, fs};
use bitsy_parser::game::Game;
use bitsy_parser::image::Image;
/// replaces the player avatar with a smiley face.
fn main() {
let input_file = env::args().nth(1)
.expect("No game data specified. Usage: `invert infile outfile`");
let output_file = env::args().nth(2)
.expect("No game data specified. Usage: `invert infile outfile`");
let mut game = Game::from(fs::read_to_string(input_file).unwrap());
game.avatar.animation_frames = vec![
Image {
pixels: vec![
0,0,1,1,1,1,0,0,
0,1,1,1,1,1,1,0,
1,1,0,1,1,0,1,1,
1,1,0,1,1,0,1,1,
1,1,1,1,1,1,1,1,
1,1,0,1,1,0,1,1,
0,1,1,0,0,1,1,0,
0,0,1,1,1,1,0,0,
]
}
];
fs::write(output_file, &game.to_string())
.expect("Failed to write to output file");
}
```
some more practical uses would be things like:
* remove duplicate tiles
* merge two Bitsy games together
* programmatically create Bitsy games
* a Bitsy game editor
## todo
### failing tests
@ -13,7 +58,3 @@ test_room_from_string shows an unexpected ordering for the items in the output o
### tidy up
* refactor the more shonky bits to idiomatic rust
### documentation
examples of use cases (dedupe tiles, merge games, etc.)

View File

@ -1,12 +1,11 @@
use crate::{AnimationFrames, Image, Position};
use crate::mock;
use crate::{AnimationFrames, Image, mock, Position};
/// avatar is a "sprite" in the game data but with a specific id
#[derive(Debug, Eq, PartialEq)]
pub struct Avatar {
pub(crate) animation_frames: Vec<Image>,
pub(crate) room: String, /// room id
pub(crate) position: Position,
pub animation_frames: Vec<Image>,
pub room: String, /// room id
pub position: Position,
}
impl From<String> for Avatar {

32
src/bin/smiley.rs Normal file
View File

@ -0,0 +1,32 @@
extern crate bitsy_parser;
use std::{env, fs};
use bitsy_parser::game::Game;
use bitsy_parser::image::Image;
/// replaces the player avatar with a smiley face.
fn main() {
let input_file = env::args().nth(1)
.expect("No game data specified. Usage: `invert infile outfile`");
let output_file = env::args().nth(2)
.expect("No game data specified. Usage: `invert infile outfile`");
let mut game = Game::from(fs::read_to_string(input_file).unwrap());
game.avatar.animation_frames = vec![
Image {
pixels: vec![
0,0,1,1,1,1,0,0,
0,1,1,1,1,1,1,0,
1,1,0,1,1,0,1,1,
1,1,0,1,1,0,1,1,
1,1,1,1,1,1,1,1,
1,1,0,1,1,0,1,1,
0,1,1,0,0,1,1,0,
0,0,1,1,1,1,0,0,
]
}
];
fs::write(output_file, &game.to_string())
.expect("Failed to write to output file");
}

View File

@ -1,8 +1,8 @@
#[derive(Debug, Eq, PartialEq)]
pub struct Colour {
pub(crate) red: u8,
pub(crate) green: u8,
pub(crate) blue: u8,
pub red: u8,
pub green: u8,
pub blue: u8,
}
impl From<String> for Colour {

View File

@ -1,7 +1,7 @@
#[derive(Debug, Eq, PartialEq)]
pub struct Dialogue {
pub(crate) id: String,
pub(crate) contents: String,
pub id: String,
pub contents: String,
}
impl From<String> for Dialogue {

View File

@ -1,8 +1,7 @@
use crate::Position;
use std::iter::Enumerate;
#[derive(Debug, Eq, PartialEq)]
pub(crate) enum Transition {
pub enum Transition {
None,
FadeToWhite,
FadeToBlack,
@ -49,9 +48,9 @@ impl ToString for Transition {
#[derive(Debug, Eq, PartialEq)]
pub struct Exit {
/// destination
pub(crate) room: String, /// id
pub(crate) position: Position,
pub(crate) effect: Transition,
pub room: String, /// id
pub position: Position,
pub effect: Transition,
}
impl From<String> for Exit {

View File

@ -1,19 +1,19 @@
use crate::{Avatar, Dialogue, Ending, Item, Palette, Room, Sprite, Tile, Variable, mock};
#[derive(Debug, PartialEq)]
pub(crate) struct Game {
pub(crate) name: String,
pub(crate) version: f64,
pub(crate) room_format: u8,
pub(crate) palettes: Vec<Palette>,
pub(crate) rooms: Vec<Room>,
pub(crate) tiles: Vec<Tile>,
pub(crate) avatar: Avatar,
pub(crate) sprites: Vec<Sprite>,
pub(crate) items: Vec<Item>,
pub(crate) dialogues: Vec<Dialogue>,
pub(crate) endings: Vec<Ending>,
pub(crate) variables: Vec<Variable>,
pub struct Game {
pub name: String,
pub version: f64,
pub room_format: u8,
pub palettes: Vec<Palette>,
pub rooms: Vec<Room>,
pub tiles: Vec<Tile>,
pub avatar: Avatar,
pub sprites: Vec<Sprite>,
pub items: Vec<Item>,
pub dialogues: Vec<Dialogue>,
pub endings: Vec<Ending>,
pub variables: Vec<Variable>,
}
impl From<String> for Game {

View File

@ -2,7 +2,7 @@ use crate::mock;
#[derive(Debug, Eq, PartialEq)]
pub struct Image {
pub(crate) pixels: Vec<u8>, // 64 for SD, 256 for HD
pub pixels: Vec<u32>, // 64 for SD, 256 for HD
}
impl From<String> for Image {
@ -12,8 +12,8 @@ impl From<String> for Image {
let pixels: Vec<&str> = string.split("").collect();
// the above seems to add an extra "" at the start and end of the vec, so strip them below
let pixels = &pixels[1..(pixels.len() - 1)];
let pixels: Vec<u8> = pixels.iter().map(|&pixel| {
pixel.parse::<u8>().unwrap()
let pixels: Vec<u32> = pixels.iter().map(|&pixel| {
pixel.parse::<u32>().unwrap()
}).collect();
Image { pixels }

View File

@ -2,10 +2,10 @@ use crate::{AnimationFrames, Image, mock};
#[derive(Debug, Eq, PartialEq)]
pub struct Item {
pub(crate) id: String,
pub(crate) animation_frames: Vec<Image>,
pub(crate) name: Option<String>,
pub(crate) dialogue: Option<String>, // dialogue id
pub id: String,
pub animation_frames: Vec<Image>,
pub name: Option<String>,
pub dialogue: Option<String>, // dialogue id
}
impl From<String> for Item {

View File

@ -67,7 +67,7 @@ pub fn avatar() -> Avatar {
}
}
pub(crate) fn sprite() -> Sprite {
pub fn sprite() -> Sprite {
Sprite {
id: "a".to_string(),
name: Some("hatch".to_string()),
@ -158,7 +158,7 @@ pub fn room() -> Room {
}
}
pub(crate) fn game_default() -> Game {
pub fn game_default() -> Game {
Game {
name: "Write your game's title here".to_string(),
version: 6.5,

View File

@ -2,9 +2,9 @@ use crate::colour::Colour;
#[derive(Debug, Eq, PartialEq)]
pub struct Palette {
pub(crate) id: String, // base36 string (why??)
pub(crate) name: Option<String>,
pub(crate) colours: Vec<Colour>,
pub id: String, // base36 string (why??)
pub name: Option<String>,
pub colours: Vec<Colour>,
}
impl From<String> for Palette {

View File

@ -1,7 +1,7 @@
#[derive(Debug, Eq, PartialEq)]
pub struct Position {
pub(crate) x: u8,
pub(crate) y: u8,
pub x: u8,
pub y: u8,
}
impl From<String> for Position {

View File

@ -2,13 +2,13 @@ use crate::{Exit, ExitInstance, Instance, mock, Position};
#[derive(Debug, Eq, PartialEq)]
pub struct Room {
pub(crate) id: String,
pub(crate) palette: String, // id
pub(crate) name: Option<String>,
pub(crate) tiles: Vec<String>, // tile ids
pub(crate) items: Vec<Instance>,
pub(crate) exits: Vec<ExitInstance>,
pub(crate) endings: Vec<Instance>,
pub id: String,
pub palette: String, // id
pub name: Option<String>,
pub tiles: Vec<String>, // tile ids
pub items: Vec<Instance>,
pub exits: Vec<ExitInstance>,
pub endings: Vec<Instance>,
}
impl From<String> for Room {

View File

@ -2,12 +2,12 @@ use crate::{AnimationFrames, Image, Position, mock};
#[derive(Debug, Eq, PartialEq)]
pub struct Sprite {
pub(crate) id: String, // lowercase base36
pub(crate) name: Option<String>,
pub(crate) animation_frames: Vec<Image>,
pub(crate) dialogue: Option<String>, /// dialogue id
pub(crate) room: String, /// room id
pub(crate) position: Position,
pub id: String, // lowercase base36
pub name: Option<String>,
pub animation_frames: Vec<Image>,
pub dialogue: Option<String>, /// dialogue id
pub room: String, /// room id
pub position: Position,
}
impl From<String> for Sprite {

View File

@ -1,7 +1,7 @@
#[derive(Debug, Eq, PartialEq)]
pub struct Variable {
pub(crate) id: String,
pub(crate) initial_value: String,
pub id: String,
pub initial_value: String,
}
impl From<String> for Variable {