1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
//! tiled_json is here to help you load Tiled maps! //! //! The primary idea of this library is getting the data loaded into a more //! manageable format. This data is not optimized toward any specific use case //! and as such should be used only as an intermediate format before //! transferring into more useful structures. This library exists soley to //! facilitate the loading of Tiled maps and is designed to be read-only. The //! data structures within have no extended functionality or any inherent purpose //! other than reading data stored in Tiled JSON maps. //! //! **This library supports loading compressed and base64 encoded maps.** //! //! **This library does NOT support loading wangsets, chunks, terrains, //! infinite maps, or external object templates.** This means when you export //! a map to JSON, you must be sure to //! - Embed Tilesets, and //! - Detach Templates, and //! - Resolve Object Types and Properties (optional). //! //! Every field of every struct is public. In order to get data, you //! may access the fields directly or use the methods by the same name. //! Each variable is named according to its Tiled JSON representation. //! Numerous convenient functions are available for accessing data that may be //! otherwise difficult or verbose to access. //! //! All enums can be converted into string slices if you need them via the //! to_string() method from implementing Display. //! //! //! This is what the data tree looks like: //! //! Map //! Layers //! Tile Layers //! Data (gids corresponding to some tileset) //! Object Groups //! Objects //! Image Layers (images directly on map) //! Groups (groups of layers) //! Tilesets //! Tiles //! Animations //! Collisions //! //! ```tiled_json::load_map(file: &str)``` is the one and only entry point into //! this library. //! //! Typically, we want to load the map, we'll capture it to a variable. Then we //! might loop through all of the tilesets and translate them to our own structures //! and then do the same for our layers. Here is what some code may look like: //! ``` //! let map = tiled_json::load_map("map1.json").unwrap(); //! let height = map.height(); //! let width = map.width(); //! // CREATE INTERNAL MAP STRUCTURE HERE, THEN //! for ls in map.layers().iter() { //! let layer_darkness = ls.get_property("darkness").get_float(); //! let layer_weather = ls.get_property("weather").get_string(); //! if ls.is_tile_layer() { //! let data = ls.get_data().unwrap(); //! for n in data.iter() { //! let flip_bits = tiled_json::gid_flipped_hvd( *n ); //! let gid = tiled_json::gid_without_flags( *n ); //! let ts = map.tileset_by_gid( gid ).unwrap(); //! let coords = ts.coord_by_gid(gid); //! if let Option::Some(tile) = ts.tile_by_gid( gid ) { //! // these are specific overrides of the tileset for a specific tile //! // these can be accessed from the tileset for easy access later. //! let anim_coords = tile.get_anim( MSECS_SINCE_WORLD_CREATION ).unwrap(); // this may not exist //! let collision = tile.objectgroup().unwrap(); // this may not exist //! let properties = tile.get_property_vector(); //! // do stuff! //! } //! //! // check if an existing instance exists of this and if not, create //! // a new instance for reference later. //! // Add value to our map. //! } //! //! } else if ls.is_object_group() { //! let objs = ls.get_objects_vector().unwrap(); //! let dro = ls.get_draworder().unwrap(); //! // See object properties to know what is relevant to you. //! //! } else if ls.is_image_layer() { //! let img = ls.get_image().unwrap(); //! let tsc = ls.get_transparentcolor().unwrap(); // this can actually be None so use with caution. //! // Determine what to do with the image. //! //! } else if ls.is_group() { //! let grp = ls.get_group().unwrap(); //! // If you have groups in your map, then you know what to do with them. //! } //! } //! for ts in map.tilesets().iter() { //! /* load stuff here //! store textures //! organize your internal data //! */ //! } //! //! ``` //! #![allow(dead_code)] pub mod color; pub mod layer; mod layerreader; pub mod map; pub mod object; pub mod property; pub mod tileset; pub use crate::color::*; pub use crate::layer::*; pub use crate::map::*; pub use crate::object::*; pub use crate::property::*; pub use crate::tileset::*; use std::fs::File; use std::io::prelude::*; use std::io::BufReader; pub const HORZ_FLIP_FLAG: u32 = 0x8000_0000; pub const VERT_FLIP_FLAG: u32 = 0x4000_0000; pub const DIAG_FLIP_FLAG: u32 = 0x2000_0000; /// It is all exposed through this function--load_map() which takes a filename /// as a string slice and (hopefully) gives you a tiled_json::Map object in /// return. /// ``` /// let map = tiled_json::load_map("map1.json"); /// if map.is_err() { /// /* do some error handling */ /// /* for std::io::Error */ /// } /// ``` pub fn load_map(file: &str) -> Result<Map, std::io::Error> { let file = File::open(file)?; let mut buf_reader = BufReader::new(file); let mut contents = String::new(); buf_reader.read_to_string(&mut contents)?; let map: Map = serde_json::from_str(&contents)?; Ok(map) } /// The gid in tile layer data tells us if the tile at a location is flipped /// on the horizontal axis. This function takes that information and determines /// that for you by returning a boolean. #[inline] pub fn gid_flipped_horizontally(gid: u32) -> bool { gid & HORZ_FLIP_FLAG > 0 } /// The gid in tile layer data tells us if the tile at a location is flipped /// on the vertical axis. This function takes that information and determines /// that for you by returning a boolean. #[inline] pub fn gid_flipped_vertically(gid: u32) -> bool { gid & VERT_FLIP_FLAG > 0 } /// The gid in tile layer data tells us if the tile at a location is flipped /// over the diagonal x=y axis. This function takes that information and determines /// that for you by returning a boolean. #[inline] pub fn gid_flipped_diagonally(gid: u32) -> bool { gid & DIAG_FLIP_FLAG > 0 } /// The gid in tile layer data tells us if the tile at a location is flipped /// on the following axes: horizontal, vertical, and diagonal. /// This function takes that information and determines that for you by returning a /// set of three booleans: (horizontal flip, vertical flip, diagonal flip). #[inline] pub fn gid_flipped_hvd(gid: u32) -> (bool,bool,bool) { (gid & HORZ_FLIP_FLAG > 0, gid & VERT_FLIP_FLAG > 0, gid & DIAG_FLIP_FLAG > 0) } /// Submit a gid and recieve a copy with the flags removed. #[inline] pub fn gid_without_flags(gid: u32) -> u32 { gid & !(HORZ_FLIP_FLAG | VERT_FLIP_FLAG | DIAG_FLIP_FLAG) }