Browse Source

Move rendering to map

master
Garrit Franke 3 years ago
parent
commit
849cab7ca5
  1. 87
      src/main.rs
  2. 89
      src/map.rs
  3. 6
      src/traits.rs

87
src/main.rs

@ -1,12 +1,15 @@
rltk::add_wasm_support!();
mod crypto;
mod map;
mod traits;
use crate::map::Chunk;
use crate::traits::Render;
use map::TileType;
use rltk::prelude::*;
use std::collections::HashMap;
struct State {
#[derive(Clone)]
pub struct State {
view: Chunk,
loaded_chunks: Box<HashMap<(i32, i32), Chunk>>,
world_pos: (i32, i32),
@ -119,8 +122,6 @@ impl State {
impl GameState for State {
#[allow(non_snake_case)]
fn tick(&mut self, ctx: &mut Rltk) {
// We'll use batched drawing
let mut draw_batch = DrawBatch::new();
match ctx.key {
None => {} // Nothing happened
Some(key) => {
@ -155,84 +156,8 @@ impl GameState for State {
}
}
// Set all tiles to not visible
for v in self.visible.iter_mut() {
*v = false;
}
// Obtain the player's visible tile set, and apply it
let player_position = self.index_to_point2d(self.player_position);
let fov = rltk::field_of_view_set(player_position, 8, self);
// Note that the steps above would generally not be run every frame!
for idx in fov.iter() {
let point = self.point2d_to_index(*idx);
self.visible[point] = true;
}
// Clear the screen
draw_batch.cls();
// Iterate the map array, incrementing coordinates as we go.
let mut y = 0;
let mut x = 0;
for (i, tile) in self.view.iter().enumerate() {
// Render a tile depending upon the tile type; now we check visibility as well!
let mut fg;
let mut glyph = ".";
match tile {
TileType::Floor => {
fg = RGB::from_f32(0.5, 0.5, 0.0);
}
TileType::Wall => {
fg = RGB::from_f32(0.0, 1.0, 0.0);
glyph = "#";
}
}
if !self.visible[i] {
fg = fg.to_greyscale();
}
draw_batch.print_color(
Point::new(x, y),
glyph,
ColorPair::new(fg, RGB::from_f32(0., 0., 0.)),
);
// Move the coordinates
x += 1;
if x > 79 {
x = 0;
y += 1;
}
}
if ctx.left_click {
let mouse_pos = ctx.mouse_pos();
self.select_object(Point::from(mouse_pos));
}
// Display selected object below the screen
let selected_object_text = match self.selected_object {
Some(obj) => format!("{}", obj),
None => "".to_string(),
};
draw_batch.print_color(
Point::new(0, 51),
selected_object_text,
ColorPair::new(RGB::from_f32(1.0, 1.0, 0.0), RGB::from_f32(0., 0., 0.)),
);
// Render the player @ symbol
let ppos = self.index_to_point2d(self.player_position);
draw_batch.print_color(
Point::new(ppos.x, ppos.y),
"@",
ColorPair::new(RGB::from_f32(1.0, 1.0, 0.0), RGB::from_f32(0., 0., 0.)),
);
draw_batch.submit(0).expect("Batch error");
render_draw_buffer(ctx).expect("Render error");
// @cleanup: We shouldn't be cloning the state on each frame
self.view.render(&mut self.clone(), ctx);
}
}

89
src/map.rs

@ -1,4 +1,7 @@
use crate::crypto;
use crate::traits::Render;
use crate::State;
use rltk::prelude::*;
use rltk::Point;
use rltk::RandomNumberGenerator;
use std::fmt::Display;
@ -20,6 +23,92 @@ impl Display for TileType {
}
}
impl Render for Chunk {
fn render(&mut self, gs: &mut State, ctx: &mut rltk::Rltk) {
// We'll use batched drawing
let mut draw_batch = DrawBatch::new();
// Set all tiles to not visible
for v in gs.visible.iter_mut() {
*v = false;
}
// Obtain the player's visible tile set, and apply it
let player_position = gs.index_to_point2d(gs.player_position);
let fov = rltk::field_of_view_set(player_position, 8, gs);
// Note that the steps above would generally not be run every frame!
for idx in fov.iter() {
let point = gs.point2d_to_index(*idx);
gs.visible[point] = true;
}
// Clear the screen
draw_batch.cls();
// Iterate the map array, incrementing coordinates as we go.
let mut y = 0;
let mut x = 0;
for (i, tile) in gs.view.iter().enumerate() {
// Render a tile depending upon the tile type; now we check visibility as well!
let mut fg;
let mut glyph = ".";
match tile {
TileType::Floor => {
fg = RGB::from_f32(0.5, 0.5, 0.0);
}
TileType::Wall => {
fg = RGB::from_f32(0.0, 1.0, 0.0);
glyph = "#";
}
}
if !gs.visible[i] {
fg = fg.to_greyscale();
}
draw_batch.print_color(
Point::new(x, y),
glyph,
ColorPair::new(fg, RGB::from_f32(0., 0., 0.)),
);
// Move the coordinates
x += 1;
if x > 79 {
x = 0;
y += 1;
}
}
if ctx.left_click {
let mouse_pos = ctx.mouse_pos();
gs.select_object(Point::from(mouse_pos));
}
// Display selected object below the screen
let selected_object_text = match gs.selected_object {
Some(obj) => format!("{}", obj),
None => "".to_string(),
};
draw_batch.print_color(
Point::new(0, 51),
selected_object_text,
ColorPair::new(RGB::from_f32(1.0, 1.0, 0.0), RGB::from_f32(0., 0., 0.)),
);
// Render the player @ symbol
let ppos = gs.index_to_point2d(gs.player_position);
draw_batch.print_color(
Point::new(ppos.x, ppos.y),
"@",
ColorPair::new(RGB::from_f32(1.0, 1.0, 0.0), RGB::from_f32(0., 0., 0.)),
);
draw_batch.submit(0).expect("Batch error");
render_draw_buffer(ctx).expect("Render error");
}
}
pub fn new_chunk(seed: u64, pos: Point) -> Chunk {
let mut map = vec![TileType::Floor; 80 * 50];
let count = map.len();

6
src/traits.rs

@ -0,0 +1,6 @@
use crate::State;
use rltk::Rltk;
pub trait Render {
fn render(&mut self, gs: &mut State, ctx: &mut Rltk);
}
Loading…
Cancel
Save