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>,
|
img: Rc<Image>,
|
||||||
font: Rc<Tileset>,
|
font: Rc<Tileset>,
|
||||||
pos: Vec2<i32>,
|
pos: Vec2<i32>,
|
||||||
|
map: HexMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -22,11 +23,16 @@ impl Game for World {
|
||||||
img: Image::load_data(include_bytes!("assets/test.gif")),
|
img: Image::load_data(include_bytes!("assets/test.gif")),
|
||||||
font: Tileset::load_data(include_bytes!("assets/ega-8x14.gif"), Vec2 { x: 16, y: 16 }),
|
font: Tileset::load_data(include_bytes!("assets/ega-8x14.gif"), Vec2 { x: 16, y: 16 }),
|
||||||
pos: Vec2::zero(),
|
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) {
|
fn update(&mut self, window_state: &mut WindowState) {
|
||||||
self.pos = window_state.mouse_pos();
|
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) {
|
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) {
|
fn draw(&self, target: &mut Image) {
|
||||||
target.clear();
|
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_image(self.pos, self.font.get(68));
|
||||||
|
|
||||||
target.draw_line(
|
target.draw_line(
|
||||||
|
@ -51,5 +58,7 @@ impl Game for World {
|
||||||
self.pos,
|
self.pos,
|
||||||
10,
|
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
|
//odd-q vertical layout https://www.redblobgames.com/grids/hexagons
|
||||||
pub struct HexMap {
|
pub struct HexMap {
|
||||||
size: Vec2<i32>,
|
size: Vec2<i32>,
|
||||||
data: Vec<i32>,
|
data: Vec<i32>,
|
||||||
tile_size: Vec2<i32>,
|
tileset: Rc<Tileset>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HexMap {
|
impl HexMap {
|
||||||
//pub static
|
//pub static
|
||||||
pub fn new(size: Vec2<i32>, tile_size: Vec2<i32>) -> Self {
|
pub fn new(size: Vec2<i32>, tileset: Rc<Tileset>) -> Self {
|
||||||
HexMap {
|
HexMap {
|
||||||
size,
|
size,
|
||||||
data: vec![0; size.size()],
|
data: vec![0; size.size()],
|
||||||
tile_size,
|
tileset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +32,22 @@ impl HexMap {
|
||||||
self.size
|
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
|
//priv
|
||||||
fn coord_to_idx(&self, coord: Vec2<i32>) -> usize {
|
fn coord_to_idx(&self, coord: Vec2<i32>) -> usize {
|
||||||
(coord.x + coord.y * self.size.x) as 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::vec2::Vec2;
|
||||||
use crate::{HexMap, Rect};
|
use crate::{HexMap, Rect, Tileset};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -55,9 +55,13 @@ impl Image {
|
||||||
self.data.as_slice()
|
self.data.as_slice()
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn draw_hexmap(&mut self, pos: Vec2<i32>, hexmap: &HexMap) {
|
pub fn draw_hexmap(&mut self, pos: Vec2<i32>, hexmap: &HexMap) {
|
||||||
// for pos in Vec2::zero()..pos {}
|
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) {
|
pub fn draw_image(&mut self, pos: Vec2<i32>, image: &Image) {
|
||||||
self.draw_image_partial(
|
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) {
|
pub fn fill(&mut self, color: u8) {
|
||||||
self.data.fill(color);
|
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 {
|
pub fn get_pixel(&self, pos: Vec2<i32>) -> u8 {
|
||||||
self.data[(pos.x + self.size.x * pos.y) as usize]
|
self.data[(pos.x + self.size.x * pos.y) as usize]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
mod console;
|
||||||
mod hexmap;
|
mod hexmap;
|
||||||
mod image;
|
mod image;
|
||||||
mod rect;
|
mod rect;
|
||||||
|
@ -5,6 +6,7 @@ mod tileset;
|
||||||
mod vec2;
|
mod vec2;
|
||||||
mod window;
|
mod window;
|
||||||
|
|
||||||
|
pub use console::*;
|
||||||
pub use hexmap::*;
|
pub use hexmap::*;
|
||||||
pub use image::*;
|
pub use image::*;
|
||||||
pub use rect::*;
|
pub use rect::*;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::vec2::Vec2;
|
use crate::vec2::Vec2;
|
||||||
|
use crate::Vec2Iter;
|
||||||
use num::{Num, ToPrimitive};
|
use num::{Num, ToPrimitive};
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -19,6 +20,10 @@ impl<T: Num + Copy + ToPrimitive + PartialOrd> Rect<T> {
|
||||||
self.pos + self.size
|
self.pos + self.size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> Vec2Iter<T> {
|
||||||
|
self.pos.iter_to(self.size)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn contains(&self, point: Vec2<T>) -> bool {
|
pub fn contains(&self, point: Vec2<T>) -> bool {
|
||||||
let p2 = self.pos2();
|
let p2 = self.pos2();
|
||||||
point.x >= self.pos.x && point.y >= self.pos.y && point.x < p2.x && point.y < p2.y
|
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,
|
x: img.size().x / tile_count.x,
|
||||||
y: img.size().y / tile_count.y,
|
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);
|
let mut image = Image::new(size);
|
||||||
image.draw_image_partial(
|
image.draw_image_partial(
|
||||||
Vec2::zero(),
|
Vec2::zero(),
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
|
use crate::console::Console;
|
||||||
use crate::image::Image;
|
use crate::image::Image;
|
||||||
use crate::vec2::Vec2;
|
use crate::vec2::Vec2;
|
||||||
|
use crate::Tileset;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
use std::num::NonZeroU32;
|
use std::num::NonZeroU32;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use winit::dpi::LogicalSize;
|
use winit::dpi::LogicalSize;
|
||||||
use winit::event::VirtualKeyCode::Escape;
|
use winit::event::ElementState::Pressed;
|
||||||
|
use winit::event::VirtualKeyCode::{Escape, F12};
|
||||||
use winit::event::{
|
use winit::event::{
|
||||||
ElementState, Event as WinitEvent, MouseButton as WinitMouseButton, WindowEvent,
|
ElementState, Event as WinitEvent, MouseButton as WinitMouseButton, WindowEvent,
|
||||||
};
|
};
|
||||||
|
@ -37,13 +40,21 @@ pub trait Game {
|
||||||
pub struct WindowState {
|
pub struct WindowState {
|
||||||
palette: [u32; 256],
|
palette: [u32; 256],
|
||||||
mouse_pos: Vec2<i32>,
|
mouse_pos: Vec2<i32>,
|
||||||
|
console: Console,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowState {
|
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 {
|
WindowState {
|
||||||
palette: [0u32; 256],
|
palette: [0u32; 256],
|
||||||
mouse_pos: Vec2::zero(),
|
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) {
|
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,
|
x: width,
|
||||||
y: height,
|
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);
|
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 frames_since_last_second = 0;
|
||||||
let mut last_second = Instant::now();
|
let mut last_second = Instant::now();
|
||||||
|
@ -129,6 +147,9 @@ pub fn run<T: Game + 'static>(width: i32, height: i32) {
|
||||||
if k == Escape {
|
if k == Escape {
|
||||||
*control_flow = ControlFlow::Exit;
|
*control_flow = ControlFlow::Exit;
|
||||||
}
|
}
|
||||||
|
if k == F12 && input.state == Pressed {
|
||||||
|
display_console = !display_console;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
WindowEvent::ModifiersChanged(_) => {}
|
WindowEvent::ModifiersChanged(_) => {}
|
||||||
|
@ -181,6 +202,13 @@ pub fn run<T: Game + 'static>(width: i32, height: i32) {
|
||||||
if Instant::now() - last_frame >= target_frame_duration {
|
if Instant::now() - last_frame >= target_frame_duration {
|
||||||
game.update(&mut window_state);
|
game.update(&mut window_state);
|
||||||
game.draw(&mut screen);
|
game.draw(&mut screen);
|
||||||
|
if display_console {
|
||||||
|
window_state.console.draw_to_image(
|
||||||
|
&mut screen,
|
||||||
|
Vec2::zero(),
|
||||||
|
&internal_font,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let size = window.inner_size();
|
let size = window.inner_size();
|
||||||
surface
|
surface
|
||||||
|
|
Loading…
Reference in New Issue