From 8a6f341421765de11fc5a811d4d15e404a4b7849 Mon Sep 17 00:00:00 2001 From: Corwin Date: Thu, 24 Feb 2022 21:45:14 +0000 Subject: [PATCH] update hat chooses wizard --- agb-image-converter/Cargo.toml | 2 +- agb/src/display/object.rs | 38 ++- .../.vscode/settings.json | 7 +- .../the-hat-chooses-the-wizard/Cargo.lock | 263 +++++++++++++++++- .../gfx/object_sheet.png | Bin 1780 -> 0 bytes .../gfx/object_sheet.toml | 6 - .../gfx/sprites.aseprite | Bin 0 -> 12101 bytes .../the-hat-chooses-the-wizard/src/enemies.rs | 127 +++++---- .../the-hat-chooses-the-wizard/src/main.rs | 143 +++++----- 9 files changed, 442 insertions(+), 144 deletions(-) delete mode 100644 examples/the-hat-chooses-the-wizard/gfx/object_sheet.png delete mode 100644 examples/the-hat-chooses-the-wizard/gfx/object_sheet.toml create mode 100644 examples/the-hat-chooses-the-wizard/gfx/sprites.aseprite diff --git a/agb-image-converter/Cargo.toml b/agb-image-converter/Cargo.toml index 63f41d98..517b174c 100644 --- a/agb-image-converter/Cargo.toml +++ b/agb-image-converter/Cargo.toml @@ -10,7 +10,7 @@ description = "Library for converting graphics for use on the Game Boy Advance" proc-macro = true [dependencies] -image = { version = "0.24.1", default-features = false, features = [ "png", "bmp" ] } +image = { version = "0.23", default-features = false, features = [ "png", "bmp" ] } toml = "0.5.8" serde = { version = "1.0", features = ["derive"] } syn = "1.0.86" diff --git a/agb/src/display/object.rs b/agb/src/display/object.rs index 3d805511..a1e1b13b 100644 --- a/agb/src/display/object.rs +++ b/agb/src/display/object.rs @@ -258,6 +258,7 @@ impl Attributes { pub struct Object<'a, 'b> { sprite: SpriteBorrow<'a>, + previous_sprite: SpriteBorrow<'a>, loan: Loan<'b>, attrs: Attributes, } @@ -316,8 +317,10 @@ impl ObjectController { index: inner.pop()?, free_list: &self.free_objects, }; + let p_sprite = sprite.clone(); Some(Object { sprite, + previous_sprite: p_sprite, loan, attrs: Attributes::new(), }) @@ -363,8 +366,18 @@ impl<'a, 'b> Object<'a, 'b> { } pub fn set_x(&mut self, x: u16) -> &mut Self { - self.attrs.a1a.set_x(x as u16); - self.attrs.a1s.set_x(x as u16); + self.attrs.a1a.set_x(x.rem_euclid(1 << 9) as u16); + self.attrs.a1s.set_x(x.rem_euclid(1 << 9) as u16); + self + } + + pub fn set_priority(&mut self, priority: Priority) -> &mut Self { + self.attrs.a2.set_priority(priority); + self + } + + pub fn hide(&mut self) -> &mut Self { + self.attrs.a0.set_object_mode(ObjectMode::Disabled); self } @@ -376,12 +389,12 @@ impl<'a, 'b> Object<'a, 'b> { pub fn set_position(&mut self, position: Vector2D) -> &mut Self { self.attrs.a0.set_y(position.y as u8); - self.attrs.a1a.set_x(position.x as u16); - self.attrs.a1s.set_x(position.x as u16); + self.attrs.a1a.set_x(position.x.rem_euclid(1 << 9) as u16); + self.attrs.a1s.set_x(position.x.rem_euclid(1 << 9) as u16); self } - pub fn commit(&self) { + pub fn commit(&mut self) { let mode = self.attrs.a0.object_mode(); let attrs: [[u8; 2]; 3] = match mode { ObjectMode::Normal => [ @@ -404,6 +417,7 @@ impl<'a, 'b> Object<'a, 'b> { ptr.add(1).write_volatile(attrs[1]); ptr.add(2).write_volatile(attrs[2]); }; + self.previous_sprite = self.sprite.clone(); } } @@ -579,6 +593,20 @@ impl<'a> Drop for SpriteBorrow<'a> { } } +impl<'a> Clone for SpriteBorrow<'a> { + fn clone(&self) -> Self { + let mut inner = self.controller.borrow_mut(); + inner.sprite.entry(self.id).and_modify(|a| a.count += 1); + let _ = inner.get_palette(self.id.get_sprite().palette).unwrap(); + Self { + id: self.id, + sprite_location: self.sprite_location, + palette_location: self.palette_location, + controller: self.controller, + } + } +} + #[derive(BitfieldSpecifier, Clone, Copy)] enum ObjectMode { Normal, diff --git a/examples/the-hat-chooses-the-wizard/.vscode/settings.json b/examples/the-hat-chooses-the-wizard/.vscode/settings.json index a3c76e3a..e58f9587 100644 --- a/examples/the-hat-chooses-the-wizard/.vscode/settings.json +++ b/examples/the-hat-chooses-the-wizard/.vscode/settings.json @@ -2,5 +2,10 @@ "files.associations": { "*.tsx": "xml", "*.tmx": "xml" - } + }, + "rust-analyzer.checkOnSave.allTargets": false, + "rust-analyzer.checkOnSave.extraArgs": [ + "--target", + "thumbv4t-none-eabi" + ] } \ No newline at end of file diff --git a/examples/the-hat-chooses-the-wizard/Cargo.lock b/examples/the-hat-chooses-the-wizard/Cargo.lock index cd5fa42c..0cb83886 100644 --- a/examples/the-hat-chooses-the-wizard/Cargo.lock +++ b/examples/the-hat-chooses-the-wizard/Cargo.lock @@ -24,6 +24,10 @@ dependencies = [ "agb_sound_converter", "bare-metal", "bitflags", + "hashbrown", + "modular-bitfield", + "phf", + "rustc-hash", ] [[package]] @@ -37,6 +41,7 @@ dependencies = [ name = "agb_image_converter" version = "0.6.0" dependencies = [ + "asefile", "image", "proc-macro2", "quote", @@ -64,6 +69,31 @@ dependencies = [ "syn", ] +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "asefile" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d5f7de918fd4cb18249819fc4bd27f6a5dbfbc9dcb271727f27dacf17ce880" +dependencies = [ + "bitflags", + "byteorder", + "flate2", + "image", + "log", + "nohash", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -117,11 +147,44 @@ dependencies = [ [[package]] name = "deflate" -version = "1.0.0" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" dependencies = [ "adler32", + "byteorder", +] + +[[package]] +name = "flate2" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +dependencies = [ + "cfg-if", + "crc32fast", + "libc", + "miniz_oxide 0.4.4", +] + +[[package]] +name = "getrandom" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hashbrown" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c21d40587b92fa6a6c6e3c1bdbf87d75511db5672f9c93175574b3a00df1758" +dependencies = [ + "ahash", ] [[package]] @@ -132,9 +195,9 @@ checksum = "8a164bb2ceaeff4f42542bdb847c41517c78a60f5649671b2a07312b6e117549" [[package]] name = "image" -version = "0.24.1" +version = "0.23.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db207d030ae38f1eb6f240d5a1c1c88ff422aa005d10f8c6c6fc5e75286ab30e" +checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1" dependencies = [ "bytemuck", "byteorder", @@ -152,14 +215,66 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] -name = "miniz_oxide" -version = "0.5.1" +name = "libc" +version = "0.2.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" +checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" dependencies = [ "adler", + "autocfg", ] +[[package]] +name = "modular-bitfield" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a53d79ba8304ac1c4f9eb3b9d281f21f7be9d4626f72ce7df4ad8fbde4f38a74" +dependencies = [ + "modular-bitfield-impl", + "static_assertions", +] + +[[package]] +name = "modular-bitfield-impl" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a7d5f7076603ebc68de2dc6a650ec331a062a13abaa346975be747bbfa4b789" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "nohash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0f889fb66f7acdf83442c35775764b51fed3c606ab9cee51500dbde2cf528ca" + [[package]] name = "num-integer" version = "0.1.44" @@ -183,9 +298,9 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" +checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" dependencies = [ "autocfg", "num-integer", @@ -202,17 +317,79 @@ dependencies = [ ] [[package]] -name = "png" -version = "0.17.5" +name = "once_cell" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc38c0ad57efb786dd57b9864e5b18bae478c00c824dc55a38bbc9da95dde3ba" +checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_macros", + "phf_shared", + "proc-macro-hack", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "png" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" dependencies = [ "bitflags", "crc32fast", "deflate", - "miniz_oxide", + "miniz_oxide 0.3.7", ] +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + [[package]] name = "proc-macro2" version = "1.0.36" @@ -231,6 +408,42 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "ryu" version = "1.0.9" @@ -268,6 +481,18 @@ dependencies = [ "serde", ] +[[package]] +name = "siphasher" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a86232ab60fa71287d7f2ddae4a7073f6b7aac33631c3015abb556f08c6d0a3e" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "syn" version = "1.0.86" @@ -302,3 +527,15 @@ name = "unicode-xid" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/examples/the-hat-chooses-the-wizard/gfx/object_sheet.png b/examples/the-hat-chooses-the-wizard/gfx/object_sheet.png deleted file mode 100644 index 5ba186476d5015837ff7afd89a1fd291d28341a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1780 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 b7?m9+xBF)Lh+M9|j?aagm-+2Kn8$wsL6bdA literal 0 HcmV?d00001 diff --git a/examples/the-hat-chooses-the-wizard/src/enemies.rs b/examples/the-hat-chooses-the-wizard/src/enemies.rs index 399474f3..c30c0ebe 100644 --- a/examples/the-hat-chooses-the-wizard/src/enemies.rs +++ b/examples/the-hat-chooses-the-wizard/src/enemies.rs @@ -1,6 +1,8 @@ -use super::{object_tiles, sfx::SfxPlayer, Entity, FixedNumberType, HatState, Level}; +use crate::TAG_MAP; + +use super::{sfx::SfxPlayer, Entity, FixedNumberType, HatState, Level}; use agb::{ - display::object::{ObjectControl, Size}, + display::object::{ObjectController, Size}, fixnum::Vector2D, }; @@ -28,11 +30,11 @@ pub enum EnemyUpdateState { } impl<'a> Enemy<'a> { - pub fn new_slime(object: &'a ObjectControl, start_pos: Vector2D) -> Self { + pub fn new_slime(object: &'a ObjectController, start_pos: Vector2D) -> Self { Enemy::Slime(Slime::new(object, start_pos + (0, 1).into())) } - pub fn new_snail(object: &'a ObjectControl, start_pos: Vector2D) -> Self { + pub fn new_snail(object: &'a ObjectController, start_pos: Vector2D) -> Self { Enemy::Snail(Snail::new(object, start_pos)) } @@ -45,6 +47,7 @@ impl<'a> Enemy<'a> { pub fn update( &mut self, + controller: &'a ObjectController, level: &Level, player_pos: Vector2D, hat_state: HatState, @@ -52,8 +55,12 @@ impl<'a> Enemy<'a> { sfx_player: &mut SfxPlayer, ) -> EnemyUpdateState { let update_state = match self { - Enemy::Slime(slime) => slime.update(level, player_pos, hat_state, timer, sfx_player), - Enemy::Snail(snail) => snail.update(level, player_pos, hat_state, timer, sfx_player), + Enemy::Slime(slime) => { + slime.update(controller, level, player_pos, hat_state, timer, sfx_player) + } + Enemy::Snail(snail) => { + snail.update(controller, level, player_pos, hat_state, timer, sfx_player) + } Enemy::Empty => UpdateState::Nothing, }; @@ -82,7 +89,7 @@ struct EnemyInfo<'a> { impl<'a> EnemyInfo<'a> { fn new( - object: &'a ObjectControl, + object: &'a ObjectController, start_pos: Vector2D, collision: Vector2D, ) -> Self { @@ -123,19 +130,18 @@ pub struct Slime<'a> { } impl<'a> Slime<'a> { - fn new(object: &'a ObjectControl, start_pos: Vector2D) -> Self { + fn new(object: &'a ObjectController, start_pos: Vector2D) -> Self { let mut slime = Slime { enemy_info: EnemyInfo::new(object, start_pos, (14u16, 14u16).into()), state: SlimeState::Idle, }; - slime.enemy_info.entity.sprite.set_sprite_size(Size::S16x16); - slime } fn update( &mut self, + controller: &'a ObjectController, level: &Level, player_pos: Vector2D, hat_state: HatState, @@ -147,11 +153,13 @@ impl<'a> Slime<'a> { match self.state { SlimeState::Idle => { - let offset = (timer / 16 % 2) * 4; - self.enemy_info - .entity - .sprite - .set_tile_id(object_tiles::SLIME_IDLE_START + offset as u16); + let offset = (timer / 16) as usize; + + let tag = TAG_MAP.get("Slime Idle").unwrap(); + let frame = tag.get_animation_sprite(offset); + let sprite = controller.get_sprite(frame).unwrap(); + + self.enemy_info.entity.sprite.set_sprite(sprite); if (self.enemy_info.entity.position - player_pos).magnitude_squared() < (64 * 64).into() @@ -178,7 +186,7 @@ impl<'a> Slime<'a> { } } SlimeState::Jumping(jumping_start_frame) => { - let offset = (timer - jumping_start_frame) / 4; + let offset = (timer - jumping_start_frame) as usize / 4; if timer == jumping_start_frame + 1 { sfx_player.slime_jump(); @@ -188,12 +196,11 @@ impl<'a> Slime<'a> { self.enemy_info.entity.velocity = (0, 0).into(); self.state = SlimeState::Idle; } else { - let sprite_offset = if offset >= 4 { 7 - offset } else { offset }; + let tag = TAG_MAP.get("Slime Jump").unwrap(); + let frame = tag.get_animation_sprite(offset); + let sprite = controller.get_sprite(frame).unwrap(); - self.enemy_info - .entity - .sprite - .set_tile_id(object_tiles::SLIME_JUMP_START + (sprite_offset * 4) as u16); + self.enemy_info.entity.sprite.set_sprite(sprite); } if player_has_collided { @@ -209,17 +216,18 @@ impl<'a> Slime<'a> { sfx_player.slime_death(); } - let offset = (timer - dying_start_frame) / 4; + let offset = (timer - dying_start_frame) as usize / 4; self.enemy_info.entity.velocity = (0, 0).into(); if offset >= 4 { return UpdateState::Remove; } - self.enemy_info - .entity - .sprite - .set_tile_id(object_tiles::SLIME_SPLAT_START + (offset * 4) as u16); + let tag = TAG_MAP.get("Slime splat").unwrap(); + let frame = tag.get_animation_sprite(offset); + let sprite = controller.get_sprite(frame).unwrap(); + + self.enemy_info.entity.sprite.set_sprite(sprite); } } @@ -247,14 +255,12 @@ pub struct Snail<'a> { } impl<'a> Snail<'a> { - fn new(object: &'a ObjectControl, start_pos: Vector2D) -> Self { + fn new(object: &'a ObjectController, start_pos: Vector2D) -> Self { let mut snail = Snail { enemy_info: EnemyInfo::new(object, start_pos, (16u16, 16u16).into()), state: SnailState::Idle(0), }; - snail.enemy_info.entity.sprite.set_sprite_size(Size::S16x16); - snail } @@ -264,6 +270,7 @@ impl<'a> Snail<'a> { fn update( &mut self, + controller: &'a ObjectController, level: &Level, player_pos: Vector2D, hat_state: HatState, @@ -288,10 +295,11 @@ impl<'a> Snail<'a> { } } - self.enemy_info - .entity - .sprite - .set_tile_id(object_tiles::SNAIL_IDLE_START); + let tag = TAG_MAP.get("Snail Idle").unwrap(); + let frame = tag.get_animation_sprite(0); + let sprite = controller.get_sprite(frame).unwrap(); + + self.enemy_info.entity.sprite.set_sprite(sprite); if player_has_collided { if hat_state != HatState::WizardTowards { return UpdateState::KillPlayer; @@ -301,17 +309,18 @@ impl<'a> Snail<'a> { } } SnailState::Emerging(time) => { - let offset = (timer - time) / 4; + let offset = (timer - time) as usize / 4; if offset >= 5 { self.state = SnailState::Moving(timer); } self.enemy_info.entity.velocity = (0, 0).into(); - self.enemy_info - .entity - .sprite - .set_tile_id(object_tiles::SNAIL_EMERGE_START + (offset * 4) as u16); + let tag = TAG_MAP.get("Snail Emerge").unwrap(); + let frame = tag.get_animation_sprite(offset); + let sprite = controller.get_sprite(frame).unwrap(); + + self.enemy_info.entity.sprite.set_sprite(sprite); if player_has_collided { if hat_state != HatState::WizardTowards { @@ -328,12 +337,13 @@ impl<'a> Snail<'a> { sfx_player.snail_retreat(); } - let offset = (timer - time) / 8 % 2; + let offset = (timer - time) as usize / 8; - self.enemy_info - .entity - .sprite - .set_tile_id(object_tiles::SNAIL_MOVE + (offset * 4) as u16); + let tag = TAG_MAP.get("Snail Move").unwrap(); + let frame = tag.get_animation_sprite(offset); + let sprite = controller.get_sprite(frame).unwrap(); + + self.enemy_info.entity.sprite.set_sprite(sprite); if timer % 32 == 0 { let x_vel: FixedNumberType = @@ -358,16 +368,17 @@ impl<'a> Snail<'a> { } } SnailState::Retreating(time) => { - let offset = 5 - (timer - time) / 4; + let offset = 5 - (timer - time) as usize / 4; if offset == 0 { self.state = SnailState::Idle(timer); } - self.enemy_info - .entity - .sprite - .set_tile_id(object_tiles::SNAIL_EMERGE_START + (offset * 4) as u16); + let tag = TAG_MAP.get("Snail Emerge").unwrap(); + let frame = tag.get_animation_sprite(offset); + let sprite = controller.get_sprite(frame).unwrap(); + + self.enemy_info.entity.sprite.set_sprite(sprite); self.enemy_info.entity.velocity = (0, 0).into(); if player_has_collided { @@ -383,18 +394,26 @@ impl<'a> Snail<'a> { sfx_player.snail_death(); } - let offset = (timer - time) / 4; - let tile_id = if offset < 5 { - object_tiles::SNAIL_EMERGE_START + ((5 - offset) * 4) as u16 + let offset = (timer - time) as usize / 4; + let frame = if offset < 5 { + TAG_MAP + .get("Snail Emerge") + .unwrap() + .get_animation_sprite(5 - offset) } else if offset == 5 { - object_tiles::SNAIL_IDLE_START + TAG_MAP.get("Snail Idle").unwrap().get_animation_sprite(0) } else if offset < 5 + 7 { - object_tiles::SNAIL_DEATH_START + ((offset - 5) * 4) as u16 + TAG_MAP + .get("Snail Death") + .unwrap() + .get_animation_sprite(offset - 5) } else { return UpdateState::Remove; }; - self.enemy_info.entity.sprite.set_tile_id(tile_id); + let sprite = controller.get_sprite(frame).unwrap(); + + self.enemy_info.entity.sprite.set_sprite(sprite); self.enemy_info.entity.velocity = (0, 0).into(); } } diff --git a/examples/the-hat-chooses-the-wizard/src/main.rs b/examples/the-hat-chooses-the-wizard/src/main.rs index 589db875..262154e2 100644 --- a/examples/the-hat-chooses-the-wizard/src/main.rs +++ b/examples/the-hat-chooses-the-wizard/src/main.rs @@ -18,27 +18,6 @@ pub struct Level { start_pos: (i32, i32), } -mod object_tiles { - pub const WIZARD_TILE_START: u16 = 0; - pub const WIZARD_JUMP: u16 = 4 * 4; - pub const WIZARD_FALL_START: u16 = 5 * 4; - - pub const HAT_TILE_START: u16 = 9 * 4; - pub const HAT_TILE_START_SECOND: u16 = 28 * 4; - pub const HAT_TILE_START_THIRD: u16 = 38 * 4; - - pub const SLIME_IDLE_START: u16 = 19 * 4; - pub const SLIME_JUMP_START: u16 = 20 * 4; - pub const SLIME_SPLAT_START: u16 = 24 * 4; - - pub const SNAIL_IDLE_START: u16 = 48 * 4; - pub const SNAIL_EMERGE_START: u16 = 49 * 4; - pub const SNAIL_MOVE: u16 = 54 * 4; - pub const SNAIL_DEATH_START: u16 = 56 * 4; -} - -agb::include_gfx!("gfx/object_sheet.toml"); - mod map_tiles { use super::Level; @@ -106,25 +85,32 @@ agb::include_gfx!("gfx/tile_sheet.toml"); use agb::{ display::{ background::BackgroundRegular, - object::{ObjectControl, ObjectStandard, Size}, + object::{Object, ObjectController, Sprite, TagMap}, Priority, HEIGHT, WIDTH, }, fixnum::{FixedNum, Vector2D}, input::{self, Button, ButtonController}, }; +const SPRITE_TAGS: (&[Sprite], &TagMap) = agb::include_aseprite!("gfx/sprites.aseprite"); +const SPRITES: &[Sprite] = SPRITE_TAGS.0; +const TAG_MAP: &TagMap = SPRITE_TAGS.1; + type FixedNumberType = FixedNum<10>; pub struct Entity<'a> { - sprite: ObjectStandard<'a>, + sprite: Object<'a, 'a>, position: Vector2D, velocity: Vector2D, collision_mask: Vector2D, } impl<'a> Entity<'a> { - pub fn new(object: &'a ObjectControl, collision_mask: Vector2D) -> Self { - let mut sprite = object.get_object_standard(); + pub fn new(object: &'a ObjectController, collision_mask: Vector2D) -> Self { + let dummy_sprite = object + .get_sprite(TAG_MAP.get("Walking").unwrap().get_sprite(0)) + .unwrap(); + let mut sprite = object.get_object(dummy_sprite).unwrap(); sprite.set_priority(Priority::P1); Entity { sprite, @@ -360,14 +346,21 @@ fn ping_pong(i: i32, n: i32) -> i32 { } impl<'a> Player<'a> { - fn new(controller: &'a ObjectControl, start_position: Vector2D) -> Self { - let mut hat = Entity::new(controller, (6_u16, 6_u16).into()); + fn new(controller: &'a ObjectController, start_position: Vector2D) -> Self { let mut wizard = Entity::new(controller, (6_u16, 14_u16).into()); + let mut hat = Entity::new(controller, (6_u16, 6_u16).into()); + + wizard.sprite.set_sprite( + controller + .get_sprite(TAG_MAP.get("Walking").unwrap().get_sprite(0)) + .unwrap(), + ); + hat.sprite.set_sprite( + controller + .get_sprite(TAG_MAP.get("HatSpin").unwrap().get_sprite(0)) + .unwrap(), + ); - wizard.sprite.set_tile_id(object_tiles::WIZARD_TILE_START); - hat.sprite.set_tile_id(object_tiles::HAT_TILE_START); - wizard.sprite.set_sprite_size(Size::S16x16); - hat.sprite.set_sprite_size(Size::S16x16); wizard.sprite.show(); hat.sprite.show(); @@ -393,6 +386,7 @@ impl<'a> Player<'a> { fn update_frame( &mut self, input: &ButtonController, + controller: &'a ObjectController, timer: i32, level: &Level, enemies: &[enemies::Enemy], @@ -467,23 +461,29 @@ impl<'a> Player<'a> { self.wizard.velocity = self.wizard.update_position(level); if self.wizard.velocity.x.abs() > 0.into() { - let offset = (ping_pong(timer / 16, 4)) as u16; + let offset = (ping_pong(timer / 16, 4)) as usize; self.wizard_frame = offset as u8; - self.wizard - .sprite - .set_tile_id(object_tiles::WIZARD_TILE_START + offset * 4); + let walk = TAG_MAP.get("Walking").unwrap(); + let frame = walk.get_animation_sprite(offset); + let sprite = controller.get_sprite(frame).unwrap(); + + self.wizard.sprite.set_sprite(sprite); } if self.wizard.velocity.y < -FixedNumberType::new(1) / 16 { // going up self.wizard_frame = 5; - self.wizard.sprite.set_tile_id(object_tiles::WIZARD_JUMP); + let walk = TAG_MAP.get("Jumping").unwrap(); + let frame = walk.get_animation_sprite(0); + let sprite = controller.get_sprite(frame).unwrap(); + + self.wizard.sprite.set_sprite(sprite); } else if self.wizard.velocity.y > FixedNumberType::new(1) / 16 { // going down let offset = if self.wizard.velocity.y * 2 > 3.into() { - ((timer / 4) % 4) as u16 + (timer / 4) as usize } else { // Don't flap beard unless going quickly 0 @@ -491,9 +491,11 @@ impl<'a> Player<'a> { self.wizard_frame = 0; - self.wizard - .sprite - .set_tile_id(object_tiles::WIZARD_FALL_START + offset * 4); + let walk = TAG_MAP.get("Falling").unwrap(); + let frame = walk.get_animation_sprite(offset); + let sprite = controller.get_sprite(frame).unwrap(); + + self.wizard.sprite.set_sprite(sprite); } if input.x_tri() != agb::input::Tri::Zero { @@ -502,19 +504,23 @@ impl<'a> Player<'a> { } let hat_base_tile = match self.num_recalls { - 0 => object_tiles::HAT_TILE_START, - 1 => object_tiles::HAT_TILE_START_SECOND, - _ => object_tiles::HAT_TILE_START_THIRD, + 0 => TAG_MAP.get("HatSpin").unwrap(), + 1 => TAG_MAP.get("HatSpin2").unwrap(), + _ => TAG_MAP.get("HatSpin3").unwrap(), }; match self.facing { agb::input::Tri::Negative => { self.wizard.sprite.set_hflip(true); - self.hat.sprite.set_tile_id(hat_base_tile + 4 * 5); + self.hat + .sprite + .set_sprite(controller.get_sprite(hat_base_tile.get_sprite(5)).unwrap()); } agb::input::Tri::Positive => { self.wizard.sprite.set_hflip(false); - self.hat.sprite.set_tile_id(hat_base_tile); + self.hat + .sprite + .set_sprite(controller.get_sprite(hat_base_tile.get_sprite(0)).unwrap()); } _ => {} } @@ -543,11 +549,13 @@ impl<'a> Player<'a> { _ => 4, }; - let hat_sprite_offset = timer / hat_sprite_divider % 10; + let hat_sprite_offset = (timer / hat_sprite_divider) as usize; - self.hat - .sprite - .set_tile_id(hat_base_tile + (hat_sprite_offset * 4) as u16); + self.hat.sprite.set_sprite( + controller + .get_sprite(hat_base_tile.get_animation_sprite(hat_sprite_offset)) + .unwrap(), + ); if self.hat_slow_counter < 30 && self.hat.velocity.magnitude() < 2.into() { self.hat.velocity = (0, 0).into(); @@ -578,9 +586,11 @@ impl<'a> Player<'a> { self.hat.position = self.wizard.position - hat_resting_position; } HatState::WizardTowards => { - self.hat - .sprite - .set_tile_id(hat_base_tile + 4 * (timer / 2 % 10) as u16); + self.hat.sprite.set_sprite( + controller + .get_sprite(hat_base_tile.get_animation_sprite(timer as usize / 2)) + .unwrap(), + ); let distance_vector = self.hat.position - self.wizard.position + hat_resting_position; let distance = distance_vector.magnitude(); @@ -617,7 +627,7 @@ enum UpdateState { impl<'a, 'b, 'c> PlayingLevel<'a, 'b> { fn open_level( level: &'a Level, - object_control: &'a ObjectControl, + object_control: &'a ObjectController, background: &'a mut BackgroundRegular<'b>, foreground: &'a mut BackgroundRegular<'b>, input: ButtonController, @@ -676,22 +686,27 @@ impl<'a, 'b, 'c> PlayingLevel<'a, 'b> { self.player.wizard.sprite.set_priority(Priority::P0); } - fn dead_update(&mut self) -> bool { + fn dead_update(&mut self, controller: &'a ObjectController) -> bool { self.timer += 1; + let tag = TAG_MAP.get("Player Death").unwrap(); + let frame = tag.get_animation_sprite(self.timer as usize / 8); + let sprite = controller.get_sprite(frame).unwrap(); + self.player.wizard.velocity += (0.into(), FixedNumberType::new(1) / 32).into(); self.player.wizard.position += self.player.wizard.velocity; - self.player - .wizard - .sprite - .set_tile_id((self.timer / 8 % 2 * 4 + 63 * 4) as u16); + self.player.wizard.sprite.set_sprite(sprite); self.player.wizard.commit_position(self.background.position); self.player.wizard.position.y - self.background.position.y < (HEIGHT + 8).into() } - fn update_frame(&mut self, sfx_player: &mut sfx::SfxPlayer) -> UpdateState { + fn update_frame( + &mut self, + controller: &'a ObjectController, + sfx_player: &mut sfx::SfxPlayer, + ) -> UpdateState { self.timer += 1; self.input.update(); @@ -699,6 +714,7 @@ impl<'a, 'b, 'c> PlayingLevel<'a, 'b> { self.player.update_frame( &self.input, + controller, self.timer, self.background.level, &self.enemies, @@ -707,6 +723,7 @@ impl<'a, 'b, 'c> PlayingLevel<'a, 'b> { for enemy in self.enemies.iter_mut() { match enemy.update( + controller, self.background.level, self.player.wizard.position, self.player.hat_state, @@ -784,8 +801,6 @@ fn main(mut agb: agb::Gba) -> ! { tiled.set_background_palettes(tile_sheet::background.palettes); tiled.set_background_tilemap(0, tile_sheet::background.tiles); - object.set_sprite_palettes(object_sheet::object_sheet.palettes); - object.set_sprite_tilemap(object_sheet::object_sheet.tiles); let mut world_display = tiled.get_raw_regular().unwrap(); world_display.clear(level_display::BLANK); @@ -793,7 +808,6 @@ fn main(mut agb: agb::Gba) -> ! { let mut background = tiled.get_regular().unwrap(); let mut foreground = tiled.get_regular().unwrap(); - object.enable(); mixer.enable(); let mut music_box = sfx::MusicBox::new(); @@ -856,11 +870,12 @@ fn main(mut agb: agb::Gba) -> ! { world_display.hide(); loop { - match level.update_frame(&mut sfx::SfxPlayer::new(&mut mixer, &music_box)) { + match level.update_frame(&object, &mut sfx::SfxPlayer::new(&mut mixer, &music_box)) + { UpdateState::Normal => {} UpdateState::Dead => { level.dead_start(); - while level.dead_update() { + while level.dead_update(&object) { music_box.before_frame(&mut mixer); mixer.frame(); vblank.wait_for_vblank();