~comcloudway/little_town

93d0409c38ab1b22d926c7beb0036a4e3f983546 — Jakob Meier 1 year, 8 months ago d0dfce7
Basic camera rendering
5 files changed, 166 insertions(+), 6 deletions(-)

A src/blocks.rs
M src/main.rs
M src/screens/build.rs
M src/textures.rs
M src/types.rs
A src/blocks.rs => src/blocks.rs +14 -0
@@ 0,0 1,14 @@
use macroquad::prelude::*;
use crate::textures::AssetStore;
use crate::types::Direction;

pub enum Block {
    Dirt(Direction)
}
impl Block {
    pub fn get_texture(&self, assets: &AssetStore) -> Texture2D {
        match self {
            Block::Dirt(d) => assets.blocks.dirt.get_dir(d)
        }
    }
}

M src/main.rs => src/main.rs +1 -0
@@ 3,6 3,7 @@ use macroquad::prelude::*;
mod screens;
mod textures;
mod types;
mod blocks;

use types::{
    GameComponent,

M src/screens/build.rs => src/screens/build.rs +77 -4
@@ 1,21 1,94 @@
use macroquad::prelude::*;
use std::collections::HashMap;
use crate::textures::AssetStore;
use crate::types::{
    GameComponent,
    GameEvent
    GameEvent,
    Pos2
};
use crate::blocks::Block;

struct Camera {
    center: Vec2,
    scale: f32
}
impl Camera {
    fn new() -> Self {
        Self {
            center: Vec2::new(0.0, 0.0),
            scale: 1.0
        }
    }
}

pub struct BuildScreen {
    grid: HashMap<Pos2, Block>,
    cam: Camera
}
impl BuildScreen {
    pub fn new() -> Self {
        Self {
        }
        let mut this = Self {
            grid: HashMap::new(),
            cam: Camera::new()
        };

        this.grid.insert(Pos2::new(0, 0), Block::Dirt(crate::types::Direction::North));
        this.grid.insert(Pos2::new(0, 1), Block::Dirt(crate::types::Direction::North));

        this
    }
}
impl GameComponent for BuildScreen {
    fn draw(&self, assets: &crate::textures::AssetStore) {
    fn draw(&self, assets: &AssetStore) {
        for (pos, block) in self.grid.iter() {
            let texture = block.get_texture(&assets);

            let size = 128.0 * self.cam.scale;
            let x = screen_width() / 2.0
                + pos.x as f32 * size
                + self.cam.center.x * size;
            let y = screen_height() / 2.0
                + pos.y as f32 * (size / 3.0)
                + self.cam.center.y * size;

            if x >= -size && x <= screen_width()
                && y >= -size && y <= screen_height() {
                // render block
                // TODO: render blocks in order:
                // - from front to back
                // - from bottom to top
            draw_texture_ex(
                texture,
                x,
                y,
                WHITE,
                DrawTextureParams {
                    dest_size: Some(Vec2::new(size, size)),
                    source: None,
                    rotation: 0.0,
                    flip_x: false,
                    flip_y: false,
                    pivot: None
                });

            }
       }
    }
    fn ev_loop(&mut self) -> GameEvent {

        if is_key_down(KeyCode::Up) {
            self.cam.center.y -= 0.1;
        }
if is_key_down(KeyCode::Down) {
            self.cam.center.y += 0.1;
        }
if is_key_down(KeyCode::Left) {
            self.cam.center.x -= 0.1;
        }
if is_key_down(KeyCode::Right) {
            self.cam.center.x += 0.1;
        }

        GameEvent::None
    }
}

M src/textures.rs => src/textures.rs +43 -2
@@ 1,4 1,5 @@
use macroquad::prelude::*;
use crate::types::Direction;

const ASSET_FOLDER: &str = "assets/";
const ASSET_BASE_FOLDER: &str = "base/";


@@ 26,8 27,45 @@ fn in_font_folder(path: &str) -> String {
/// Collection of textures required by game
pub struct AssetStore {
    pub font: Font,
    pub long_button: (Texture2D, Texture2D)
    pub long_button: (Texture2D, Texture2D),
    pub blocks: BlockAssetCollection
}
pub struct DirectionalTexture {
    pub north: Texture2D,
    pub south: Texture2D,
    pub east: Texture2D,
    pub west: Texture2D,
}
impl DirectionalTexture {
    async fn from_auto_png(name: &str) -> Self {
        Self {
            north: load_texture(
                &in_base_folder(&format!("{}_N.png", name)))
                    .await.expect("Unable to load texture N"),
            south: load_texture(
                &in_base_folder(&format!("{}_S.png", name)))
                    .await.expect("Unable to load texture S"),
            west: load_texture(
                &in_base_folder(&format!("{}_W.png", name)))
                    .await.expect("Unable to load texture W"),
            east: load_texture(
                &in_base_folder(&format!("{}_E.png", name)))
                    .await.expect("Unable to load texture E"),
        }
    }
    pub fn get_dir(&self, dir: &Direction) -> Texture2D {
        match dir {
            Direction::North => self.north,
            Direction::South => self.south,
            Direction::East => self.east,
            Direction::West => self.west
        }
    }
}
pub struct BlockAssetCollection {
    pub dirt: DirectionalTexture
}

impl AssetStore {
    /// loads all the textures
    pub async fn init() -> Self {


@@ 40,7 78,10 @@ impl AssetStore {
                    .await.expect("Unable to load texture"),
                load_texture(
                    &in_ui_folder("PNG/buttonLong_brown_pressed.png"))
                    .await.expect("Unable to load texture"))
                    .await.expect("Unable to load texture")),
            blocks: BlockAssetCollection {
                dirt: DirectionalTexture::from_auto_png("Tiles/dirt_center").await
            }
        }
    }
}

M src/types.rs => src/types.rs +31 -0
@@ 1,6 1,37 @@
use crate::textures::AssetStore;
use crate::Screen;

#[derive(Debug,Eq,Hash,PartialEq)]
pub struct Pos2 {
    pub x: isize,
    pub y: isize
}
impl Pos2 {
    pub fn new(x: isize, y: isize) -> Self {
        Self {
            x,
            y
        }
    }
}

/// Directions
#[derive(PartialEq)]
pub enum Direction {
    /// Left
    /// (left edge of screen)
    West,
    /// Right
    /// (right edge of screen)
    East,
    /// Up
    /// (top edge of screen)
    North,
    /// Down
    /// (bottom edge of screen)
    South
}

/// A basic Game component
/// which can be drawn
/// and has a handler for the event loop