Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Bevy Micro LDTK
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Model registry
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Microhacks
Bevy Micro LDTK
Commits
24a2956c
Verified
Commit
24a2956c
authored
2 years ago
by
Louis
Browse files
Options
Downloads
Patches
Plain Diff
Wrap levels and layers, preprocess layers to extract tile info
parent
ec233e24
No related branches found
No related tags found
No related merge requests found
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
src/assets.rs
+9
-5
9 additions, 5 deletions
src/assets.rs
src/lib.rs
+12
-4
12 additions, 4 deletions
src/lib.rs
src/map_query.rs
+32
-175
32 additions, 175 deletions
src/map_query.rs
src/types.rs
+210
-0
210 additions, 0 deletions
src/types.rs
src/utils.rs
+11
-21
11 additions, 21 deletions
src/utils.rs
with
274 additions
and
205 deletions
src/assets.rs
+
9
−
5
View file @
24a2956c
...
@@ -5,10 +5,11 @@ use anyhow::Error;
...
@@ -5,10 +5,11 @@ use anyhow::Error;
use
bevy
::
asset
::{
AssetEvent
,
AssetLoader
,
Assets
,
BoxedFuture
,
LoadContext
,
LoadedAsset
};
use
bevy
::
asset
::{
AssetEvent
,
AssetLoader
,
Assets
,
BoxedFuture
,
LoadContext
,
LoadedAsset
};
use
bevy
::
prelude
::{
EventReader
,
Res
,
ResMut
,
Resource
};
use
bevy
::
prelude
::{
EventReader
,
Res
,
ResMut
,
Resource
};
use
bevy
::
reflect
::
TypeUuid
;
use
bevy
::
reflect
::
TypeUuid
;
use
ldtk_rust
::
{
Level
,
Project
,
TilesetDefinition
}
;
use
ldtk_rust
::
Project
;
use
serde_json
::
Value
;
use
serde_json
::
Value
;
use
crate
::
utils
::
SerdeClone
;
use
crate
::
utils
::
SerdeClone
;
use
crate
::
LdtkLevel
;
#[derive(TypeUuid)]
#[derive(TypeUuid)]
#[uuid
=
"292a8918-9487-11ed-8dd2-43b6f36cb076"
]
#[uuid
=
"292a8918-9487-11ed-8dd2-43b6f36cb076"
]
...
@@ -51,9 +52,9 @@ impl AssetLoader for LdtkLoader {
...
@@ -51,9 +52,9 @@ impl AssetLoader for LdtkLoader {
}
}
#[derive(Resource,
Default)]
#[derive(Resource,
Default)]
pub
struct
LevelIndex
(
pub
HashMap
<
String
,
Level
>
);
pub
struct
LevelIndex
(
pub
HashMap
<
String
,
Ldtk
Level
>
);
impl
Deref
for
LevelIndex
{
impl
Deref
for
LevelIndex
{
type
Target
=
HashMap
<
String
,
Level
>
;
type
Target
=
HashMap
<
String
,
Ldtk
Level
>
;
fn
deref
(
&
self
)
->
&
Self
::
Target
{
fn
deref
(
&
self
)
->
&
Self
::
Target
{
&
self
.0
&
self
.0
}
}
...
@@ -92,7 +93,10 @@ pub fn handle_ldtk_project_events(
...
@@ -92,7 +93,10 @@ pub fn handle_ldtk_project_events(
AssetEvent
::
Created
{
handle
}
|
AssetEvent
::
Modified
{
handle
}
=>
{
AssetEvent
::
Created
{
handle
}
|
AssetEvent
::
Modified
{
handle
}
=>
{
if
let
Some
(
LdtkProject
(
project
))
=
assets
.get
(
handle
)
{
if
let
Some
(
LdtkProject
(
project
))
=
assets
.get
(
handle
)
{
for
level
in
&
project
.levels
{
for
level
in
&
project
.levels
{
level_index
.insert
(
level
.identifier
.clone
(),
level
.serde_clone
());
level_index
.insert
(
level
.identifier
.clone
(),
LdtkLevel
::
from
(
level
.serde_clone
()),
);
}
}
for
tileset
in
&
project
.defs.tilesets
{
for
tileset
in
&
project
.defs.tilesets
{
...
@@ -100,7 +104,7 @@ pub fn handle_ldtk_project_events(
...
@@ -100,7 +104,7 @@ pub fn handle_ldtk_project_events(
for
custom
in
&
tileset
.custom_data
{
for
custom
in
&
tileset
.custom_data
{
tile_meta
.insert
(
tile_meta
.insert
(
custom
.tile_id
,
custom
.tile_id
,
serde_json
::
from_str
(
&
*
custom
.data
)
.unwrap
(),
serde_json
::
from_str
(
&
custom
.data
)
.unwrap
(),
);
);
}
}
tilset_index
.insert
(
tileset
.identifier
.clone
(),
TileMetadata
(
tile_meta
));
tilset_index
.insert
(
tileset
.identifier
.clone
(),
TileMetadata
(
tile_meta
));
...
...
This diff is collapsed.
Click to expand it.
src/lib.rs
+
12
−
4
View file @
24a2956c
...
@@ -2,6 +2,7 @@ mod assets;
...
@@ -2,6 +2,7 @@ mod assets;
mod
camera
;
mod
camera
;
mod
locator
;
mod
locator
;
mod
map_query
;
mod
map_query
;
mod
types
;
pub
(
crate
)
mod
utils
;
pub
(
crate
)
mod
utils
;
// mod spawning;
// mod spawning;
...
@@ -45,6 +46,13 @@ mod __plugin {
...
@@ -45,6 +46,13 @@ mod __plugin {
}
}
}
}
}
}
impl
<
CameraFilter
:
ReadOnlyWorldQuery
+
Send
+
Sync
+
'static
>
Default
for
MicroLDTKCameraPlugin
<
CameraFilter
>
{
fn
default
()
->
Self
{
Self
::
new
()
}
}
pub
struct
MicroLDTKCameraPlugin
<
CameraFilter
:
ReadOnlyWorldQuery
>
{
pub
struct
MicroLDTKCameraPlugin
<
CameraFilter
:
ReadOnlyWorldQuery
>
{
_p
:
PhantomData
<
CameraFilter
>
,
_p
:
PhantomData
<
CameraFilter
>
,
...
@@ -65,7 +73,7 @@ use std::sync::atomic::{AtomicU32, Ordering};
...
@@ -65,7 +73,7 @@ use std::sync::atomic::{AtomicU32, Ordering};
pub
use
__plugin
::{
MicroLDTKCameraPlugin
,
MicroLDTKPlugin
};
pub
use
__plugin
::{
MicroLDTKCameraPlugin
,
MicroLDTKPlugin
};
pub
use
assets
::{
LdtkLoader
,
LdtkProject
,
LevelIndex
,
TileMetadata
,
TilesetIndex
};
pub
use
assets
::{
LdtkLoader
,
LdtkProject
,
LevelIndex
,
TileMetadata
,
TilesetIndex
};
pub
use
map_qu
er
y
::
{
CameraBound
s
,
LayerRef
,
MapQuery
,
TileRef
}
;
pub
use
cam
er
a
::
CameraBound
er
;
pub
use
utils
::{
pub
use
map_query
::{
CameraBounds
,
MapQuery
};
entity_centre
,
entity_to_worldspace
,
grid_to_px
,
px_to_grid
,
ActiveLevel
,
WorldLinked
,
pub
use
types
::{
LdtkLayer
,
LdtkLevel
,
SpatialIndex
,
TileFlip
,
TileRef
};
};
pub
use
utils
::{
entity_centre
,
grid_to_px
,
px_to_grid
,
ActiveLevel
,
WorldLinked
};
This diff is collapsed.
Click to expand it.
src/map_query.rs
+
32
−
175
View file @
24a2956c
use
std
::
fmt
::
{
Debug
,
Formatter
}
;
use
std
::
fmt
::
Debug
;
use
std
::
marker
::
PhantomData
;
use
std
::
marker
::
PhantomData
;
use
std
::
path
::
Path
;
use
std
::
str
::
FromStr
;
use
std
::
str
::
FromStr
;
use
bevy
::
ecs
::
system
::
SystemParam
;
use
bevy
::
ecs
::
system
::
SystemParam
;
use
bevy
::
prelude
::
*
;
use
bevy
::
prelude
::
*
;
use
ldtk_rust
::{
EntityInstance
,
LayerInstance
,
Level
,
TileInstance
};
use
ldtk_rust
::
EntityInstance
;
use
num_traits
::
AsPrimitive
;
// use crate::assets::level_index::LevelIndex;
use
crate
::
assets
::
LevelIndex
;
use
crate
::
assets
::{
LdtkProject
,
LevelIndex
};
use
crate
::
utils
::{
ActiveLevel
,
SerdeClone
};
use
crate
::
utils
::{
ActiveLevel
,
Indexer
,
SerdeClone
};
use
crate
::{
get_ldtk_tile_scale
,
LdtkLayer
,
LdtkLevel
};
use
crate
::{
get_ldtk_tile_scale
,
px_to_grid
};
#[derive(SystemParam)]
#[derive(SystemParam)]
pub
struct
MapQuery
<
'w
,
's
>
{
pub
struct
MapQuery
<
'w
,
's
>
{
assets
:
Res
<
'w
,
Assets
<
LdtkProject
>>
,
active
:
Option
<
Res
<
'w
,
ActiveLevel
>>
,
active
:
Option
<
Res
<
'w
,
ActiveLevel
>>
,
index
:
Res
<
'w
,
LevelIndex
>
,
index
:
Res
<
'w
,
LevelIndex
>
,
#[system_param(ignore)]
#[system_param(ignore)]
_e
:
PhantomData
<&
's
()
>
,
_e
:
PhantomData
<&
's
()
>
,
}
}
pub
struct
TileRef
<
'a
>
{
pub
tile
:
&
'a
TileInstance
,
}
#[repr(C)]
#[derive(Copy,
Clone,
Ord,
PartialOrd,
Eq,
PartialEq,
Default,
Debug)]
pub
enum
TileFlip
{
#[default]
None
=
0
,
Horizontal
=
1
,
Vertical
=
2
,
Both
=
3
,
}
impl
TileFlip
{
pub
fn
is_horizontal
(
&
self
)
->
bool
{
match
self
{
Self
::
None
|
Self
::
Vertical
=>
false
,
Self
::
Horizontal
|
Self
::
Both
=>
true
,
}
}
pub
fn
is_vertical
(
&
self
)
->
bool
{
match
self
{
Self
::
None
|
Self
::
Horizontal
=>
false
,
Self
::
Vertical
|
Self
::
Both
=>
true
,
}
}
}
impl
<
'a
>
TileRef
<
'a
>
{
pub
fn
new
(
tile
:
&
'a
TileInstance
)
->
Self
{
TileRef
{
tile
}
}
pub
fn
gid
(
&
self
)
->
usize
{
(
self
.tile.src
[
0
]
*
self
.tile.src
[
1
])
.unsigned_abs
()
as
usize
}
pub
fn
get_flip
(
&
self
)
->
TileFlip
{
match
self
.tile.f
{
1
=>
TileFlip
::
Horizontal
,
2
=>
TileFlip
::
Vertical
,
3
=>
TileFlip
::
Both
,
_
=>
TileFlip
::
None
,
}
}
}
impl
<
'a
>
Debug
for
TileRef
<
'a
>
{
fn
fmt
(
&
self
,
f
:
&
mut
Formatter
<
'_
>
)
->
std
::
fmt
::
Result
{
f
.debug_struct
(
"TileRef"
)
.field
(
"gid"
,
&
self
.gid
())
.field
(
"tile.t"
,
&
self
.tile.t
)
.field
(
"tile.d"
,
&
self
.tile.d
)
.field
(
"tile.px"
,
&
self
.tile.px
)
.field
(
"tile.src"
,
&
self
.tile.src
)
.finish
()
}
}
pub
struct
InstanceRef
<
'a
>
{
pub
struct
InstanceRef
<
'a
>
{
pub
entity
:
&
'a
EntityInstance
,
pub
entity
:
&
'a
EntityInstance
,
}
}
...
@@ -98,7 +36,7 @@ impl<'a> InstanceRef<'a> {
...
@@ -98,7 +36,7 @@ impl<'a> InstanceRef<'a> {
return
field
return
field
.value
.value
.as_ref
()
.as_ref
()
.map
(|
v
|
v
.clone
()
)
.clone
d
()
.unwrap_or
(
serde_json
::
Value
::
Null
);
.unwrap_or
(
serde_json
::
Value
::
Null
);
}
}
}
}
...
@@ -107,77 +45,6 @@ impl<'a> InstanceRef<'a> {
...
@@ -107,77 +45,6 @@ impl<'a> InstanceRef<'a> {
}
}
}
}
pub
struct
LayerRef
<
'a
>
{
pub
idx
:
usize
,
pub
indexer
:
Indexer
,
pub
layer
:
&
'a
LayerInstance
,
}
impl
<
'a
>
LayerRef
<
'a
>
{
pub
fn
new
(
idx
:
usize
,
indexer
:
Indexer
,
layer
:
&
'a
LayerInstance
)
->
Self
{
LayerRef
{
layer
,
indexer
,
idx
,
}
}
pub
fn
has_tiles
(
&
self
)
->
bool
{
!
(
self
.layer.auto_layer_tiles
.is_empty
()
&&
self
.layer.grid_tiles
.is_empty
())
}
pub
fn
for_each_tile
(
&
self
,
mut
cb
:
impl
FnMut
(
i64
,
i64
,
TileRef
))
{
self
.layer
.grid_tiles
.iter
()
.chain
(
self
.layer.auto_layer_tiles
.iter
())
.for_each
(|
tile
:
&
TileInstance
|
{
let
(
x
,
y
)
=
match
tile
.px
.as_slice
()
{
&
[
x
,
y
]
=>
(
px_to_grid
(
x
),
px_to_grid
(
y
)),
_
=>
{
return
;
}
};
cb
(
x
,
y
,
TileRef
::
new
(
tile
));
});
}
pub
fn
get_z_delta
(
&
self
)
->
f32
{
(
self
.idx
as
f32
)
/
100.0
}
pub
fn
get_tile_at
(
&
self
,
x
:
impl
AsPrimitive
<
isize
>
,
y
:
impl
AsPrimitive
<
isize
>
,
)
->
Option
<
TileRef
>
{
let
idx
=
self
.indexer
.index
(
x
,
y
);
match
self
.layer.grid_tiles
.is_empty
()
{
true
=>
self
.layer
.auto_layer_tiles
.get
(
idx
)
.map
(|
tile
|
TileRef
::
new
(
tile
)),
false
=>
self
.layer
.grid_tiles
.get
(
idx
)
.map
(|
tile
|
TileRef
::
new
(
tile
)),
}
}
/// Returns the inferred name of the tileset used for this layer. This is assumed to be the
/// name of the tileset file, without the preceding path segments or the file extension. Case
/// remains unchanged
pub
fn
infer_tileset_name
(
&
self
)
->
Option
<
String
>
{
self
.layer.tileset_rel_path
.as_ref
()
.and_then
(|
path
|
{
Path
::
new
(
path
)
.file_stem
()
.and_then
(|
stem
|
stem
.to_str
())
.map
(
String
::
from
)
})
}
}
#[derive(Copy,
Clone,
Debug)]
#[derive(Copy,
Clone,
Debug)]
pub
struct
CameraBounds
{
pub
struct
CameraBounds
{
pub
left
:
f32
,
pub
left
:
f32
,
...
@@ -206,24 +73,15 @@ impl<'w, 's> MapQuery<'w, 's> {
...
@@ -206,24 +73,15 @@ impl<'w, 's> MapQuery<'w, 's> {
// --- than the currently active one. 'active' methods are a convenience to
// --- than the currently active one. 'active' methods are a convenience to
// --- call the static accessors on whatever the current level is
// --- call the static accessors on whatever the current level is
pub
fn
get_indexer_for
(
level
:
&
Level
)
->
Indexer
{
pub
fn
for_each_layer_of
(
level
:
&
LdtkLevel
,
mut
cb
:
impl
FnMut
(
&
LdtkLayer
))
{
Indexer
::
new
(
px_to_grid
(
level
.px_wid
),
px_to_grid
(
level
.px_hei
))
for
layer
in
level
.layers
()
.rev
()
{
}
cb
(
layer
);
pub
fn
for_each_layer_of
(
level
:
&
Level
,
mut
cb
:
impl
FnMut
(
LayerRef
))
{
if
let
Some
(
layers
)
=
level
.layer_instances
.as_ref
()
{
for
layer
in
layers
.iter
()
.rev
()
.enumerate
()
{
cb
(
LayerRef
::
new
(
layer
.0
,
MapQuery
::
get_indexer_for
(
level
),
layer
.1
,
));
}
}
}
}
}
pub
fn
get_entities_of
(
level
:
&
Level
)
->
Vec
<&
EntityInstance
>
{
pub
fn
get_entities_of
(
level
:
&
Ldtk
Level
)
->
Vec
<&
EntityInstance
>
{
level
level
.level_ref
()
.layer_instances
.layer_instances
.as_ref
()
.as_ref
()
.map
(|
layers
|
{
.map
(|
layers
|
{
...
@@ -235,8 +93,9 @@ impl<'w, 's> MapQuery<'w, 's> {
...
@@ -235,8 +93,9 @@ impl<'w, 's> MapQuery<'w, 's> {
.unwrap_or_default
()
.unwrap_or_default
()
}
}
pub
fn
get_instance_refs_of
(
level
:
&
Level
)
->
Vec
<
InstanceRef
>
{
pub
fn
get_instance_refs_of
(
level
:
&
Ldtk
Level
)
->
Vec
<
InstanceRef
>
{
level
level
.level_ref
()
.layer_instances
.layer_instances
.as_ref
()
.as_ref
()
.map
(|
layers
|
{
.map
(|
layers
|
{
...
@@ -250,34 +109,32 @@ impl<'w, 's> MapQuery<'w, 's> {
...
@@ -250,34 +109,32 @@ impl<'w, 's> MapQuery<'w, 's> {
}
}
pub
fn
get_filtered_entities_of
(
pub
fn
get_filtered_entities_of
(
level
:
&
Level
,
level
:
&
Ldtk
Level
,
entity_type
:
impl
ToString
,
entity_type
:
impl
ToString
,
)
->
Vec
<&
EntityInstance
>
{
)
->
Vec
<&
EntityInstance
>
{
let
e_type
=
entity_type
.to_string
();
let
e_type
=
entity_type
.to_string
();
match
level
.layer_instances
.as_ref
()
{
level
Some
(
inst
)
=>
inst
.layers
()
.iter
()
.flat_map
(|
layer
|
layer
.as_ref
()
.entity_instances
.iter
())
.flat_map
(|
layer
|
layer
.entity_instances
.iter
())
.filter
(|
inst
|
inst
.identifier
==
e_type
)
.filter
(|
inst
|
inst
.identifier
==
e_type
)
.collect
()
.collect
(),
None
=>
Vec
::
new
(),
}
}
}
pub
fn
get_owned_entities_of
(
level
:
&
Level
)
->
Vec
<
EntityInstance
>
{
pub
fn
get_owned_entities_of
(
level
:
&
Ldtk
Level
)
->
Vec
<
EntityInstance
>
{
level
level
.layer_instances
.layers
()
.as_ref
()
.flat_map
(|
layer
|
{
.map
(|
layers
|
{
layer
layers
.as_ref
()
.entity_instances
.iter
()
.iter
()
.flat_map
(|
layer
|
layer
.entity_instances
.iter
()
.map
(|
inst
|
inst
.serde_clone
()))
.map
(|
inst
|
inst
.serde_clone
())
.collect
()
})
})
.
unwrap_or_defaul
t
()
.
collec
t
()
}
}
pub
fn
get_camera_bounds_of
(
level
:
&
Level
)
->
CameraBounds
{
pub
fn
get_camera_bounds_of
(
level
:
&
LdtkLevel
)
->
CameraBounds
{
let
level
=
level
.level_ref
();
CameraBounds
{
CameraBounds
{
left
:
0.0
,
left
:
0.0
,
top
:
level
.px_hei
as
f32
,
top
:
level
.px_hei
as
f32
,
...
@@ -286,7 +143,7 @@ impl<'w, 's> MapQuery<'w, 's> {
...
@@ -286,7 +143,7 @@ impl<'w, 's> MapQuery<'w, 's> {
}
}
}
}
pub
fn
get_active_level
(
&
self
)
->
Option
<&
Level
>
{
pub
fn
get_active_level
(
&
self
)
->
Option
<&
Ldtk
Level
>
{
self
.active
self
.active
.as_ref
()
.as_ref
()
.and_then
(|
index
|
self
.index
.get
(
&
index
.map
))
.and_then
(|
index
|
self
.index
.get
(
&
index
.map
))
...
@@ -294,7 +151,7 @@ impl<'w, 's> MapQuery<'w, 's> {
...
@@ -294,7 +151,7 @@ impl<'w, 's> MapQuery<'w, 's> {
pub
fn
get_entities
(
&
self
)
->
Vec
<&
EntityInstance
>
{
pub
fn
get_entities
(
&
self
)
->
Vec
<&
EntityInstance
>
{
self
.get_active_level
()
self
.get_active_level
()
.map
(
|
level
|
MapQuery
::
get_entities_of
(
level
)
)
.map
(
MapQuery
::
get_entities_of
)
.unwrap_or_default
()
.unwrap_or_default
()
}
}
...
@@ -302,7 +159,7 @@ impl<'w, 's> MapQuery<'w, 's> {
...
@@ -302,7 +159,7 @@ impl<'w, 's> MapQuery<'w, 's> {
self
.get_active_level
()
.map
(
MapQuery
::
get_camera_bounds_of
)
self
.get_active_level
()
.map
(
MapQuery
::
get_camera_bounds_of
)
}
}
pub
fn
for_each_layer
(
&
self
,
mut
cb
:
impl
FnMut
(
Layer
Ref
))
{
pub
fn
for_each_layer
(
&
self
,
cb
:
impl
FnMut
(
&
Ldtk
Layer
))
{
if
let
Some
(
level
)
=
self
.get_active_level
()
{
if
let
Some
(
level
)
=
self
.get_active_level
()
{
Self
::
for_each_layer_of
(
level
,
cb
);
Self
::
for_each_layer_of
(
level
,
cb
);
}
}
...
...
This diff is collapsed.
Click to expand it.
src/types.rs
0 → 100644
+
210
−
0
View file @
24a2956c
use
std
::
fmt
::{
Debug
,
Formatter
};
use
std
::
path
::
Path
;
use
bevy
::
math
::{
IVec2
,
UVec2
};
use
bevy
::
utils
::
HashMap
;
use
ldtk_rust
::{
LayerInstance
,
Level
,
TileInstance
};
use
num_traits
::
AsPrimitive
;
use
crate
::
utils
::{
Indexer
,
SerdeClone
};
use
crate
::{
get_ldtk_tile_scale
,
px_to_grid
};
pub
struct
TileRef
<
'a
>
{
pub
tile
:
&
'a
TileInstance
,
}
#[repr(C)]
#[derive(Copy,
Clone,
Ord,
PartialOrd,
Eq,
PartialEq,
Default,
Debug)]
pub
enum
TileFlip
{
#[default]
None
=
0
,
Horizontal
=
1
,
Vertical
=
2
,
Both
=
3
,
}
impl
TileFlip
{
pub
fn
is_horizontal
(
&
self
)
->
bool
{
match
self
{
Self
::
None
|
Self
::
Vertical
=>
false
,
Self
::
Horizontal
|
Self
::
Both
=>
true
,
}
}
pub
fn
is_vertical
(
&
self
)
->
bool
{
match
self
{
Self
::
None
|
Self
::
Horizontal
=>
false
,
Self
::
Vertical
|
Self
::
Both
=>
true
,
}
}
}
impl
<
'a
>
TileRef
<
'a
>
{
pub
fn
new
(
tile
:
&
'a
TileInstance
)
->
Self
{
TileRef
{
tile
}
}
pub
fn
gid
(
&
self
)
->
usize
{
(
self
.tile.src
[
0
]
*
self
.tile.src
[
1
])
.unsigned_abs
()
as
usize
}
pub
fn
get_flip
(
&
self
)
->
TileFlip
{
match
self
.tile.f
{
1
=>
TileFlip
::
Horizontal
,
2
=>
TileFlip
::
Vertical
,
3
=>
TileFlip
::
Both
,
_
=>
TileFlip
::
None
,
}
}
}
impl
<
'a
>
Debug
for
TileRef
<
'a
>
{
fn
fmt
(
&
self
,
f
:
&
mut
Formatter
<
'_
>
)
->
std
::
fmt
::
Result
{
f
.debug_struct
(
"TileRef"
)
.field
(
"gid"
,
&
self
.gid
())
.field
(
"tile.t"
,
&
self
.tile.t
)
.field
(
"tile.d"
,
&
self
.tile.d
)
.field
(
"tile.px"
,
&
self
.tile.px
)
.field
(
"tile.src"
,
&
self
.tile.src
)
.finish
()
}
}
#[derive(Ord,
PartialOrd,
Eq,
PartialEq,
Clone,
Copy,
Hash,
Debug)]
pub
struct
SpatialIndex
(
i64
,
i64
);
impl
<
A
,
B
>
From
<
(
A
,
B
)
>
for
SpatialIndex
where
A
:
AsPrimitive
<
i64
>
,
B
:
AsPrimitive
<
i64
>
,
{
fn
from
(
value
:
(
A
,
B
))
->
Self
{
Self
(
value
.0
.as_
(),
value
.1
.as_
())
}
}
impl
From
<
UVec2
>
for
SpatialIndex
{
fn
from
(
value
:
UVec2
)
->
Self
{
Self
(
value
.x
as
i64
,
value
.y
as
i64
)
}
}
impl
From
<
IVec2
>
for
SpatialIndex
{
fn
from
(
value
:
IVec2
)
->
Self
{
Self
(
value
.x
as
i64
,
value
.y
as
i64
)
}
}
pub
struct
LdtkLevel
{
level
:
Level
,
processed_layers
:
Vec
<
LdtkLayer
>
,
}
impl
LdtkLevel
{
pub
fn
level_ref
(
&
self
)
->
&
Level
{
&
self
.level
}
pub
fn
level_ref_mut
(
&
mut
self
)
->
&
mut
Level
{
&
mut
self
.level
}
pub
fn
layers
(
&
self
)
->
impl
DoubleEndedIterator
<
Item
=
&
LdtkLayer
>
{
self
.processed_layers
.iter
()
}
pub
fn
layers_mut
(
&
mut
self
)
->
impl
DoubleEndedIterator
<
Item
=
&
mut
LdtkLayer
>
{
self
.processed_layers
.iter_mut
()
}
pub
fn
get_indexer
(
&
self
)
->
Indexer
{
Indexer
::
new
(
px_to_grid
(
self
.level.px_wid
),
px_to_grid
(
self
.level.px_hei
))
}
}
impl
From
<
Level
>
for
LdtkLevel
{
fn
from
(
mut
value
:
Level
)
->
Self
{
let
layers
=
value
.layer_instances
.take
();
Self
{
processed_layers
:
layers
.unwrap_or_default
()
.into_iter
()
.enumerate
()
.map
(|(
idx
,
inst
)|
LdtkLayer
::
new
(
idx
,
inst
))
.collect
(),
level
:
value
,
}
}
}
pub
struct
LdtkLayer
{
layer
:
LayerInstance
,
position_lookup
:
HashMap
<
SpatialIndex
,
TileInstance
>
,
level
:
usize
,
indexer
:
Indexer
,
}
impl
LdtkLayer
{
pub
fn
new
(
index
:
usize
,
layer
:
LayerInstance
)
->
Self
{
let
tile_list
=
layer
.grid_tiles
.iter
()
.chain
(
&
layer
.auto_layer_tiles
);
let
mut
position_lookup
=
HashMap
::
with_capacity
(
layer
.grid_tiles
.len
()
+
layer
.auto_layer_tiles
.len
());
let
scale
=
get_ldtk_tile_scale
()
as
i64
;
let
indexer
=
Indexer
::
new
(
layer
.c_wid
,
layer
.c_hei
);
for
tile
in
tile_list
{
let
x
=
tile
.px
[
0
]
/
scale
;
let
y
=
tile
.px
[
1
]
/
scale
;
position_lookup
.insert
((
x
,
y
)
.into
(),
tile
.serde_clone
());
}
Self
{
level
:
index
,
indexer
,
layer
,
position_lookup
,
}
}
pub
fn
indexer
(
&
self
)
->
Indexer
{
self
.indexer
}
pub
fn
has_tiles
(
&
self
)
->
bool
{
!
(
self
.layer.auto_layer_tiles
.is_empty
()
&&
self
.layer.grid_tiles
.is_empty
())
}
pub
fn
for_each_tile
(
&
self
,
mut
cb
:
impl
FnMut
(
i64
,
i64
,
TileRef
))
{
self
.position_lookup
.iter
()
.for_each
(|(
pos
,
tile
)|
{
cb
(
pos
.0
,
pos
.1
,
TileRef
::
new
(
tile
));
});
}
pub
fn
get_z_delta
(
&
self
)
->
f32
{
(
self
.level
as
f32
)
/
100.0
}
pub
fn
get_tile
(
&
self
,
pos
:
impl
Into
<
SpatialIndex
>
)
->
Option
<
TileRef
>
{
self
.position_lookup
.get
(
&
pos
.into
())
.map
(
TileRef
::
new
)
}
pub
fn
get_tile_at
(
&
self
,
a
:
impl
AsPrimitive
<
i64
>
,
b
:
impl
AsPrimitive
<
i64
>
,
)
->
Option
<
TileRef
>
{
self
.position_lookup
.get
(
&
SpatialIndex
(
a
.as_
(),
b
.as_
()))
.map
(
TileRef
::
new
)
}
/// Returns the inferred name of the tileset used for this layer. This is assumed to be the
/// name of the tileset file, without the preceding path segments or the file extension. Case
/// remains unchanged
pub
fn
infer_tileset_name
(
&
self
)
->
Option
<
String
>
{
self
.layer.tileset_rel_path
.as_ref
()
.and_then
(|
path
|
{
Path
::
new
(
path
)
.file_stem
()
.and_then
(|
stem
|
stem
.to_str
())
.map
(
String
::
from
)
})
}
}
impl
AsRef
<
LayerInstance
>
for
LdtkLayer
{
fn
as_ref
(
&
self
)
->
&
LayerInstance
{
&
self
.layer
}
}
This diff is collapsed.
Click to expand it.
src/utils.rs
+
11
−
21
View file @
24a2956c
...
@@ -15,7 +15,7 @@ where
...
@@ -15,7 +15,7 @@ where
T
:
Serialize
+
DeserializeOwned
,
T
:
Serialize
+
DeserializeOwned
,
{
{
fn
serde_clone
(
&
self
)
->
Self
{
fn
serde_clone
(
&
self
)
->
Self
{
serde_json
::
from_value
(
serde_json
::
to_value
(
&
self
)
.unwrap
())
.unwrap
()
serde_json
::
from_value
(
serde_json
::
to_value
(
self
)
.unwrap
())
.unwrap
()
}
}
}
}
...
@@ -27,19 +27,9 @@ pub fn grid_to_px<T: AsPrimitive<f32>>(t: T) -> f32 {
...
@@ -27,19 +27,9 @@ pub fn grid_to_px<T: AsPrimitive<f32>>(t: T) -> f32 {
t
.as_
()
*
get_ldtk_tile_scale
()
t
.as_
()
*
get_ldtk_tile_scale
()
}
}
pub
fn
entity_to_worldspace
(
level_height
:
i64
,
entity
:
&
EntityInstance
)
->
(
f32
,
f32
)
{
let
centre_align_pixel_x
=
grid_to_px
(
entity
.grid
[
0
])
-
(
get_ldtk_tile_scale
()
/
2.0
);
let
centre_align_pixel_y
=
grid_to_px
(
entity
.grid
[
1
])
-
(
get_ldtk_tile_scale
()
/
2.0
);
let
inverted_pixel_y
=
level_height
as
f32
-
centre_align_pixel_y
-
get_ldtk_tile_scale
();
let
box_aligned_x
=
centre_align_pixel_x
+
(
entity
.width
/
2
)
as
f32
;
let
box_aligned_y
=
inverted_pixel_y
-
(
entity
.height
/
2
)
as
f32
;
(
box_aligned_x
,
box_aligned_y
)
}
pub
fn
entity_centre
(
level_height
:
i64
,
entity
:
&
EntityInstance
)
->
(
f32
,
f32
)
{
pub
fn
entity_centre
(
level_height
:
i64
,
entity
:
&
EntityInstance
)
->
(
f32
,
f32
)
{
let
x
=
entity
.px
[
0
]
-
(
entity
.width
/
2
);
let
x
=
entity
.px
[
0
]
-
(
entity
.width
/
2
);
let
y
=
(
level_height
-
entity
.px
[
1
]
-
entity
.height
/
2
)
;
let
y
=
level_height
-
entity
.px
[
1
]
-
entity
.height
/
2
;
(
x
as
f32
,
y
as
f32
)
(
x
as
f32
,
y
as
f32
)
}
}
...
@@ -63,33 +53,33 @@ impl ActiveLevel {
...
@@ -63,33 +53,33 @@ impl ActiveLevel {
#[derive(Debug,
Copy,
Clone)]
#[derive(Debug,
Copy,
Clone)]
pub
struct
Indexer
{
pub
struct
Indexer
{
width
:
i
size
,
width
:
i
64
,
height
:
i
size
,
height
:
i
64
,
}
}
impl
Indexer
{
impl
Indexer
{
pub
fn
new
(
width
:
impl
AsPrimitive
<
i
size
>
,
height
:
impl
AsPrimitive
<
i
size
>
)
->
Self
{
pub
fn
new
(
width
:
impl
AsPrimitive
<
i
64
>
,
height
:
impl
AsPrimitive
<
i
64
>
)
->
Self
{
Self
{
Self
{
width
:
width
.as_
(),
width
:
width
.as_
(),
height
:
height
.as_
(),
height
:
height
.as_
(),
}
}
}
}
pub
fn
index
(
&
self
,
x
:
impl
AsPrimitive
<
i
size
>
,
y
:
impl
AsPrimitive
<
i
size
>
)
->
usize
{
pub
fn
index
(
&
self
,
x
:
impl
AsPrimitive
<
i
64
>
,
y
:
impl
AsPrimitive
<
i
64
>
)
->
usize
{
((
y
.as_
()
*
self
.width
)
+
x
.as_
())
.as_
()
((
y
.as_
()
*
self
.width
)
+
x
.as_
())
.as_
()
}
}
pub
fn
reverse
(
&
self
,
index
:
impl
AsPrimitive
<
i
size
>
)
->
(
usize
,
usize
)
{
pub
fn
reverse
(
&
self
,
index
:
impl
AsPrimitive
<
i
64
>
)
->
(
usize
,
usize
)
{
(
(
(
index
.as_
()
%
self
.width
)
as
usize
,
(
index
.as_
()
%
self
.width
)
.max
(
0
)
as
usize
,
(
index
.as_
()
/
self
.width
)
as
usize
,
(
index
.as_
()
/
self
.width
)
.max
(
0
)
as
usize
,
)
)
}
}
pub
fn
width
(
&
self
)
->
i
size
{
pub
fn
width
(
&
self
)
->
i
64
{
self
.width
self
.width
}
}
pub
fn
height
(
&
self
)
->
i
size
{
pub
fn
height
(
&
self
)
->
i
64
{
self
.height
self
.height
}
}
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment