added console
This commit is contained in:
parent
d264935ca3
commit
a9ffc9bc6f
Binary file not shown.
After Width: | Height: | Size: 925 B |
|
@ -8,6 +8,7 @@ struct World {
|
|||
img: Rc<Image>,
|
||||
font: Rc<Tileset>,
|
||||
pos: Vec2<i32>,
|
||||
map: HexMap,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -22,11 +23,16 @@ impl Game for World {
|
|||
img: Image::load_data(include_bytes!("assets/test.gif")),
|
||||
font: Tileset::load_data(include_bytes!("assets/ega-8x14.gif"), Vec2 { x: 16, y: 16 }),
|
||||
pos: Vec2::zero(),
|
||||
map: HexMap::new(
|
||||
Vec2 { x: 27, y: 13 },
|
||||
Tileset::load_data(include_bytes!("assets/hex2.gif"), Vec2 { x: 1, y: 1 }),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, window_state: &mut WindowState) {
|
||||
self.pos = window_state.mouse_pos();
|
||||
window_state.log(format!("{}x{}", self.pos.x, self.pos.y).as_str());
|
||||
}
|
||||
|
||||
fn on_event(&mut self, window_state: &mut WindowState, event: Event) {
|
||||
|
@ -40,7 +46,8 @@ impl Game for World {
|
|||
|
||||
fn draw(&self, target: &mut Image) {
|
||||
target.clear();
|
||||
target.draw_image(Vec2 { x: 200, y: 100 }, &self.img);
|
||||
target.draw_hexmap(Vec2 { x: 0, y: 0 }, &self.map);
|
||||
/*target.draw_image(Vec2 { x: 200, y: 100 }, &self.img);
|
||||
target.draw_image(self.pos, self.font.get(68));
|
||||
|
||||
target.draw_line(
|
||||
|
@ -51,5 +58,7 @@ impl Game for World {
|
|||
self.pos,
|
||||
10,
|
||||
);
|
||||
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
use crate::{Image, Rect, Tileset, Vec2};
|
||||
use std::collections::VecDeque;
|
||||
|
||||
pub(crate) struct Console {
|
||||
lines: VecDeque<String>,
|
||||
max_lines: usize,
|
||||
max_line_length: usize,
|
||||
}
|
||||
|
||||
impl Console {
|
||||
pub(crate) fn new(max_lines: i32, max_line_length: i32) -> Self {
|
||||
Self {
|
||||
lines: VecDeque::new(),
|
||||
max_lines: max_lines as usize,
|
||||
max_line_length: max_line_length as usize,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn add(&mut self, str: &str) {
|
||||
if str.len() > self.max_line_length {
|
||||
let (first, rest) = str.split_at(self.max_line_length);
|
||||
self.add(first);
|
||||
self.add(rest);
|
||||
} else {
|
||||
self.lines.push_back(str.into());
|
||||
while self.lines.len() > self.max_lines {
|
||||
self.lines.pop_front();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn draw_to_image(&self, target: &mut Image, pos: Vec2<i32>, font: &Tileset) {
|
||||
let height = self.max_lines as i32 * font.tile_size().y;
|
||||
let width = self.max_line_length as i32 * font.tile_size().x;
|
||||
target.fill_rect(
|
||||
Rect {
|
||||
pos,
|
||||
size: Vec2 {
|
||||
x: width,
|
||||
y: height,
|
||||
},
|
||||
},
|
||||
254,
|
||||
);
|
||||
let y = height + pos.y;
|
||||
target.draw_line(
|
||||
Vec2 { x: pos.x, y },
|
||||
Vec2 {
|
||||
x: pos.x + width,
|
||||
y,
|
||||
},
|
||||
253,
|
||||
);
|
||||
for (i, str) in self.lines.iter().enumerate() {
|
||||
target.draw_string(
|
||||
pos + Vec2 {
|
||||
x: 0,
|
||||
y: i as i32 * font.tile_size().y,
|
||||
},
|
||||
str,
|
||||
font,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
|
@ -1,19 +1,20 @@
|
|||
use crate::Vec2;
|
||||
use crate::{Image, Tileset, Vec2};
|
||||
use std::rc::Rc;
|
||||
|
||||
//odd-q vertical layout https://www.redblobgames.com/grids/hexagons
|
||||
pub struct HexMap {
|
||||
size: Vec2<i32>,
|
||||
data: Vec<i32>,
|
||||
tile_size: Vec2<i32>,
|
||||
tileset: Rc<Tileset>,
|
||||
}
|
||||
|
||||
impl HexMap {
|
||||
//pub static
|
||||
pub fn new(size: Vec2<i32>, tile_size: Vec2<i32>) -> Self {
|
||||
pub fn new(size: Vec2<i32>, tileset: Rc<Tileset>) -> Self {
|
||||
HexMap {
|
||||
size,
|
||||
data: vec![0; size.size()],
|
||||
tile_size,
|
||||
tileset,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,6 +32,22 @@ impl HexMap {
|
|||
self.size
|
||||
}
|
||||
|
||||
//pubcrate
|
||||
pub(crate) fn draw_tile_to_image(
|
||||
&self,
|
||||
target: &mut Image,
|
||||
coord: Vec2<i32>,
|
||||
offset: Vec2<i32>,
|
||||
) {
|
||||
let x = coord.x * (self.tileset.tile_size().x as f64 * 3.0 / 4.0).ceil() as i32;
|
||||
let y =
|
||||
coord.y * self.tileset.tile_size().y + (coord.x % 2) * (self.tileset.tile_size().y / 2);
|
||||
target.draw_image(
|
||||
Vec2 { x, y } + offset,
|
||||
self.tileset.get(self.data[self.coord_to_idx(coord)]),
|
||||
)
|
||||
}
|
||||
|
||||
//priv
|
||||
fn coord_to_idx(&self, coord: Vec2<i32>) -> usize {
|
||||
(coord.x + coord.y * self.size.x) as usize
|
||||
|
|
32
src/image.rs
32
src/image.rs
|
@ -1,5 +1,5 @@
|
|||
use crate::vec2::Vec2;
|
||||
use crate::{HexMap, Rect};
|
||||
use crate::{HexMap, Rect, Tileset};
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::rc::Rc;
|
||||
|
@ -55,9 +55,13 @@ impl Image {
|
|||
self.data.as_slice()
|
||||
}
|
||||
|
||||
//pub fn draw_hexmap(&mut self, pos: Vec2<i32>, hexmap: &HexMap) {
|
||||
// for pos in Vec2::zero()..pos {}
|
||||
//}
|
||||
pub fn draw_hexmap(&mut self, pos: Vec2<i32>, hexmap: &HexMap) {
|
||||
for i in hexmap.size().to_rect().iter() {
|
||||
if i.x % 1 == 0 {
|
||||
hexmap.draw_tile_to_image(self, i, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw_image(&mut self, pos: Vec2<i32>, image: &Image) {
|
||||
self.draw_image_partial(
|
||||
|
@ -110,10 +114,30 @@ impl Image {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn draw_string(&mut self, pos: Vec2<i32>, str: &str, font: &Tileset) {
|
||||
assert!(str.is_ascii());
|
||||
let array = str.as_bytes();
|
||||
for i in 0..array.len() {
|
||||
self.draw_image(
|
||||
Vec2 {
|
||||
x: pos.x + font.tile_size().x * i as i32,
|
||||
y: pos.y,
|
||||
},
|
||||
font.get(array[i] as i32),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fill(&mut self, color: u8) {
|
||||
self.data.fill(color);
|
||||
}
|
||||
|
||||
pub fn fill_rect(&mut self, rect: Rect<i32>, color: u8) {
|
||||
for pos in rect.iter() {
|
||||
self.set_pixel(pos, color);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_pixel(&self, pos: Vec2<i32>) -> u8 {
|
||||
self.data[(pos.x + self.size.x * pos.y) as usize]
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
mod console;
|
||||
mod hexmap;
|
||||
mod image;
|
||||
mod rect;
|
||||
|
@ -5,6 +6,7 @@ mod tileset;
|
|||
mod vec2;
|
||||
mod window;
|
||||
|
||||
pub use console::*;
|
||||
pub use hexmap::*;
|
||||
pub use image::*;
|
||||
pub use rect::*;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::vec2::Vec2;
|
||||
use crate::Vec2Iter;
|
||||
use num::{Num, ToPrimitive};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
@ -19,6 +20,10 @@ impl<T: Num + Copy + ToPrimitive + PartialOrd> Rect<T> {
|
|||
self.pos + self.size
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> Vec2Iter<T> {
|
||||
self.pos.iter_to(self.size)
|
||||
}
|
||||
|
||||
pub fn contains(&self, point: Vec2<T>) -> bool {
|
||||
let p2 = self.pos2();
|
||||
point.x >= self.pos.x && point.y >= self.pos.y && point.x < p2.x && point.y < p2.y
|
||||
|
|
|
@ -20,7 +20,7 @@ impl Tileset {
|
|||
x: img.size().x / tile_count.x,
|
||||
y: img.size().y / tile_count.y,
|
||||
};
|
||||
for tile in Vec2::zero().iter_to(tile_count) {
|
||||
for tile in tile_count.to_rect().iter() {
|
||||
let mut image = Image::new(size);
|
||||
image.draw_image_partial(
|
||||
Vec2::zero(),
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
use crate::console::Console;
|
||||
use crate::image::Image;
|
||||
use crate::vec2::Vec2;
|
||||
use crate::Tileset;
|
||||
use rand::Rng;
|
||||
use std::cmp::{max, min};
|
||||
use std::num::NonZeroU32;
|
||||
use std::time::{Duration, Instant};
|
||||
use winit::dpi::LogicalSize;
|
||||
use winit::event::VirtualKeyCode::Escape;
|
||||
use winit::event::ElementState::Pressed;
|
||||
use winit::event::VirtualKeyCode::{Escape, F12};
|
||||
use winit::event::{
|
||||
ElementState, Event as WinitEvent, MouseButton as WinitMouseButton, WindowEvent,
|
||||
};
|
||||
|
@ -37,13 +40,21 @@ pub trait Game {
|
|||
pub struct WindowState {
|
||||
palette: [u32; 256],
|
||||
mouse_pos: Vec2<i32>,
|
||||
console: Console,
|
||||
}
|
||||
|
||||
impl WindowState {
|
||||
fn new() -> Self {
|
||||
pub fn log(&mut self, msg: &str) {
|
||||
self.console.add(msg);
|
||||
}
|
||||
}
|
||||
|
||||
impl WindowState {
|
||||
fn new(console_size: Vec2<i32>) -> Self {
|
||||
WindowState {
|
||||
palette: [0u32; 256],
|
||||
mouse_pos: Vec2::zero(),
|
||||
console: Console::new(console_size.y, console_size.x),
|
||||
}
|
||||
}
|
||||
pub fn set_palette(&mut self, index: u8, r: u8, g: u8, b: u8) {
|
||||
|
@ -84,8 +95,15 @@ pub fn run<T: Game + 'static>(width: i32, height: i32) {
|
|||
x: width,
|
||||
y: height,
|
||||
});
|
||||
let mut window_state = WindowState::new();
|
||||
let internal_font = Tileset::load_data(include_bytes!("ega-8x14.gif"), Vec2 { x: 16, y: 16 });
|
||||
let mut window_state = WindowState::new(Vec2 {
|
||||
x: width / internal_font.tile_size().x,
|
||||
y: height / internal_font.tile_size().y / 3,
|
||||
});
|
||||
let mut game = T::new(&mut window_state);
|
||||
window_state.console.add("Initialising Skunk2d");
|
||||
|
||||
let mut display_console = true;
|
||||
|
||||
let mut frames_since_last_second = 0;
|
||||
let mut last_second = Instant::now();
|
||||
|
@ -129,6 +147,9 @@ pub fn run<T: Game + 'static>(width: i32, height: i32) {
|
|||
if k == Escape {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
if k == F12 && input.state == Pressed {
|
||||
display_console = !display_console;
|
||||
}
|
||||
};
|
||||
}
|
||||
WindowEvent::ModifiersChanged(_) => {}
|
||||
|
@ -181,6 +202,13 @@ pub fn run<T: Game + 'static>(width: i32, height: i32) {
|
|||
if Instant::now() - last_frame >= target_frame_duration {
|
||||
game.update(&mut window_state);
|
||||
game.draw(&mut screen);
|
||||
if display_console {
|
||||
window_state.console.draw_to_image(
|
||||
&mut screen,
|
||||
Vec2::zero(),
|
||||
&internal_font,
|
||||
);
|
||||
}
|
||||
|
||||
let size = window.inner_size();
|
||||
surface
|
||||
|
|
Loading…
Reference in New Issue