Skip to content

Commit df48ecd

Browse files
authored
Sprite visibility (#80)
* Expose sprite visibility * expose context clearing in graphics intf * Add sprite visibility example to hello_world
1 parent 26afcc3 commit df48ecd

File tree

5 files changed

+84
-0
lines changed

5 files changed

+84
-0
lines changed

Crank.toml

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
[[target]]
22
name = "hello_world"
33

4+
assets = [
5+
"examples/assets/heart.png",
6+
]
7+
48
[target.metadata]
59
name = "Hello World"
610
version = "0.1.0"

examples/assets/heart.png

324 Bytes
Loading

examples/hello_world.rs

+36
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
extern crate alloc;
44

5+
use crankstart::log_to_console;
6+
use crankstart::sprite::{Sprite, SpriteManager};
7+
use crankstart_sys::{LCDBitmapFlip, PDButtons};
58
use {
69
alloc::boxed::Box,
710
anyhow::Error,
@@ -19,21 +22,37 @@ use {
1922
struct State {
2023
location: ScreenPoint,
2124
velocity: ScreenVector,
25+
sprite: Sprite,
26+
}
27+
28+
fn load_sprite() -> Result<Sprite, Error> {
29+
let sprite_manager = SpriteManager::get_mut();
30+
let mut sprite = sprite_manager.new_sprite()?;
31+
let image = Graphics::get().load_bitmap("examples/assets/heart")?;
32+
sprite.set_image(image, LCDBitmapFlip::kBitmapUnflipped)?;
33+
sprite.move_to(200.0, 120.0)?;
34+
sprite.set_z_index(10)?;
35+
sprite.set_opaque(false)?;
36+
sprite_manager.add_sprite(&sprite)?;
37+
Ok(sprite)
2238
}
2339

2440
impl State {
2541
pub fn new(_playdate: &Playdate) -> Result<Box<Self>, Error> {
2642
crankstart::display::Display::get().set_refresh_rate(20.0)?;
43+
let sprite = load_sprite()?;
2744
Ok(Box::new(Self {
2845
location: point2(INITIAL_X, INITIAL_Y),
2946
velocity: vec2(1, 2),
47+
sprite,
3048
}))
3149
}
3250
}
3351

3452
impl Game for State {
3553
fn update(&mut self, _playdate: &mut Playdate) -> Result<(), Error> {
3654
let graphics = Graphics::get();
55+
graphics.clear_context()?;
3756
graphics.clear(LCDColor::Solid(LCDSolidColor::kColorWhite))?;
3857
graphics.draw_text("Hello World Rust", self.location)?;
3958

@@ -47,10 +66,27 @@ impl Game for State {
4766
self.velocity.y = -self.velocity.y;
4867
}
4968

69+
let (_, pushed, _) = System::get().get_button_state()?;
70+
if (pushed & PDButtons::kButtonA).0 != 0 {
71+
log_to_console!("Button A pushed");
72+
self.sprite
73+
.set_visible(!self.sprite.is_visible().unwrap_or(false))
74+
.unwrap();
75+
}
76+
5077
System::get().draw_fps(0, 0)?;
5178

5279
Ok(())
5380
}
81+
82+
fn update_sprite(
83+
&mut self,
84+
sprite: &mut Sprite,
85+
_playdate: &mut Playdate,
86+
) -> Result<(), Error> {
87+
sprite.mark_dirty()?;
88+
Ok(())
89+
}
5490
}
5591

5692
const INITIAL_X: i32 = (400 - TEXT_WIDTH) / 2;

src/graphics.rs

+5
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,11 @@ impl Graphics {
500500
pd_func_caller!((*self.0).pushContext, raw_bitmap)
501501
}
502502

503+
/// Clear the context stack for graphics to make all drawing go to the display framebuffer.
504+
pub fn clear_context(&self) -> Result<(), Error> {
505+
pd_func_caller!((*self.0).pushContext, core::ptr::null_mut())
506+
}
507+
503508
/// Internal function; use `with_context`.
504509
fn pop_context(&self) -> Result<(), Error> {
505510
pd_func_caller!((*self.0).popContext)

src/sprite.rs

+39
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,27 @@ impl SpriteInner {
239239
pd_func_caller!((*self.playdate_sprite).getTag, self.raw_sprite)
240240
}
241241

242+
pub fn set_visible(&mut self, visible: bool) -> Result<(), Error> {
243+
pd_func_caller!(
244+
(*self.playdate_sprite).setVisible,
245+
self.raw_sprite,
246+
visible as i32
247+
)
248+
}
249+
250+
pub fn is_visible(&self) -> Result<bool, Error> {
251+
let visible = pd_func_caller!((*self.playdate_sprite).isVisible, self.raw_sprite)?;
252+
Ok(visible != 0)
253+
}
254+
255+
pub fn set_opaque(&self, opaque: bool) -> Result<(), Error> {
256+
pd_func_caller!(
257+
(*self.playdate_sprite).setOpaque,
258+
self.raw_sprite,
259+
opaque as i32
260+
)
261+
}
262+
242263
pub fn move_to(&mut self, x: f32, y: f32) -> Result<(), Error> {
243264
pd_func_caller!((*self.playdate_sprite).moveTo, self.raw_sprite, x, y)
244265
}
@@ -423,6 +444,24 @@ impl Sprite {
423444
.move_to(x, y)
424445
}
425446

447+
pub fn set_visible(&mut self, visible: bool) -> Result<(), Error> {
448+
self.inner
449+
.try_borrow_mut()
450+
.map_err(Error::msg)?
451+
.set_visible(visible)
452+
}
453+
454+
pub fn is_visible(&self) -> Result<bool, Error> {
455+
self.inner.try_borrow().map_err(Error::msg)?.is_visible()
456+
}
457+
458+
pub fn set_opaque(&self, opaque: bool) -> Result<(), Error> {
459+
self.inner
460+
.try_borrow_mut()
461+
.map_err(Error::msg)?
462+
.set_opaque(opaque)
463+
}
464+
426465
pub fn get_position(&self) -> Result<(f32, f32), Error> {
427466
self.inner.try_borrow().map_err(Error::msg)?.get_position()
428467
}

0 commit comments

Comments
 (0)