parent
cf9392a33b
commit
a6a1949914
File diff suppressed because it is too large
Load Diff
@ -0,0 +1 @@ |
||||
//! Handle user CLI inputs
|
@ -0,0 +1,5 @@ |
||||
|
||||
|
||||
pub const NAME: &'static str = "RST Node"; |
||||
pub const VERSION: &'static str = env!("CARGO_PKG_VERSION"); |
||||
pub const AUTHORS: &'static str = env!("CARGO_PKG_AUTHORS"); |
@ -0,0 +1,30 @@ |
||||
//! Small context builder
|
||||
|
||||
use crate::{ |
||||
constants::{AUTHORS, NAME, VERSION}, |
||||
GameSettings, |
||||
}; |
||||
|
||||
use ggez::{ |
||||
conf::{WindowMode, WindowSetup}, |
||||
ContextBuilder, |
||||
}; |
||||
|
||||
/// Construct a context builder with default & user window settings
|
||||
pub fn build(settings: &GameSettings) -> ContextBuilder { |
||||
ContextBuilder::new(NAME, AUTHORS) |
||||
.window_setup(WindowSetup { |
||||
title: format!("{} (v{})", NAME, VERSION), |
||||
samples: (&settings.graphics.samples).into(), |
||||
vsync: settings.graphics.vsync, |
||||
icon: "".into(), |
||||
srgb: true, |
||||
}) |
||||
.window_mode(WindowMode { |
||||
width: settings.window.width as f32, |
||||
height: settings.window.height as f32, |
||||
maximized: settings.window.window_mode.maximized(), |
||||
fullscreen_type: settings.window.window_mode._type(), |
||||
..Default::default() |
||||
}) |
||||
} |
@ -0,0 +1,43 @@ |
||||
//! Game entity rendering
|
||||
//!
|
||||
//! Generally the naming convention should be: `{type}Rndr`
|
||||
//! (`Renderer`, but shorter).
|
||||
|
||||
use super::prelude::*; |
||||
|
||||
use rst_core::data::Node; |
||||
use std::sync::Arc; |
||||
|
||||
/// A set of universal X/Y coordinates
|
||||
pub struct Coordinates(pub f32, pub f32); |
||||
|
||||
impl<'a> From<&'a Coordinates> for Point2<f32> { |
||||
fn from(c: &'a Coordinates) -> Self { |
||||
Point2 { x: c.0, y: c.1 } |
||||
} |
||||
} |
||||
|
||||
pub struct NodeRndr { |
||||
pub loc: Coordinates, |
||||
pub inner: Arc<Node>, |
||||
} |
||||
|
||||
impl EventHandler for NodeRndr { |
||||
fn update(&mut self, _: &mut Context) -> GameResult<()> { |
||||
Ok(()) |
||||
} |
||||
|
||||
fn draw(&mut self, ctx: &mut Context) -> GameResult<()> { |
||||
let circ = Mesh::new_circle( |
||||
ctx, |
||||
DrawMode::fill(), |
||||
Point2::from(&self.loc), |
||||
35.0, |
||||
0.1, |
||||
graphics::WHITE, |
||||
).unwrap(); |
||||
|
||||
circ.draw(ctx, DrawParam::new()).unwrap(); |
||||
Ok(()) |
||||
} |
||||
} |
@ -0,0 +1,16 @@ |
||||
//! Graphics module
|
||||
//!
|
||||
//! Each entity in the game has a graphics companion object in
|
||||
//! [`entities`](self::entities), which knows how to render a given
|
||||
//! object. Different game screens and UI elements can be found in
|
||||
//! [`ui`](self::ui).
|
||||
|
||||
pub mod entities; |
||||
pub mod ui; |
||||
|
||||
/// A utility module to include everything required to implement a
|
||||
/// graphics entity
|
||||
pub(self) mod prelude { |
||||
pub use ggez::{event::EventHandler, graphics::{self, Drawable, DrawParam, Mesh, DrawMode}, Context, GameResult}; |
||||
pub use mint::Point2; |
||||
} |
@ -0,0 +1 @@ |
||||
//! Different UI states
|
@ -1,3 +1,22 @@ |
||||
mod cli; |
||||
mod constants; |
||||
mod ctx; |
||||
mod graphics; |
||||
mod settings; |
||||
mod state; |
||||
mod window; |
||||
|
||||
pub(crate) use settings::*; |
||||
pub(crate) use state::*; |
||||
|
||||
fn main() { |
||||
println!("Hello, world!"); |
||||
let settings = default(); |
||||
|
||||
let state = ClientState::new(&settings); |
||||
window::run(&settings, state) |
||||
|
||||
// let my_game = GameState::new(&mut ctx);
|
||||
|
||||
// // Run!
|
||||
// event::run(ctx, eloop, my_game);
|
||||
} |
||||
|
@ -0,0 +1,73 @@ |
||||
//! Configuration structures for the game client
|
||||
|
||||
use ggez::conf::{FullscreenType, NumSamples}; |
||||
|
||||
pub fn default() -> GameSettings { |
||||
GameSettings { |
||||
window: WindowSettings { |
||||
width: 1280, |
||||
height: 720, |
||||
window_mode: WindowMode::Windowed, |
||||
}, |
||||
graphics: GraphicsSettings { |
||||
samples: Samples(0), |
||||
vsync: true, |
||||
}, |
||||
} |
||||
} |
||||
|
||||
/// Complete tree of basic game client settings
|
||||
pub struct GameSettings { |
||||
pub window: WindowSettings, |
||||
pub graphics: GraphicsSettings, |
||||
} |
||||
|
||||
/// Window setup specific settings
|
||||
pub struct WindowSettings { |
||||
pub width: u16, |
||||
pub height: u16, |
||||
pub window_mode: WindowMode, |
||||
} |
||||
|
||||
/// Graphic settings
|
||||
pub struct GraphicsSettings { |
||||
pub samples: Samples, |
||||
pub vsync: bool, |
||||
} |
||||
|
||||
pub struct Samples(pub u8); |
||||
|
||||
impl<'s> From<&'s Samples> for NumSamples { |
||||
fn from(s: &'s Samples) -> Self { |
||||
match s.0 { |
||||
0 => Self::Zero, |
||||
1 => Self::One, |
||||
2 => Self::Two, |
||||
4 => Self::Four, |
||||
8 => Self::Eight, |
||||
16 => Self::Sixteen, |
||||
_ => panic!("Invalid multisampling value: {}", s.0), |
||||
} |
||||
} |
||||
} |
||||
|
||||
pub enum WindowMode { |
||||
Windowed, |
||||
Fullscreen, |
||||
} |
||||
|
||||
impl WindowMode { |
||||
pub fn maximized(&self) -> bool { |
||||
match self { |
||||
Self::Fullscreen => true, |
||||
_ => false, |
||||
} |
||||
} |
||||
|
||||
pub fn _type(&self) -> FullscreenType { |
||||
match self { |
||||
Self::Fullscreen => FullscreenType::Desktop, |
||||
Self::Windowed => FullscreenType::Windowed, |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,48 @@ |
||||
//! Game client state handling
|
||||
|
||||
use crate::{ |
||||
graphics::entities::{Coordinates, NodeRndr}, |
||||
GameSettings, |
||||
}; |
||||
use ggez::{event::EventHandler, graphics, Context, GameResult}; |
||||
use rst_core::data::{Node, Owner, Upgrade}; |
||||
use std::sync::Arc; |
||||
|
||||
pub struct ClientState { |
||||
node: NodeRndr, |
||||
} |
||||
|
||||
impl ClientState { |
||||
pub fn new(_settings: &GameSettings) -> Self { |
||||
Self { |
||||
node: NodeRndr { |
||||
loc: Coordinates(250.0, 250.0), |
||||
inner: Arc::new(Node { |
||||
id: 0, |
||||
health: 100.into(), |
||||
max_health: 100.into(), |
||||
owner: Owner::Neutral, |
||||
type_: Upgrade::Base, |
||||
links: 0, |
||||
link_states: vec![], |
||||
buffer: vec![], |
||||
}), |
||||
}, |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl EventHandler for ClientState { |
||||
fn update(&mut self, _ctx: &mut Context) -> GameResult<()> { |
||||
Ok(()) |
||||
} |
||||
|
||||
fn draw(&mut self, ctx: &mut Context) -> GameResult<()> { |
||||
graphics::clear(ctx, graphics::Color::from_rgb(15, 15, 15)); |
||||
|
||||
// Render the node
|
||||
self.node.draw(ctx).unwrap(); |
||||
|
||||
graphics::present(ctx) |
||||
} |
||||
} |
@ -0,0 +1,10 @@ |
||||
//! Basic window setup code
|
||||
|
||||
use crate::{ctx, state::ClientState, GameSettings}; |
||||
use ggez::event; |
||||
|
||||
/// Start the main event loop with game settings and state
|
||||
pub fn run(settings: &GameSettings, state: ClientState) -> ! { |
||||
let (ctx, eloop) = ctx::build(settings).build().unwrap(); |
||||
event::run(ctx, eloop, state) |
||||
} |
Loading…
Reference in new issue