Fix Changed<T> by rewriting ecs `Filter`s, position `TileMapPos` entities with ChildOf relations
This commit is contained in:
parent
418765d595
commit
5a0e06f94d
|
@ -56,12 +56,15 @@ impl ComponentColumn {
|
|||
pub unsafe fn new(info: ComponentInfo, capacity: usize) -> Self {
|
||||
let data = ComponentColumn::alloc(info.layout(), capacity);
|
||||
|
||||
let mut ticks = Vec::with_capacity(capacity);
|
||||
ticks.resize(capacity, Tick::from(0));
|
||||
|
||||
Self {
|
||||
data: RefCell::new(data),
|
||||
capacity,
|
||||
info,
|
||||
len: 0,
|
||||
entity_ticks: Vec::new(),
|
||||
entity_ticks: ticks,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,9 +102,7 @@ impl ComponentColumn {
|
|||
let dest = NonNull::new_unchecked(data.as_ptr().add(entity_index * size));
|
||||
ptr::copy_nonoverlapping(comp_src.as_ptr(), dest.as_ptr(), size);
|
||||
|
||||
// check if a component spot is being set twice and that the entity's tick is
|
||||
// already stored
|
||||
self.entity_ticks.push(tick);
|
||||
self.entity_ticks[entity_index] = tick;
|
||||
self.len += 1;
|
||||
}
|
||||
|
||||
|
@ -175,6 +176,7 @@ impl ComponentColumn {
|
|||
*data = new_ptr;
|
||||
}
|
||||
|
||||
self.entity_ticks.resize(new_capacity, Tick::from(0));
|
||||
self.capacity = new_capacity;
|
||||
}
|
||||
|
||||
|
|
|
@ -272,11 +272,11 @@ mod tests {
|
|||
let mut world = World::new();
|
||||
let e = world.spawn(b);
|
||||
|
||||
let pos = world.view_one::<&Vec2>(e).get()
|
||||
let pos = world.view_one::<&Vec2>(e)
|
||||
.expect("failed to find spawned Vec2 from Bundle on Entity");
|
||||
assert!(pos.x == b_pos.x && pos.y == b_pos.y, "Spawned Vec2 values were not correct, got: {:?}, expected: {:?}", *pos, b_pos);
|
||||
|
||||
let flag = world.view_one::<&SomeFlag>(e).get()
|
||||
let flag = world.view_one::<&SomeFlag>(e)
|
||||
.expect("failed to find spawned SomeFlag from Bundle on Entity");
|
||||
assert_eq!(*flag, b_flag);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::{any::Any, cell::RefMut, mem::{self, MaybeUninit}, ptr::{self, NonNull}};
|
||||
|
||||
use crate::{system::FnArgFetcher, Access, Bundle, Entities, Entity, World};
|
||||
use crate::{system::FnArgFetcher, Access, Bundle, Entities, Entity, Relation, World};
|
||||
|
||||
/// A Command be used to delay mutation of the world until after this system is ran.
|
||||
pub trait Command: Any {
|
||||
|
@ -175,6 +175,12 @@ impl<'a, 'b> Commands<'a, 'b> {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn add_relation<R: Relation>(&mut self, origin: Entity, relation: R, target: Entity){
|
||||
self.add(move | world: &mut World| {
|
||||
world.add_relation(origin, relation, target);
|
||||
});
|
||||
}
|
||||
|
||||
/// Execute all commands in the queue, in order of insertion
|
||||
pub fn execute(&mut self, world: &mut World) {
|
||||
self.queue.execute(Some(world));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use crate::{query::{AsFilter, AsQuery, Fetch, Filter, Query}, Component, ComponentColumn, DynTypeId, Tick, World};
|
||||
use crate::{query::{AsQuery, Fetch, Query}, Component, ComponentColumn, DynTypeId, Tick, World};
|
||||
|
||||
pub struct ChangedFetcher<'a, T> {
|
||||
col: &'a ComponentColumn,
|
||||
|
@ -20,7 +20,10 @@ where
|
|||
|
||||
unsafe fn get_item(&mut self, entity: crate::world::ArchetypeEntityId) -> Self::Item {
|
||||
let tick = self.col.entity_ticks[entity.0 as usize];
|
||||
*tick >= (*self.tick) - 1
|
||||
if *tick > 50 {
|
||||
//debug!("tick: {}, world tick: {}", *tick, *self.tick);
|
||||
}
|
||||
*tick >= *self.tick
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,10 +80,10 @@ where
|
|||
archetype.has_column(self.type_id)
|
||||
}
|
||||
|
||||
unsafe fn fetch<'a>(&self, w: &'a World, a: &'a crate::archetype::Archetype, _: crate::Tick) -> Self::Fetch<'a> {
|
||||
unsafe fn fetch<'a>(&self, _: &'a World, a: &'a crate::archetype::Archetype, tick: crate::Tick) -> Self::Fetch<'a> {
|
||||
ChangedFetcher {
|
||||
col: a.get_column(self.type_id).unwrap(),
|
||||
tick: w.current_tick(),
|
||||
tick,
|
||||
_phantom: PhantomData::<&T>,
|
||||
}
|
||||
}
|
||||
|
@ -88,10 +91,4 @@ where
|
|||
|
||||
impl<T: Component> AsQuery for Changed<T> {
|
||||
type Query = Self;
|
||||
}
|
||||
|
||||
impl<T: Component> Filter for Changed<T> { }
|
||||
|
||||
impl<T: Component> AsFilter for Changed<T> {
|
||||
type Filter = Self;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use crate::{query::{AsFilter, AsQuery, Filter, Query}, Archetype, Component, DynTypeId, World};
|
||||
use crate::{query::{AsQuery, Query}, Archetype, Component, DynTypeId, World};
|
||||
|
||||
use super::StaticFetcher;
|
||||
|
||||
|
@ -45,8 +45,8 @@ impl<C: Component> AsQuery for Has<C> {
|
|||
type Query = Self;
|
||||
}
|
||||
|
||||
impl<C: Component> Filter for Has<C> { }
|
||||
//impl<C: Component> Filter for Has<C> { }
|
||||
|
||||
impl<C: Component> AsFilter for Has<C> {
|
||||
/* impl<C: Component> AsFilter for Has<C> {
|
||||
type Filter = Self;
|
||||
}
|
||||
} */
|
|
@ -10,7 +10,73 @@ pub use not::*;
|
|||
mod changed;
|
||||
pub use changed::*;
|
||||
|
||||
use super::Fetch;
|
||||
use crate::{Archetype, ArchetypeEntityId, Tick, World};
|
||||
|
||||
use super::{Fetch, Query};
|
||||
|
||||
pub trait FilterFetch<'a> {
|
||||
/// Returns true if the entity should be visited or skipped.
|
||||
fn can_visit(&mut self, entity: ArchetypeEntityId) -> bool;
|
||||
}
|
||||
|
||||
pub trait Filter: Copy {
|
||||
/// The fetcher used for the filter
|
||||
type Fetch<'a>: FilterFetch<'a>;
|
||||
|
||||
fn new() -> Self;
|
||||
|
||||
/// Returns true if the archetype should be visited or skipped.
|
||||
fn can_visit_archetype(&self, archetype: &Archetype) -> bool;
|
||||
|
||||
unsafe fn fetch<'a>(&self, world: &'a World, archetype: &'a Archetype, tick: Tick) -> Self::Fetch<'a>;
|
||||
|
||||
/// Returns a fetcher that doesn't fetch from an archetype.
|
||||
unsafe fn fetch_world<'a>(&self, world: &'a World) -> Option<Self::Fetch<'a>> {
|
||||
let _ = world;
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait for getting the filter of a type.
|
||||
pub trait AsFilter {
|
||||
/// The query for this type
|
||||
type Filter: Filter;
|
||||
}
|
||||
|
||||
impl<Q> Filter for Q
|
||||
where
|
||||
Q: for <'a> Query<Item<'a> = bool>,
|
||||
{
|
||||
type Fetch<'a> = Q::Fetch<'a>;
|
||||
|
||||
fn new() -> Self {
|
||||
Query::new()
|
||||
}
|
||||
|
||||
fn can_visit_archetype(&self, archetype: &Archetype) -> bool {
|
||||
Query::can_visit_archetype(self, archetype)
|
||||
}
|
||||
|
||||
unsafe fn fetch<'a>(&self, world: &'a World, archetype: &'a Archetype, tick: Tick) -> Self::Fetch<'a> {
|
||||
Query::fetch(self, world, archetype, tick)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, F> FilterFetch<'a> for F
|
||||
where
|
||||
F: Fetch<'a, Item = bool>
|
||||
{
|
||||
fn can_visit(&mut self, entity: ArchetypeEntityId) -> bool {
|
||||
Fetch::can_visit_item(self, entity) && unsafe { Fetch::get_item(self, entity) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q> AsFilter for Q
|
||||
where
|
||||
Q: for <'a> Query<Item<'a> = bool>
|
||||
{
|
||||
type Filter = Q;
|
||||
}
|
||||
|
||||
/// A fetcher that just returns a provided value
|
||||
pub struct StaticFetcher<T: Clone> {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{query::{AsFilter, AsQuery, Filter, Query}, Archetype, World};
|
||||
use crate::{query::{AsQuery, Query}, Archetype, World};
|
||||
|
||||
use super::StaticFetcher;
|
||||
|
||||
|
@ -43,10 +43,4 @@ impl<Q: Query> Query for Not<Q> {
|
|||
|
||||
impl<Q: Query> AsQuery for Not<Q> {
|
||||
type Query = Self;
|
||||
}
|
||||
|
||||
impl<Q: Query> Filter for Not<Q> { }
|
||||
|
||||
impl<Q: Query> AsFilter for Not<Q> {
|
||||
type Filter = Self;
|
||||
}
|
|
@ -38,6 +38,7 @@ pub use world_tick::*;
|
|||
pub mod dynamic;
|
||||
|
||||
pub mod filter;
|
||||
pub use filter::{Filter, AsFilter};
|
||||
|
||||
/// A [`Fetch`]er implementation gets data out of an archetype.
|
||||
pub trait Fetch<'a> {
|
||||
|
@ -93,30 +94,24 @@ pub trait AsQuery {
|
|||
type Query: Query;
|
||||
}
|
||||
|
||||
/// A trait for getting the filter of a type.
|
||||
pub trait AsFilter {
|
||||
/// The query for this type
|
||||
type Filter: Filter;
|
||||
}
|
||||
|
||||
pub trait IntoQuery {
|
||||
fn into_query(self) -> Self;
|
||||
}
|
||||
|
||||
impl<'a> Fetch<'a> for () {
|
||||
type Item = ();
|
||||
type Item = bool;
|
||||
|
||||
fn dangling() -> Self {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
unsafe fn get_item(&mut self, _: ArchetypeEntityId) -> Self::Item {
|
||||
()
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl Query for () {
|
||||
type Item<'a> = ();
|
||||
type Item<'a> = bool;
|
||||
|
||||
type Fetch<'a> = ();
|
||||
|
||||
|
@ -135,22 +130,10 @@ impl Query for () {
|
|||
}
|
||||
}
|
||||
|
||||
impl Filter for () {
|
||||
type Item<'a> = bool;
|
||||
}
|
||||
|
||||
impl AsQuery for () {
|
||||
type Query = ();
|
||||
}
|
||||
|
||||
pub trait Filter: Query {
|
||||
type Item<'a> = bool;
|
||||
}
|
||||
|
||||
impl AsFilter for () {
|
||||
type Filter = ();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{World, archetype::Archetype, tests::Vec2};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::World;
|
||||
|
||||
use super::{Query, Fetch, AsQuery, Filter, AsFilter};
|
||||
use super::{Query, Fetch, AsQuery, Filter, AsFilter, filter::FilterFetch, ArchetypeEntityId};
|
||||
|
||||
/* impl<'a, F1> Fetch<'a> for (F1,)
|
||||
where
|
||||
|
@ -139,10 +139,7 @@ macro_rules! impl_bundle_tuple {
|
|||
|
||||
fn can_visit_archetype(&self, archetype: &crate::archetype::Archetype) -> bool {
|
||||
let ( $($name,)+ ) = self;
|
||||
|
||||
// this is the only way I could figure out how to do an 'and'
|
||||
let bools = vec![$($name.can_visit_archetype(archetype),)+];
|
||||
bools.iter().all(|b| *b)
|
||||
$($name.can_visit_archetype(archetype)) &&+
|
||||
}
|
||||
|
||||
unsafe fn fetch<'a>(&self, world: &'a World, archetype: &'a crate::archetype::Archetype, tick: crate::Tick) -> Self::Fetch<'a> {
|
||||
|
@ -156,26 +153,30 @@ macro_rules! impl_bundle_tuple {
|
|||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
impl<$($name: Filter),+> Filter for ($($name,)+) {
|
||||
//type Item<'a> = ($(<$name as Query>::Item<'a>,)+);
|
||||
//type Fetch<'a> = ($(<$name as Query>::Fetch<'a>,)+);
|
||||
impl<'a, $($name: FilterFetch<'a>),+> FilterFetch<'a> for ($($name,)+) {
|
||||
fn can_visit(&mut self, entity: ArchetypeEntityId) -> bool {
|
||||
let ( $($name,)+ ) = self;
|
||||
$($name.can_visit(entity)) &&+
|
||||
}
|
||||
}
|
||||
|
||||
/* fn new() -> Self {
|
||||
#[allow(non_snake_case)]
|
||||
impl<$($name: Filter),+> Filter for ($($name,)+) {
|
||||
type Fetch<'a> = ($(<$name as Filter>::Fetch<'a>,)+);
|
||||
|
||||
fn new() -> Self {
|
||||
( $($name::new(),)+ )
|
||||
}
|
||||
|
||||
fn can_visit_archetype(&self, archetype: &crate::archetype::Archetype) -> bool {
|
||||
let ( $($name,)+ ) = self;
|
||||
|
||||
// this is the only way I could figure out how to do an 'and'
|
||||
let bools = vec![$($name.can_visit_archetype(archetype),)+];
|
||||
bools.iter().all(|b| *b)
|
||||
$($name.can_visit_archetype(archetype)) &&+
|
||||
}
|
||||
|
||||
unsafe fn fetch<'a>(&self, world: &'a World, archetype: &'a crate::archetype::Archetype, tick: crate::Tick) -> Self::Fetch<'a> {
|
||||
let ( $($name,)+ ) = self;
|
||||
( $($name.fetch(world, archetype, tick),)+ )
|
||||
} */
|
||||
}
|
||||
}
|
||||
|
||||
impl<$($name: AsFilter),+> AsFilter for ($($name,)+) {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::ops::Range;
|
||||
use std::{ops::Range, ptr::NonNull};
|
||||
|
||||
use crate::{archetype::Archetype, world::{ArchetypeEntityId, World}, EntityId, Tick};
|
||||
use crate::{archetype::Archetype, system::FnArgFetcher, world::{ArchetypeEntityId, World}, Entity, Tick};
|
||||
|
||||
use super::{AsFilter, AsQuery, Fetch, Filter, Query};
|
||||
use super::{filter::{AsFilter, Filter, FilterFetch}, AsQuery, Fetch, Query};
|
||||
|
||||
pub type View<'a, Q, F = ()> = ViewState<'a, <Q as AsQuery>::Query, <F as AsQuery>::Query>;
|
||||
|
||||
|
@ -109,7 +109,7 @@ where
|
|||
let filter_fetcher = self.filter_fetcher.as_mut().unwrap();
|
||||
let entity_index = ArchetypeEntityId(entity_index);
|
||||
|
||||
if fetcher.can_visit_item(entity_index) && filter_fetcher.can_visit_item(entity_index) {
|
||||
if fetcher.can_visit_item(entity_index) && filter_fetcher.can_visit(entity_index) {
|
||||
let i = unsafe { fetcher.get_item(entity_index) };
|
||||
return Some(i);
|
||||
}
|
||||
|
@ -138,27 +138,27 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub struct ViewOne<'a, Q: Query> {
|
||||
pub type ViewOne<'a, Q> = ViewOneState<'a, <Q as AsQuery>::Query>;
|
||||
|
||||
pub struct ViewOneState<'a, Q: Query> {
|
||||
world: &'a World,
|
||||
tick: Tick,
|
||||
entity: EntityId,
|
||||
query: Q,
|
||||
}
|
||||
|
||||
impl<'a, Q: Query> ViewOne<'a, Q> {
|
||||
pub fn new(world: &'a World, entity: EntityId, query: Q) -> Self {
|
||||
impl<'a, Q: Query> ViewOneState<'a, Q> {
|
||||
pub fn new(world: &'a World, query: Q) -> Self {
|
||||
//let tick = world.tick_tracker().tick_when(Q::MUTATES);
|
||||
|
||||
Self {
|
||||
world,
|
||||
tick: world.current_tick(),
|
||||
entity,
|
||||
query
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(self) -> Option<Q::Item<'a>> {
|
||||
if let Some(record) = self.world.entities.arch_index.get(&self.entity) {
|
||||
pub fn get(&self, entity: Entity) -> Option<Q::Item<'a>> {
|
||||
if let Some(record) = self.world.entities.arch_index.get(&entity.id()) {
|
||||
let arch = self.world.archetypes.get(&record.id)
|
||||
.expect("An invalid record was specified for an entity");
|
||||
|
||||
|
@ -172,4 +172,18 @@ impl<'a, Q: Query> ViewOne<'a, Q> {
|
|||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Query> FnArgFetcher for ViewOneState<'_, Q> {
|
||||
type State = ();
|
||||
type Arg<'a, 'state> = ViewOneState<'a, Q>;
|
||||
|
||||
unsafe fn get<'a, 'state>(_: &'state mut Self::State, world: NonNull<World>) -> Self::Arg<'a, 'state> {
|
||||
let world = world.as_ref();
|
||||
ViewOneState::<Q>::new(world, Q::new())
|
||||
}
|
||||
|
||||
fn apply_deferred(_: Self::State, _: NonNull<World>) { }
|
||||
|
||||
fn create_state(_: NonNull<World>) -> Self::State { () }
|
||||
}
|
|
@ -2,7 +2,7 @@ use std::{any::TypeId, collections::HashMap, ops::Deref, ptr::NonNull};
|
|||
|
||||
use atomic_refcell::{AtomicRef, AtomicRefMut};
|
||||
|
||||
use crate::{archetype::{Archetype, ArchetypeId}, bundle::Bundle, query::{dynamic::DynamicView, AsFilter, AsQuery, Query, Res, ResMut, ViewIter, ViewOne, ViewState}, resource::ResourceData, ComponentInfo, DynTypeId, DynamicBundle, Entities, Entity, ResourceObject, Tick, TickTracker, TrackedResource};
|
||||
use crate::{archetype::{Archetype, ArchetypeId}, bundle::Bundle, query::{dynamic::DynamicView, Filter, AsFilter, AsQuery, Query, Res, ResMut, ViewIter, ViewOneState, ViewState}, resource::ResourceData, ComponentInfo, DynTypeId, DynamicBundle, Entities, Entity, ResourceObject, Tick, TickTracker, TrackedResource};
|
||||
|
||||
/// The id of the entity for the Archetype.
|
||||
///
|
||||
|
@ -397,8 +397,8 @@ impl World {
|
|||
DynamicView::new(self)
|
||||
}
|
||||
|
||||
pub fn view_one<T: AsQuery>(&self, entity: Entity) -> ViewOne<T::Query> {
|
||||
ViewOne::new(self, entity.id, T::Query::new())
|
||||
pub fn view_one<T: AsQuery>(&self, entity: Entity) -> Option<<T::Query as Query>::Item<'_>> {
|
||||
ViewOneState::<T::Query>::new(self, T::Query::new()).get(entity)
|
||||
}
|
||||
|
||||
/// Add a resource to the world.
|
||||
|
@ -688,7 +688,7 @@ mod tests {
|
|||
|
||||
world.insert(e, (Vec3::rand(),));
|
||||
|
||||
assert!(world.view_one::<&Vec3>(e).get().is_some())
|
||||
assert!(world.view_one::<&Vec3>(e).is_some())
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -698,7 +698,7 @@ mod tests {
|
|||
|
||||
world.insert(e, (Vec3::rand(),));
|
||||
|
||||
assert!(world.view_one::<&Vec3>(e).get().is_some())
|
||||
assert!(world.view_one::<&Vec3>(e).is_some())
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -712,7 +712,7 @@ mod tests {
|
|||
let e3 = world.spawn(v2s[2]);
|
||||
println!("Spawned entities");
|
||||
|
||||
let ev2 = world.view_one::<&Vec2>(e2).get()
|
||||
let ev2 = world.view_one::<&Vec2>(e2)
|
||||
.expect("Failed to find Vec2 and Vec3 on inserted entity!");
|
||||
assert_eq!(*ev2, v2s[1]);
|
||||
drop(ev2);
|
||||
|
@ -722,7 +722,7 @@ mod tests {
|
|||
world.insert(e, (v3,));
|
||||
println!("inserted entity");
|
||||
|
||||
let (ev2, ev3) = world.view_one::<(&Vec2, &Vec3)>(e).get()
|
||||
let (ev2, ev3) = world.view_one::<(&Vec2, &Vec3)>(e)
|
||||
.expect("Failed to find Vec2 and Vec3 on inserted entity!");
|
||||
assert_eq!(*ev2, v2);
|
||||
assert_eq!(*ev3, v3);
|
||||
|
@ -747,7 +747,7 @@ mod tests {
|
|||
let e = world.spawn((v,));
|
||||
|
||||
let view = world.view_one::<&Vec2>(e);
|
||||
assert_eq!(*view.get().unwrap(), v);
|
||||
assert_eq!(*view.unwrap(), v);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -782,11 +782,11 @@ mod tests {
|
|||
|
||||
world.insert(first, Vec2::new(50.0, 50.0));
|
||||
|
||||
let pos = world.view_one::<&mut Vec2>(first).get().unwrap();
|
||||
let pos = world.view_one::<&mut Vec2>(first).unwrap();
|
||||
assert_eq!(*pos, Vec2::new(50.0, 50.0));
|
||||
drop(pos);
|
||||
|
||||
let pos = world.view_one::<&mut Vec2>(second).get().unwrap();
|
||||
let pos = world.view_one::<&mut Vec2>(second).unwrap();
|
||||
assert_eq!(*pos, Vec2::new(5.0, 5.0));
|
||||
}
|
||||
|
||||
|
|
|
@ -43,8 +43,6 @@ impl TransformsNode {
|
|||
|
||||
fn process_component_queue(world: &mut lyra_ecs::World, component_queue: Vec<(Entity, Option<InterpTransform>, Option<TransformIndex>)>) {
|
||||
for (en, interp, index) in component_queue {
|
||||
println!("writing index {:?} for entity {}", index, en.id().0);
|
||||
|
||||
match (interp, index) {
|
||||
(None, None) => unreachable!(),
|
||||
(None, Some(index)) => world.insert(en, index),
|
||||
|
@ -94,7 +92,7 @@ fn update_transforms(
|
|||
// Interpolate the transform for this entity using a component.
|
||||
// If the entity does not have the component then it will be queued to be added
|
||||
// to it after all the entities are prepared for rendering.
|
||||
let transform = match interp_tran {
|
||||
/* let transform = match interp_tran {
|
||||
Some(mut interp_transform) => {
|
||||
// found in https://youtu.be/YJB1QnEmlTs?t=472
|
||||
interp_transform.alpha = 1.0 - interp_transform.alpha.powf(*delta_time);
|
||||
|
@ -112,6 +110,21 @@ fn update_transforms(
|
|||
component_queue.push((entity, Some(interp), None));
|
||||
transform
|
||||
}
|
||||
}; */
|
||||
|
||||
let transform = match interp_tran {
|
||||
Some(mut interp_transform) => {
|
||||
interp_transform.last_transform = transform;
|
||||
transform
|
||||
}
|
||||
None => {
|
||||
let interp = InterpTransform {
|
||||
last_transform: transform,
|
||||
alpha: 1.0,
|
||||
};
|
||||
component_queue.push((entity, Some(interp), None));
|
||||
transform
|
||||
}
|
||||
};
|
||||
|
||||
// Get the TransformIndex from the entity, or reserve a new one if the entity doesn't have
|
||||
|
@ -120,11 +133,6 @@ fn update_transforms(
|
|||
Some(i) => *i,
|
||||
None => {
|
||||
let i = buffers.reserve_transform(&device);
|
||||
debug!(
|
||||
"Reserved transform index {:?} for entity {}",
|
||||
i,
|
||||
entity.id().0
|
||||
);
|
||||
|
||||
component_queue.push((entity, None, Some(i)));
|
||||
i
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
use std::collections::VecDeque;
|
||||
|
||||
use glam::{UVec2, UVec3, Vec2, Vec3};
|
||||
use lyra_ecs::{
|
||||
query::{Entities, View},
|
||||
relation::ChildOf,
|
||||
Commands, Component, Entity, World,
|
||||
query::{
|
||||
filter::{Changed, Has, Not},
|
||||
Entities, View, ViewOne,
|
||||
},
|
||||
relation::{ChildOf, RelationOriginComponent},
|
||||
Commands, Component, Entity,
|
||||
};
|
||||
use lyra_math::Transform;
|
||||
use lyra_reflect::Reflect;
|
||||
use lyra_resource::ResHandle;
|
||||
use lyra_scene::WorldTransform;
|
||||
use tracing::{debug, error};
|
||||
use tracing::error;
|
||||
|
||||
use crate::{game::GameStages, plugin::Plugin};
|
||||
|
||||
use super::{AtlasSprite, TextureAtlas};
|
||||
|
||||
/// A position relative to a tile on a tilemap
|
||||
/// A position on a tile map
|
||||
#[derive(Clone, Copy, Component, Reflect)]
|
||||
pub struct RelativeToTile {
|
||||
pub struct TileMapPos {
|
||||
#[reflect(skip)] // TODO: impl reflect for Entity
|
||||
pub tilemap_entity: Entity,
|
||||
/// The position of the tile to spawn at.
|
||||
|
@ -107,9 +108,9 @@ impl TileMap {
|
|||
/// A system to update the tilemap when tiles are inserted/removed.
|
||||
pub fn system_tilemap_update(
|
||||
mut commands: Commands,
|
||||
view: View<(&mut TileMap, &Transform)>,
|
||||
view: View<(Entities, &mut TileMap)>,
|
||||
) -> anyhow::Result<()> {
|
||||
for (mut map, pos) in view.into_iter() {
|
||||
for (map_en, mut map) in view.into_iter() {
|
||||
let tile_size = map.tile_size;
|
||||
let atlas_handle = map.atlas.clone();
|
||||
let atlas = match atlas_handle.data_ref() {
|
||||
|
@ -128,15 +129,32 @@ pub fn system_tilemap_update(
|
|||
};
|
||||
|
||||
let grid = tile.tile.position * tile_size;
|
||||
let sprite_pos = *pos
|
||||
+ Transform::from_xyz(
|
||||
grid.x as _,
|
||||
grid.y as _,
|
||||
tile.tile.z_level as _,
|
||||
);
|
||||
let sprite_pos = Transform::from_xyz(
|
||||
grid.x as _,
|
||||
// expand the grid downwards so 0,0 is top left of the tilemap
|
||||
-(grid.y as f32),
|
||||
tile.tile.z_level as _,
|
||||
);
|
||||
|
||||
tile.entity = Some(commands.spawn((sprite, sprite_pos, WorldTransform::default())));
|
||||
debug!("Spawned tile at ({}, {})", grid.x, grid.y);
|
||||
let tile_en = commands.spawn((
|
||||
sprite,
|
||||
TileMapPos {
|
||||
tilemap_entity: map_en,
|
||||
position: tile.tile.position,
|
||||
z_level: tile.tile.z_level,
|
||||
},
|
||||
tile.tile,
|
||||
sprite_pos,
|
||||
WorldTransform::default(),
|
||||
));
|
||||
commands.add_relation(tile_en, ChildOf, map_en);
|
||||
tile.entity = Some(tile_en);
|
||||
//debug!("Spawned tile at ({}, {})", grid.x, grid.y);
|
||||
|
||||
/* let tile_en = commands.spawn((sprite, sprite_pos, WorldTransform::default()));
|
||||
commands.add_relation(tile_en, ChildOf, map_en);
|
||||
tile.entity = Some(tile_en);
|
||||
debug!("Spawned tile at ({}, {})", grid.x, grid.y); */
|
||||
} else {
|
||||
error!(
|
||||
"Invalid atlas index '{}' for tile at pos '{:?}'",
|
||||
|
@ -152,17 +170,22 @@ pub fn system_tilemap_update(
|
|||
}
|
||||
|
||||
fn system_relative_tile_position_update(
|
||||
world: &mut World,
|
||||
view: View<(Entities, &RelativeToTile)>,
|
||||
mut commands: Commands,
|
||||
view: View<
|
||||
(
|
||||
Entities,
|
||||
&TileMapPos,
|
||||
Option<&mut Transform>,
|
||||
Option<&WorldTransform>,
|
||||
),
|
||||
(Changed<TileMapPos>, Not<Has<Tile>>),
|
||||
>,
|
||||
tile_map_view: ViewOne<&TileMap>,
|
||||
child_of_rel_view: ViewOne<&RelationOriginComponent<ChildOf>>,
|
||||
) -> anyhow::Result<()> {
|
||||
let mut to_relate = VecDeque::new();
|
||||
|
||||
for (en, rel) in view.into_iter() {
|
||||
match world
|
||||
.view_one::<(&TileMap, &Transform)>(rel.tilemap_entity)
|
||||
.get()
|
||||
{
|
||||
Some((map, pos)) => {
|
||||
for (en, rel, pos, wpos) in view.into_iter() {
|
||||
match tile_map_view.get(rel.tilemap_entity) {
|
||||
Some(map) => {
|
||||
let layer = map.layers.last().unwrap();
|
||||
|
||||
if let Some(tile_en) = layer
|
||||
|
@ -171,7 +194,27 @@ fn system_relative_tile_position_update(
|
|||
.find(|t| t.tile.position == rel.position)
|
||||
.and_then(|t| t.entity)
|
||||
{
|
||||
to_relate.push_back((en, tile_en, Transform::from_translation(Vec3::new(0.0, 0.0, rel.z_level as _))));
|
||||
if child_of_rel_view
|
||||
.get(en)
|
||||
.map(|rel| rel.target() != tile_en)
|
||||
.unwrap_or(true)
|
||||
{
|
||||
commands.add_relation(en, ChildOf, tile_en);
|
||||
}
|
||||
|
||||
if let Some(mut pos) = pos {
|
||||
*pos = Transform::from_translation(Vec3::new(0.0, 0.0, rel.z_level as _));
|
||||
|
||||
if wpos.is_none() {
|
||||
commands.insert(en, WorldTransform::from(*pos));
|
||||
}
|
||||
} else {
|
||||
let pos =
|
||||
Transform::from_translation(Vec3::new(0.0, 0.0, rel.z_level as _));
|
||||
commands.insert(en, (pos, WorldTransform::from(pos)));
|
||||
}
|
||||
} else {
|
||||
error!("Unknown tile in map at {:?}", rel.position);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
|
@ -183,13 +226,6 @@ fn system_relative_tile_position_update(
|
|||
}
|
||||
}
|
||||
|
||||
while let Some((from, to, pos)) = to_relate.pop_front() {
|
||||
if world.view_one::<&WorldTransform>(from).get().is_none() {
|
||||
world.add_relation(from, ChildOf, to);
|
||||
world.insert(from, (pos, WorldTransform::default()));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ impl ApplicationHandler for WinitRunner {
|
|||
.expect("missing window entity");
|
||||
|
||||
// update the window and its cache so the sync system doesn't try to update the window
|
||||
let (mut en_window, mut en_last_win) = self.app.world.view_one::<(&mut WindowOptions, &mut LastWindow)>(*en).get().unwrap();
|
||||
let (mut en_window, mut en_last_win) = self.app.world.view_one::<(&mut WindowOptions, &mut LastWindow)>(*en).unwrap();
|
||||
let pos = Some(DVec2::new(position.x, position.y));
|
||||
en_window.set_physical_cursor_position(pos);
|
||||
en_last_win.set_physical_cursor_position(pos);
|
||||
|
@ -242,7 +242,7 @@ impl ApplicationHandler for WinitRunner {
|
|||
.expect("world missing WinitWindows resource")
|
||||
.window_to_entity
|
||||
.get(&window_id)
|
||||
.and_then(|e| self.app.world.view_one::<(&mut WindowOptions, &mut LastWindow)>(*e).get())
|
||||
.and_then(|e| self.app.world.view_one::<(&mut WindowOptions, &mut LastWindow)>(*e))
|
||||
.unwrap();
|
||||
|
||||
// update the window and its cache so the sync system doesn't try to update the window
|
||||
|
@ -259,7 +259,7 @@ impl ApplicationHandler for WinitRunner {
|
|||
.expect("world missing WinitWindows resource")
|
||||
.window_to_entity
|
||||
.get(&window_id)
|
||||
.and_then(|e| self.app.world.view_one::<(&mut WindowOptions, &mut LastWindow)>(*e).get())
|
||||
.and_then(|e| self.app.world.view_one::<(&mut WindowOptions, &mut LastWindow)>(*e))
|
||||
.unwrap();
|
||||
window.set_physical_cursor_position(None);
|
||||
last_window.set_physical_cursor_position(None);
|
||||
|
@ -284,7 +284,7 @@ impl ApplicationHandler for WinitRunner {
|
|||
.expect("world missing WinitWindows resource")
|
||||
.window_to_entity
|
||||
.get(&window_id)
|
||||
.and_then(|e| self.app.world.view_one::<&mut WindowOptions>(*e).get())
|
||||
.and_then(|e| self.app.world.view_one::<&mut WindowOptions>(*e))
|
||||
.unwrap();
|
||||
window_opts.focused = focused;
|
||||
},
|
||||
|
@ -299,7 +299,7 @@ impl ApplicationHandler for WinitRunner {
|
|||
.expect("world missing WinitWindows resource")
|
||||
.window_to_entity
|
||||
.get(&window_id)
|
||||
.and_then(|e| self.app.world.view_one::<&mut WindowOptions>(*e).get())
|
||||
.and_then(|e| self.app.world.view_one::<&mut WindowOptions>(*e))
|
||||
.unwrap();
|
||||
window_opts.scale_factor = scale_factor;
|
||||
},
|
||||
|
@ -311,7 +311,7 @@ impl ApplicationHandler for WinitRunner {
|
|||
.expect("world missing WinitWindows resource")
|
||||
.window_to_entity
|
||||
.get(&window_id)
|
||||
.and_then(|e| self.app.world.view_one::<&mut WindowOptions>(*e).get())
|
||||
.and_then(|e| self.app.world.view_one::<&mut WindowOptions>(*e))
|
||||
.unwrap();
|
||||
window_opts.theme = Some(theme);
|
||||
},
|
||||
|
@ -323,7 +323,7 @@ impl ApplicationHandler for WinitRunner {
|
|||
.expect("world missing WinitWindows resource")
|
||||
.window_to_entity
|
||||
.get(&window_id)
|
||||
.and_then(|e| self.app.world.view_one::<&mut WindowOptions>(*e).get())
|
||||
.and_then(|e| self.app.world.view_one::<&mut WindowOptions>(*e))
|
||||
.unwrap();
|
||||
window_opts.occluded = occ;
|
||||
},
|
||||
|
|
|
@ -224,7 +224,8 @@ impl ResourceLoader for GltfLoader {
|
|||
}
|
||||
|
||||
for en in graph.world().view_iter::<query::Entities>() {
|
||||
graph.world().view_one::<(&WorldTransform, &Transform)>(en).get().expect("Scene node is missing world and local transform bundle!");
|
||||
graph.world().view_one::<(&WorldTransform, &Transform)>(en)
|
||||
.expect("Scene node is missing world and local transform bundle!");
|
||||
}
|
||||
|
||||
let graph = ResHandle::new_ready(Some(path.as_str()), graph);
|
||||
|
@ -300,14 +301,14 @@ mod tests {
|
|||
let mut node = None;
|
||||
//scene.world().view::<SceneNodeFlag()
|
||||
scene.traverse_down::<_, &WorldTransform>(|_, no, tran| {
|
||||
tran.get().expect("scene node is missing a WorldTransform");
|
||||
tran.expect("scene node is missing a WorldTransform");
|
||||
node = Some(no.clone());
|
||||
});
|
||||
|
||||
let world = scene.world();
|
||||
let node = node.unwrap();
|
||||
|
||||
let data = world.view_one::<(&ResHandle<Mesh>, &Transform)>(node.entity()).get();
|
||||
let data = world.view_one::<(&ResHandle<Mesh>, &Transform)>(node.entity());
|
||||
debug_assert!(data.is_some(), "The mesh was not loaded"); // transform will always be there
|
||||
let data = data.unwrap();
|
||||
|
||||
|
|
|
@ -73,17 +73,17 @@ impl<C: Component + Reflect> FromType<C> for ReflectedComponent {
|
|||
},
|
||||
fn_reflect: |world: &World, entity: Entity| {
|
||||
world.view_one::<&C>(entity)
|
||||
.get().map(|c| c as Ref<dyn Reflect>)
|
||||
.map(|c| c as Ref<dyn Reflect>)
|
||||
},
|
||||
fn_reflect_mut: |world: &mut World, entity: Entity| {
|
||||
world.view_one::<&mut C>(entity)
|
||||
.get().map(|c| c as RefMut<dyn Reflect>)
|
||||
.map(|c| c as RefMut<dyn Reflect>)
|
||||
},
|
||||
fn_reflect_tick: |world: &World, entity: Entity| {
|
||||
world.view_one::<TickOf<C>>(entity).get()
|
||||
world.view_one::<TickOf<C>>(entity)
|
||||
},
|
||||
fn_reflect_is_changed: |world: &World, entity: Entity| {
|
||||
world.view_one::<Changed<C>>(entity).get()
|
||||
world.view_one::<Changed<C>>(entity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ pub use node::*;
|
|||
mod world_transform;
|
||||
pub use world_transform::*;
|
||||
|
||||
use lyra_ecs::{query::{Entities, ViewOne}, relation::ChildOf, Bundle, Component, World};
|
||||
use lyra_ecs::{query::{Entities, Query}, relation::ChildOf, Bundle, Component, World};
|
||||
use lyra_math::Transform;
|
||||
|
||||
// So we can use lyra_ecs::Component derive macro
|
||||
|
@ -95,7 +95,7 @@ impl SceneGraph {
|
|||
/// The traversal does not include the root scene node.
|
||||
pub fn traverse_down<F, Q>(&self, mut callback: F)
|
||||
where
|
||||
F: FnMut(&World, &SceneNode, ViewOne<Q::Query>),
|
||||
F: FnMut(&World, &SceneNode, Option<<Q::Query as Query>::Item<'_>>),
|
||||
Q: lyra_ecs::query::AsQuery,
|
||||
{
|
||||
self.traverse_down_from::<F, Q>(self.root_node.clone(), &mut callback);
|
||||
|
@ -105,7 +105,7 @@ impl SceneGraph {
|
|||
/// SceneNode and its world transform.
|
||||
fn traverse_down_from<F, Q>(&self, start: SceneNode, callback: &mut F)
|
||||
where
|
||||
F: FnMut(&World, &SceneNode, ViewOne<Q::Query>),
|
||||
F: FnMut(&World, &SceneNode, Option<<Q::Query as Query>::Item<'_>>),
|
||||
Q: lyra_ecs::query::AsQuery,
|
||||
{
|
||||
let v = self.world
|
||||
|
@ -211,7 +211,7 @@ pub mod tests {
|
|||
|
||||
let mut idx = 0;
|
||||
scene.traverse_down::<_, &WorldTransform>(|_, _, v| {
|
||||
let pos = v.get().unwrap();
|
||||
let pos = v.unwrap();
|
||||
if idx == 0 {
|
||||
assert_eq!(**pos, Transform::from_translation(v2s[idx]));
|
||||
} else if idx == 1 {
|
||||
|
|
|
@ -25,7 +25,7 @@ impl SceneNode {
|
|||
if let Some(parent) = self.parent {
|
||||
let v = graph.world.view_one::<&RelationOriginComponent<ChildOf>>(parent);
|
||||
|
||||
let p_parent = if let Some(pp) = v.get() {
|
||||
let p_parent = if let Some(pp) = v {
|
||||
Some(pp.target())
|
||||
} else { None };
|
||||
|
||||
|
@ -81,7 +81,7 @@ mod tests {
|
|||
let view = scene.world.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<Has<RelationOriginComponent<ChildOf>>>>();
|
||||
crate::system_update_world_transforms(&scene.world, view).unwrap();
|
||||
|
||||
let tran = scene.world.view_one::<&WorldTransform>(b.entity).get().unwrap();
|
||||
let tran = scene.world.view_one::<&WorldTransform>(b.entity).unwrap();
|
||||
assert_eq!(**tran, Transform::from_translation(Vec3::new(60.0, 60.0, 60.0)));
|
||||
}
|
||||
}
|
|
@ -104,7 +104,7 @@ mod tests {
|
|||
let view = world.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<Has<RelationOriginComponent<ChildOf>>>>();
|
||||
system_update_world_transforms(&world, view).unwrap();
|
||||
|
||||
let g = world.view_one::<&WorldTransform>(child).get().unwrap();
|
||||
let g = world.view_one::<&WorldTransform>(child).unwrap();
|
||||
assert_eq!(**g, Transform::from_xyz(25.0, 25.0, 25.0));
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ mod tests {
|
|||
|
||||
let mut base_offset = 25.0;
|
||||
for child in children.into_iter() {
|
||||
let g = world.view_one::<&WorldTransform>(child).get().unwrap();
|
||||
let g = world.view_one::<&WorldTransform>(child).unwrap();
|
||||
println!("Child {:?} at {:?}", child, g.translation);
|
||||
assert_eq!(**g, Transform::from_xyz(base_offset, base_offset, base_offset));
|
||||
|
||||
|
@ -162,7 +162,7 @@ mod tests {
|
|||
let view = world.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<Has<RelationOriginComponent<ChildOf>>>>();
|
||||
system_update_world_transforms(&world, view).unwrap();
|
||||
|
||||
let g = world.view_one::<&WorldTransform>(five_child).get().unwrap();
|
||||
let g = world.view_one::<&WorldTransform>(five_child).unwrap();
|
||||
assert_eq!(**g, Transform::from_xyz(611.0, 248.0, 899.0));
|
||||
}
|
||||
|
||||
|
@ -189,13 +189,13 @@ mod tests {
|
|||
let view = world.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<Has<RelationOriginComponent<ChildOf>>>>();
|
||||
system_update_world_transforms(&world, view).unwrap();
|
||||
|
||||
let g = world.view_one::<&WorldTransform>(five_child).get().unwrap();
|
||||
let g = world.view_one::<&WorldTransform>(five_child).unwrap();
|
||||
assert_eq!(**g, Transform::from_xyz(536.0, 102.0, 817.0));
|
||||
|
||||
let g = world.view_one::<&WorldTransform>(thir_chi).get().unwrap();
|
||||
let g = world.view_one::<&WorldTransform>(thir_chi).unwrap();
|
||||
assert_eq!(**g, Transform::from_xyz(76.0, 110.0, 42.0));
|
||||
|
||||
let g = world.view_one::<&WorldTransform>(four_child).get().unwrap();
|
||||
let g = world.view_one::<&WorldTransform>(four_child).unwrap();
|
||||
assert_eq!(**g, Transform::from_xyz(100.0, 171.0, 107.0));
|
||||
}
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
use lyra_engine::{
|
||||
assets::{Image, ResourceManager},
|
||||
ecs::{
|
||||
query::{Res, ResMut, View}, Commands, Component, Entity, World
|
||||
query::{Res, View, WorldTick},
|
||||
relation::{ChildOf, RelationOriginComponent},
|
||||
Commands, Component, Entity, World,
|
||||
},
|
||||
game::App,
|
||||
game::{App, GameStages},
|
||||
gltf::Gltf,
|
||||
input::{
|
||||
Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource,
|
||||
|
@ -18,8 +20,8 @@ use lyra_engine::{
|
|||
ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN,
|
||||
},
|
||||
sprite::{
|
||||
self, AtlasAnimations, AtlasSprite, Pivot, RelativeToTile, Sprite, SpriteAnimation,
|
||||
TextureAtlas, TileMap, TileMapPlugin,
|
||||
self, AtlasAnimations, AtlasSprite, Pivot, Sprite, SpriteAnimation, TextureAtlas, Tile,
|
||||
TileMap, TileMapPlugin, TileMapPos,
|
||||
},
|
||||
DeltaTime,
|
||||
};
|
||||
|
@ -27,7 +29,6 @@ use rand::{
|
|||
distributions::{Distribution, WeightedIndex},
|
||||
Rng,
|
||||
};
|
||||
use tracing::debug;
|
||||
|
||||
#[async_std::main]
|
||||
async fn main() {
|
||||
|
@ -105,41 +106,21 @@ async fn main() {
|
|||
.with_plugin(setup_scene_plugin)
|
||||
.with_plugin(action_handler_plugin)
|
||||
.with_plugin(TileMapPlugin)
|
||||
//.with_plugin(camera_debug_plugin)
|
||||
.with_plugin(TopDown2dCameraPlugin)
|
||||
.with_system(
|
||||
.add_system_to_stage(
|
||||
GameStages::Last,
|
||||
"update_world_transforms",
|
||||
system_update_world_transforms,
|
||||
&[],
|
||||
).with_system(
|
||||
"spawn_egg",
|
||||
system_spawn_egg,
|
||||
&[],
|
||||
).with_system(
|
||||
"egg_location",
|
||||
system_egg_location,
|
||||
&[],
|
||||
);
|
||||
)
|
||||
.with_system("spawn_egg", system_spawn_egg, &[]);
|
||||
a.run();
|
||||
}
|
||||
|
||||
fn setup_scene_plugin(app: &mut App) {
|
||||
/* app.with_system(
|
||||
"sprite_atlas_animation",
|
||||
sprite::system_sprite_atlas_animation,
|
||||
&[],
|
||||
); */
|
||||
|
||||
let world = &mut app.world;
|
||||
let resman = world.get_resource_mut::<ResourceManager>().unwrap();
|
||||
|
||||
let cube_gltf = resman
|
||||
.request::<Gltf>("../assets/cube-texture-embedded.gltf")
|
||||
.unwrap();
|
||||
|
||||
cube_gltf.wait_recurse_dependencies_load().unwrap();
|
||||
let cube_mesh = &cube_gltf.data_ref().unwrap().scenes[0];
|
||||
|
||||
let grass_tileset = resman
|
||||
.request::<Image>("../assets/sprout_lands/Tilesets/Grass.png")
|
||||
.unwrap();
|
||||
|
@ -209,7 +190,7 @@ fn setup_scene_plugin(app: &mut App) {
|
|||
},
|
||||
Transform::from_xyz(
|
||||
(map_size.x * tile_size.x) as f32 * 0.5,
|
||||
(map_size.y * tile_size.y) as f32 * 0.5,
|
||||
(map_size.y * tile_size.y) as f32 * -0.5,
|
||||
0.0,
|
||||
),
|
||||
TopDown2dCamera {
|
||||
|
@ -223,25 +204,13 @@ fn setup_scene_plugin(app: &mut App) {
|
|||
|
||||
struct GroundTileMap(Entity);
|
||||
|
||||
#[derive(Component)]
|
||||
struct EggEntity;
|
||||
|
||||
fn system_egg_location(view: View<(&WorldTransform, &EggEntity)>) -> anyhow::Result<()> {
|
||||
for (pos, _) in view.into_iter() {
|
||||
println!("Found egg at world pos {:?}", **pos);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn system_spawn_egg(
|
||||
mut commands: Commands,
|
||||
inputs: Res<ActionHandler>,
|
||||
tile_map: Res<GroundTileMap>,
|
||||
resman: Res<ResourceManager>,
|
||||
wtick: WorldTick,
|
||||
) -> anyhow::Result<()> {
|
||||
let debug_state = inputs.get_action_state("Debug").unwrap();
|
||||
|
||||
if inputs.was_action_just_pressed("Debug").unwrap() {
|
||||
let egg = resman
|
||||
.request::<Image>("../assets/sprout_lands/Objects/Egg_item.png")
|
||||
|
@ -250,12 +219,14 @@ fn system_spawn_egg(
|
|||
let x = rand::thread_rng().gen_range(0..32);
|
||||
let y = rand::thread_rng().gen_range(0..16);
|
||||
|
||||
let rtt = RelativeToTile {
|
||||
let rtt = TileMapPos {
|
||||
tilemap_entity: tile_map.0,
|
||||
position: UVec2::new(x, y),
|
||||
z_level: -9,
|
||||
z_level: 2,
|
||||
};
|
||||
|
||||
//println!("Spawned egg at ({}, {}) on tick {}", x, y, **wtick);
|
||||
|
||||
commands.spawn((
|
||||
Sprite {
|
||||
texture: egg,
|
||||
|
@ -263,7 +234,6 @@ fn system_spawn_egg(
|
|||
pivot: Pivot::TopLeft,
|
||||
},
|
||||
rtt,
|
||||
EggEntity
|
||||
));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue