Initial commit
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
/.idea
|
|
@ -0,0 +1,401 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "audir-sles"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea47348666a8edb7ad80cbee3940eb2bccf70df0e6ce09009abe1a836cb779f5"
|
||||
|
||||
[[package]]
|
||||
name = "audrey"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58b92a84e89497e3cd25d3672cd5d1c288abaac02c18ff21283f17d118b889b8"
|
||||
dependencies = [
|
||||
"dasp_frame",
|
||||
"dasp_sample",
|
||||
"hound",
|
||||
"lewton",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "blobcat-delivery"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"macroquad",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dasp_frame"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2a3937f5fe2135702897535c8d4a5553f8b116f76c1529088797f2eee7c5cd6"
|
||||
dependencies = [
|
||||
"dasp_sample",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dasp_sample"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f"
|
||||
|
||||
[[package]]
|
||||
name = "fdeflate"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10"
|
||||
dependencies = [
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fontdue"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0793f5137567643cf65ea42043a538804ff0fbf288649e2141442b602d81f9bc"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
"ttf-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glam"
|
||||
version = "0.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "518faa5064866338b013ff9b2350dc318e14cc4fcd6cb8206d7e7c9886c98815"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hound"
|
||||
version = "3.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d13cdbd5dbb29f9c88095bbdc2590c9cba0d0a1269b983fef6b2cdd7e9f4db1"
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.24.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"color_quant",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
"png",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lewton"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d542c1a317036c45c2aa1cf10cc9d403ca91eb2d333ef1a4917e5cb10628bd0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"ogg",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.142"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317"
|
||||
|
||||
[[package]]
|
||||
name = "macroquad"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3790f7fd2e4c480108cbfc86488f023b72e1e0bb6ffd5c6cba38049c7e2fbfc"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"fontdue",
|
||||
"glam",
|
||||
"image",
|
||||
"macroquad_macro",
|
||||
"miniquad",
|
||||
"quad-rand",
|
||||
"quad-snd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "macroquad_macro"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5cecfede1e530599c8686f7f2d609489101d3d63741a6dc423afc997ce3fcc8"
|
||||
|
||||
[[package]]
|
||||
name = "malloc_buf"
|
||||
version = "0.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "maybe-uninit"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
||||
|
||||
[[package]]
|
||||
name = "miniquad"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46381fe09fbf91bfa402a3e4fc26a104c9130562d51f89964c46adbc00591496"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"ndk-sys",
|
||||
"objc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndk-sys"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121"
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
|
||||
dependencies = [
|
||||
"malloc_buf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ogg"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13e571c3517af9e1729d4c63571a27edd660ade0667973bfc74a67c660c2b651"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.17.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aaeebc51f9e7d2c150d3f3bfeb667f2aa985db5ef1e3d212847bdedb488beeaa"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crc32fast",
|
||||
"fdeflate",
|
||||
"flate2",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quad-alsa-sys"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c66c2f04a6946293477973d85adc251d502da51c57b08cd9c997f0cfd8dcd4b5"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quad-rand"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "658fa1faf7a4cc5f057c9ee5ef560f717ad9d8dc66d975267f709624d6e1ab88"
|
||||
|
||||
[[package]]
|
||||
name = "quad-snd"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53c954bb70493a2872775b74b663a767686e6d96d242e789d6a92cc4ebd2a64e"
|
||||
dependencies = [
|
||||
"audir-sles",
|
||||
"audrey",
|
||||
"libc",
|
||||
"quad-alsa-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "0.6.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0"
|
||||
dependencies = [
|
||||
"maybe-uninit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ttf-parser"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
@ -0,0 +1,7 @@
|
|||
[package]
|
||||
name = "blobcat-delivery"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
macroquad = "0.3"
|
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 788 B |
After Width: | Height: | Size: 744 B |
After Width: | Height: | Size: 584 B |
After Width: | Height: | Size: 840 B |
After Width: | Height: | Size: 804 B |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 753 B |
|
@ -0,0 +1,171 @@
|
|||
use macroquad::audio::{load_sound_from_bytes, set_sound_volume, Sound};
|
||||
use macroquad::color::Color;
|
||||
use macroquad::miniquad::FilterMode;
|
||||
use macroquad::prelude::{Image, ImageFormat};
|
||||
use macroquad::text::{
|
||||
camera_font_scale, draw_text_ex, load_ttf_font_from_bytes, Font, TextParams,
|
||||
};
|
||||
use macroquad::texture::Texture2D;
|
||||
|
||||
pub struct Assets {
|
||||
pub blobcat_texture: Texture2D,
|
||||
pub cloud_texture: Texture2D,
|
||||
pub sun_texture: Texture2D,
|
||||
pub grass_top_texture: Texture2D,
|
||||
pub grass_bottom_texture: Texture2D,
|
||||
pub road_texture: Texture2D,
|
||||
pub house_texture: Texture2D,
|
||||
pub bike_texture: Texture2D,
|
||||
pub projectiles_texture: Texture2D,
|
||||
pub particles_texture: Texture2D,
|
||||
pub menu_texture: Texture2D,
|
||||
pub controls_texture: Texture2D,
|
||||
pub miss_sound: Sound,
|
||||
pub shoot_sound: Sound,
|
||||
pub hit_sound: Sound,
|
||||
pub lose_life_sound: Sound,
|
||||
pub font: Font,
|
||||
}
|
||||
|
||||
impl Assets {
|
||||
pub async fn load() -> Self {
|
||||
let blobcat_basic = Image::from_file_with_format(
|
||||
include_bytes!("../assets/blobcat_basic.png"),
|
||||
Some(ImageFormat::Png),
|
||||
);
|
||||
let blobcat_texture = Texture2D::from_image(&blobcat_basic);
|
||||
blobcat_texture.set_filter(FilterMode::Nearest);
|
||||
|
||||
let cloud = Image::from_file_with_format(
|
||||
include_bytes!("../assets/cloud1.png"),
|
||||
Some(ImageFormat::Png),
|
||||
);
|
||||
let cloud_texture = Texture2D::from_image(&cloud);
|
||||
cloud_texture.set_filter(FilterMode::Nearest);
|
||||
|
||||
let sun = Image::from_file_with_format(
|
||||
include_bytes!("../assets/sun.png"),
|
||||
Some(ImageFormat::Png),
|
||||
);
|
||||
let sun_texture = Texture2D::from_image(&sun);
|
||||
sun_texture.set_filter(FilterMode::Nearest);
|
||||
|
||||
let grass_top1 = Image::from_file_with_format(
|
||||
include_bytes!("../assets/grass_top.png"),
|
||||
Some(ImageFormat::Png),
|
||||
);
|
||||
let grass_top_texture = Texture2D::from_image(&grass_top1);
|
||||
grass_top_texture.set_filter(FilterMode::Nearest);
|
||||
|
||||
let grass_bottom1 = Image::from_file_with_format(
|
||||
include_bytes!("../assets/grass_bottom.png"),
|
||||
Some(ImageFormat::Png),
|
||||
);
|
||||
let grass_bottom_texture = Texture2D::from_image(&grass_bottom1);
|
||||
grass_bottom_texture.set_filter(FilterMode::Nearest);
|
||||
|
||||
let road = Image::from_file_with_format(
|
||||
include_bytes!("../assets/road.png"),
|
||||
Some(ImageFormat::Png),
|
||||
);
|
||||
let road_texture = Texture2D::from_image(&road);
|
||||
road_texture.set_filter(FilterMode::Nearest);
|
||||
|
||||
let house = Image::from_file_with_format(
|
||||
include_bytes!("../assets/house.png"),
|
||||
Some(ImageFormat::Png),
|
||||
);
|
||||
let house_texture = Texture2D::from_image(&house);
|
||||
house_texture.set_filter(FilterMode::Nearest);
|
||||
|
||||
let bike = Image::from_file_with_format(
|
||||
include_bytes!("../assets/bike.png"),
|
||||
Some(ImageFormat::Png),
|
||||
);
|
||||
let bike_texture = Texture2D::from_image(&bike);
|
||||
bike_texture.set_filter(FilterMode::Nearest);
|
||||
|
||||
let projectiles = Image::from_file_with_format(
|
||||
include_bytes!("../assets/projectiles.png"),
|
||||
Some(ImageFormat::Png),
|
||||
);
|
||||
let projectiles_texture = Texture2D::from_image(&projectiles);
|
||||
projectiles_texture.set_filter(FilterMode::Nearest);
|
||||
|
||||
let particles = Image::from_file_with_format(
|
||||
include_bytes!("../assets/particles.png"),
|
||||
Some(ImageFormat::Png),
|
||||
);
|
||||
let particles_texture = Texture2D::from_image(&particles);
|
||||
particles_texture.set_filter(FilterMode::Nearest);
|
||||
|
||||
let menu = Image::from_file_with_format(
|
||||
include_bytes!("../assets/logo.png"),
|
||||
Some(ImageFormat::Png),
|
||||
);
|
||||
let menu_texture = Texture2D::from_image(&menu);
|
||||
menu_texture.set_filter(FilterMode::Nearest);
|
||||
|
||||
let controls = Image::from_file_with_format(
|
||||
include_bytes!("../assets/controls.png"),
|
||||
Some(ImageFormat::Png),
|
||||
);
|
||||
let controls_texture = Texture2D::from_image(&controls);
|
||||
controls_texture.set_filter(FilterMode::Nearest);
|
||||
|
||||
let font = load_ttf_font_from_bytes(include_bytes!("../assets/plutostardust.ttf")).unwrap();
|
||||
|
||||
let miss_sound = load_sound_from_bytes(include_bytes!("../assets/miss.ogg"))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let shoot_sound = load_sound_from_bytes(include_bytes!("../assets/shoot.ogg"))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let hit_sound = load_sound_from_bytes(include_bytes!("../assets/hit.ogg"))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let lose_life_sound = load_sound_from_bytes(include_bytes!("../assets/lose-life.ogg"))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
Self {
|
||||
blobcat_texture,
|
||||
cloud_texture,
|
||||
sun_texture,
|
||||
grass_top_texture,
|
||||
grass_bottom_texture,
|
||||
road_texture,
|
||||
house_texture,
|
||||
bike_texture,
|
||||
projectiles_texture,
|
||||
particles_texture,
|
||||
menu_texture,
|
||||
controls_texture,
|
||||
miss_sound,
|
||||
shoot_sound,
|
||||
hit_sound,
|
||||
lose_life_sound,
|
||||
font,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw_string(text: &str, x: f32, y: f32, color: Color, font: Font) {
|
||||
let (f_size, f_scale, f_aspect) = camera_font_scale(8.0);
|
||||
draw_text_ex(
|
||||
text,
|
||||
x,
|
||||
y,
|
||||
TextParams {
|
||||
font_scale: f_scale,
|
||||
font_size: f_size,
|
||||
font_scale_aspect: f_aspect,
|
||||
font,
|
||||
color,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
pub const SCREEN_WIDTH: f32 = 320.0;
|
||||
pub const SCREEN_HEIGHT: f32 = 180.0;
|
||||
|
||||
pub const SCREEN_ASPECT: f32 = SCREEN_WIDTH / SCREEN_HEIGHT;
|
|
@ -0,0 +1,70 @@
|
|||
pub mod assets;
|
||||
pub mod config;
|
||||
pub mod game;
|
||||
mod menu;
|
||||
pub mod particle;
|
||||
pub mod sky;
|
||||
|
||||
use crate::assets::Assets;
|
||||
use crate::config::{SCREEN_ASPECT, SCREEN_HEIGHT, SCREEN_WIDTH};
|
||||
use crate::game::{GameState, GameWorld};
|
||||
use crate::menu::GameMenu;
|
||||
use macroquad::audio::AudioContext;
|
||||
use macroquad::prelude::*;
|
||||
|
||||
fn window_conf() -> Conf {
|
||||
Conf {
|
||||
window_title: "Blobcat Delivery".parse().unwrap(),
|
||||
window_width: 1280,
|
||||
window_height: 720,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[macroquad::main(window_conf)]
|
||||
async fn main() {
|
||||
let _audio = AudioContext::new();
|
||||
let assets = Assets::load().await;
|
||||
|
||||
let mut game_state = GameState::Menu(GameMenu::default());
|
||||
|
||||
loop {
|
||||
let sw = screen_width();
|
||||
let sh = screen_height();
|
||||
let rr = sw / sh;
|
||||
let rw = if rr > SCREEN_ASPECT {
|
||||
SCREEN_ASPECT / rr
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
let rh = if rr > SCREEN_ASPECT {
|
||||
1.0
|
||||
} else {
|
||||
rr / SCREEN_ASPECT
|
||||
};
|
||||
|
||||
set_camera(&Camera2D {
|
||||
zoom: vec2(
|
||||
1.0 / SCREEN_WIDTH * 2.0 * rw,
|
||||
1.0 / -SCREEN_HEIGHT * 2.0 * rh,
|
||||
),
|
||||
target: vec2(SCREEN_WIDTH / 2.0, SCREEN_HEIGHT / 2.0),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
match &mut game_state {
|
||||
GameState::Game(game) => {
|
||||
clear_background(SKYBLUE);
|
||||
game.frame(&assets).await;
|
||||
}
|
||||
GameState::Menu(menu) => {
|
||||
clear_background(DARKBLUE);
|
||||
if menu.frame(&assets).await {
|
||||
game_state = GameState::Game(GameWorld::default());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
next_frame().await
|
||||
}
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
use crate::assets::{draw_string, Assets};
|
||||
use crate::config::{SCREEN_HEIGHT, SCREEN_WIDTH};
|
||||
use crate::sky::Sky;
|
||||
use macroquad::color;
|
||||
use macroquad::input::{is_key_pressed, KeyCode};
|
||||
use macroquad::math::{vec2, Rect, Vec2};
|
||||
use macroquad::prelude::draw_texture_ex;
|
||||
use macroquad::texture::{draw_texture, DrawTextureParams};
|
||||
use macroquad::time::get_frame_time;
|
||||
|
||||
struct BlobCat {
|
||||
pos: Vec2,
|
||||
velocity: Vec2,
|
||||
rot: f32,
|
||||
}
|
||||
|
||||
impl Default for BlobCat {
|
||||
fn default() -> Self {
|
||||
BlobCat {
|
||||
pos: vec2(25.0, 100.0),
|
||||
velocity: vec2(25.0, 25.0),
|
||||
rot: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BlobCat {
|
||||
fn render(&mut self, assets: &Assets) {
|
||||
if self.pos.x < 0.0 {
|
||||
self.velocity.x = self.velocity.x.abs();
|
||||
}
|
||||
|
||||
if self.pos.x > SCREEN_WIDTH - 32.0 {
|
||||
self.velocity.x = -self.velocity.x.abs();
|
||||
}
|
||||
|
||||
if self.pos.y < 0.0 {
|
||||
self.velocity.y = self.velocity.y.abs();
|
||||
}
|
||||
|
||||
if self.pos.y > SCREEN_HEIGHT - 32.0 {
|
||||
self.velocity.y = -self.velocity.y.abs();
|
||||
}
|
||||
|
||||
let dt = get_frame_time();
|
||||
self.pos += self.velocity * dt;
|
||||
self.rot += dt;
|
||||
|
||||
draw_texture_ex(
|
||||
assets.blobcat_texture,
|
||||
self.pos.x,
|
||||
self.pos.y,
|
||||
color::WHITE,
|
||||
DrawTextureParams {
|
||||
rotation: self.rot,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct GameMenu {
|
||||
sky: Sky,
|
||||
blobcat: BlobCat,
|
||||
}
|
||||
|
||||
impl GameMenu {
|
||||
pub async fn frame(&mut self, assets: &Assets) -> bool {
|
||||
self.sky.render(assets);
|
||||
|
||||
self.blobcat.render(assets);
|
||||
|
||||
draw_texture(
|
||||
assets.menu_texture,
|
||||
SCREEN_WIDTH / 2.0 - 64.0,
|
||||
SCREEN_HEIGHT / 2.0 - 95.0,
|
||||
color::BLACK,
|
||||
);
|
||||
draw_texture(
|
||||
assets.menu_texture,
|
||||
SCREEN_WIDTH / 2.0 - 64.0,
|
||||
SCREEN_HEIGHT / 2.0 - 96.0,
|
||||
color::WHITE,
|
||||
);
|
||||
|
||||
draw_texture_ex(
|
||||
assets.controls_texture,
|
||||
SCREEN_WIDTH / 2.0 - 96.0,
|
||||
SCREEN_HEIGHT / 2.0 - 5.0,
|
||||
color::WHITE,
|
||||
DrawTextureParams {
|
||||
source: Some(Rect::new(0.0, 0.0, 106.0, 32.0)),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
let move_text = "Movement";
|
||||
let move_x = SCREEN_WIDTH / 2.0 - 60.0;
|
||||
let move_y = SCREEN_HEIGHT / 2.0 + 38.0;
|
||||
draw_string(move_text, move_x, move_y + 0.4, color::BLACK, assets.font);
|
||||
draw_string(move_text, move_x, move_y, color::WHITE, assets.font);
|
||||
|
||||
draw_texture_ex(
|
||||
assets.controls_texture,
|
||||
SCREEN_WIDTH / 2.0 + 24.0,
|
||||
SCREEN_HEIGHT / 2.0 + 13.0,
|
||||
color::WHITE,
|
||||
DrawTextureParams {
|
||||
source: Some(Rect::new(0.0, 32.0, 48.0, 16.0)),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
let shoot_text = "Shoot";
|
||||
let shoot_x = SCREEN_WIDTH / 2.0 + 35.0;
|
||||
let shoot_y = SCREEN_HEIGHT / 2.0 + 38.0;
|
||||
draw_string(
|
||||
shoot_text,
|
||||
shoot_x,
|
||||
shoot_y + 0.4,
|
||||
color::BLACK,
|
||||
assets.font,
|
||||
);
|
||||
draw_string(shoot_text, shoot_x, shoot_y, color::WHITE, assets.font);
|
||||
|
||||
let play_text = "Press [Space] to play...";
|
||||
let play_x = SCREEN_WIDTH / 2.0 - 40.0;
|
||||
let play_y = SCREEN_HEIGHT / 2.0 + 60.0;
|
||||
draw_string(play_text, play_x, play_y + 0.4, color::BLACK, assets.font);
|
||||
draw_string(play_text, play_x, play_y, color::WHITE, assets.font);
|
||||
|
||||
is_key_pressed(KeyCode::Space)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,363 @@
|
|||
use crate::assets::Assets;
|
||||
use macroquad::color;
|
||||
use macroquad::color::Color;
|
||||
use macroquad::logging::debug;
|
||||
use macroquad::math::{vec2, Rect, Vec2};
|
||||
use macroquad::prelude::DrawTextureParams;
|
||||
use macroquad::rand::RandomRange;
|
||||
use macroquad::texture::draw_texture_ex;
|
||||
use std::ops::Range;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ParticleWorld<'a> {
|
||||
particles: Vec<Particle<'a>>,
|
||||
}
|
||||
|
||||
impl ParticleWorld<'_> {
|
||||
pub fn spawn<C>(
|
||||
&mut self,
|
||||
config: C,
|
||||
controller: &'_ (impl ParticleController + ParticleSpawner<Config = C>),
|
||||
) {
|
||||
controller.spawn(config, |c| self.particles.push(c));
|
||||
}
|
||||
|
||||
pub fn render(&mut self, dt: f32, assets: &Assets) {
|
||||
self.particles.retain_mut(|particle| {
|
||||
!matches!(
|
||||
particle.controller.render(dt, particle, assets),
|
||||
ParticleLifetime::Destroy
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum ParticleType {
|
||||
Spark,
|
||||
Heart,
|
||||
Explosion,
|
||||
Score100,
|
||||
Score200,
|
||||
Fail,
|
||||
}
|
||||
|
||||
const SPARK_FRAMES: &[Rect] = &[
|
||||
Rect {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
w: 8.0,
|
||||
h: 8.0,
|
||||
},
|
||||
Rect {
|
||||
x: 8.0,
|
||||
y: 0.0,
|
||||
w: 8.0,
|
||||
h: 8.0,
|
||||
},
|
||||
Rect {
|
||||
x: 16.0,
|
||||
y: 0.0,
|
||||
w: 8.0,
|
||||
h: 8.0,
|
||||
},
|
||||
Rect {
|
||||
x: 24.0,
|
||||
y: 0.0,
|
||||
w: 8.0,
|
||||
h: 8.0,
|
||||
},
|
||||
];
|
||||
|
||||
const HEART_FRAMES: &[Rect] = &[
|
||||
Rect {
|
||||
x: 0.0,
|
||||
y: 8.0,
|
||||
w: 8.0,
|
||||
h: 8.0,
|
||||
},
|
||||
Rect {
|
||||
x: 8.0,
|
||||
y: 8.0,
|
||||
w: 8.0,
|
||||
h: 8.0,
|
||||
},
|
||||
Rect {
|
||||
x: 16.0,
|
||||
y: 8.0,
|
||||
w: 8.0,
|
||||
h: 8.0,
|
||||
},
|
||||
Rect {
|
||||
x: 24.0,
|
||||
y: 8.0,
|
||||
w: 8.0,
|
||||
h: 8.0,
|
||||
},
|
||||
];
|
||||
|
||||
const EXPLOSION_FRAMES: &[Rect] = &[
|
||||
Rect {
|
||||
x: 0.0,
|
||||
y: 16.0,
|
||||
w: 8.0,
|
||||
h: 8.0,
|
||||
},
|
||||
Rect {
|
||||
x: 8.0,
|
||||
y: 16.0,
|
||||
w: 8.0,
|
||||
h: 8.0,
|
||||
},
|
||||
Rect {
|
||||
x: 16.0,
|
||||
y: 16.0,
|
||||
w: 8.0,
|
||||
h: 8.0,
|
||||
},
|
||||
Rect {
|
||||
x: 24.0,
|
||||
y: 16.0,
|
||||
w: 8.0,
|
||||
h: 8.0,
|
||||
},
|
||||
];
|
||||
|
||||
const SCORE100_FRAMES: &[Rect] = &[Rect {
|
||||
x: 1.0,
|
||||
y: 25.0,
|
||||
w: 27.0,
|
||||
h: 15.0,
|
||||
}];
|
||||
|
||||
const SCORE200_FRAMES: &[Rect] = &[Rect {
|
||||
x: 33.0,
|
||||
y: 25.0,
|
||||
w: 27.0,
|
||||
h: 15.0,
|
||||
}];
|
||||
|
||||
const FAIL_FRAMES: &[Rect] = &[Rect {
|
||||
x: 32.0,
|
||||
y: 9.0,
|
||||
w: 14.0,
|
||||
h: 14.0,
|
||||
}];
|
||||
|
||||
impl ParticleType {
|
||||
fn frames(&self) -> &[Rect] {
|
||||
match *self {
|
||||
ParticleType::Spark => SPARK_FRAMES,
|
||||
ParticleType::Heart => HEART_FRAMES,
|
||||
ParticleType::Explosion => EXPLOSION_FRAMES,
|
||||
ParticleType::Score100 => SCORE100_FRAMES,
|
||||
ParticleType::Score200 => SCORE200_FRAMES,
|
||||
ParticleType::Fail => FAIL_FRAMES,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Default)]
|
||||
pub enum AnimationMode {
|
||||
#[default]
|
||||
TieToLifetime,
|
||||
Repeat(f32),
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ParticleState {
|
||||
pos: Vec2,
|
||||
velocity: Vec2,
|
||||
accel: Vec2,
|
||||
rot: f32,
|
||||
rot_velocity: f32,
|
||||
lifetime: f32,
|
||||
max_lifetime: f32,
|
||||
color: Color,
|
||||
animation_mode: AnimationMode,
|
||||
scale: f32,
|
||||
fade_start: f32,
|
||||
}
|
||||
|
||||
pub struct Particle<'a> {
|
||||
particle_type: ParticleType,
|
||||
state: ParticleState,
|
||||
controller: &'a dyn ParticleController,
|
||||
}
|
||||
|
||||
pub enum ParticleLifetime {
|
||||
Keep,
|
||||
Destroy,
|
||||
}
|
||||
|
||||
pub trait ParticleSpawner {
|
||||
type Config;
|
||||
|
||||
fn spawn<'a>(&'a self, config: Self::Config, consumer: impl FnMut(Particle<'a>));
|
||||
}
|
||||
|
||||
pub trait ParticleController {
|
||||
fn render(&self, dt: f32, particle: &mut Particle<'_>, assets: &Assets) -> ParticleLifetime;
|
||||
}
|
||||
|
||||
// Implementations!
|
||||
|
||||
fn tick(state: &mut ParticleState, dt: f32) {
|
||||
state.lifetime += dt;
|
||||
state.velocity += state.accel * dt;
|
||||
state.pos += state.velocity * dt;
|
||||
state.rot += state.rot_velocity * dt;
|
||||
state.color.a = ((state.fade_start - state.lifetime) / (state.max_lifetime - state.fade_start))
|
||||
.max(0.0)
|
||||
.min(1.0)
|
||||
}
|
||||
|
||||
fn render_quad(particle_type: ParticleType, state: &ParticleState, assets: &Assets) {
|
||||
let sprite_rect = particle_type.frames();
|
||||
|
||||
let frame = match state.animation_mode {
|
||||
AnimationMode::TieToLifetime if state.max_lifetime <= 0.0 => sprite_rect[0],
|
||||
AnimationMode::TieToLifetime => {
|
||||
sprite_rect[((state.lifetime / state.max_lifetime) * sprite_rect.len() as f32).floor()
|
||||
as usize
|
||||
% sprite_rect.len()]
|
||||
}
|
||||
AnimationMode::Repeat(loop_len) => {
|
||||
sprite_rect[((state.lifetime / loop_len % 1.0) * sprite_rect.len() as f32).floor()
|
||||
as usize
|
||||
% sprite_rect.len()]
|
||||
}
|
||||
};
|
||||
|
||||
draw_texture_ex(
|
||||
assets.particles_texture,
|
||||
state.pos.x,
|
||||
state.pos.y,
|
||||
state.color,
|
||||
DrawTextureParams {
|
||||
dest_size: Some(frame.size() * state.scale),
|
||||
rotation: state.rot,
|
||||
source: Some(frame),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Ring
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ConfigRingBasic {
|
||||
pub particle_type: ParticleType,
|
||||
pub pos: Vec2,
|
||||
pub lifetime: f32,
|
||||
pub count: usize,
|
||||
pub radius: Range<f32>,
|
||||
pub velocity: f32,
|
||||
pub scale: f32,
|
||||
pub color: Color,
|
||||
pub fade_start: f32,
|
||||
pub angle_cone: Option<Range<f32>>,
|
||||
}
|
||||
|
||||
pub struct ParticleControllerRing;
|
||||
|
||||
impl ParticleSpawner for ParticleControllerRing {
|
||||
type Config = ConfigRingBasic;
|
||||
|
||||
fn spawn<'a>(&'a self, config: Self::Config, mut consumer: impl FnMut(Particle<'a>)) {
|
||||
for _ in 0..config.count {
|
||||
let angle = if let Some(ref cone) = config.angle_cone {
|
||||
f32::gen_range(cone.start, cone.end)
|
||||
} else {
|
||||
f32::gen_range(0.0, 2.0 * std::f32::consts::PI)
|
||||
};
|
||||
let r = f32::gen_range(config.radius.start, config.radius.end);
|
||||
|
||||
let cos_t = angle.cos();
|
||||
let sin_t = -angle.sin();
|
||||
|
||||
let x = config.pos.x + cos_t * r;
|
||||
let y = config.pos.y + sin_t * r;
|
||||
|
||||
let vel = vec2(cos_t, sin_t) * config.velocity;
|
||||
|
||||
consumer(Particle {
|
||||
particle_type: config.particle_type,
|
||||
state: ParticleState {
|
||||
pos: vec2(x, y),
|
||||
velocity: vel,
|
||||
rot: f32::gen_range(0.0, 2.0 * std::f32::consts::PI),
|
||||
color: config.color,
|
||||
max_lifetime: config.lifetime,
|
||||
scale: config.scale,
|
||||
fade_start: config.fade_start,
|
||||
..Default::default()
|
||||
},
|
||||
controller: self,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ParticleController for ParticleControllerRing {
|
||||
fn render(&self, dt: f32, particle: &mut Particle<'_>, assets: &Assets) -> ParticleLifetime {
|
||||
tick(&mut particle.state, dt);
|
||||
|
||||
if particle.state.lifetime > particle.state.max_lifetime {
|
||||
ParticleLifetime::Destroy
|
||||
} else {
|
||||
render_quad(particle.particle_type, &particle.state, assets);
|
||||
ParticleLifetime::Keep
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PopUp
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ConfigPopUpBasic {
|
||||
pub particle_type: ParticleType,
|
||||
pub pos: Vec2,
|
||||
pub lifetime: f32,
|
||||
pub velocity: Vec2,
|
||||
pub scale: f32,
|
||||
pub color: Color,
|
||||
pub fade_start: f32,
|
||||
pub accel: Vec2,
|
||||
}
|
||||
|
||||
pub struct ParticleControllerPopUp;
|
||||
|
||||
impl ParticleSpawner for ParticleControllerPopUp {
|
||||
type Config = ConfigPopUpBasic;
|
||||
|
||||
fn spawn<'a>(&'a self, config: Self::Config, mut consumer: impl FnMut(Particle<'a>)) {
|
||||
consumer(Particle {
|
||||
particle_type: config.particle_type,
|
||||
state: ParticleState {
|
||||
pos: config.pos,
|
||||
velocity: config.velocity,
|
||||
color: config.color,
|
||||
max_lifetime: config.lifetime,
|
||||
scale: config.scale,
|
||||
fade_start: config.fade_start,
|
||||
accel: config.accel,
|
||||
..Default::default()
|
||||
},
|
||||
controller: self,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl ParticleController for ParticleControllerPopUp {
|
||||
fn render(&self, dt: f32, particle: &mut Particle<'_>, assets: &Assets) -> ParticleLifetime {
|
||||
tick(&mut particle.state, dt);
|
||||
|
||||
if particle.state.lifetime > particle.state.max_lifetime {
|
||||
ParticleLifetime::Destroy
|
||||
} else {
|
||||
render_quad(particle.particle_type, &particle.state, assets);
|
||||
ParticleLifetime::Keep
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
use crate::assets::Assets;
|
||||
use crate::config::{SCREEN_HEIGHT, SCREEN_WIDTH};
|
||||
use macroquad::color;
|
||||
use macroquad::color::Color;
|
||||
use macroquad::math::Vec2;
|
||||
use macroquad::prelude::{draw_texture, draw_texture_ex, get_frame_time, DrawTextureParams};
|
||||
use macroquad::rand::RandomRange;
|
||||
|
||||
pub struct Sky {
|
||||
sun: Sun,
|
||||
clouds: Vec<Cloud>,
|
||||
}
|
||||
|
||||
impl Default for Sky {
|
||||
fn default() -> Self {
|
||||
let sun = Sun {
|
||||
rot: -core::f32::consts::FRAC_PI_6,
|
||||
pos: Vec2::new(25.0, 25.0),
|
||||
};
|
||||
|
||||
let mut clouds = Vec::new();
|
||||
const CLOUD_CNT: usize = 20;
|
||||
|
||||
for i in 0..CLOUD_CNT {
|
||||
let pos_x = f32::gen_range(0.0, SCREEN_WIDTH);
|
||||
let pos_y = f32::gen_range(0.0, 16384.0);
|
||||
let speed = f32::gen_range(5.0, 15.0);
|
||||
clouds.push(Cloud {
|
||||
pos: Vec2::new(pos_x, pos_y),
|
||||
speed,
|
||||
shade: 0.75 + 0.25 * i as f32 / CLOUD_CNT as f32,
|
||||
})
|
||||
}
|
||||
|
||||
Self { sun, clouds }
|
||||
}
|
||||
}
|
||||
|
||||
impl Sky {
|
||||
pub fn render(&mut self, assets: &Assets) {
|
||||
self.sun.draw(assets);
|
||||
|
||||
self.clouds.iter_mut().for_each(|cloud| cloud.draw(assets));
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Sun {
|
||||
pub pos: Vec2,
|
||||
pub rot: f32,
|
||||
}
|
||||
|
||||
impl Sun {
|
||||
pub fn draw(&self, assets: &Assets) {
|
||||
draw_texture_ex(
|
||||
assets.sun_texture,
|
||||
self.pos.x,
|
||||
self.pos.y,
|
||||
color::WHITE,
|
||||
DrawTextureParams {
|
||||
rotation: self.rot,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Cloud {
|
||||
pos: Vec2,
|
||||
speed: f32,
|
||||
shade: f32,
|
||||
}
|
||||
|
||||
impl Cloud {
|
||||
pub fn draw(&mut self, assets: &Assets) {
|
||||
self.pos.x -= self.speed * get_frame_time();
|
||||
|
||||
let w = assets.cloud_texture.width();
|
||||
let h = assets.cloud_texture.height();
|
||||
|
||||
draw_texture(
|
||||
assets.cloud_texture,
|
||||
self.pos.x.rem_euclid(SCREEN_WIDTH + w * 4.0) - w * 2.0,
|
||||
self.pos.y.rem_euclid(SCREEN_HEIGHT / 3.0 - h),
|
||||
Color::new(self.shade, self.shade, 1.0, 1.0),
|
||||
);
|
||||
}
|
||||
}
|