diff --git a/Cargo.lock b/Cargo.lock index 22907c5..67e6e0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -86,6 +86,13 @@ dependencies = [ "arduboy-rust", ] +[[package]] +name = "demo9" +version = "0.1.0" +dependencies = [ + "arduboy-rust", +] + [[package]] name = "drboy" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 6ece195..9aa17d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ members = [ "Examples/Arduboy-Tutorials/demo5", "Examples/Arduboy-Tutorials/demo6", "Examples/Arduboy-Tutorials/demo7", + "Examples/Arduboy-Tutorials/demo9", "Examples/drboy", "Examples/ardvoice", "Examples/rustacean", diff --git a/Examples/Arduboy-Tutorials/demo9/Cargo.toml b/Examples/Arduboy-Tutorials/demo9/Cargo.toml new file mode 100644 index 0000000..2071360 --- /dev/null +++ b/Examples/Arduboy-Tutorials/demo9/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "demo9" +version = "0.1.0" +authors = ["ZennDev "] +edition = "2021" + +[lib] +crate-type = ["staticlib"] + +[dependencies] +arduboy-rust = { path = "../../../arduboy-rust" } diff --git a/Examples/Arduboy-Tutorials/demo9/assets/GRASS.png b/Examples/Arduboy-Tutorials/demo9/assets/GRASS.png new file mode 100644 index 0000000..6634a1a Binary files /dev/null and b/Examples/Arduboy-Tutorials/demo9/assets/GRASS.png differ diff --git a/Examples/Arduboy-Tutorials/demo9/assets/STONE.png b/Examples/Arduboy-Tutorials/demo9/assets/STONE.png new file mode 100644 index 0000000..01028e5 Binary files /dev/null and b/Examples/Arduboy-Tutorials/demo9/assets/STONE.png differ diff --git a/Examples/Arduboy-Tutorials/demo9/assets/TREES.png b/Examples/Arduboy-Tutorials/demo9/assets/TREES.png new file mode 100644 index 0000000..62a85cd Binary files /dev/null and b/Examples/Arduboy-Tutorials/demo9/assets/TREES.png differ diff --git a/Examples/Arduboy-Tutorials/demo9/assets/WATER.png b/Examples/Arduboy-Tutorials/demo9/assets/WATER.png new file mode 100644 index 0000000..db486e2 Binary files /dev/null and b/Examples/Arduboy-Tutorials/demo9/assets/WATER.png differ diff --git a/Examples/Arduboy-Tutorials/demo9/src/lib.rs b/Examples/Arduboy-Tutorials/demo9/src/lib.rs new file mode 100644 index 0000000..57fa09c --- /dev/null +++ b/Examples/Arduboy-Tutorials/demo9/src/lib.rs @@ -0,0 +1,207 @@ +#![no_std] +#![allow(non_upper_case_globals)] + +//Include the Arduboy Library +#[allow(unused_imports)] +use arduboy_rust::prelude::*; + +#[allow(dead_code)] +const arduboy: Arduboy2 = Arduboy2::new(); +const WORLD_WIDTH: usize = 14; +const WORLD_HEIGHT: usize = 7; +const PLAYER_SIZE: i16 = 16; +const PLAYER_X_OFFSET: i16 = WIDTH as i16 / 2 - PLAYER_SIZE / 2; +const PLAYER_Y_OFFSET: i16 = HEIGHT as i16 / 2 - PLAYER_SIZE / 2; +const TILE_SIZE: u8 = 16; +const GRASS: u8 = 0; +const WATER: u8 = 1; +const TREES: u8 = 2; +const STONE: u8 = 3; +const world: [[u8; WORLD_WIDTH]; WORLD_HEIGHT] = [ + [ + TREES, GRASS, GRASS, WATER, GRASS, GRASS, GRASS, TREES, GRASS, GRASS, GRASS, GRASS, GRASS, + TREES, + ], + [ + GRASS, WATER, WATER, WATER, GRASS, WATER, GRASS, GRASS, GRASS, GRASS, GRASS, STONE, GRASS, + GRASS, + ], + [ + GRASS, GRASS, GRASS, GRASS, GRASS, WATER, STONE, GRASS, GRASS, GRASS, TREES, GRASS, GRASS, + GRASS, + ], + [ + STONE, GRASS, GRASS, STONE, TREES, WATER, WATER, WATER, GRASS, WATER, WATER, GRASS, TREES, + GRASS, + ], + [ + GRASS, GRASS, GRASS, GRASS, TREES, GRASS, GRASS, GRASS, TREES, WATER, GRASS, GRASS, STONE, + TREES, + ], + [ + GRASS, GRASS, GRASS, WATER, STONE, GRASS, GRASS, TREES, TREES, TREES, GRASS, GRASS, WATER, + WATER, + ], + [ + GRASS, WATER, WATER, TREES, GRASS, WATER, WATER, TREES, TREES, GRASS, GRASS, GRASS, GRASS, + STONE, + ], +]; +#[derive(Copy, Clone)] +enum Gamestate { + GameTitle, + GamePlay, + GameOver, + GameHigh, +} +impl Gamestate { + fn update(&mut self, new_state: Gamestate) { + *self = new_state; + } +} + +// Progmem data +progmem!( + static tiles: [u8; _] = [ + 16, 16, // width, height, + //Grass + 0xff, 0x7f, 0xfb, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xf7, 0xff, 0xfd, 0xff, 0xff, 0xf7, 0x7f, + 0xff, 0xdf, 0xff, 0xff, 0xfb, 0x7f, 0xff, 0xff, 0xff, 0xef, 0xfe, 0xff, 0xff, 0xfb, 0xff, + 0x7f, 0xff, //Water + 0x08, 0x10, 0x10, 0x08, 0x10, 0x08, 0x10, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x40, 0x40, 0x20, 0x00, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02, 0x21, + 0x40, 0x40, //Tree + 0xff, 0x1f, 0x5b, 0x3f, 0xeb, 0xdd, 0xff, 0xf7, 0xbb, 0xef, 0xfd, 0x7f, 0xe3, 0xcb, 0xe3, + 0xff, 0xff, 0xc7, 0x96, 0xc7, 0xff, 0xff, 0xef, 0xfd, 0xff, 0xe3, 0xcb, 0xe3, 0xff, 0xff, + 0x7b, 0xff, //Stone + 0xff, 0xdf, 0x7b, 0x3f, 0x9f, 0x6f, 0x77, 0xab, 0xdb, 0xd7, 0xcd, 0x5f, 0xbf, 0x77, 0xff, + 0xff, 0xff, 0xc1, 0xdc, 0xd3, 0xaf, 0x9f, 0xae, 0xb0, 0xbb, 0xbd, 0xbd, 0xba, 0xd7, 0xcc, + 0x63, 0xff, + ]; +); + +// dynamic ram variables +static mut gamestate: Gamestate = Gamestate::GameTitle; +static mut mapx: i16 = 0; +static mut mapy: i16 = 0; +// The setup() function runs once when you turn your Arduboy on +#[no_mangle] +pub unsafe extern "C" fn setup() { + // put your setup code here, to run once: + arduboy.begin(); + arduboy.set_frame_rate(45); + arduboy.display(); + arduboy.init_random_seed(); + arduboy.clear(); +} + +// The loop() function repeats forever after setup() is done +#[no_mangle] +#[export_name = "loop"] +pub unsafe extern "C" fn loop_() { + // put your main code here, to run repeatedly: + if !arduboy.next_frame() { + return; + } + arduboy.poll_buttons(); + arduboy.clear(); + gameloop(); + arduboy.display(); +} +unsafe fn draw_player() { + arduboy.fill_rect( + PLAYER_X_OFFSET, + PLAYER_Y_OFFSET, + PLAYER_SIZE as u8, + PLAYER_SIZE as u8, + Color::Black, + ) +} + +unsafe fn draw_world() { + let tileswide: u8 = WIDTH / TILE_SIZE + 1; + let tilestall: u8 = HEIGHT / TILE_SIZE + 1; + for y in 0..tilestall as i16 { + for x in 0..tileswide as i16 { + let tilesx: i16 = x - mapx / TILE_SIZE as i16; + let tilesy: i16 = y - mapy / TILE_SIZE as i16; + if tilesx >= 0 + && tilesy >= 0 + && tilesx < WORLD_WIDTH as i16 + && tilesy < WORLD_HEIGHT as i16 + { + sprites::draw_override( + x * TILE_SIZE as i16 + mapx % TILE_SIZE as i16, + y * TILE_SIZE as i16 + mapy % TILE_SIZE as i16, + get_sprite_addr!(tiles), + world[tilesy as usize][tilesx as usize], + ) + } + } + } + arduboy.fill_rect(0, 0, 48, 8, Color::Black); + arduboy.set_cursor(0, 0); + arduboy.print(0 - mapx / TILE_SIZE as i16); + arduboy.print(f!(b",\0")); + arduboy.print(0 - mapy / TILE_SIZE as i16) +} +fn titlescreen() { + arduboy.set_cursor(0, 0); + arduboy.print(f!(b"Title Screen\n\0")); + if arduboy.just_pressed(A_BUTTON) { + unsafe { gamestate.update(Gamestate::GamePlay) } + } +} +unsafe fn player_input() { + if arduboy.pressed(UP) { + if mapy < PLAYER_Y_OFFSET { + mapy += 1 + } + } + if arduboy.pressed(DOWN) { + if PLAYER_Y_OFFSET + PLAYER_SIZE < mapy + TILE_SIZE as i16 * WORLD_HEIGHT as i16 { + mapy -= 1 + } + } + if arduboy.pressed(LEFT) { + if mapx < PLAYER_X_OFFSET { + mapx += 1 + } + } + if arduboy.pressed(RIGHT) { + if PLAYER_X_OFFSET + PLAYER_SIZE < mapx + TILE_SIZE as i16 * WORLD_WIDTH as i16 { + mapx -= 1 + } + } +} +unsafe fn gameplay() { + player_input(); + draw_world(); + draw_player(); + if arduboy.just_pressed(A_BUTTON) { + unsafe { gamestate.update(Gamestate::GameOver) } + } +} +fn gameover_screen() { + arduboy.set_cursor(0, 0); + arduboy.print(f!(b"Game Over Screen\n\0")); + if arduboy.just_pressed(A_BUTTON) { + unsafe { gamestate.update(Gamestate::GameHigh) } + } +} +fn highscore_screen() { + arduboy.set_cursor(0, 0); + arduboy.print(f!(b"High Score Screen\n\0")); + if arduboy.just_pressed(A_BUTTON) { + unsafe { gamestate.update(Gamestate::GameTitle) } + } +} + +unsafe fn gameloop() { + match unsafe { gamestate } { + Gamestate::GameTitle => titlescreen(), + Gamestate::GamePlay => gameplay(), + Gamestate::GameOver => gameover_screen(), + Gamestate::GameHigh => highscore_screen(), + } +} diff --git a/README.md b/README.md index a92b745..6d2668b 100644 --- a/README.md +++ b/README.md @@ -146,7 +146,8 @@ Windows: - [demo6] [Make Your Own Arduboy Game: Part 6 - Graphics!](https://community.arduboy.com/t/make-your-own-arduboy-game-part-6-graphics/7929) Link for the [ZennDev1337 Tile Converter](https://zenndev1337.github.io/Rust-for-Arduboy/tile-converter.html) - [demo7] [Make Your Own Arduboy Game: Part 7 - Make Pong From Scratch!](https://community.arduboy.com/t/make-your-own-arduboy-game-part-7-make-pong-from-scratch/7930) -- not done [demo8] [Make Your Own Arduboy Game: Part 8 - Starting DinoSmasher](https://community.arduboy.com/t/make-your-own-arduboy-game-part-8-starting-dinosmasher/7932) +- Prepare for demo9 [Make Your Own Arduboy Game: Part 8 - Starting DinoSmasher](https://community.arduboy.com/t/make-your-own-arduboy-game-part-8-starting-dinosmasher/7932) +- [demo9] [Make Your Own Arduboy Game: Part 9 - Mapping DinoSmasher](https://community.arduboy.com/t/make-your-own-arduboy-game-part-9-mapping-dinosmasher/7931) - [eeprom] [Help, I’m struggling with EEPROM!](https://community.arduboy.com/t/help-im-struggling-with-eeprom/7178) - [progmem] Usage of the big 28'000 Bytes flash memory for Bitmaps Sound sequeces and Text. - [tone] [ArduboyTonesTest](https://github.com/MLXXXp/ArduboyTones/blob/master/examples/ArduboyTonesTest/ArduboyTonesTest.ino) @@ -162,6 +163,7 @@ Linux: ./run demo5 ./run demo6 ./run demo7 +./run demo9 ./run eeprom ./run eeprom-byte ./run progmem diff --git a/run b/run index dc8a191..a1c2d54 100755 --- a/run +++ b/run @@ -5,6 +5,14 @@ option=$1 upload(){ cargo build -p $option --release && cp ./target/arduboy/release/lib$option.a ./arduboy-rust/Wrapper-Project/lib/libgame.a && cd arduboy-rust/Wrapper-Project/ && pio run -v -t upload && cp ./.pio/build/arduboy/firmware.hex ./build/$option.hex && pio run -t clean && rm lib/libgame.a && cd ../../ } +start(){ + if upload ; then + echo "all fine" + else + echo Usage: for uploading your game \|./run.sh + echo Usage: for uploading an example game \| ./run.sh \ + fi +} if [ -z "$option" ] then @@ -12,50 +20,11 @@ then elif [ "$option" = "doc" ] then cargo doc -p arduboy-rust && rm -r ./docs/doc/ && cp -r ./target/arduboy/doc ./docs/ -elif [ "$option" = "snake" ] -then - upload -elif [ "$option" = "drboy" ] -then - upload -elif [ "$option" = "ardvoice" ] -then - upload -elif [ "$option" = "rustacean" ] -then - upload -elif [ "$option" = "tone" ] -then - upload -elif [ "$option" = "eeprom" ] -then - upload elif [ "$option" = "eeprom-byte" ] then cargo build -p eeprom-byte --release && cp ./target/arduboy/release/libeeprom_byte.a ./arduboy-rust/Wrapper-Project/lib/libgame.a && cd arduboy-rust/Wrapper-Project/ && pio run -v -t upload && cp ./.pio/build/arduboy/firmware.hex ./build/eeprom-byte.hex && pio run -t clean && rm lib/libgame.a && cd ../../ -elif [ "$option" = "progmem" ] -then - upload -elif [ "$option" = "demo2" ] -then - upload -elif [ "$option" = "demo3" ] -then - upload -elif [ "$option" = "demo4" ] -then - upload -elif [ "$option" = "demo5" ] -then - upload -elif [ "$option" = "demo6" ] -then - upload -elif [ "$option" = "demo7" ] -then - upload else - upload + start # echo Usage: for uploading your game \|./run.sh # echo Usage: for uploading an example game \| ./run.sh \ fi diff --git a/run.bat b/run.bat index f80675b..62e2677 100644 --- a/run.bat +++ b/run.bat @@ -5,48 +5,21 @@ set option=%1 if [%option%]==[] ( powershell -Command "cargo build -p game --release; cp ./target/arduboy/release/libgame.a ./arduboy-rust/Wrapper-Project/lib/libgame.a; cd arduboy-rust/Wrapper-Project/; pio run -v -t upload; cp ./.pio/build/arduboy/firmware.hex ./build/game.hex; pio run -t clean; rm lib/libgame.a; cd ../../" goto :eof -) - -if %option%==snake ( - goto :run ) else if %option%==doc ( powershell -Command "cargo doc -p arduboy-rust; rm -r ./docs/doc/; cp -r ./target/arduboy/doc ./docs/" goto :eof -) else if %option%==pong ( - goto :run -) else if %option%==drboy ( - goto :run -) else if %option%==ardvoice ( - goto :run -) else if %option%==rustacean ( - goto :run -) else if %option%==tone ( - goto :run -) else if %option%==eeprom ( - goto :run ) else if %option%==eeprom-byte ( powershell -Command "cargo build -p %option% --release; cp ./target/arduboy/release/libeeprom_byte.a ./arduboy-rust/Wrapper-Project/lib/libgame.a; cd arduboy-rust/Wrapper-Project/; pio run -v -t upload; cp ./.pio/build/arduboy/firmware.hex ./build/%option%.hex; pio run -t clean; rm lib/libgame.a; cd ../../" -goto :eof -) else if %option%==progmem ( - goto :run -) else if %option%==demo2 ( - goto :run -) else if %option%==demo3 ( - goto :run -) else if %option%==demo4 ( - goto :run -) else if %option%==demo5 ( - goto :run -) else if %option%==demo6 ( - goto :run -) else if %option%==demo7 ( - goto :run + goto :eof ) else ( goto :run ) :run -powershell -Command "cargo build -p %option% --release; cp ./target/arduboy/release/lib%option%.a ./arduboy-rust/Wrapper-Project/lib/libgame.a; cd arduboy-rust/Wrapper-Project/; pio run -v -t upload; cp ./.pio/build/arduboy/firmware.hex ./build/%option%.hex; pio run -t clean; rm lib/libgame.a; cd ../../" +powershell -Command "$ErrorActionPreference='Stop'; cargo build -p %option% --release; cp ./target/arduboy/release/lib%option%.a ./arduboy-rust/Wrapper-Project/lib/libgame.a; cd arduboy-rust/Wrapper-Project/; pio run -v -t upload; cp ./.pio/build/arduboy/firmware.hex ./build/%option%.hex; pio run -t clean; rm lib/libgame.a; cd ../../" +if ERRORLEVEL 1 ( + goto :help +) goto :eof :help