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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
//! Bevy Retrograde is a 2D, pixel-perfect renderer for [Bevy] that can target both web and desktop using
//! OpenGL/WebGL.
//!
//! [Bevy]: https://bevyengine.org
//!
//! Bevy Retrograde is focused on providing an easy and ergonomic way to write 2D, pixel-perfect games.
//! Compared to the out-of-the-box Bevy setup, you do not have to work with a 3D scene to create 2D
//! games. Sprites and their coordinates are based on pixel positions in a retro-resolution scene.
//!
//! Bevy Retrograde replaces almost all of the out-of-the-box Bevy components and Bundles that you would
//! normally use ( `Transform`, `Camera2DBundle`, etc. ) and comes with its own `Position`,
//! `Camera`, `Image`, `Sprite`, etc. components and bundles. Bevy Retrograde tries to provide a focused
//! 2D-centric experience on top of Bevy that helps take out some of the pitfalls and makes it
//! easier to think about your game when all you need is 2D.
//!
//! We want to provide a batteries-included plugin that comes with almost everything you need to
//! make a 2D pixel game with Bevy including, collisions, sound, saving data, etc. While adding
//! these features we will try to maintain full web compatibility, but it can't be guaranteed that
//! all features will be feasible to implement for web.
//!
//! These extra features will be included as optional cargo features that can be disabled if not
//! needed and, where applicable, may be packaged as separate Rust crates that can be used even if
//! you don't want to use the rest of Bevy Retrograde.
//!
//! # License
//!
//! Bevy Retrograde LDtk is licensed under the [Katharos License][k_license] which places certain
//! restrictions on what you are allowed to use it for. Please read and understand the terms before
//! using Bevy Retrograde for your project.
//!
//! [k_license]: https://github.com/katharostech/katharos-license
//!
//! # Development Status
//!
//! Bevy Retrograde is in early stages of development. The API is not stable, but there are not many
//! large anticipated changes. Bevy Retrograde should be usable enough to use in your own projects if you
//! are fine adapting to some API changes as they come.
//!
//! See also [Supported Bevy Version](#supported-bevy-version) below.
//!
//! # Features & Examples
//!
//! Check out our [examples] list to see how to use each Bevy Retrograde feature:
//!
//! - Supports web and desktop out-of-the-box
//! - Integer pixel coordinates
//! - Supports sprites and sprite sheets
//! - A super-simple hierarchy system
//! - Scaled pixel-perfect rendering with three camera modes: fixed width, fixed height, and
//!   letter-boxed
//! - [LDtk](https://ldtk.io) map loading and rendering
//! - An integration with the [RAUI] UI library for building in-game user interfaces and HUD
//! - Pixel-perfect collision detection
//! - Text rendering of BDF fonts
//! - Custom shaders for post-processing, including a built-in CRT shader
//! - Render hooks allowing you to drop down into raw [Luminance] calls for custom rendering
//!
//! [examples]: https://github.com/katharostech/bevy_retrograde/tree/master/examples#bevy-retro-examples
//!
//! [luminance]: https://github.com/phaazon/luminance-rs
//!
//! [RAUI]: https://raui-labs.github.io/raui/
//!
//! # Supported Bevy Version
//!
//! Bevy Retrograde currently works on the latest Bevy release and _may_ support Bevy master as well.
//! Bevy Retrograde will try to follow the latest Bevy release, but if there are features introduced in
//! Bevy master that we need, we may require Bevy master for a time until the next Bevy release.
//!
//! When depending on the `bevy` crate, you must be sure to set `default-features` to `false` in
//! your `Cargo.toml` so that the rendering types in `bevy` don't conflict with the ones in
//! `bevy_retrograde`.
//!
//! **`Cargo.toml`:**
//!
//! ```toml
//! # Be sure to turn off the default features of Bevy to avoid conflicts with the
//! # Bevy Retrograde renderer types.
//! bevy = { version = "0.5", default-features = false }
//! bevy_retrograde = "0.1.0"
//! ```
//! # Sample
//!
//! Here's a quick sample of what using Bevy Retrograde looks like:
//!
//! **`main.rs`:**
//!
//! ```no_run
//! use bevy::prelude::*;
//! use bevy_retrograde::prelude::*;
//!
//! fn main() {
//!     App::build()
//!         .add_plugins(RetroPlugins)
//!         .add_startup_system(setup.system())
//!         .run();
//! }
//!
//! struct Player;
//!
//! fn setup(
//!     mut commands: Commands,
//!     asset_server: Res<AssetServer>,
//!     mut scene_graph: ResMut<SceneGraph>,
//! ) {
//!     // Load our sprites
//!     let red_radish_image = asset_server.load("redRadish.png");
//!     let yellow_radish_image = asset_server.load("yellowRadish.png");
//!     let blue_radish_image = asset_server.load("blueRadish.png");
//!
//!     // Spawn the camera
//!     commands.spawn().insert_bundle(CameraBundle {
//!         camera: Camera {
//!             // Set our camera to have a fixed height and an auto-resized width
//!             size: CameraSize::FixedHeight(100),
//!             background_color: Color::new(0.2, 0.2, 0.2, 1.0),
//!             ..Default::default()
//!         },
//!         position: Position::new(0, 0, 0),
//!         ..Default::default()
//!     });
//!
//!     // Spawn a red radish
//!     let red_radish = commands
//!         .spawn()
//!         .insert_bundle(SpriteBundle {
//!             image: red_radish_image,
//!             position: Position::new(0, 0, 0),
//!             sprite: Sprite {
//!                 flip_x: true,
//!                 flip_y: false,
//!                 ..Default::default()
//!             },
//!             ..Default::default()
//!         })
//!         // Add our player marker component so we can move it
//!         .insert(Player)
//!         .id();
//!
//!     // Spawn a yellow radish
//!     let yellow_radish = commands
//!         .spawn()
//!         .insert_bundle(SpriteBundle {
//!             image: yellow_radish_image,
//!             position: Position::new(-20, 0, 0),
//!             sprite: Sprite {
//!                 flip_x: true,
//!                 flip_y: false,
//!                 ..Default::default()
//!             },
//!             ..Default::default()
//!         })
//!         .id();
//!
//!     // Make the yellow radish a child of the red radish
//!     scene_graph
//!         .add_child(red_radish, yellow_radish)
//!         // This could fail if the child is an ancestor of the parent
//!         .unwrap();
//!
//!     // Spawn a blue radish
//!     commands.spawn().insert_bundle(SpriteBundle {
//!         image: blue_radish_image,
//!         // Set the blue radish back a layer so that he shows up under the other two
//!         position: Position::new(-20, -20, -1),
//!         sprite: Sprite {
//!             flip_x: true,
//!             flip_y: false,
//!             ..Default::default()
//!         },
//!         ..Default::default()
//!     });
//! }
//! ```

