Struct mooeye::sprite::Sprite

source ·
pub struct Sprite { /* private fields */ }
Expand description

A Sprite is an advanced version of an image element, displaying an animated picture that can have multiple states (e.g. a walking, attacking, etc. version of a player character) The sprite is initalized using an image file that contains multiple rows of images (each row representing a variant), where each row contains the same number of animation frames for each variant. Drawing the sprite repeatedly draws every frame of the selected variant in order and then repeats from the beginning.

Implementations§

source§

impl Sprite

source

pub fn new(spritesheet: Image, w: u32, h: u32, frame_time: Duration) -> Self

Create a new sprite using the passed ggez::graphics::Image and set the duration after which a frame change occurs. The values for the width and height of a single image within the sheet have to be passed manually. Will never fail, as the image is already loaded by ggez.

source

pub fn from_path( path: impl AsRef<Path>, ctx: &Context, w: u32, h: u32, frame_time: Duration ) -> Result<Self, GameError>

Create a new sprite from the file found at the passed path and set the duration after which a frame change occurs. The values for the width and height of a single image within the sheet have to be passed manually. May fail if the image cannot be loaded, because f.e. the path is wrong. Passing ‘wrong’ size values will yield unexpected behaviour but not panic.

Examples found in repository?
examples/ui_examples/f_sprites.rs (lines 60-66)
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
    pub fn new(ctx: &Context) -> Result<Self, GameError> {
        // Reusing the visuals from E.

        let vis = ui::Visuals::new(
            Color::from_rgb(180, 120, 60),
            Color::from_rgb(18, 12, 6),
            1.,
            0.,
        );

        let hover_vis = ui::Visuals::new(
            Color::from_rgb(160, 100, 40),
            Color::from_rgb(18, 12, 6),
            3.,
            0.,
        );

        let cont_vis = ui::Visuals::new(
            Color::from_rgb(60, 120, 180),
            Color::from_rgb(180, 180, 190),
            1.,
            0.,
        );

        // A sprite can be loaded by specifying a path, just like an Image.
        // Additionaly, you need to inform the sprite of the grid size of its sheet and the duration each frame is displayed.
        let ui_sprite = sprite::Sprite::from_path(
            "/moo-sheet_16_16.png",
            ctx,
            16,
            24,
            Duration::from_secs_f32(0.25),
        )?
        // Just like any UI element, a sprite can have visuals, tooltip, ect.
        .to_element_builder(1, ctx)
        .scaled(5., 5.)
        .with_visuals(vis)
        .with_hover_visuals(hover_vis)
        .with_tooltip(
            graphics::Text::new("This is a sprite! Click it to end the scene.")
                .set_scale(28.)
                .set_font("Bahnschrift")
                .to_owned()
                .to_element_builder(0, ctx)
                .with_visuals(cont_vis)
                .build(),
        )
        .as_shrink()
        .build();

        // Sprites can also be initiated from a sprite pool, to make repeated file system access unneccessary
        // and streamline loading of multiple sprites. This requires sprites in the folder to be formatted appropriately.

        let sprite_pool = sprite::SpritePool::new()
            // with_folder loads all .png/.bmp/.jpg/.jpeg files from the passed folder and optionally its subfolders
            .with_folder(ctx, "/", true);

        // We can now init a sprite from the pool. Sprites are saved in the pool with a key corresponding to their relative path
        // (from the resource folder) with the format information and file ending removed.
        let non_ui_sprite = sprite_pool.init_sprite("/mage-sheet", Duration::from_secs_f32(0.2))?;

        // you can also initialize a sprite pool without any folder at all
        let mut sprite_pool2 = sprite::SpritePool::new();

        // in this case, you can use lazy initialisation of sprites to fill the sprite pool only with those sprites currently needed.
        // Lazy initilisation draws from the pool if possible, from the file system if needed (and loads into the pool in this case) and panics if it can't find anything in the fs.
        // Requires a mutable sprite pool!
        // For testing purposes, we are loading a sprite we have already loaded - this should be drawn from the pool.
        let lazy_sprite =
            sprite_pool2.init_sprite_lazy(ctx, "/mage-sheet", Duration::from_secs_f32(0.5))?;
        // now load the correct sprite
        let lazy_sprite =
            sprite_pool2.init_sprite_lazy(ctx, "/moo-sheet", lazy_sprite.get_frame_time())?;

        Ok(Self {
            gui: ui_sprite,
            sprite: non_ui_sprite,
            sprite2: lazy_sprite,
            pos: Vec2::new(50., 200.),
            v: Vec2::new(4., 4.),
        })
    }
source

pub fn from_path_fmt( path: impl AsRef<Path>, ctx: &Context, frame_time: Duration ) -> Result<Self, GameError>

Create a new sprite using from the file found at the passed path and set the duration after which a frame change occurs. The values for the width and height of a single image are read from the file name. The file name needs to be formatted as name_possibly_containing_underscores_width_height.extension. May fail if the image cannot be loaded (e.g. if the path is wrong) or the file name is not formatted correctly.

source

pub fn set_variant(&mut self, variant: u32)

Sets the variant this sprite is currently displaying. Numbers that are too large to represent a valid variant will wrap around.

Examples found in repository?
examples/ui_examples/f_sprites.rs (line 127)
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    fn update(&mut self, ctx: &mut Context) -> Result<scene_manager::SceneSwitch, GameError> {
        // Actually implementing some game state logic.

        // Pressing space changes the variant of the sprite.
        if ctx
            .keyboard
            .is_key_just_pressed(winit::event::VirtualKeyCode::Space)
        {
            self.sprite.set_variant(self.sprite.get_variant() + 1);
        }

        // Move the sprite.
        self.pos += self.v;

        // Make the sprite bounce off the screen edges.
        let scaling = 5.;

        if self.pos.x - scaling * 4. < 0. || self.pos.x + scaling * 4. >= ctx.gfx.drawable_size().0
        {
            self.v.x *= -1.;
        }

        if self.pos.y - scaling * 8. < 0. || self.pos.y + scaling * 8. >= ctx.gfx.drawable_size().1
        {
            self.v.y *= -1.;
        }

        // And handle messages as usual

        let messages = self.gui.manage_messages(ctx, None);

        if messages.contains(&ui::UiMessage::Triggered(1)) {
            return Ok(scene_manager::SceneSwitch::pop(1));
        }

        Ok(scene_manager::SceneSwitch::None)
    }
source

pub fn get_variant(&self) -> u32

Returns the variant this sprite is currently displaying.

Examples found in repository?
examples/ui_examples/f_sprites.rs (line 127)
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    fn update(&mut self, ctx: &mut Context) -> Result<scene_manager::SceneSwitch, GameError> {
        // Actually implementing some game state logic.

        // Pressing space changes the variant of the sprite.
        if ctx
            .keyboard
            .is_key_just_pressed(winit::event::VirtualKeyCode::Space)
        {
            self.sprite.set_variant(self.sprite.get_variant() + 1);
        }

        // Move the sprite.
        self.pos += self.v;

        // Make the sprite bounce off the screen edges.
        let scaling = 5.;

        if self.pos.x - scaling * 4. < 0. || self.pos.x + scaling * 4. >= ctx.gfx.drawable_size().0
        {
            self.v.x *= -1.;
        }

        if self.pos.y - scaling * 8. < 0. || self.pos.y + scaling * 8. >= ctx.gfx.drawable_size().1
        {
            self.v.y *= -1.;
        }

        // And handle messages as usual

        let messages = self.gui.manage_messages(ctx, None);

        if messages.contains(&ui::UiMessage::Triggered(1)) {
            return Ok(scene_manager::SceneSwitch::pop(1));
        }

        Ok(scene_manager::SceneSwitch::None)
    }
source

pub fn get_dimensions(&self) -> (f32, f32)

Returns the width and height of a single frame of this sprite.

source

pub fn get_frame_time(&self) -> Duration

Returns the duration between two frames.

