Room Creating: Place Kitchen Furniture (#11)
Some checks failed
Rust / rustfmt (push) Successful in 24s
Rust / clippy (push) Failing after 2m27s
Rust / build (push) Successful in 3m8s

Co-authored-by: Glaeder <niklas@vousten.dev>
Co-authored-by: Fredi <fredrik.konrad@rwth-aachen.de>
Reviewed-on: #11
Co-authored-by: Dominic <git@msrd0.de>
Co-committed-by: Dominic <git@msrd0.de>
This commit is contained in:
Dominic 2024-07-07 11:54:42 +00:00 committed by msrd0
parent 1275b92a5b
commit 33b301a410
54 changed files with 569 additions and 46 deletions

1
Cargo.lock generated
View file

@ -2129,6 +2129,7 @@ version = "0.1.0"
dependencies = [
"comfy",
"heck",
"indexmap",
"resvg",
]

View file

@ -16,6 +16,7 @@ opt-level = 3
[dependencies]
comfy = { version = "0.4.0", features = ["wayland"] }
indexmap = "2"
[build-dependencies]
heck = "0.5"

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
assets/furniture/drawer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
assets/furniture/dryer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
assets/furniture/fridge.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

BIN
assets/furniture/kettle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
assets/furniture/oven.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
assets/furniture/sink.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
assets/furniture/stove.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -0,0 +1,113 @@
use comfy::{error, texture_id, EngineContext, HashSet, Lazy, Mutex, TextureHandle};
use std::{fmt::Debug, fs, io, sync::Arc};
static ASSETS_LOADED: Lazy<Arc<Mutex<HashSet<String>>>> =
Lazy::new(|| Arc::new(Mutex::new(HashSet::new())));
#[derive(Debug)]
struct FurnitureAsset {
folder: String,
name: String
}
#[derive(Debug)]
struct FurnitureTextureHandles {
human: Option<TextureHandle>,
magnet: Option<TextureHandle>,
elec: Option<TextureHandle>
}
impl FurnitureAsset {
fn asset_path(&self) -> String {
format!("{}/{}.png", self.folder, self.name)
}
fn asset_path_magnet(&self) -> String {
format!("{}/magnet/{}.png", self.folder, self.name)
}
fn asset_path_elec(&self) -> String {
format!("{}/elec/{}.png", self.folder, self.name)
}
fn load_asset_path(
&self,
path: String,
ctx: &mut EngineContext<'_>
) -> Option<TextureHandle> {
let mut loaded = ASSETS_LOADED.lock();
if loaded.contains(&path) {
return Some(texture_id(&path));
}
let bytes = match fs::read(format!(
"{}/assets/furniture/{path}",
env!("CARGO_MANIFEST_DIR")
)) {
Ok(bytes) => bytes,
Err(err) if err.kind() == io::ErrorKind::NotFound => return None,
Err(err) => {
error!("Failed to load asset {path:?}: {err}");
return None;
}
};
ctx.load_texture_from_bytes(&path, &bytes);
let handle = texture_id(&path);
loaded.insert(path);
Some(handle)
}
/// Attempt to load the assets. Silently ignore missing assets.
fn load_assets(&self, ctx: &mut EngineContext<'_>) -> FurnitureTextureHandles {
FurnitureTextureHandles {
human: self.load_asset_path(self.asset_path(), ctx),
magnet: self.load_asset_path(self.asset_path_magnet(), ctx),
elec: self.load_asset_path(self.asset_path_elec(), ctx)
}
}
}
pub struct Furniture {
asset: FurnitureAsset,
handles: FurnitureTextureHandles,
on: Box<dyn Fn() -> bool>
}
impl Debug for Furniture {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Furniture")
.field("asset", &self.asset)
.field("handles", &self.handles)
.finish_non_exhaustive()
}
}
impl Furniture {
pub fn new<F: Into<String>, N: Into<String>>(
folder: F,
name: N,
ctx: &mut EngineContext<'_>
) -> Self {
let asset = FurnitureAsset {
folder: folder.into(),
name: name.into()
};
let handles = asset.load_assets(ctx);
Self {
asset,
handles,
on: Box::new(|| false)
}
}
pub fn get_human_texture_handle(&self) -> Option<TextureHandle> {
self.handles.human
}
pub fn get_elec_texture_handle(&self) -> Option<TextureHandle> {
self.handles.elec
}
pub fn get_magnet_texture_handle(&self) -> Option<TextureHandle> {
self.handles.magnet
}
}

View file

