mirror of
https://github.com/scratchfoundation/scratch-tech-explorations.git
synced 2025-08-28 21:38:45 -04:00
feat: load a project file and display a loading screen
This commit is contained in:
parent
044b13ad4f
commit
780dba67c0
4 changed files with 121 additions and 24 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
@ -2484,6 +2484,8 @@ name = "scratch-bevy"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bevy",
|
||||
"futures-lite",
|
||||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3295,3 +3297,15 @@ name = "xi-unicode"
|
|||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a"
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "537ce7411d25e54e8ae21a7ce0b15840e7bfcff15b51d697ec3266cc76bdf080"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"crc32fast",
|
||||
"crossbeam-utils",
|
||||
"flate2",
|
||||
]
|
||||
|
|
|
@ -8,6 +8,8 @@ rust-version = "1.65"
|
|||
|
||||
[dependencies]
|
||||
bevy = "0.9.1"
|
||||
futures-lite = "1.12.0"
|
||||
zip = { version = "0.6.3", default-features = false, features = ["deflate"] }
|
||||
|
||||
[features]
|
||||
# remember to disable bevy's "dynamic" feature for release builds
|
||||
|
|
BIN
assets/Infinite Toebeans.sb3
Normal file
BIN
assets/Infinite Toebeans.sb3
Normal file
Binary file not shown.
129
src/main.rs
129
src/main.rs
|
@ -1,11 +1,20 @@
|
|||
use bevy::{
|
||||
prelude::*,
|
||||
tasks::*,
|
||||
time::FixedTimestep,
|
||||
window::*,
|
||||
};
|
||||
use futures_lite::future;
|
||||
|
||||
const TIME_STEP: f64 = 1. / 30.;
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
|
||||
enum AppState {
|
||||
Loading,
|
||||
Running,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins.set(WindowPlugin {
|
||||
|
@ -20,12 +29,69 @@ fn main() {
|
|||
},
|
||||
..default()
|
||||
}))
|
||||
.add_plugin(ScratchLoadingScreenPlugin)
|
||||
.add_plugin(ScratchStagePlugin)
|
||||
.add_plugin(ScratchDemoProjectPlugin)
|
||||
.add_system(close_on_esc)
|
||||
.run();
|
||||
}
|
||||
|
||||
//
|
||||
// Loading screen
|
||||
//
|
||||
|
||||
pub struct ScratchLoadingScreenPlugin;
|
||||
|
||||
#[derive(Component)]
|
||||
struct LoadingScreen;
|
||||
|
||||
impl Plugin for ScratchLoadingScreenPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app
|
||||
.add_state(AppState::Loading)
|
||||
.add_system_set(
|
||||
SystemSet::on_enter(AppState::Loading)
|
||||
.with_system(ScratchLoadingScreenPlugin::start_loading_screen)
|
||||
)
|
||||
.add_system_set(
|
||||
SystemSet::on_update(AppState::Loading)
|
||||
.with_system(ScratchLoadingScreenPlugin::update_loading_screen)
|
||||
)
|
||||
.add_system_set(
|
||||
SystemSet::on_exit(AppState::Loading)
|
||||
.with_system(ScratchLoadingScreenPlugin::stop_loading_screen)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
impl ScratchLoadingScreenPlugin {
|
||||
|
||||
fn start_loading_screen(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
commands.spawn((
|
||||
SpriteBundle {
|
||||
texture: asset_server.load("squirrel.png"),
|
||||
..default()
|
||||
},
|
||||
LoadingScreen
|
||||
));
|
||||
}
|
||||
|
||||
fn update_loading_screen(mut loading_screen_query: Query<&mut Transform, With<LoadingScreen>>) {
|
||||
let one_degree_in_radians: f32 = (1.0_f32).to_radians();
|
||||
|
||||
for mut transform in &mut loading_screen_query {
|
||||
transform.rotate_z(-one_degree_in_radians);
|
||||
}
|
||||
}
|
||||
|
||||
fn stop_loading_screen(mut commands: Commands, mut loading_screen_query: Query<Entity, With<LoadingScreen>>) {
|
||||
for loading_screen in &mut loading_screen_query {
|
||||
commands.entity(loading_screen).despawn();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Sprite
|
||||
//
|
||||
|
@ -109,31 +175,46 @@ pub struct ScratchDemoProjectPlugin;
|
|||
impl Plugin for ScratchDemoProjectPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app
|
||||
.add_startup_system(add_demo_project_sprites);
|
||||
.add_startup_system(project_load)
|
||||
.add_system_set(
|
||||
SystemSet::on_update(AppState::Loading)
|
||||
.with_system(project_check_load)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn add_demo_project_sprites(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
commands.spawn(
|
||||
SpriteBundle {
|
||||
texture: asset_server.load("squirrel.png"),
|
||||
transform: Transform::from_scale(Vec3::new(0.5, 0.5, 1.)),
|
||||
..default()
|
||||
})
|
||||
.insert(Name("Sprite 1".to_string()))
|
||||
.insert(ScratchScripts(vec![
|
||||
ScratchCode::MoveOneStep,
|
||||
ScratchCode::TurnClockwise,
|
||||
]));
|
||||
commands.spawn(
|
||||
SpriteBundle {
|
||||
texture: asset_server.load("squirrel.png"),
|
||||
transform: Transform::from_scale(Vec3::new(0.5, 0.5, 1.)),
|
||||
..default()
|
||||
})
|
||||
.insert(Name("Sprite 2".to_string()))
|
||||
.insert(ScratchScripts(vec![
|
||||
ScratchCode::MoveTwoSteps,
|
||||
ScratchCode::TurnCounterClockwise,
|
||||
]));
|
||||
#[derive(Resource)]
|
||||
struct ProjectZip(HandleUntyped);
|
||||
|
||||
#[derive(Resource)]
|
||||
struct ProjectLoadTask(Task<i32>);
|
||||
|
||||
fn project_load(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
info!("Starting project load");
|
||||
let project_handle = asset_server.load_untyped("Infinite Toebeans.sb3");
|
||||
commands.insert_resource(ProjectZip(project_handle))
|
||||
}
|
||||
|
||||
fn project_check_load(mut commands: Commands, mut app_state: ResMut<State<AppState>>, project_zip: Option<Res<ProjectZip>>, mut project_task: Option<ResMut<ProjectLoadTask>>) {
|
||||
if let Some(project_zip) = project_zip {
|
||||
if project_zip.is_added() {
|
||||
info!("Project archive is loaded. Time to unpack...");
|
||||
let thread_pool = AsyncComputeTaskPool::get();
|
||||
let load_task = thread_pool.spawn(async move {
|
||||
let start_time = std::time::Instant::now();
|
||||
while start_time.elapsed() < std::time::Duration::from_secs_f32(4.2)
|
||||
{
|
||||
// spin
|
||||
}
|
||||
42 // return hydrated project
|
||||
});
|
||||
commands.insert_resource(ProjectLoadTask(load_task));
|
||||
}
|
||||
else if let Some(project_task) = &mut project_task {
|
||||
if let Some(project_data) = future::block_on(future::poll_once(&mut project_task.0)) {
|
||||
info!("Project data is: {}", project_data);
|
||||
app_state.set(AppState::Running).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue