embedded_sprites/
sprite.rs

1use crate::image::Image;
2use core::fmt::Debug;
3use embedded_graphics::{geometry::Point, pixelcolor::PixelColor, prelude::DrawTarget, Drawable, Pixel};
4
5/// A [`Sprite`] given a [`Image`](crate::image::Image) a postion and make it draw able.
6///
7/// Since a [`Sprite`] does only store a reference to a [`Image`](crate::image::Image) its light.
8/// Multiple sprites can even use the same [`Image`](crate::image::Image).
9#[derive(Debug)]
10pub struct Sprite<'a, C: PixelColor> {
11	//postion of the top left pixel of the Sprite
12	pub offset: Point,
13	pub image: &'a Image<'a, C>,
14}
15
16impl<'a, C: PixelColor> Sprite<'a, C> {
17	pub const fn new(offset: Point, image: &'a Image<C>) -> Self {
18		Sprite { offset, image }
19	}
20}
21
22#[derive(Debug)]
23pub struct PixelIter<'a, C: PixelColor> {
24	/// index of the next elment
25	next: usize,
26	tm_lengt: usize,
27	sprite: &'a Sprite<'a, C>,
28}
29
30impl<'a, C: PixelColor> Iterator for PixelIter<'a, C> {
31	type Item = Pixel<C>;
32	fn next(&mut self) -> Option<Self::Item> {
33		// allow also empty / shorter transparenty map
34		while self.next < self.tm_lengt
35			&& (self.sprite.image.transparenty[self.next / 8] & (0b10000000 >> (self.next % 8))) != 0
36		{
37			// simple skipt transparenty pixel
38			self.next += 1;
39		}
40		if self.next < self.sprite.image.colors.len() {
41			let color = self.sprite.image.colors[self.next];
42			let point = Point::new(
43				(self.next % self.sprite.image.width as usize) as i32 + self.sprite.offset.x,
44				(self.next / self.sprite.image.width as usize) as i32 + self.sprite.offset.y,
45			);
46			self.next += 1;
47			return Some(Pixel(point, color));
48		}
49		None
50	}
51}
52
53impl<'a, C: PixelColor> Drawable for Sprite<'a, C> {
54	type Color = C;
55	type Output = ();
56
57	fn draw<D>(&self, target: &mut D) -> Result<Self::Output, D::Error>
58	where
59		D: DrawTarget<Color = Self::Color>,
60	{
61		target.draw_iter(PixelIter {
62			next: 0,
63			tm_lengt: self.image.transparenty.len() * 8,
64			sprite: self,
65		})
66	}
67}