extern crate clap;
extern crate ggez;
use clap::{App, Arg};
use ggez::conf;
use ggez::event::{self, Keycode, Mod};
use ggez::graphics::{self, DrawMode, Point2};
use ggez::timer;
use ggez::{Context, GameResult};
use std::env;
use std::path;
struct WindowSettings {
window_size_toggle: bool,
toggle_fullscreen: bool,
is_fullscreen: bool,
num_of_resolutions: usize,
resolution_index: usize,
resize_projection: bool,
}
struct MainState {
angle: f32, zoom: f32,
image: graphics::Image,
window_settings: WindowSettings,
}
impl MainState {
fn new(ctx: &mut Context) -> GameResult<MainState> {
let mut s = MainState {
angle: 0.0,
zoom: 1.0,
image: graphics::Image::new(ctx, "/tile.png")?,
window_settings: WindowSettings {
toggle_fullscreen: false,
window_size_toggle: false,
is_fullscreen: false,
resolution_index: 0,
num_of_resolutions: 0,
resize_projection: false,
},
};
let resolutions = ggez::graphics::get_fullscreen_modes(ctx, 0)?;
s.window_settings.num_of_resolutions = resolutions.len();
Ok(s)
}
}
impl event::EventHandler for MainState {
fn update(&mut self, ctx: &mut Context) -> GameResult<()> {
const DESIRED_FPS: u32 = 60;
while timer::check_update_time(ctx, DESIRED_FPS) {
self.angle += 0.01;
if self.window_settings.toggle_fullscreen {
ggez::graphics::set_fullscreen(ctx, self.window_settings.is_fullscreen)?;
self.window_settings.toggle_fullscreen = false;
}
if self.window_settings.window_size_toggle {
let resolutions = ggez::graphics::get_fullscreen_modes(ctx, 0)?;
let (width, height) = resolutions[self.window_settings.resolution_index];
ggez::graphics::set_resolution(ctx, width, height)?;
self.window_settings.window_size_toggle = false;
}
}
Ok(())
}
fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
graphics::set_background_color(ctx, graphics::BLACK);
graphics::clear(ctx);
let rotation = timer::get_ticks(ctx) % 1000;
graphics::set_color(ctx, graphics::WHITE)?;
let circle = graphics::Mesh::new_circle(
ctx,
DrawMode::Line(3.0),
Point2::new(0.0, 0.0),
100.0,
4.0,
)?;
graphics::draw(ctx, &self.image, Point2::new(400.0, 300.0), 0.0)?;
graphics::draw(ctx, &circle, Point2::new(400.0, 300.0), rotation as f32)?;
const COUNT: i32 = 10;
for x in -COUNT..COUNT {
for y in -COUNT..COUNT {
const SPACING: i32 = 100;
let fx = (x * SPACING) as f32;
let fy = (y * SPACING) as f32;
let r = (x as f32) / (COUNT as f32);
let b = (y as f32) / (COUNT as f32);
let color = graphics::Color::new(r, 0.0, b, 1.0);
graphics::set_color(ctx, color)?;
graphics::rectangle(
ctx,
graphics::DrawMode::Fill,
graphics::Rect::new(fx, fy, 5.0, 5.0),
)?
}
}
graphics::present(ctx);
Ok(())
}
fn mouse_button_down_event(
&mut self,
_ctx: &mut Context,
_btn: event::MouseButton,
x: i32,
y: i32,
) {
println!("Button clicked at: {} {}", x, y);
}
fn key_up_event(&mut self, ctx: &mut Context, keycode: Keycode, _keymod: Mod, repeat: bool) {
if !repeat {
match keycode {
Keycode::F => {
self.window_settings.toggle_fullscreen = true;
self.window_settings.is_fullscreen = !self.window_settings.is_fullscreen;
}
Keycode::H => {
self.window_settings.window_size_toggle = true;
self.window_settings.resolution_index += 1;
self.window_settings.resolution_index %=
self.window_settings.num_of_resolutions;
}
Keycode::G => {
if self.window_settings.resolution_index > 0 {
self.window_settings.window_size_toggle = true;
self.window_settings.resolution_index -= 1;
self.window_settings.resolution_index %=
self.window_settings.num_of_resolutions;
}
}
Keycode::Up => {
self.zoom += 0.1;
println!("Zoom is now {}", self.zoom);
let (w, h) = graphics::get_size(ctx);
let new_rect =
graphics::Rect::new(0.0, 0.0, w as f32 * self.zoom, h as f32 * self.zoom);
graphics::set_screen_coordinates(ctx, new_rect).unwrap();
}
Keycode::Down => {
self.zoom -= 0.1;
println!("Zoom is now {}", self.zoom);
let (w, h) = graphics::get_size(ctx);
let new_rect =
graphics::Rect::new(0.0, 0.0, w as f32 * self.zoom, h as f32 * self.zoom);
graphics::set_screen_coordinates(ctx, new_rect).unwrap();
}
Keycode::Space => {
self.window_settings.resize_projection =
!self.window_settings.resize_projection;
println!(
"Resizing the projection on window resize is now: {}",
self.window_settings.resize_projection
);
}
_ => {}
}
}
}
fn resize_event(&mut self, ctx: &mut Context, width: u32, height: u32) {
println!("Resized screen to {}, {}", width, height);
if self.window_settings.resize_projection {
let new_rect = graphics::Rect::new(
0.0,
0.0,
width as f32 * self.zoom,
height as f32 * self.zoom,
);
graphics::set_screen_coordinates(ctx, new_rect).unwrap();
}
}
}
fn print_help() {
println!("GRAPHICS SETTING EXAMPLE:");
println!(" F: toggle fullscreen");
println!(" G/H: Increase/decrease window sizes");
println!(" Up/Down: Zoom in/out");
println!(
" Spacebar: Toggle whether or not to resize the projection when the window is resized"
);
println!(" ");
println!(" To see command-line options, run with `cargo run --example graphics_settings -- --help`");
println!(" ");
}
pub fn main() {
let matches = App::new("ggez graphics settings example")
.arg(
Arg::with_name("msaa")
.short("m")
.value_name("N")
.help("Number of MSAA samples to do (powers of 2 from 1 to 16)")
.takes_value(true),
)
.get_matches();
let msaa: u32 = matches
.value_of("msaa")
.unwrap_or("1")
.parse()
.expect("Option msaa needs to be a number!");
let mut c = conf::Conf::new();
c.window_mode.fullscreen_type = conf::FullscreenType::Off;
c.window_setup.samples =
conf::NumSamples::from_u32(msaa).expect("Option msaa needs to be 1, 2, 4, 8 or 16!");
c.window_setup.resizable = true;
println!("{:?}", c);
let ctx = &mut Context::load_from_conf("graphics_settings", "ggez", c).unwrap();
if let Ok(manifest_dir) = env::var("CARGO_MANIFEST_DIR") {
let mut path = path::PathBuf::from(manifest_dir);
path.push("resources");
ctx.filesystem.mount(&path, true);
println!("Adding path {:?}", path);
} else {
println!("not building with cargo?");
}
print_help();
let state = &mut MainState::new(ctx).unwrap();
event::run(ctx, state).unwrap();
}