commit 9fdcfbf0319894cdcf70ccd9036085a58ba7302b
parent 08178cd94b5133862634507fda68e2cf74c12e22
Author: MTRNord <mtrnord1@gmail.com>
Date: Thu, 1 Apr 2021 02:17:12 +0200
Improve texture loading
Took 50 minutes
Diffstat:
3 files changed, 102 insertions(+), 15 deletions(-)
diff --git a/src/main.rs b/src/main.rs
@@ -7,14 +7,19 @@ use crate::plugins::{
use bevy::diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin};
use bevy::render::camera::{OrthographicProjection, ScalingMode};
use bevy::{prelude::*, window::WindowMode};
+use std::collections::HashMap;
mod entities;
mod plugins;
+#[derive(Default)]
+pub struct AssetsLoading(Vec<HandleUntyped>);
+
#[derive(Default, Clone)]
pub struct GameState {
pub spawned: bool,
pub world_state: WorldState,
+ pub asset_map: HashMap<String, Handle<Texture>>,
}
fn main() {
@@ -29,6 +34,7 @@ fn main() {
..Default::default()
})
.init_resource::<GameState>()
+ .init_resource::<AssetsLoading>()
.add_plugins(DefaultPlugins)
.add_plugin(FrameTimeDiagnosticsPlugin::default())
.add_plugin(LogDiagnosticsPlugin::default())
@@ -39,7 +45,12 @@ fn main() {
.run();
}
-fn setup(commands: &mut Commands /*mut kurinji: ResMut<Kurinji>*/) {
+fn setup(
+ commands: &mut Commands,
+ mut loading: ResMut<AssetsLoading>,
+ asset_server: Res<AssetServer>,
+ mut game_state: ResMut<GameState>,
+) {
commands
// Spawn a camera
.spawn(OrthographicCameraBundle {
@@ -58,4 +69,18 @@ fn setup(commands: &mut Commands /*mut kurinji: ResMut<Kurinji>*/) {
})
.with(PLAYER_START)
.with(MainCamera);
+
+ let sunny_texture_handle = asset_server.load("tilesets/SunnyLand_by_Ansimuz-extended.png");
+ loading.0.push(sunny_texture_handle.clone_untyped());
+ game_state
+ .asset_map
+ .insert("Sunnyland".into(), sunny_texture_handle);
+ let dungeon_tileset_texture_handle =
+ asset_server.load("tilesets/0x72_DungeonTilesetII_v1.3.png");
+ loading
+ .0
+ .push(dungeon_tileset_texture_handle.clone_untyped());
+ game_state
+ .asset_map
+ .insert("DungeonTileset".into(), dungeon_tileset_texture_handle);
}
diff --git a/src/plugins/player.rs b/src/plugins/player.rs
@@ -2,7 +2,8 @@ use crate::entities::common::Health;
use crate::entities::markers::{Movable, Player, Wall};
use crate::entities::player::{PlayerBundle, PlayerName, PlayerXp};
use crate::plugins::world::{GridLocation, MainCamera, SPRITE_HEIGHT, SPRITE_WIDTH};
-use crate::GameState;
+use crate::{AssetsLoading, GameState};
+use bevy::asset::LoadState;
use bevy::prelude::*;
use std::collections::HashMap;
@@ -13,8 +14,7 @@ pub struct PlayerPlugin;
impl Plugin for PlayerPlugin {
fn build(&self, app: &mut AppBuilder) {
app.add_system(player_movement.system())
- .add_system(setup_player.system())
- .add_startup_system(setup_player.system());
+ .add_system(setup_player.system());
}
}
@@ -23,14 +23,33 @@ fn setup_player(
asset_server: Res<AssetServer>,
texture_atlases: ResMut<Assets<TextureAtlas>>,
game_state: ResMut<GameState>,
+ loading: Res<AssetsLoading>,
+ textures: Res<Assets<Texture>>,
) {
if !game_state.spawned {
+ let mut ready = true;
+ for handle in loading.0.iter() {
+ match asset_server.get_load_state(handle) {
+ LoadState::Failed => {
+ ready = false;
+ }
+ LoadState::Loaded => {}
+ _ => {
+ ready = false;
+ }
+ }
+ }
+
+ if !ready {
+ return;
+ }
+
setup_player_internal(
PLAYER_START,
&mut commands,
- asset_server,
texture_atlases,
game_state,
+ &textures,
);
}
}
@@ -38,12 +57,20 @@ fn setup_player(
fn setup_player_internal(
grid_location: GridLocation,
commands: &mut Commands,
- asset_server: Res<AssetServer>,
mut texture_atlases: ResMut<Assets<TextureAtlas>>,
mut game_state: ResMut<GameState>,
+ textures: &Res<Assets<Texture>>,
) {
- let texture_handle = asset_server.load("tilesets/0x72_DungeonTilesetII_v1.3.png");
- let texture_atlas = TextureAtlas::from_grid(texture_handle, Vec2::new(16.0, 16.0), 32, 32);
+ let texture_handle = game_state.asset_map.get("DungeonTileset").unwrap();
+ let texture: &Texture = textures.get(texture_handle.id).unwrap();
+ let cols = texture.size.width / 16;
+ let rows = texture.size.height / 16;
+ let texture_atlas = TextureAtlas::from_grid(
+ texture_handle.clone(),
+ Vec2::new(16.0, 16.0),
+ cols as usize,
+ rows as usize,
+ );
let texture_atlas_handle = texture_atlases.add(texture_atlas);
// Spawn player
diff --git a/src/plugins/world.rs b/src/plugins/world.rs
@@ -1,6 +1,7 @@
use crate::entities::markers::Wall;
use crate::plugins::player::PLAYER_START;
-use crate::GameState;
+use crate::{AssetsLoading, GameState};
+use bevy::asset::LoadState;
use bevy::prelude::*;
use noise::{NoiseFn, OpenSimplex, Seedable};
use rand::Rng;
@@ -88,16 +89,25 @@ pub const SPRITE_HEIGHT: f32 = 16.0;
fn setup_wall(
grid_location: GridLocation,
commands: &mut Commands,
- asset_server: &Res<AssetServer>,
+ game_state: &ResMut<GameState>,
texture_atlases: &mut ResMut<Assets<TextureAtlas>>,
+ textures: &Res<Assets<Texture>>,
) {
- let texture_handle = asset_server.load("tilesets/SunnyLand_by_Ansimuz-extended.png");
- let texture_atlas = TextureAtlas::from_grid(texture_handle, Vec2::new(16.0, 16.0), 23, 21);
+ let texture_handle = game_state.asset_map.get("Sunnyland").unwrap();
+ let texture: &Texture = textures.get(texture_handle.id).unwrap();
+ let cols = texture.size.width / 16;
+ let rows = texture.size.height / 16;
+ let texture_atlas = TextureAtlas::from_grid(
+ texture_handle.clone(),
+ Vec2::new(17.0, 17.0),
+ cols as usize,
+ rows as usize,
+ );
let texture_atlas_handle = texture_atlases.add(texture_atlas);
commands
.spawn(SpriteSheetBundle {
sprite: TextureAtlasSprite {
- index: 6,
+ index: 48,
..Default::default()
},
transform: Transform::from_translation(Vec3::new(
@@ -115,8 +125,10 @@ fn setup_wall(
fn draw(
commands: &mut Commands,
mut game_state: ResMut<GameState>,
- asset_server: Res<AssetServer>,
mut texture_atlases: ResMut<Assets<TextureAtlas>>,
+ server: Res<AssetServer>,
+ loading: Res<AssetsLoading>,
+ textures: Res<Assets<Texture>>,
) {
if game_state.world_state.map_loaded
&& game_state.world_state.level == game_state.world_state.requested_level
@@ -124,6 +136,23 @@ fn draw(
return;
}
+ let mut ready = true;
+ for handle in loading.0.iter() {
+ match server.get_load_state(handle) {
+ LoadState::Failed => {
+ ready = false;
+ }
+ LoadState::Loaded => {}
+ _ => {
+ ready = false;
+ }
+ }
+ }
+
+ if !ready {
+ return;
+ }
+
if game_state.world_state.seed.is_none() {
let mut rng = rand::thread_rng();
game_state.world_state.seed = Some(rng.gen());
@@ -149,7 +178,13 @@ fn draw(
let noise_value = f * 16.0 + (16.0 / 2.0);
if noise_value > 4.8 {
- setup_wall(coord, commands, &asset_server, &mut texture_atlases);
+ setup_wall(
+ coord,
+ commands,
+ &game_state,
+ &mut texture_atlases,
+ &textures,
+ );
}
}
}