Examples found in repository?
examples/ui_examples/f_sprites.rs (line 106)
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
    pub fn new(ctx: &Context) -> Result<Self, GameError> {
        // Reusing the visuals from E.

        let vis = ui::Visuals::new(
            Color::from_rgb(180, 120, 60),
            Color::from_rgb(18, 12, 6),
            1.,
            0.,
        );

        let hover_vis = ui::Visuals::new(
            Color::from_rgb(160, 100, 40),
            Color::from_rgb(18, 12, 6),
            3.,
            0.,
        );

        let cont_vis = ui::Visuals::new(
            Color::from_rgb(60, 120, 180),
            Color::from_rgb(180, 180, 190),
            1.,
            0.,
        );

        // A sprite can be loaded by specifying a path, just like an Image.
        // Additionaly, you need to inform the sprite of the grid size of its sheet and the duration each frame is displayed.
        let ui_sprite = sprite::Sprite::from_path(
            "/moo-sheet_16_16.png",
            ctx,
            16,
            24,
            Duration::from_secs_f32(0.25),
        )?
        // Just like any UI element, a sprite can have visuals, tooltip, ect.
        .to_element_builder(1, ctx)
        .scaled(5., 5.)
        .with_visuals(vis)
        .with_hover_visuals(hover_vis)
        .with_tooltip(
            graphics::Text::new("This is a sprite! Click it to end the scene.")
                .set_scale(28.)
                .set_font("Bahnschrift")
                .to_owned()
                .to_element_builder(0, ctx)
                .with_visuals(cont_vis)
                .build(),
        )
        .as_shrink()
        .build();

        // Sprites can also be initiated from a sprite pool, to make repeated file system access unneccessary
        // and streamline loading of multiple sprites. This requires sprites in the folder to be formatted appropriately.

        let sprite_pool = sprite::SpritePool::new()
            // with_folder loads all .png/.bmp/.jpg/.jpeg files from the passed folder and optionally its subfolders
            .with_folder(ctx, "/", true);

        // We can now init a sprite from the pool. Sprites are saved in the pool with a key corresponding to their relative path
        // (from the resource folder) with the format information and file ending removed.
        let non_ui_sprite = sprite_pool.init_sprite("/mage-sheet", Duration::from_secs_f32(0.2))?;

        // you can also initialize a sprite pool without any folder at all
        let mut sprite_pool2 = sprite::SpritePool::new();

        // in this case, you can use lazy initialisation of sprites to fill the sprite pool only with those sprites currently needed.
        // Lazy initilisation draws from the pool if possible, from the file system if needed (and loads into the pool in this case) and panics if it can't find anything in the fs.
        // Requires a mutable sprite pool!
        // For testing purposes, we are loading a sprite we have already loaded - this should be drawn from the pool.
        let lazy_sprite =
            sprite_pool2.init_sprite_lazy(ctx, "/mage-sheet", Duration::from_secs_f32(0.5))?;
        // now load the correct sprite
        let lazy_sprite =
            sprite_pool2.init_sprite_lazy(ctx, "/moo-sheet", lazy_sprite.get_frame_time())?;

        Ok(Self {
            gui: ui_sprite,
            sprite: non_ui_sprite,
            sprite2: lazy_sprite,
            pos: Vec2::new(50., 200.),
            v: Vec2::new(4., 4.),
        })
    }
source

pub fn set_frame_time(&mut self, frame_time: Duration)

Set the duration to wait between displaying two succeding frames.

source

pub fn get_cycle_time(&self) -> Duration

Returns the required time to cycle through every frame of the sprite. Returns 0 if the sprite has a frame time of zero.

source

pub fn draw_sprite( &mut self, ctx: &Context, canvas: &mut Canvas, param: impl Into<DrawParam> )

Draws this sprite as given by the paramters, advancing the displayed frame as needed.