/// The Bevy Retrograde default plugins
pub struct RetroPlugins;

impl bevy::app::PluginGroup for RetroPlugins {
    fn build(&mut self, group: &mut bevy::app::PluginGroupBuilder) {
        // Add the plugins we need from Bevy
        group.add(bevy::log::LogPlugin::default());
        group.add(bevy::core::CorePlugin::default());
        group.add(bevy::diagnostic::DiagnosticsPlugin::default());
        group.add(bevy::input::InputPlugin::default());
        group.add(bevy::window::WindowPlugin::default());
        group.add(bevy::asset::AssetPlugin::default());
        group.add(bevy::winit::WinitPlugin::default());
        group.add(bevy::scene::ScenePlugin::default());

        group.add(core::RetroCorePlugin);

        #[cfg(feature = "audio")]
        group.add(audio::RetroAudioPlugin);

        #[cfg(feature = "ldtk")]
        group.add(ldtk::LdtkPlugin);

        #[cfg(feature = "text")]
        group.add(text::RetroTextPlugin);

        #[cfg(feature = "ui")]
        group.add(ui::RetroUiPlugin);
    }
}

/// The Bevy Retrograde prelude
#[doc(hidden)]
pub mod prelude {
    pub use crate::*;
    pub use bevy_retrograde_core::prelude::*;
    pub use bevy_retrograde_macros::impl_deref;

    #[cfg(feature = "audio")]
    pub use bevy_retrograde_audio::*;

    #[cfg(feature = "text")]
    pub use bevy_retrograde_text::prelude::*;

    #[cfg(feature = "ldtk")]
    pub use bevy_retrograde_ldtk::*;

    #[cfg(feature = "ui")]
    pub use bevy_retrograde_ui::*;
}

#[doc(inline)]
pub use bevy_retrograde_core as core;

#[cfg(feature = "re-export-bevy")]
pub use bevy;

pub use bevy_retrograde_macros::impl_deref;

#[cfg(feature = "audio")]
#[doc(inline)]
pub use bevy_retrograde_audio as audio;

#[cfg(feature = "text")]
#[doc(inline)]
pub use bevy_retrograde_text as text;

#[cfg(feature = "ldtk")]
pub use bevy_retrograde_ldtk as ldtk;

#[cfg(feature = "ui")]
#[doc(inline)]
pub use bevy_retrograde_ui as ui;