Added basic working code
parent
bd138d3db3
commit
f5f52e7e75
|
@ -0,0 +1,404 @@
|
||||||
|
# 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 = "autocfg"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bit_field"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytemuck"
|
||||||
|
version = "1.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[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 = "crossbeam-deque"
|
||||||
|
version = "0.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-epoch",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.9.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"memoffset",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-utils"
|
||||||
|
version = "0.8.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crunchy"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "exr"
|
||||||
|
version = "1.71.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "832a761f35ab3e6664babfbdc6cef35a4860e816ec3916dcfd0882954e98a8a8"
|
||||||
|
dependencies = [
|
||||||
|
"bit_field",
|
||||||
|
"flume",
|
||||||
|
"half",
|
||||||
|
"lebe",
|
||||||
|
"miniz_oxide",
|
||||||
|
"rayon-core",
|
||||||
|
"smallvec",
|
||||||
|
"zune-inflate",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fdeflate"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "64d6dafc854908ff5da46ff3f8f473c6984119a2876a383a860246dd7841a868"
|
||||||
|
dependencies = [
|
||||||
|
"simd-adler32",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flate2"
|
||||||
|
version = "1.0.28"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e"
|
||||||
|
dependencies = [
|
||||||
|
"crc32fast",
|
||||||
|
"miniz_oxide",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flume"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
|
||||||
|
dependencies = [
|
||||||
|
"spin",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "game"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"image",
|
||||||
|
"sdl2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gif"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045"
|
||||||
|
dependencies = [
|
||||||
|
"color_quant",
|
||||||
|
"weezl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "half"
|
||||||
|
version = "2.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0"
|
||||||
|
dependencies = [
|
||||||
|
"crunchy",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "image"
|
||||||
|
version = "0.24.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
"byteorder",
|
||||||
|
"color_quant",
|
||||||
|
"exr",
|
||||||
|
"gif",
|
||||||
|
"jpeg-decoder",
|
||||||
|
"num-rational",
|
||||||
|
"num-traits",
|
||||||
|
"png",
|
||||||
|
"qoi",
|
||||||
|
"tiff",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jpeg-decoder"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e"
|
||||||
|
dependencies = [
|
||||||
|
"rayon",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lebe"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.151"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.4.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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 = "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.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "png"
|
||||||
|
version = "0.17.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"crc32fast",
|
||||||
|
"fdeflate",
|
||||||
|
"flate2",
|
||||||
|
"miniz_oxide",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "qoi"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"rayon-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sdl2"
|
||||||
|
version = "0.36.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8356b2697d1ead5a34f40bcc3c5d3620205fe0c7be0a14656223bfeec0258891"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
|
"sdl2-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sdl2-sys"
|
||||||
|
version = "0.36.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "26bcacfdd45d539fb5785049feb0038a63931aa896c7763a2a12e125ec58bd29"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"version-compare",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "simd-adler32"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.11.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.9.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tiff"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6d172b0f4d3fba17ba89811858b9d3d97f928aece846475bbda076ca46736211"
|
||||||
|
dependencies = [
|
||||||
|
"flate2",
|
||||||
|
"jpeg-decoder",
|
||||||
|
"weezl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version-compare"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "weezl"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zune-inflate"
|
||||||
|
version = "0.2.54"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
|
||||||
|
dependencies = [
|
||||||
|
"simd-adler32",
|
||||||
|
]
|
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "game"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
image = "0.24.7"
|
||||||
|
|
||||||
|
[dependencies.sdl2]
|
||||||
|
version = "0.36"
|
||||||
|
default-features = false
|
||||||
|
#features = ["ttf"]
|
|
@ -0,0 +1,74 @@
|
||||||
|
use sdl2::rect::{Point, Rect};
|
||||||
|
use sdl2::render::Canvas;
|
||||||
|
use sdl2::video::Window;
|
||||||
|
|
||||||
|
use crate::physics::PhysVec;
|
||||||
|
use crate::Camera;
|
||||||
|
use crate::Drawable;
|
||||||
|
use crate::SpriteAtlas;
|
||||||
|
|
||||||
|
pub struct Doodad {
|
||||||
|
sprite: String,
|
||||||
|
pos: PhysVec,
|
||||||
|
scale: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Doodad {
|
||||||
|
pub fn new(pos: PhysVec) -> Self {
|
||||||
|
Doodad {
|
||||||
|
sprite: "a0.png".to_owned(),
|
||||||
|
pos,
|
||||||
|
scale: 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drawable for Doodad {
|
||||||
|
fn position(&self) -> PhysVec {
|
||||||
|
self.pos
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(
|
||||||
|
&self,
|
||||||
|
canvas: &mut Canvas<Window>,
|
||||||
|
sa: &SpriteAtlas,
|
||||||
|
c: &Camera,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
let win_size = PhysVec::from(canvas.window().size());
|
||||||
|
let draw_pos = self.screen_position(canvas, &c);
|
||||||
|
|
||||||
|
// Don't draw if off screen
|
||||||
|
if draw_pos.x < 0.0
|
||||||
|
|| draw_pos.x > win_size.x
|
||||||
|
|| draw_pos.y < 0.0
|
||||||
|
|| draw_pos.y > win_size.y
|
||||||
|
{
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let sprite = sa.get(&self.sprite);
|
||||||
|
|
||||||
|
let mut dest_rect_0 = Rect::new(0, 0, 112 / self.scale, 112 / self.scale);
|
||||||
|
dest_rect_0.center_on(Point::new(
|
||||||
|
112 / (2 * self.scale) as i32,
|
||||||
|
112 / (2 * self.scale) as i32,
|
||||||
|
));
|
||||||
|
|
||||||
|
// set the current frame for time
|
||||||
|
dest_rect_0.set_x(draw_pos.x.round() as i32);
|
||||||
|
dest_rect_0.set_y(draw_pos.y.round() as i32);
|
||||||
|
|
||||||
|
// copy the frame to the canvas
|
||||||
|
canvas.copy_ex(
|
||||||
|
&sprite.texture,
|
||||||
|
Some(sprite.rect),
|
||||||
|
Some(dest_rect_0),
|
||||||
|
0.0, // angle
|
||||||
|
Point::new(120 / (2 * self.scale) as i32, 270 / (2 * self.scale) as i32), // center
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
use sdl2::{event::Event, keyboard::Keycode};
|
||||||
|
|
||||||
|
// TODO: no boolean modification (no pub)
|
||||||
|
pub struct InputStatus {
|
||||||
|
pub key_left: bool,
|
||||||
|
pub key_right: bool,
|
||||||
|
pub key_thrust: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InputStatus {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
InputStatus {
|
||||||
|
key_left: false,
|
||||||
|
key_right: false,
|
||||||
|
key_thrust: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_keyup(&mut self, keycode: Keycode) {
|
||||||
|
match keycode {
|
||||||
|
Keycode::Left => self.key_left = false,
|
||||||
|
Keycode::Right => self.key_right = false,
|
||||||
|
Keycode::Up => self.key_thrust = false,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_keydown(&mut self, keycode: Keycode) {
|
||||||
|
match keycode {
|
||||||
|
Keycode::Left => self.key_left = true,
|
||||||
|
Keycode::Right => self.key_right = true,
|
||||||
|
Keycode::Up => self.key_thrust = true,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(&mut self, event: Event) {
|
||||||
|
match event {
|
||||||
|
Event::KeyDown {
|
||||||
|
keycode: Some(key), ..
|
||||||
|
} => self.handle_keydown(key),
|
||||||
|
Event::KeyUp {
|
||||||
|
keycode: Some(key), ..
|
||||||
|
} => self.handle_keyup(key),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,175 @@
|
||||||
|
use sdl2::{event::Event, keyboard::Keycode, render::Canvas, video::Window};
|
||||||
|
use std::{time::Duration, time::Instant};
|
||||||
|
|
||||||
|
mod doodad;
|
||||||
|
mod inputstatus;
|
||||||
|
mod physics;
|
||||||
|
mod ship;
|
||||||
|
mod spriteatlas;
|
||||||
|
|
||||||
|
use crate::doodad::Doodad;
|
||||||
|
use crate::inputstatus::InputStatus;
|
||||||
|
use crate::physics::PhysVec;
|
||||||
|
use crate::ship::Ship;
|
||||||
|
use crate::spriteatlas::SpriteAtlas;
|
||||||
|
|
||||||
|
trait Drawable {
|
||||||
|
/// Return the world position of this object
|
||||||
|
fn position(&self) -> PhysVec;
|
||||||
|
|
||||||
|
/// Get the position of this drawable on the screen
|
||||||
|
/// (0, 0) is at top-left corner.
|
||||||
|
///
|
||||||
|
/// Returned position is this object's center.
|
||||||
|
fn screen_position(&self, canvas: &mut Canvas<Window>, c: &Camera) -> PhysVec {
|
||||||
|
let win_size = PhysVec::from(canvas.window().size());
|
||||||
|
let h = win_size / 2.0;
|
||||||
|
return self.position() - c.pos + h;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw this item on the screen
|
||||||
|
fn draw(&self, canvas: &mut Canvas<Window>, sa: &SpriteAtlas, c: &Camera)
|
||||||
|
-> Result<(), String>;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ShipKind {
|
||||||
|
Gypsum,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ShipKind {
|
||||||
|
fn sprite(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::Gypsum => "gypsum.png",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Camera {
|
||||||
|
pos: PhysVec,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Camera {
|
||||||
|
fn new() -> Self {
|
||||||
|
Camera {
|
||||||
|
pos: PhysVec::zero(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static FTL: f64 = 1.0 / 140.0; // frame time limit
|
||||||
|
|
||||||
|
struct System {
|
||||||
|
decor: Vec<Box<dyn Drawable>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl System {
|
||||||
|
fn new() -> Self {
|
||||||
|
let mut s = System { decor: Vec::new() };
|
||||||
|
|
||||||
|
s.decor.push(Box::new(Doodad::new(PhysVec::zero())));
|
||||||
|
s.decor
|
||||||
|
.push(Box::new(Doodad::new(PhysVec { x: 100.0, y: 23.0 })));
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(
|
||||||
|
&self,
|
||||||
|
canvas: &mut Canvas<Window>,
|
||||||
|
sa: &SpriteAtlas,
|
||||||
|
c: &Camera,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
for d in &self.decor {
|
||||||
|
d.draw(canvas, sa, c)?
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<(), String> {
|
||||||
|
let sdl_context = sdl2::init()?;
|
||||||
|
let video_subsystem = sdl_context.video()?;
|
||||||
|
|
||||||
|
let window = video_subsystem
|
||||||
|
.window("SDL2", 640, 480)
|
||||||
|
.position_centered()
|
||||||
|
.resizable()
|
||||||
|
.build()
|
||||||
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
let mut canvas = window
|
||||||
|
.into_canvas()
|
||||||
|
.accelerated()
|
||||||
|
.build()
|
||||||
|
.map_err(|e| e.to_string())?;
|
||||||
|
let texture_creator = canvas.texture_creator();
|
||||||
|
|
||||||
|
let sa = SpriteAtlas::new(&texture_creator)?;
|
||||||
|
let mut event_pump = sdl_context.event_pump()?;
|
||||||
|
|
||||||
|
let system = System::new();
|
||||||
|
|
||||||
|
let mut i = InputStatus::new();
|
||||||
|
let mut c = Camera::new();
|
||||||
|
|
||||||
|
let mut s = Ship::new(ShipKind::Gypsum);
|
||||||
|
|
||||||
|
//let mut last_frame_time = 0f64;
|
||||||
|
let mut frame_start;
|
||||||
|
|
||||||
|
let mut running = true;
|
||||||
|
while running {
|
||||||
|
frame_start = Instant::now();
|
||||||
|
|
||||||
|
for event in event_pump.poll_iter() {
|
||||||
|
match event {
|
||||||
|
Event::Quit { .. }
|
||||||
|
| Event::KeyDown {
|
||||||
|
keycode: Some(Keycode::Escape),
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
_ => i.update(event),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.pos = s.body.pos;
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
canvas.clear();
|
||||||
|
system.draw(&mut canvas, &sa, &c)?;
|
||||||
|
s.draw(&mut canvas, &sa, &c)?;
|
||||||
|
canvas.present();
|
||||||
|
|
||||||
|
let frame_time = frame_start.elapsed().as_secs_f64();
|
||||||
|
|
||||||
|
// Wait
|
||||||
|
// (limit frame rate)
|
||||||
|
if frame_time < FTL {
|
||||||
|
std::thread::sleep(Duration::from_secs_f64(FTL - frame_time));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply input
|
||||||
|
|
||||||
|
let frame_time = frame_start.elapsed().as_secs_f64();
|
||||||
|
//last_frame_time = frame_time;
|
||||||
|
|
||||||
|
s.body.tick(frame_time);
|
||||||
|
|
||||||
|
if i.key_thrust {
|
||||||
|
s.body.thrust(50.0 * frame_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
if i.key_right {
|
||||||
|
s.body.rot(-1.0 * frame_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
if i.key_left {
|
||||||
|
s.body.rot(1.0 * frame_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
use sdl2::rect::{Point, Rect};
|
||||||
|
use sdl2::render::Canvas;
|
||||||
|
use sdl2::video::Window;
|
||||||
|
|
||||||
|
use crate::physics::PhysBody;
|
||||||
|
use crate::physics::PhysVec;
|
||||||
|
use crate::Camera;
|
||||||
|
use crate::Drawable;
|
||||||
|
use crate::ShipKind;
|
||||||
|
use crate::SpriteAtlas;
|
||||||
|
|
||||||
|
pub struct Ship {
|
||||||
|
pub body: PhysBody,
|
||||||
|
kind: ShipKind,
|
||||||
|
scale: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ship {
|
||||||
|
pub fn new(kind: ShipKind) -> Self {
|
||||||
|
Ship {
|
||||||
|
body: PhysBody::new(),
|
||||||
|
kind,
|
||||||
|
scale: 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drawable for Ship {
|
||||||
|
fn position(&self) -> PhysVec {
|
||||||
|
return self.body.pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(
|
||||||
|
&self,
|
||||||
|
canvas: &mut Canvas<Window>,
|
||||||
|
sa: &SpriteAtlas,
|
||||||
|
c: &Camera,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
let win_size = PhysVec::from(canvas.window().size());
|
||||||
|
let draw_pos = self.screen_position(canvas, &c);
|
||||||
|
// Don't draw if off screen
|
||||||
|
if draw_pos.x < 0.0
|
||||||
|
|| draw_pos.x > win_size.x
|
||||||
|
|| draw_pos.y < 0.0
|
||||||
|
|| draw_pos.y > win_size.y
|
||||||
|
{
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let sprite = sa.get(self.kind.sprite());
|
||||||
|
|
||||||
|
let mut dest_rect_0 = Rect::new(0, 0, 120 / self.scale, 270 / self.scale);
|
||||||
|
dest_rect_0.center_on(Point::new(
|
||||||
|
120 / (2 * self.scale) as i32,
|
||||||
|
270 / (2 * self.scale) as i32,
|
||||||
|
));
|
||||||
|
|
||||||
|
// set the current frame for time
|
||||||
|
dest_rect_0.set_x(draw_pos.x.round() as i32);
|
||||||
|
dest_rect_0.set_y(draw_pos.y.round() as i32);
|
||||||
|
|
||||||
|
// copy the frame to the canvas
|
||||||
|
canvas.copy_ex(
|
||||||
|
&sprite.texture,
|
||||||
|
Some(sprite.rect),
|
||||||
|
Some(dest_rect_0),
|
||||||
|
self.body.angle.to_degrees(), // angle
|
||||||
|
Point::new(120 / (2 * self.scale) as i32, 270 / (2 * self.scale) as i32), // center
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
use image::io::Reader as ImageReader;
|
||||||
|
use sdl2::{
|
||||||
|
rect::Rect,
|
||||||
|
render::{Texture, TextureCreator},
|
||||||
|
video::WindowContext,
|
||||||
|
};
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
/// A handle for a sprite inside a SpriteAtlas
|
||||||
|
pub struct Sprite<'a> {
|
||||||
|
pub texture: &'a Texture<'a>,
|
||||||
|
pub rect: Rect,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A cache of textures we use when drawing the screen.
|
||||||
|
///
|
||||||
|
/// This is implemented very carefully, since SDL2 textures have tricky lifetimes.
|
||||||
|
pub struct SpriteAtlas<'a> {
|
||||||
|
data: HashMap<String, (Texture<'a>, Rect)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> SpriteAtlas<'a> {
|
||||||
|
pub fn new(texture_creator: &'a TextureCreator<WindowContext>) -> Result<Self, String> {
|
||||||
|
let mut b = Self {
|
||||||
|
data: HashMap::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
b.load_one(texture_creator, "gypsum.png")?;
|
||||||
|
b.load_one(texture_creator, "a0.png")?;
|
||||||
|
|
||||||
|
return Ok(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&'a self, name: &str) -> Sprite<'a> {
|
||||||
|
let (texture, rect) = self.data.get(name).unwrap();
|
||||||
|
return Sprite {
|
||||||
|
texture,
|
||||||
|
rect: rect.clone(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_one(
|
||||||
|
&mut self,
|
||||||
|
texture_creator: &'a TextureCreator<WindowContext>,
|
||||||
|
s: &str,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
let im = ImageReader::open(format!("assets/{s}"))
|
||||||
|
.unwrap()
|
||||||
|
.decode()
|
||||||
|
.unwrap();
|
||||||
|
let width = im.width();
|
||||||
|
let height = im.height();
|
||||||
|
let mut im = im.as_bytes().to_vec();
|
||||||
|
|
||||||
|
let surface = sdl2::surface::Surface::from_data(
|
||||||
|
&mut im,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
width * 4,
|
||||||
|
sdl2::pixels::PixelFormatEnum::RGBA32,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let texture = texture_creator
|
||||||
|
.create_texture_from_surface(&surface)
|
||||||
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
self.data
|
||||||
|
.insert(s.to_owned(), (texture, Rect::new(0, 0, width, height)));
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue