state switching better, but need to transfer sprites

master
mitchellhansen 5 years ago
parent fc0cb579b3
commit 58f0c2a8d8

@ -37,6 +37,36 @@
y: 490, y: 490,
width: 17, width: 17,
height: 13, height: 13,
) ),
( // Tap Tap Dialogue
x: 292,
y: 91,
width: 56,
height: 48,
),
( // Play Button
x: 354,
y: 118,
width: 50,
height: 28,
),
( // Leaderboard button
x: 414,
y: 118,
width: 42,
height: 28,
),
( // Get Ready
x: 295,
y: 59,
width: 91,
height: 24,
),
( // Flappy Bird Text
x: 351,
y: 91,
width: 88,
height: 25,
),
] ]
) )

@ -51,8 +51,9 @@ fn main() -> amethyst::Result<()> {
.with_plugin(RenderFlat2D::default()), .with_plugin(RenderFlat2D::default()),
)?; )?;
// Creates the app with the startup state and bound game data // Creates the app with the startup state and bound game data
let mut game = Application::new(resources, state::PlayState::default(), game_data)?; let mut game = Application::new(resources, state::SplashState::default(), game_data)?;
game.run(); game.run();
Ok(()) Ok(())

@ -16,16 +16,90 @@ use crate::systems::{BirbGravity, ScrollScrollables};
#[derive(Default)] #[derive(Default)]
pub struct PlayState<'a, 'b> { pub struct PlayState<'a, 'b> {
/// The `State` specific `Dispatcher`, containing `System`s only relevant for this `State`.
// Custom dispatch systems for this state
dispatcher: Option<Dispatcher<'a, 'b>>, dispatcher: Option<Dispatcher<'a, 'b>>,
sprites: Vec<Entity>,
}
impl<'a, 'b> PlayState<'a, 'b> {
fn init_sprites(&mut self, world: &mut World) {
let sprites = world.try_fetch_mut::<HashMap<String, SpriteRender>>().unwrap().clone();
let dimensions = (*world.read_resource::<ScreenDimensions>()).clone();
let background_sprite = sprites.get("day-background").unwrap().clone();
let background_object = TiledScroller {
speed: -75.0,
position: 1.0,
width: 144.0 * 3.0,
height: 256.0 * 3.0,
};
let mut transform = Transform::default();
transform.set_scale(Vector3::new(3.0, 3.0, 3.0));
transform.set_translation_xyz(background_object.width/2.0, background_object.height/2.0, 0.0);
self.sprites.push(world
.create_entity()
.with(background_sprite.clone()) // Sprite Render
.with(background_object.clone())
.with(transform.clone())
.build());
transform.set_translation_xyz(3.0*144.0/2.0*3.0, 3.0*256.0/2.0, 0.0);
self.sprites.push(world
.create_entity()
.with(background_sprite.clone()) // Sprite Render
.with(TiledScroller {
speed: -75.0,
position: 2.0,
width: 0.0,
height: 0.0
})
.with(transform.clone())
.build());
let ground_sprite = sprites.get("ground").unwrap();
transform.set_translation_xyz(3.0*168.0/2.0*3.0, 3.0*56.0/2.0, 0.1);
self.sprites.push(world
.create_entity()
.with(ground_sprite.clone()) // Sprite Render
.with(TiledScroller {
speed: -100.0,
position: 2.0,
width: 0.0,
height: 0.0,
})
.with(transform.clone())
.build());
let birb_sprite = sprites.get("floppy").unwrap();
transform.set_translation_xyz(dimensions.width()/2.0, dimensions.height()/2.0, 0.2);
self.sprites.push(world
.create_entity()
.with(birb_sprite.clone()) // Sprite Render
.with(Birb {
vertical_speed: 0.0,
position: 0.0,
starting_height: 0.0
})
.with(transform)
.build());
}
} }
impl<'a, 'b> SimpleState for PlayState<'a, 'b> { impl<'a, 'b> SimpleState for PlayState<'a, 'b> {
// On start will run when this state is initialized. For more
// state lifecycle hooks, see:
// https://book.amethyst.rs/stable/concepts/state.html#life-cycle
fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) { fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) {
let world = data.world; let world = data.world;
// Get the screen dimensions so we can initialize the camera and // Get the screen dimensions so we can initialize the camera and
@ -36,7 +110,7 @@ impl<'a, 'b> SimpleState for PlayState<'a, 'b> {
// Place the camera // Place the camera
/// function sets size of camera window /// function sets size of camera window
init_camera(world, &dimensions);
// Create the `DispatcherBuilder` and register some `System`s that should only run for this `State`. // Create the `DispatcherBuilder` and register some `System`s that should only run for this `State`.
let mut dispatcher_builder = DispatcherBuilder::new(); let mut dispatcher_builder = DispatcherBuilder::new();
@ -49,10 +123,7 @@ impl<'a, 'b> SimpleState for PlayState<'a, 'b> {
self.dispatcher = Some(dispatcher); self.dispatcher = Some(dispatcher);
// Load our sprites and display them PlayState::init_sprites(self, world);
let sprites = load_sprites(world);
world.insert(sprites.clone());
init_sprites(world, &sprites, &dimensions);
} }
@ -69,13 +140,9 @@ impl<'a, 'b> SimpleState for PlayState<'a, 'b> {
} }
if is_key_down(&event, VirtualKeyCode::P) { if is_key_down(&event, VirtualKeyCode::P) {
// So I need to set the scrolling and gravity systems to pause return Trans::Pop;
return Trans::Push(Box::new(PausedState{ sprite: None }));
} }
} }
// Keep going
Trans::None Trans::None
} }
@ -84,163 +151,263 @@ impl<'a, 'b> SimpleState for PlayState<'a, 'b> {
if let Some(dispatcher) = self.dispatcher.as_mut() { if let Some(dispatcher) = self.dispatcher.as_mut() {
dispatcher.dispatch(&data.world); dispatcher.dispatch(&data.world);
} }
Trans::None Trans::None
} }
} }
fn init_camera(world: &mut World, dimensions: &ScreenDimensions) { #[derive(Default)]
// Center the camera in the middle of the screen, and let it cover pub struct SplashState {
// the entire screen sprites: Vec<Entity>,
let mut transform = Transform::default();
transform.set_translation_xyz(dimensions.width() * 0.5, dimensions.height() * 0.5, 1.);
world
.create_entity()
.with(Camera::standard_2d(dimensions.width(), dimensions.height()))
.with(transform)
.build();
} }
fn load_sprites(world: &mut World) -> HashMap<String, SpriteRender> { impl SplashState {
// Load the texture for our sprites. We'll later need to
// add a handle to this texture to our `SpriteRender`s, so
// we need to keep a reference to it.
let texture_handle = {
let loader = world.read_resource::<Loader>();
let texture_storage = world.read_resource::<AssetStorage<Texture>>();
loader.load(
"sprites/flappy.png",
ImageFormat::default(),
(),
&texture_storage,
)
};
// Load the spritesheet definition file, which contains metadata on our
// spritesheet texture.
let sheet_handle = {
let loader = world.read_resource::<Loader>();
let sheet_storage = world.read_resource::<AssetStorage<SpriteSheet>>();
loader.load(
"sprites/flappy.ron",
SpriteSheetFormat(texture_handle),
(),
&sheet_storage,
)
};
let sprite_map = vec![
("day-background".to_string(), 0),
("night-background".to_string(), 1),
("down-pipe".to_string(), 2),
("up-pipe".to_string(), 3),
("ground".to_string(), 4),
("floppy".to_string(), 5),
];
sprite_map.iter()
.map(|i| (i.0.clone(), SpriteRender {
sprite_sheet: sheet_handle.clone(),
sprite_number: i.1,
}))
.collect()
}
fn init_sprites(world: &mut World, sprites: &HashMap<String, SpriteRender>, dimensions: &ScreenDimensions) { fn init_camera(world: &mut World) {
let background_sprite = sprites.get("day-background").unwrap(); let dimensions = (*world.read_resource::<ScreenDimensions>()).clone();
// Center the camera in the middle of the screen, and let it cover
// the entire screen
let mut transform = Transform::default();
transform.set_translation_xyz(dimensions.width() * 0.5, dimensions.height() * 0.5, 1.);
let background_object = TiledScroller { world
speed: -75.0, .create_entity()
position: 1.0, .with(Camera::standard_2d(dimensions.width(), dimensions.height()))
width: 144.0 * 3.0, .with(transform)
height: 256.0 * 3.0, .build();
}; }
let mut transform = Transform::default(); fn init_sprites(&mut self, world: &mut World) {
transform.set_scale(Vector3::new(3.0, 3.0, 3.0)); let sprites = world.try_fetch_mut::<HashMap<String, SpriteRender>>().unwrap().clone();
transform.set_translation_xyz(background_object.width/2.0, background_object.height/2.0, 0.0);
let dimensions = (*world.read_resource::<ScreenDimensions>()).clone();
world let flappy_bird_text_sprite = sprites
.create_entity() .get("flappy-bird-text").unwrap().clone();
.with(background_sprite.clone()) // Sprite Render let play_button_sprite = sprites
.with(background_object.clone()) .get("play-button").unwrap().clone();
.with(transform.clone()) let leaderboard_button_sprite = sprites
.build(); .get("leaderboard-button").unwrap().clone();
let background_sprite = sprites
.get("day-background").unwrap().clone();
let ground_sprite = sprites
.get("ground").unwrap().clone();
let background_object = TiledScroller {
speed: -75.0,
position: 1.0,
width: 144.0 * 3.0,
height: 256.0 * 3.0,
};
transform.set_translation_xyz(3.0*144.0/2.0*3.0, 3.0*256.0/2.0, 0.0); let mut transform = Transform::default();
transform.set_scale(Vector3::new(3.0, 3.0, 3.0));
transform.set_translation_xyz(dimensions.width()/2.0 - 100.0, dimensions.height() - 100.0, 0.1);
world self.sprites.push(world
.create_entity() .create_entity()
.with(background_sprite.clone()) // Sprite Render .with(background_sprite.clone()) // Sprite Render
.with(TiledScroller { .with(background_object.clone())
speed: -75.0, .with(transform.clone())
position: 2.0, .build());
width: 0.0,
height: 0.0
})
.with(transform.clone())
.build();
let ground_sprite = sprites.get("ground").unwrap();
transform.set_translation_xyz(3.0*168.0/2.0*3.0, 3.0*56.0/2.0, 0.1);
world
.create_entity()
.with(ground_sprite.clone()) // Sprite Render
.with(TiledScroller {
speed: -100.0,
position: 2.0,
width: 0.0,
height: 0.0,
})
.with(transform.clone())
.build();
let birb_sprite = sprites.get("floppy").unwrap();
transform.set_translation_xyz(dimensions.width()/2.0, dimensions.height()/2.0, 0.2);
world
.create_entity()
.with(birb_sprite.clone()) // Sprite Render
.with(Birb {
vertical_speed: 0.0,
position: 0.0,
starting_height: 0.0
})
.with(transform)
.build();
} transform.set_translation_xyz(3.0*144.0/2.0*3.0, 3.0*256.0/2.0, 0.0);
#[derive(Default)] self.sprites.push(world
pub struct PausedState { .create_entity()
sprite: Option<Entity>, .with(background_sprite.clone()) // Sprite Render
.with(TiledScroller {
speed: -75.0,
position: 2.0,
width: 0.0,
height: 0.0
})
.with(transform.clone())
.build());
transform.set_translation_xyz(3.0*168.0/2.0*3.0, 3.0*56.0/2.0, 0.1);
self.sprites.push(world
.create_entity()
.with(ground_sprite.clone()) // Sprite Render
.with(TiledScroller {
speed: -100.0,
position: 2.0,
width: 0.0,
height: 0.0,
})
.with(transform.clone())
.build());
transform.set_translation_xyz(background_object.width/2.0, background_object.height/2.0, 0.0);
self.sprites.push(world
.create_entity()
.with(flappy_bird_text_sprite.clone())
.with(transform.clone())
.build());
transform.set_translation_xyz(100.0/2.0, 100.0/2.0, 0.1);
self.sprites.push(world
.create_entity()
.with(play_button_sprite.clone())
.with(transform.clone())
.build());
transform.set_translation_xyz(500.0/2.0, 100.0/2.0, 0.1);
self.sprites.push(world
.create_entity()
.with(leaderboard_button_sprite.clone())
.with(transform.clone())
.build());
}
fn load_sprites(world: &mut World) -> HashMap<String, SpriteRender> {
// Load the texture for our sprites. We'll later need to
// add a handle to this texture to our `SpriteRender`s, so
// we need to keep a reference to it.
let texture_handle = {
let loader = world.read_resource::<Loader>();
let texture_storage = world.read_resource::<AssetStorage<Texture>>();
loader.load(
"sprites/flappy.png",
ImageFormat::default(),
(),
&texture_storage,
)
};
// Load the spritesheet definition file, which contains metadata on our
// spritesheet texture.
let sheet_handle = {
let loader = world.read_resource::<Loader>();
let sheet_storage = world.read_resource::<AssetStorage<SpriteSheet>>();
loader.load(
"sprites/flappy.ron",
SpriteSheetFormat(texture_handle),
(),
&sheet_storage,
)
};
let sprite_map = vec![
("day-background".to_string(), 0),
("night-background".to_string(), 1),
("down-pipe".to_string(), 2),
("up-pipe".to_string(), 3),
("ground".to_string(), 4),
("floppy".to_string(), 5),
("tap-tap-dialogue".to_string(), 6),
("play-button".to_string(), 7),
("leaderboard-button".to_string(), 8),
("get-ready-text".to_string(), 9),
("flappy-bird-text".to_string(), 10),
];
sprite_map.iter()
.map(|i| (i.0.clone(), SpriteRender {
sprite_sheet: sheet_handle.clone(),
sprite_number: i.1,
}))
.collect()
}
} }
impl SimpleState for PausedState { impl SimpleState for SplashState {
fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) { fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) {
let world = data.world; let world = data.world;
// Load the sprites. Insert them into the world as this is the first function to be called
let sprites = SplashState::load_sprites(world);
world.insert(sprites.clone());
SplashState::load_sprites(world);
SplashState::init_camera(world);
SplashState::init_sprites(self, world);
}
fn handle_event(
&mut self,
mut data: StateData<'_, GameData<'_, '_>>,
event: StateEvent,
) -> SimpleTrans {
if let StateEvent::Window(event) = &event {
// Check if the window should be closed
if is_close_requested(&event) || is_key_down(&event, VirtualKeyCode::Escape) {
return Trans::Quit;
}
// Check if the window should be closed
if is_key_down(&event, VirtualKeyCode::Space) {
let world = data.world;
for i in &self.sprites {
world.delete_entity(*i);
}
self.sprites.clear();
return Trans::Push(Box::new(ReadyState::default()));
}
}
// Keep going
Trans::None
}
fn update(&mut self, data: &mut StateData<'_, GameData<'_, '_>>) -> SimpleTrans {
Trans::None
}
}
#[derive(Default)]
pub struct ReadyState {
sprites: Vec<Entity>,
}
impl ReadyState {
fn init_sprites(&mut self, world: &mut World, dimensions: &ScreenDimensions) {
let dimensions = (*world.read_resource::<ScreenDimensions>()).clone(); let dimensions = (*world.read_resource::<ScreenDimensions>()).clone();
let sprites = world.try_fetch_mut::<HashMap<String, SpriteRender>>().unwrap().clone();
let get_ready_text_sprite = sprites
.get("get-ready-text").unwrap().clone();
let sprite = world.try_fetch::<HashMap<String, SpriteRender>>().unwrap().get("up-pipe").unwrap().clone(); let tap_tap_dialogue_sprite = sprites
.get("tap-tap-dialogue").unwrap().clone();
// let sprite = resource.get("up-pipe").unwrap().clone();
let mut transform = Transform::default(); let mut transform = Transform::default();
transform.set_scale(Vector3::new(3.0, 3.0, 3.0)); transform.set_scale(Vector3::new(3.0, 3.0, 3.0));
transform.set_translation_xyz(dimensions.width()/2.0 - 100.0, dimensions.height() - 100.0, 0.1);
self.sprites.push(world
.create_entity()
.with(get_ready_text_sprite.clone()) // Sprite Render
.with(transform.clone())
.build());
transform.set_translation_xyz(500.0/2.0, 500.0/2.0, 0.1); transform.set_translation_xyz(500.0/2.0, 500.0/2.0, 0.1);
self.sprite = Some(world self.sprites.push(world
.create_entity() .create_entity()
.with(sprite.clone()) // Sprite Render .with(tap_tap_dialogue_sprite.clone()) // Sprite Render
.with(transform.clone()) .with(transform.clone())
.build()); .build());
} }
}
impl SimpleState for ReadyState {
fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) {
let world = data.world;
}
fn handle_event( fn handle_event(
&mut self, &mut self,
@ -250,12 +417,19 @@ impl SimpleState for PausedState {
if let StateEvent::Window(event) = &event { if let StateEvent::Window(event) = &event {
// Check if the window should be closed // Check if the window should be closed
if is_key_down(&event, VirtualKeyCode::Space) { if is_close_requested(&event) || is_key_down(&event, VirtualKeyCode::Escape) {
return Trans::Quit;
}
// Check if the window should be closed
if is_key_down(&event, VirtualKeyCode::Space) {
let world = data.world; let world = data.world;
world.delete_entity(self.sprite.unwrap()); for i in &self.sprites {
self.sprite = None; world.delete_entity(*i);
return Trans::Pop; }
self.sprites.clear();
return Trans::Push(Box::new(PlayState::default()));
} }
} }

Loading…
Cancel
Save