Skip to content

Instantly share code, notes, and snippets.

@desophos
Created May 25, 2015 20:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save desophos/25559efaf50b8558fd48 to your computer and use it in GitHub Desktop.
Save desophos/25559efaf50b8558fd48 to your computer and use it in GitHub Desktop.
extern crate rand;
extern crate graphics;
extern crate image;
extern crate sprite;
extern crate cgmath;
use std::rc::Rc;
use std::clone::Clone;
use std::path::PathBuf;
use std::borrow::Borrow;
use self::rand::distributions::{ Range, IndependentSample };
use graphics::math::Matrix2d;
use glium::{ Texture2d, Surface };
use glium_graphics::{ GliumGraphics, GliumWindow, DrawTexture };
use self::sprite::Sprite;
fn rand_choices<'a, T: 'a + Clone>(items: &Vec<T>, n: usize) -> Vec<T> {
let range = Range::new(0, items.len());
let mut rng = rand::thread_rng();
let mut choices: Vec<T> = Vec::with_capacity(n);
for _ in 0..n {
// grab item at random index of items
choices.push(items[range.ind_sample(&mut rng)].clone());
}
choices
}
pub struct Gene {
pub name: String,
pub sprite: Sprite<DrawTexture>,
}
impl Gene {
fn new((nm, w): (&str, Rc<GliumWindow>)) -> Gene {
let mut path = PathBuf::from(".");
path.push("bin");
path.push("assets");
path.push(format!("{}.png", nm));
Gene {
name: nm.to_string(),
sprite: Sprite::from_texture(
Rc::new(
DrawTexture::new({
Texture2d::new(
&*w, image::open(&path).unwrap()
)
})
)
),
}
}
}
pub struct Genome<'a> {
pub genes: Vec<Gene>,
possible_genes: Vec<(&'a str, Rc<GliumWindow>)>,
}
impl<'a> Genome<'a> {
pub fn new(w: Rc<GliumWindow>) -> Genome<'a> {
let possible_gs = vec![
("A", w.clone()),
("B", w.clone()),
("C", w.clone()),
];
let mut gs = Vec::<Gene>::with_capacity(10);
for gene_args in rand_choices(&possible_gs, 10).into_iter() {
gs.push(Gene::new(gene_args));
}
Genome {
genes: gs,
possible_genes: possible_gs,
}
}
fn add_gene(&mut self, gene: Gene) {
self.genes.push(gene)
}
fn add_random_gene(&mut self) {
let new_gene = Gene::new(rand_choices(&self.possible_genes, 1).pop().unwrap());
self.add_gene(new_gene); // can't borrow self again in the same expression
}
pub fn stringify(&self) -> String {
self.genes.iter().fold("".to_string(), |acc, gene| acc.to_string() + &gene.name)
}
}
mod genome;
extern crate piston;
extern crate image;
extern crate graphics;
extern crate window;
extern crate glium;
extern crate glium_graphics;
extern crate glutin_window;
extern crate shader_version;
extern crate cgmath;
use std::rc::Rc;
use std::cell::RefCell;
use std::borrow::Borrow;
use window::Window;
use image::GenericImage;
use glium::{ Surface, Texture2d, Frame };
use glium_graphics::{ Glium2d, GliumGraphics, GliumWindow, DrawTexture };
use graphics::{ clear, Transformed };
use graphics::math::Matrix2d;
use piston::window::{ WindowSettings, Size };
use piston::event::*;
use piston::input;
use piston::input::{ Input, Key, mouse, keyboard };
use glutin_window::GlutinWindow;
use shader_version::opengl;
use cgmath::*;
//use cgmath::aabb::Aabb;
//use cgmath::vector::Vector2;
//use cgmath::point::Point;
/*
trait Renderable {
fn render<'d, 's, S: Surface>(&self, g: &mut GliumGraphics<'d, 's, S>, w: &GliumWindow, transform: Matrix2d);
fn getPos(&self) -> (f64, f64);
fn setPos(&mut self, pos: (f64, f64));
}
*/
pub struct App<'a> {
w: Rc<RefCell<GlutinWindow>>,
gw: Rc<GliumWindow>,
g2d: Glium2d,
gen: genome::Genome<'a>,
}
impl<'a> App<'a> {
fn render(&mut self, args: &RenderArgs) {
let mut target = self.gw.draw();
{
let mut g = GliumGraphics::new(&mut self.g2d, &mut target);
const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
//const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];
clear(WHITE, &mut g);
let mut x: f64 = 0.0;
// have to specify type for borrow
let borrowed_window: &RefCell<GlutinWindow> = self.w.borrow();
let dim = borrowed_window.borrow().size();
let transform = graphics::math::abs_transform(dim.width as f64, dim.height as f64);
for gene in self.gen.genes.iter_mut() {
let gene_w = gene.sprite.bounding_box()[2]; // width
let gene_h = gene.sprite.bounding_box()[3]; // height
gene.sprite.set_position(x + gene_w/2.0, gene_h/2.0);
//println!("{} {}", gene.sprite.position().0, gene.sprite.position().1);
gene.sprite.draw(transform, &mut g);
x += gene_w; // draw genes next to each other
}
//println!("");
}
target.finish();
}
fn update(&mut self, args: &UpdateArgs) {
}
fn press(&mut self, args: &input::Button, cursor: &(f64, f64)) {
println!("{:?}", self.gen.stringify());
if let &input::Button::Mouse(button) = args {
println!("Pressed mouse button '{:?}'", button);
if button == mouse::MouseButton::Left {
for gene in self.gen.genes.iter() {
let aabb: Aabb2<f64> = Aabb2::new(
Point2::new( // top left
gene.sprite.bounding_box()[0],
gene.sprite.bounding_box()[1]
),
Point2::new( // bottom right
gene.sprite.bounding_box()[2],
gene.sprite.bounding_box()[3]
)
);
if aabb.contains(&Point2::new(cursor.0, cursor.1)) {
//println!("{} {}", cursor.0, cursor.1);
//println!("{} {}, {} {}", aabb.min.x, aabb.min.y, aabb.max.x, aabb.max.y);
println!("gene {} clicked", gene.name);
}
}
}
}
if let &input::Button::Keyboard(key) = args {
println!("Pressed key '{:?}'", key);
}
}
}
fn main() {
let opengl = opengl::OpenGL::_3_2;
let settings = WindowSettings::new(
"My application".to_string(),
Size::from((200, 200))
).exit_on_esc(true);
let window = Rc::new(RefCell::new(
GlutinWindow::new(opengl, settings)
));
let glium_window = Rc::new(GliumWindow::new(&window).unwrap());
let mut app = App {
w: window.clone(),
gw: glium_window.clone(),
g2d: Glium2d::new(opengl, &*glium_window.clone()),
gen: genome::Genome::new(glium_window.clone())
};
let mut cursor = (0.0, 0.0);
for e in window.events() {
if let Some(r) = e.render_args() {
app.render(&r);
}
if let Some(u) = e.update_args() {
app.update(&u);
}
e.mouse_cursor(|x, y| {
cursor = (x, y);
});
if let Some(p) = e.press_args() {
app.press(&p, &cursor);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment