sprite
A library for sprite hierarchy and scene management
Example
Here is an example what sprite
can do.
(The gif has low FPS, you can try the example yourself to see the full effect)
A library for sprite hierarchy and scene management
License: MIT License
A library for sprite hierarchy and scene management
Here is an example what sprite
can do.
(The gif has low FPS, you can try the example yourself to see the full effect)
There is no need for f64
precision for colors. The get/set methods should also be updated.
This will make it more consistent with piston-event.
Multiple scenes are common in a large game. We should add several built in transition effects. The basic idea of how to do transition are:
from_scene
and the scene to be transited to to_scene
.from_scene
to a texture, and create a sprite from_sprite
.to_scene
have enough resources to render. We render one frame of to_scene
to a texture, and crate a sprite to_sprite
.from_sprite
and to_sprite
.to_scene
.As you can see, the most important step is render to texture. So we should find a way to render scene to a texture first and then do the scene transition.
Any suggestions?
I think the word "animation" is more suitable, while "action" sounds a bit too generic.
For example, instead of run_action
, we could only have run
.
Probably because I'm new to rust still, and i don't understand the reasoning. But having used so many GC languages lately, I know to avoiding creating new temp objects in mid game loop is key. So i'm wondering if it's possible to refactor the child(&self, id: Uuid) -> Option<&Sprite<I>>
to accept an immutable reference instead. Simplifying use of the api.
The example in the piston-examples repo doesn't seem to be up to date with the current API.
When initializing the Scene as shown in the example, I get the following error:
wrong number of type arguments: expected 1, found 0
I think I have to specify a Texture type, but am not exactly sure on how to get this to work. An up-to-date example would help me a lot!
It would be nice if there were an online reference to this library (probably at docs.piston.rs?)
I have a "destroy" animation for my sprite, which finishes with the sprite not being visible. I don't think there is a great way to track this right now and remove the sprite once it's finished animating.
WDYT of the following interface? (I might try implementing it):
scene.remove_child_when_done(sprite_id);
This would keep a list of sprites that could be checked at the end of the event
method.
Another option would be to add a method that allows checking for number of animations for a sprite (currently find
requires you to keep track of the animation - I don't care which animation, I just want them all to be finished.)
If not, what interface would you propose?
Thanks,
Xavier
PS really digging this library!
This will make it possible to save and restore application state.
The example link in the README is broken and 404s.
The term "action" is ambiguous and used to mean two different things in Sprite and Rust-Event.
Currently to control z-ordering I remove a sprite from a scene then re-add it to place it on top (example). This is kind of hackish.
Did you envision this library handling such a thing? I might have a crack at it if you're interested. I was thinking of adding a z-attr to Sprite
then sorting by that before drawing at https://github.com/PistonDevelopers/sprite/blob/master/src/scene.rs#L84
Thanks!
Xavier
I'm having a weird type error when I extract my draw loop out of main() into its own function:
fn run<I: ImageSize>(window: &mut PistonWindow, scene: &Scene<I>) {
while let Some(e) = window.next() {
window.draw_2d(&e, |c, g| {
clear([1.0; 4], g);
rectangle([1.0, 0.0, 0.0, 1.0], // red
[0.0, 0.0, 100.0, 100.0],
c.transform,
g);
scene.draw(c.transform, g);
});
}
}
...
fn main() {
...
run(&mut window, &scene);
...
And I get:
src/main.rs:17:19: 17:23 error: type mismatch resolving `<gfx_graphics::back_end::GfxGraphics<'_, gfx_device_gl::Resources, gfx_device_gl::command::CommandBuffer> as graphics::graphics::Graphics>::Texture == I`:
expected struct `gfx_texture::Texture`,
found type parameter [E0271]
src/main.rs:17 scene.draw(c.transform, g);
^~~~
src/main.rs:17:19: 17:23 help: run `rustc --explain E0271` to see a detailed explanation
Can anyone provide a clue as to how to write this function so it doesn't cause the type checker to shout at me? It's as if g
from draw_2d
is not understood somehow when I've extracted this out.
Guidelines are here PistonDevelopers/piston#882
Sprite::visible
=> Sprite::get_visible
Sprite::anchor
=> Sprite::get_anchor
Sprite::position
=> Sprite::get_position
Sprite::color
=> Sprite::get_color
Sprite::rotation
=> Sprite::get_rotation
Sprite::scale
=> Sprite::get_scale
Sprite::flip_x
=> Sprite::get_flip_x
Sprite::flip_y
=> Sprite::get_flip_y
Sprite::opacity
=> Sprite::get_opacity
Sprite::texture
=> Sprite::get_texture
We have some places in library that we might improve by replacing them to if let
syntax.
Or maybe it's not documented? I need to animate a Rectangle's opacity and I don't see how that could be done.
Make mod ease;
as pub mod ease;
.
This allows use of ease functions as ease::<ease_function>
from other crates.
Attempting to run one of the piston examples, i get a few compile errors in piston-sprite2d
src/animation.rs:163:30: 163:60 error: box expression syntax is experimental in alpha release; you can call `Box::new` instead.
src/animation.rs:163 EaseState(f, box animation.to_state(sprite))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/animation.rs:163:30: 163:60 help: add #![feature(box_syntax)] to the crate attributes to enable
src/animation.rs:163 EaseState(f, box animation.to_state(sprite))
^~~~
src/animation.rs:242:21: 242:56 error: box pattern syntax is experimental in alpha release
src/animation.rs:242 box MoveState(t, bx, by, cx, cy, d) => {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/animation.rs:242:21: 242:56 help: add #![feature(box_syntax)] to the crate attributes to enable
src/animation.rs:242 box MoveState(t, bx, by, cx, cy, d) => {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/animation.rs:247:21: 247:48 error: box pattern syntax is experimental in alpha release
src/animation.rs:247 box RotateState(t, b, c, d) => {
^~~~~~~~~~~~~~~~~~~~~~~~~~~
src/animation.rs:247:21: 247:48 help: add #![feature(box_syntax)] to the crate attributes to enable
src/animation.rs:247 box RotateState(t, b, c, d) => {
^~~~~~~~~~~~~~~~~~~~~~~~~~~
src/animation.rs:251:21: 251:57 error: box pattern syntax is experimental in alpha release
src/animation.rs:251 box ScaleState(t, bx, by, cx, cy, d) => {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/animation.rs:251:21: 251:57 help: add #![feature(box_syntax)] to the crate attributes to enable
src/animation.rs:251 box ScaleState(t, bx, by, cx, cy, d) => {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/animation.rs:255:21: 255:46 error: box pattern syntax is experimental in alpha release
src/animation.rs:255 box FadeState(t, b, c, d) => {
^~~~~~~~~~~~~~~~~~~~~~~~~
src/animation.rs:255:21: 255:46 help: add #![feature(box_syntax)] to the crate attributes to enable
src/animation.rs:255 box FadeState(t, b, c, d) => {
^~~~~~~~~~~~~~~~~~~~~~~~~
src/animation.rs:274:44: 274:53 error: box expression syntax is experimental in alpha release; you can call `Box::new` instead.
src/animation.rs:274 (Some(EaseState(f, box state)),
^~~~~~~~~
src/animation.rs:274:44: 274:53 help: add #![feature(box_syntax)] to the crate attributes to enable
src/animation.rs:274 (Some(EaseState(f, box state)),
I'd be happy to fork and make a pull request to change via the error message. But not sure if there's something else I should be doing instead :)
I'm running the latest nightly:
rustc 1.0.0-nightly (3d0d9bb6f 2015-01-12 22:56:20 +0000)
The way it currently works, is each Sprite
having children. When it renders, it renders first the parent and then the children. Each Sprite
stores a Uuid.
Enabled in Travis, but requires a .travis.yml
file.
src/scene.rs:125:50: 125:58 error: type `(ai_behavior::behavior::Behavior<animation::Animation>, ai_behavior::state::State<animation::Animation, animation::AnimationState>, bool)` does not implement any method in scope named `unwrap`
src/scene.rs:125 let (b, s, _) = animations.remove(i).unwrap();
^~~~~~~~
src/scene.rs:137:50: 137:58 error: type `(ai_behavior::behavior::Behavior<animation::Animation>, ai_behavior::state::State<animation::Animation, animation::AnimationState>, bool)` does not implement any method in scope named `unwrap`
src/scene.rs:137 let (b, s, _) = animations.remove(i).unwrap();
^~~~~~~~
src/scene.rs:148:55: 148:63 error: type `(ai_behavior::behavior::Behavior<animation::Animation>, ai_behavior::state::State<animation::Animation, animation::AnimationState>, bool)` does not implement any method in scope named `unwrap`
src/scene.rs:148 let (b, s, paused) = animations.remove(i).unwrap();
^~~~~~~~
src/scene.rs:149:37: 149:43 error: the type of this value must be known in this context
src/scene.rs:149 animations.push((b, s, !paused));
^~~~~~
src/scene.rs:196:55: 196:63 error: type `sprite::Sprite<I>` does not implement any method in scope named `unwrap`
src/scene.rs:196 let removed = self.children.remove(i).unwrap();
^~~~~~~~
src/sprite.rs:206:55: 206:63 error: type `sprite::Sprite<I>` does not implement any method in scope named `unwrap`
src/sprite.rs:206 let removed = self.children.remove(i).unwrap();
^~~~~~~~
error: aborting due to 6 previous errors
Could not compile `piston2d-sprite`.
Now we can change the sprite's texture easily by sprite.set_texture(...)
. We can manually set the sprite's texture to do animation but we should have a convenient way to do it.
One way in my mind is that we can define a struct Animation
to describe the animation which may contain information like:
Once we have the Animation
, we can construct an Action
for it. So to do animation, the code may look like:
scene.run_action(sprite, Action(Animation(a)));
As we can pause/resume/toggle/stop actions, we can easily pause/resume/toggle/stop animations.
We should focus on this after #6 finished.
Any suggestions?
probably implement with https://crates.io/crates/keyframe
Since we are using Uuid
, we don't have to store the textures within the scene structure but can store it outside. When rendering one would call a method with a closure that gets called back for each sprite with the Uuid
and a transformed context.
This will make is possible to handle all kinds of events.
The branch "olddesign" is no longer needed.
This is to avoid confusion with hierarchical structures.
This is probably me being extremely dumb as I'm new to rust but after you've added a sprite to a scene you can no longer change the sprite's position.
sprite.set_position(1600 as f64 / 2.0, 900 as f64 / 2.0);
scene.add_child(sprite);
sprite.set_position(400 as f64 / 2.0, 400 as f64 / 2.0);
When we access the 'sprite' object again, the value has moved and is no longer valid to use. Using the wonderful methods for getting a child by it's id returns an std::option type, not a sprite.
sprite.set_position(1600 as f64 / 2.0, 900 as f64 / 2.0);
let id = scene.add_child(sprite);
let sprite_ref = scene.child(id);
sprite_ref.set_position(400 as f64 / 2.0, 400 as f64 / 2.0);
Thanks for your help!
I'd like to set a window rectangle such that the parts of sprites that are outside of it. This is supported by underlying graphics library, I'm just not sure how it should all tie together.
Sprite.draw()
function?sprite.set_clip(Rectangle::new())
?Links:
default_draw_state()
.Currently we have broken build.
I keep getting this message when trying to "cargo run" the code:
error: a bin target must be available for "cargo run"
I'm using Rust 1.9 on GNU/Linux. Please let me know if I'm missing something.
Currently we have warnings related to deprecated methods.
src/scene.rs:103:28: 103:44 warning: use of deprecated item: Renamed to `get`, #[warn(deprecated)] on by default
src/scene.rs:103 match self.running.find(&sprite_id) {
^~~~~~~~~~~~~~~~
src/scene.rs:194:49: 194:57 warning: use of deprecated item: Renamed to `remove`, #[warn(deprecated)] on by default
src/scene.rs:194 let removed = match self.children_index.pop(&id) {
^~~~~~~~
...
As a prerequisite for sprite-sheet animations, I would like to have some mechanism to invoke my own callbacks as part of a sequence of animation steps.
This could be useful to:
This issue was automatically generated. Feel free to close without ceremony if
you do not agree with re-licensing or if it is not possible for other reasons.
Respond to @cmr with any questions or concerns, or pop over to
#rust-offtopic
on IRC to discuss.
You're receiving this because someone (perhaps the project maintainer)
published a crates.io package with the license as "MIT" xor "Apache-2.0" and
the repository field pointing here.
TL;DR the Rust ecosystem is largely Apache-2.0. Being available under that
license is good for interoperation. The MIT license as an add-on can be nice
for GPLv2 projects to use your code.
The MIT license requires reproducing countless copies of the same copyright
header with different names in the copyright field, for every MIT library in
use. The Apache license does not have this drawback. However, this is not the
primary motivation for me creating these issues. The Apache license also has
protections from patent trolls and an explicit contribution licensing clause.
However, the Apache license is incompatible with GPLv2. This is why Rust is
dual-licensed as MIT/Apache (the "primary" license being Apache, MIT only for
GPLv2 compat), and doing so would be wise for this project. This also makes
this crate suitable for inclusion and unrestricted sharing in the Rust
standard distribution and other projects using dual MIT/Apache, such as my
personal ulterior motive, the Robigalia project.
Some ask, "Does this really apply to binary redistributions? Does MIT really
require reproducing the whole thing?" I'm not a lawyer, and I can't give legal
advice, but some Google Android apps include open source attributions using
this interpretation. Others also agree with
it.
But, again, the copyright notice redistribution is not the primary motivation
for the dual-licensing. It's stronger protections to licensees and better
interoperation with the wider Rust ecosystem.
To do this, get explicit approval from each contributor of copyrightable work
(as not all contributions qualify for copyright, due to not being a "creative
work", e.g. a typo fix) and then add the following to your README:
## License
Licensed under either of
* Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.
and in your license headers, if you have them, use the following boilerplate
(based on that used in Rust):
// Copyright 2016 sprite developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
It's commonly asked whether license headers are required. I'm not comfortable
making an official recommendation either way, but the Apache license
recommends it in their appendix on how to use the license.
Be sure to add the relevant LICENSE-{MIT,APACHE}
files. You can copy these
from the Rust repo for a plain-text
version.
And don't forget to update the license
metadata in your Cargo.toml
to:
license = "MIT/Apache-2.0"
I'll be going through projects which agree to be relicensed and have approval
by the necessary contributors and doing this changes, so feel free to leave
the heavy lifting to me!
To agree to relicensing, comment with :
I license past and future contributions under the dual MIT/Apache-2.0 license, allowing licensees to chose either at their option.
Or, if you're a contributor, you can check the box in this repo next to your
name. My scripts will pick this exact phrase up and check your checkbox, but
I'll come through and manually review this issue later as well.
Please release a new version on crates.io with the latest dependency updates. The current old uuid dependency on crates.io breaks the build.
The current design does not support multiple children per sprite, but this can be supported by adding a separate namespace tree structure.
pub struct Namespace {
/// Stores names and corresponding Uuid.
names: Vec<(String, Uuid)>,
/// Maps from Uuid to name index.
from_name_index: HashMap<Uuid, uint>,
/// Stores sub node ranges.
sub_node_ranges: Vec<Uuid>,
/// Points to a range in `sub_node_range`.
in_sub_node_ranges: HashMap<Uuid, (uint, uint)>,
}
Float/FloatMath stuff.
Currently, the only way to use them is through the Ease
enum. It would be nice if you could call a gobal function in the case you want a specific ease function.
Rust no longer puts enum variants in the same namespace as the enum.
Hi,
I would like to ask if there is some kind of active development in this library?
is it there some meeting hub to have discussions?
I see plenty of potential in this tool but I get the feeling that it has been left behind.
Instead of storing one state per behavior, which will not work when there are more than one action running at the same time within same behavior.
EmptyState can be removed.
PausedState could be a bool
replacing the state per behavior.
Sprite uses the whole texture at the moment. We should find a way that we can specify a sub region of the texture for sprite to use.
One way in my mind is that we can define a enum Frame
like:
pub enum Frame {
WholeTexture(Rc<Texture>),
SubTexture(Rc<Texture>, x, y, w, h),
}
The sprite can use the frame rather than texture directly so we can change between the whole texture and sub texture easily.
Any suggestions?
Currently it keeps a &'a Uuid
to track running animations. This can be a copy to get rid of the lifetime.
src/scene.rs:91:36: 91:82 warning: use of deprecated item: use entry instead, #[warn(deprecated)] on by default
src/scene.rs:91 let actions = self.running.find_or_insert_with(sprite_id, |_| Vec::new());
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Behavior
is powerful enough to describe sprite animations, including delays, loops etc. This means that if we had an editor for a scene we could modify the behavior and animations through the same tools. The problem we have to solve is coming up with a design that is serializable. Rc<Texture>
is not serializable.
One idea is to use hidden sprites for animation, such that we can use uuid to point to the sprite. This can be specified in the Behavior<Animation>
structure, as Animation(SetFrame(WholeFrame(uuid)))
, Animation(SetFrame(SubFrame(uuid, SourceRectangle)))
or Animation(SetFrame(DefaultFrame))
.
All sprites got a default frame. After displaying a temporary frame, you can set it back to default by using Animation(SetFrame(DefaultFrame))
. Default frames means you don't have to add a behavior in order to display something.
With #23 we will get a step closer to unifying actions and sprite animations.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.