Examples found in repository?
examples/ui_examples/f_sprites.rs (lines 169-178)
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
    fn draw(&mut self, ctx: &mut Context, mouse_listen: bool) -> Result<(), GameError> {
        // Once again, we first create a canvas and set a pixel sampler. Note that this time, we dont clear the background.

        let mut canvas = ggez::graphics::Canvas::from_frame(ctx, None);
        canvas.set_sampler(ggez::graphics::Sampler::nearest_clamp());

        // Drawing of our (limited) game state.

        // see if we need to mirror our sprite if it moves left
        let mirroring = if self.v.x > 0. { 1. } else { -1. };
        let scaling = 5.;

        self.sprite.draw_sprite(
            ctx,
            &mut canvas,
            DrawParam::new().dest_rect(Rect::new(
                self.pos.x - scaling * 4. * mirroring,
                self.pos.y - scaling * 8.,
                scaling * mirroring,
                scaling,
            )),
        );

        let scaling = 2.;

        self.sprite2.draw_sprite(
            ctx,
            &mut canvas,
            DrawParam::new().dest_rect(Rect::new(
                self.pos.x - scaling * 4. + 32.,
                self.pos.y - scaling * 8. + 32.,
                scaling,
                scaling,
            )),
        );

        // And once again drawing the GUI.

        self.gui.draw_to_screen(ctx, &mut canvas, mouse_listen);

        canvas.finish(ctx)?;

        Ok(())
    }

Trait Implementations§

source§

impl Clone for Sprite

source§

fn clone(&self) -> Sprite

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Sprite

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Sprite

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl Drawable for Sprite

source§

fn draw(&self, canvas: &mut Canvas, param: impl Into<DrawParam>)

Draws the drawable onto the canvas.
source§

fn dimensions(&self, _gfx: &impl Has<GraphicsContext>) -> Option<Rect>

Returns a bounding box in the form of a Rect. Read more
source§

impl<T: Copy + Eq + Hash> UiContent<T> for Sprite

source§

fn to_element_builder(self, id: u32, _ctx: &Context) -> UiElementBuilder<T>where Self: Sized + 'static,

Wraps the content into a UiElementBuilder and returns the builder. Use ID 0 iff you do not want this element to send any messages by itself. Overwrite this if your element should use special defaults. Context may be passed in if some elements (image element, text element) need to use context to measure themselves.
source§

fn draw_content( &mut self, ctx: &mut Context, canvas: &mut Canvas, param: UiDrawParam )

Takes in a rectangle target, a canvas, a context and draws the contents (not the border etc.) to that rectangle within that canvas using that context. Normally, this will only be called from within private functions, when the cache has been modified appropiately and only use the inner rectangle of the draw cache as content_bounds. Do not call otherwise.
source§

fn to_element(self, id: u32, ctx: &Context) -> UiElement<T>where Self: Sized + 'static,

A shorthand for creating an element builder and immediately building an element. Useful only if you do not want to diverge from any default layouts/visuals.
source§

fn expired(&self) -> bool

Returns a bool value. Returning true indicates to any container this element is a child of that this element wishes to be removed from the container (and discarded).
source§

fn container(&self) -> Option<&dyn UiContainer<T>>

Returns an immutable reference to Self (cast to a container) if this element also implements UiContainer. If it does not, returns None. Remember to overwrite this function for all of your custom containers!
source§

fn container_mut(&mut self) -> Option<&mut dyn UiContainer<T>>

Returns a mutable reference to Self (cast to a container) if this element also implements UiContainer. If it does not, returns None. Remember to overwrite this function for all of your custom containers!

Auto Trait Implementations§

§

impl !RefUnwindSafe for Sprite

§

impl Send for Sprite

§

impl Sync for Sprite

§

impl Unpin for Sprite

§

impl !UnwindSafe for Sprite

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> Downcast<T> for T

§

fn downcast(&self) -> &T

source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<S> FromSample<S> for S

§

fn from_sample_(s: S) -> S

source§

impl<T> Has<T> for T

source§

fn retrieve(&self) -> &T

Method to retrieve the context type.
source§

impl<T> HasMut<T> for T

source§

fn retrieve_mut(&mut self) -> &mut T

Method to retrieve the context type as mutable.
source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<F, T> IntoSample<T> for Fwhere T: FromSample<F>,

§

fn into_sample(self) -> T

§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

impl<T, U> ToSample<U> for Twhere U: FromSample<T>,

§

fn to_sample_(self) -> U

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> Upcast<T> for T

§

fn upcast(&self) -> Option<&T>

§

impl<V, T> VZip<V> for Twhere V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<S, T> Duplex<S> for Twhere T: FromSample<S> + ToSample<S>,