@ -13,6 +13,13 @@ impl Default for Grid {
}
impl Grid {
pub fn new(nodes: Vec<Vec2>, connections: Vec<(usize, usize)>) -> Self {
let mut grid = Grid { nodes, connections };
grid.sanitize();
grid
}
fn load() -> Self {
let mut grid = Self {
nodes: vec![

View file

@ -1,26 +1,52 @@
mod furniture;
mod grid;
mod player;
mod room;
use grid::Grid;
use player::Player;
use self::{grid::Grid, player::Player, room::Room};
use crate::State;
use comfy::{error, EngineContext};
#[derive(Debug, Default)]
#[derive(Debug)]
pub struct HouseState {
grid: Grid,
room: Room,
//grid: Grid,
player: Player
}
pub fn draw(state: &crate::State, _engine: &comfy::EngineContext<'_>) {
if let Some(house) = state.house() {
impl HouseState {
pub fn generate_new_house(ctx: &mut EngineContext<'_>) -> Self {
let room = Room::new(ctx);
let player = Player::new(&room);
HouseState { room, player }
}
}
pub fn draw(state: &State, _ctx: &comfy::EngineContext<'_>) {
let Some(house) = state.house() else {
error!("How can I render a house when I'm not in one?!?");
return;
};
//Draw House
house.room.draw();
//Draw Grid
house.grid.draw();
//state.house.grid.draw();
//Draw Player
house.player.draw();
}
}
pub fn update(state: &mut crate::State, _engine: &mut comfy::EngineContext<'_>) {
let house = state.house_mut();
house.player.update(&house.grid);
pub fn update(state: &mut State, ctx: &mut comfy::EngineContext<'_>) {
let house = state.house_mut(ctx);
house.player.update(&house.room.grid);
if house.player.is_moving_to_right_room(&house.room) {
house.room = Room::new(ctx);
house.player.reset_on_room(&house.room, true);
} else if house.player.is_moving_to_left_room(&house.room) {
house.room = Room::new(ctx);
house.player.reset_on_room(&house.room, false);
}
}

View file

@ -1,4 +1,7 @@
use super::Grid;
use super::{
room::{Room, SCALE},
Grid
};
use comfy::{delta, draw_circle, is_key_down, vec2, KeyCode, Vec2, RED};
use std::collections::HashSet;
@ -10,20 +13,23 @@ pub struct Player {
next_connections: Vec<usize>
}
impl Default for Player {
fn default() -> Self {
Self {
position: Default::default(),
impl Player {
pub fn new(room: &Room) -> Self {
Player {
position: vec2(
((0.25) - room.size.0 as f32 / 2.0) * SCALE,
room.grid.nodes.first().unwrap().y
),
speed: 10.0,
connection: 0,
next_connections: vec![1, 2, 3]
next_connections: vec![1]
}
}
}
impl Player {
pub fn draw(&self) {
draw_circle(self.position, 0.5, RED, 0);
}
pub fn update(&mut self, grid: &Grid) {
let allowed_movement = get_allowed_movement(self, grid);
@ -33,6 +39,27 @@ impl Player {
snap_to_closest_node(self, grid);
}
}
pub fn is_moving_to_right_room(&self, room: &Room) -> bool {
self.position.x > (room.size.0 as f32 / 2.0) * SCALE
}
pub fn is_moving_to_left_room(&self, room: &Room) -> bool {
self.position.x < -(room.size.0 as f32 / 2.0) * SCALE
}
pub fn reset_on_room(&mut self, room: &Room, place_left: bool) {
let offset = 0.1;
let x = if place_left {
(offset - room.size.0 as f32 / 2.0) * SCALE
} else {
(room.size.0 as f32 / 2.0 - offset) * SCALE
};
self.position = vec2(x, room.grid.nodes.first().unwrap().y);
self.connection = 0;
self.next_connections = vec![1];
}
}
fn move_player(player: &mut Player, allowed_movement: (bool, bool, bool, bool)) {

View file

@ -0,0 +1,355 @@
use super::{furniture::Furniture, grid::Grid};
use crate::game;
use comfy::{
draw_rect, draw_rect_outline, draw_sprite, error, random_i32, vec2, EngineContext,
HashSet, RandomRange as _, Vec2, GREEN, PURPLE, RED, WHITE
};
use indexmap::IndexSet;
pub const SCALE: f32 = 4.0;
#[derive(Debug, PartialEq)]
enum RoomType {
Kitchen,
Bath,
Toilett,
LivingRoom,
SleepingRoom
}
#[derive(Debug)]
struct Tile {
pos: Vec2,
size: Vec2,
f: Furniture,
z: i32
}
#[derive(Debug)]
pub struct Room {
_room_type: RoomType,
pub size: (u8, u8), //(width, height)
pub grid: Grid,
furnitures: Vec<Tile>
}
impl RoomType {
pub fn random() -> Self {
match random_i32(0, 4) {
0 => RoomType::Kitchen,
1 => RoomType::Bath,
2 => RoomType::Toilett,
3 => RoomType::LivingRoom,
4 => RoomType::SleepingRoom,
_ => panic!("Somehow you where unlucky and got a random number out of range")
}
}
}
impl Room {
pub fn new(ctx: &mut EngineContext<'_>) -> Self {
let room_type = RoomType::random();
let size = Self::random_size(&room_type);
let furnitures = Self::random_room_furniture(&room_type, size, ctx);
Room {
_room_type: room_type,
size,
grid: Self::create_grid(size.0, size.1),
furnitures
}
}
fn random_size(room_type: &RoomType) -> (u8, u8) {
//Kitchen + Living Room 5-8
//Bath + sleepingroom 4-6
//Toilet 2-3
match room_type {
RoomType::Kitchen | RoomType::LivingRoom => (random_i32(5, 8) as u8, 3),
RoomType::Bath | RoomType::SleepingRoom => (random_i32(4, 6) as u8, 3),
RoomType::Toilett => (random_i32(2, 3) as u8, 3)
}
}
fn random_room_furniture(
room_type: &RoomType,
(width, _height): (u8, u8),
ctx: &mut EngineContext<'_>
) -> Vec<Tile> {
let mut furnitures = Vec::new();
let mut empty_spots: IndexSet<u8> = (0 .. width).collect();
fn random_empty_spot<T>(empty_spots: &mut IndexSet<T>) -> Option<T> {
if empty_spots.is_empty() {
return None;
}
let random_idx = usize::gen_range(0, empty_spots.len());
empty_spots.swap_remove_index(random_idx)
}
fn random_appliance<T>(empty_spots: &mut Vec<T>) -> Option<T> {
if empty_spots.is_empty() {
return None;
}
let random_idx = usize::gen_range(0, empty_spots.len());
Some(empty_spots.swap_remove(random_idx))
}
const SIDEBOARD_HEIGHT: f32 = 0.1;
const STOVE_HEIGHT: f32 = 0.025;
const SINK_HEIGHT: f32 = 0.5;
#[allow(clippy::single_match)] // we'll add more stuff later
match room_type {
RoomType::Kitchen => {
// in a kitchen, we always add a fridge
let fridge_pos = u8::gen_range(0, 2) * (width - 1);
empty_spots.swap_remove(&fridge_pos);
furnitures.push(Tile {
pos: vec2(fridge_pos as f32, 0.0),
size: vec2(1.0, 2.0),
f: Furniture::new("kitchen", "fridge", ctx),
z: 0
});
// and we always add an oven
let Some(oven_pos) = random_empty_spot(&mut empty_spots) else {
error!("How can I not fit an oven in a kitchen?!?");
return furnitures;
};
furnitures.push(Tile {
pos: vec2(oven_pos as f32, 0.0),
size: vec2(1.0, 1.0),
f: Furniture::new("kitchen", "oven", ctx),
z: 0
});
// there's always sideboard above the oven with a stove
furnitures.push(Tile {
pos: vec2(oven_pos as f32, 1.0),
size: vec2(1.0, SIDEBOARD_HEIGHT),
f: Furniture::new("kitchen", "sideboard_1", ctx),
z: 1
});
furnitures.push(Tile {
pos: vec2(oven_pos as f32, 1.0 + SIDEBOARD_HEIGHT),
size: vec2(1.0, STOVE_HEIGHT),
f: Furniture::new("kitchen", "stove", ctx),
z: 0
});
// and we always add a drawer that houses a sink
let Some(sink_pos) = random_empty_spot(&mut empty_spots) else {
error!("How can I not fit a sink in a kitchen?!?");
return furnitures;
};
furnitures.push(Tile {
pos: vec2(sink_pos as f32, 0.0),
size: vec2(1.0, 1.0),
f: Furniture::new("kitchen", "drawer_cupboard", ctx),
z: 0
});
// there's always sideboard above that drawer with a sink **behind** it
furnitures.push(Tile {
pos: vec2(sink_pos as f32, 1.0),
size: vec2(1.0, SINK_HEIGHT),
f: Furniture::new("kitchen", "sink", ctx),
z: 0
});
furnitures.push(Tile {
pos: vec2(sink_pos as f32, 1.0),
size: vec2(1.0, SIDEBOARD_HEIGHT),
f: Furniture::new("kitchen", "sideboard_1", ctx),
z: 1
});
// the current list of empty spots is the same list we can use to place
// on-the-counter appliances later
let mut empty_spots_clone = empty_spots.clone();
// build a list of the remaining kitchen appliances. we only want them
// included once, most kitchens don't contain two washing machines etc
let mut remaining_appliances: IndexSet<&'static str> =
["dishwasher", "dryer", "minifridge", "washing_machine"]
.into_iter()
.collect();
// let's add at most half of the remaining positions as big appliances
for _ in 0 .. empty_spots.len() / 2 {
let Some(asset) = random_empty_spot(&mut remaining_appliances) else {
break;
};
let Some(spot) = random_empty_spot(&mut empty_spots) else {
error!("WTF I shouldn't've used more than half of the available spots");
return furnitures;
};
furnitures.push(Tile {
pos: vec2(spot as f32, 0.0),
size: vec2(1.0, 1.0),
f: Furniture::new("kitchen", asset, ctx),
z: 0
});
furnitures.push(Tile {
pos: vec2(spot as f32, 1.0),
size: vec2(1.0, SIDEBOARD_HEIGHT),
f: Furniture::new("kitchen", "sideboard_1", ctx),
z: 1
});
}
// and fill the remainder with drawers
while !empty_spots.is_empty() {
let asset = match u8::gen_range(0, 2) {
0 => "drawer",
1 => "drawer_cupboard",
_ => unreachable!()
};
let Some(spot) = random_empty_spot(&mut empty_spots) else {
error!("WTF I should still have spots available");
return furnitures;
};
furnitures.push(Tile {
pos: vec2(spot as f32, 0.0),
size: vec2(1.0, 1.0),
f: Furniture::new("kitchen", asset, ctx),
z: 0
});
furnitures.push(Tile {
pos: vec2(spot as f32, 1.0),
size: vec2(1.0, SIDEBOARD_HEIGHT),
f: Furniture::new("kitchen", "sideboard_1", ctx),
z: 1
});
}
// build a list of on-the-counter kitchen appliances. we only want them
// included once, most kitchens don't contain two toasters etc
let mut remaining_appliances: Vec<(&'static str, f32, f32)> = [
("blender", 0.3, 0.45),
("kettle", 0.3, 0.4),
("toaster", 0.5, 0.25)
]
.into_iter()
.collect();
// and then we fill like half the counter with appliances
for _ in 0 .. empty_spots_clone.len() / 2 {
let Some((asset, asset_w, asset_h)) =
random_appliance(&mut remaining_appliances)
else {
break;
};
let Some(spot) = random_empty_spot(&mut empty_spots_clone) else {
error!("WTF I shouldn't've used more than half of the available spots");
return furnitures;
};
furnitures.push(Tile {
pos: vec2(spot as f32 + 0.5, 1.0 + SIDEBOARD_HEIGHT),
size: vec2(asset_w, asset_h),
f: Furniture::new("kitchen", asset, ctx),
z: 0
});
}
},
_ => {}
}
furnitures
}
fn create_grid(width: u8, height: u8) -> Grid {
error!("START GRID CREATION!");
let left_border = width as f32 / 2.0;
let lower_border = height as f32 / 2.0;
//Lower Cable
let lower_cable_y = height as f32 / 6.0;
let mut current_x = -0.5;
let mut nodes = Vec::new();
let max_offset = ((width / 2) as i32).max(1);
while current_x < width as f32 {
nodes.push(vec2(
(current_x - left_border) * SCALE,
(lower_cable_y - lower_border) * SCALE
));
current_x += random_i32(1, max_offset) as f32;
}
current_x = width as f32 + 0.5;
nodes.push(vec2(
(current_x - left_border) * SCALE,
(lower_cable_y - lower_border) * SCALE
));
let mut connections = Vec::new();
for i in 1 .. nodes.len() {
connections.push((i - 1, i));
}
//Lamps
let upper_cable_y = height as f32 - 0.25;
let max_lamps = (width as f32 / 2.5).round() as i32;
let lamp_amount = random_i32(1, max_lamps + 1);
let node_indices: HashSet<usize> = (0 .. lamp_amount)
.map(|_| random_i32(1, nodes.len() as i32 - 1) as usize)
.collect();
let last_lower_node_index = nodes.len();
for (i, index) in node_indices.iter().enumerate() {
nodes.push(vec2(
nodes.get(*index).unwrap().x,
(upper_cable_y - lower_border) * SCALE
));
connections.push((*index, last_lower_node_index + i));
}
Grid::new(nodes, connections)
}
pub fn draw(&self) {
let (width, height) = self.size;
draw_rect(
vec2(0.0, 0.0),
vec2(width as f32 * SCALE, height as f32 * SCALE),
PURPLE,
game::ZLayer::MapMax as i32 - 2
);
draw_rect_outline(
vec2(0.0, 0.0),
vec2(width as f32 * SCALE, height as f32 * SCALE),
0.3,
RED,
game::ZLayer::MapMax as i32 - 1
);
for tile in &self.furnitures {
let mut pos = tile.pos - vec2(width as f32 / 2.0, height as f32 / 2.0);
pos += tile.size * 0.5;
if let Some(texture) = tile.f.get_human_texture_handle() {
draw_sprite(
texture,
pos * SCALE,
WHITE,
game::ZLayer::MapMax as i32 + tile.z,
tile.size * SCALE
);
} else {
draw_rect_outline(
pos * SCALE,
tile.size * SCALE,
0.3,
GREEN,
game::ZLayer::MapMax as i32 + tile.z
);
}
}
self.grid.draw();
}
}

View file

@ -1,11 +1,4 @@
use crate::{
activities::{
house::{self, HouseState},
Activity
},
game::ZLayer,
State
};
use crate::{activities::Activity, game::ZLayer, State};
use comfy::{
draw_circle, draw_rect_outline, draw_sprite, error, info, is_key_down,
main_camera_mut, EngineContext, IVec2, KeyCode, Vec2, RED, WHITE
@ -32,7 +25,7 @@ pub fn draw(state: &crate::State, _engine: &comfy::EngineContext<'_>) {
draw_circle(state.ghost.overworld_pos, 0.5, RED, ZLayer::Ghost.into());
}
fn update_move_player(state: &mut State) {
fn update_move_player(state: &mut State, ctx: &mut EngineContext<'_>) {
let now = Instant::now();
// Are there any pending position updates? If so, we ignore all user input and execute
@ -160,18 +153,18 @@ fn update_move_player(state: &mut State) {
if current_tile.can_enter_house() {
info!("enter house at {tile_pos}");
state.activity = Activity::House(tile_pos);
state.house_mut(); // gen new house
state.house_mut(ctx); // gen new house
}
}
}
pub fn update(state: &mut State, _ctx: &mut EngineContext<'_>) {
pub fn update(state: &mut State, ctx: &mut EngineContext<'_>) {
let mut camera = main_camera_mut();
camera.center = Vec2::ZERO;
camera.zoom = 30.0;
// move player
update_move_player(state);
update_move_player(state, ctx);
// generate more chunks if needed
{

View file

@ -1,5 +1,6 @@
use crate::{
activities::{house, overworld, Activity},
assets::Assets,
State
};
use comfy::{EngineContext, Vec2};
@ -85,6 +86,10 @@ impl Sub<i32> for ZLayer {
}
}
pub fn setup(_state: &mut State, ctx: &mut EngineContext<'_>) {
Assets::load(ctx);
}
pub fn update(state: &mut State, engine: &mut EngineContext<'_>) {
state.score += engine.delta * 10.0;
match state.activity {

View file

@ -12,7 +12,6 @@ mod ui;
use self::{
activities::{house::HouseState, overworld::worldgen::Overworld, Activity},
assets::Assets,
game::Ghost
};
use comfy::{
@ -41,13 +40,13 @@ impl State {
}
fn house(&self) -> Option<&HouseState> {
self.houses.get(&self.get_house_pos().unwrap())
self.houses.get(&self.get_house_pos()?)
}
fn house_mut(&mut self) -> &mut HouseState {
fn house_mut(&mut self, ctx: &mut EngineContext<'_>) -> &mut HouseState {
self.houses
.entry(self.get_house_pos().unwrap())
.or_insert_with(HouseState::default)
.or_insert_with(|| HouseState::generate_new_house(ctx))
}
}
@ -56,14 +55,14 @@ impl GameLoop for State {
Self::default()
}
fn update(&mut self, engine: &mut EngineContext<'_>) {
fn update(&mut self, ctx: &mut EngineContext<'_>) {
if !self.setup_called {
setup(engine);
game::setup(self, ctx);
self.setup_called = true;
}
game::update(self, engine);
game::draw(self, engine);
game::update(self, ctx);
game::draw(self, ctx);
}
}
@ -71,10 +70,6 @@ fn config(config: GameConfig) -> GameConfig {
config
}
fn setup(ctx: &mut EngineContext<'_>) {
Assets::load(ctx);
}
async fn run() {
init_game_config(GAME_NAME.to_string(), env!("CARGO_PKG_VERSION"), config);
let mut engine = EngineState::new();