Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extern crate piston_window;
- extern crate rand;
- extern crate array_init;
- extern crate hsl;
- use piston_window::*;
- use rand::Rng;
- use hsl::*;
- const CUBE_SIZE: i32 = 100;
- const NUM_CUBES: usize = 8;
- const PIXEL_SIZE: i32 = 10; //CUBE_SIZE / PIXEL_SIZE should be a whole number. This is used to split the rendering of the cubes into pixels, as to have diffrent colors
- fn main() {
- let mut window: PistonWindow = WindowSettings::new("Window", [800, 800]).exit_on_esc(true).build().unwrap();
- let mut cube_array: [Cube; NUM_CUBES] = array_init::array_init(|_i| Cube::new(&window));
- let max = CUBE_SIZE / PIXEL_SIZE;
- let mut time = 0;
- let mul = 2;
- while let Some(event) = window.next() {
- let mut local_pos_array: [Position; NUM_CUBES] = array_init::array_init(|i| cube_array[i].get_local(&window));
- let size = window.size();
- window.draw_2d(&event, |context, graphics| {
- clear([0.1; 4], graphics);
- for i in 0..NUM_CUBES {
- let pos = &local_pos_array[i];
- for x in 0..max {
- for y in 0..max {
- let color = HSL {
- h: ((pos.x + x * PIXEL_SIZE) as f64 / (size.width as i32 - CUBE_SIZE) as f64) * 360.0,
- s: 0.5,
- l: {
- let mut l = (pos.y + y * PIXEL_SIZE) as f64 / (size.height as i32 - CUBE_SIZE) as f64;
- if l < 0.0 {
- l = 0.0;
- }
- if l > 1.0 {
- l = 1.0;
- }
- l = l * 0.7 + 0.15; //Get a range between 0.15 and 0.85
- 1.0 - l
- }
- }.to_rgb();
- rectangle([color.0 as f32 / 255.0, color.1 as f32 / 255.0, color.2 as f32 / 255.0, 1.0],
- [(pos.x + x * PIXEL_SIZE) as f64, (pos.y + y * PIXEL_SIZE) as f64, PIXEL_SIZE as f64, PIXEL_SIZE as f64],
- context.transform,
- graphics);
- }
- }
- }
- });
- time += 1;
- if time % mul != 0 {
- continue;
- }
- let position_array: [Position; NUM_CUBES] = array_init::array_init(|i| cube_array[i].get_position());
- for i in 0..NUM_CUBES {
- let cube = &mut cube_array[i];
- cube.tick(&window, &position_array, i as i32)
- }
- }
- }
- struct Cube {
- pub r: f32,
- pub g: f32,
- pub b: f32,
- x_pos: i32,
- y_pos: i32,
- x_dir: i32,
- y_dir: i32
- }
- impl Cube {
- pub fn new(window: &PistonWindow) -> Cube {
- let position: Position = window.get_position().unwrap();
- let size: Size = window.size();
- let mut rng = rand::thread_rng();
- let mut x = 1;
- if rng.gen_bool(0.5) {
- x = -1;
- }
- let mut y = 1;
- if rng.gen_bool(0.5) {
- y = -1;
- }
- Cube {
- r: rng.gen(),
- g: rng.gen(),
- b: rng.gen(),
- x_pos: position.x + rng.gen_range(0, size.height as i32 - CUBE_SIZE),
- y_pos: position.y + rng.gen_range(0, size.height as i32 - CUBE_SIZE),
- x_dir: x,
- y_dir: y
- }
- }
- pub fn get_local(&self, window: &PistonWindow) -> Position {
- let position: Position = window.get_position().unwrap();
- Position {
- x: self.x_pos - position.x,
- y: self.y_pos - position.y
- }
- }
- pub fn tick(&mut self, window: &PistonWindow, positions: &[Position; NUM_CUBES], index: i32) {
- let pos: Position = self.get_local(window);
- let size: Size = window.size();
- let window_pos = window.get_position().unwrap();
- //Detect wall collision
- if pos.x < 0 || pos.x + CUBE_SIZE > size.width as i32 {
- self.x_dir *= -1;
- if pos.x < 0 { //If outside of the window, go into the window
- self.x_pos = window_pos.x;
- } else {
- self.x_pos = window_pos.x + size.width as i32 - CUBE_SIZE;
- }
- }
- if pos.y < 0 || pos.y + CUBE_SIZE > size.height as i32 {
- self.y_dir *= -1;
- if pos.y < 0 { //If outside of the window, go into the window
- self.y_pos = window_pos.y;
- } else {
- self.y_pos = window_pos.y + size.height as i32 - CUBE_SIZE;
- }
- }
- //Detect cube collision
- for i in 0..NUM_CUBES {
- if i as i32 == index { //Don't collide with self
- continue;
- }
- let pos = positions[i];
- let mut dest_x = pos.x + CUBE_SIZE + 1;
- let mut dest_y = pos.y + CUBE_SIZE + 1;
- let mut intersect_x = (pos.x + CUBE_SIZE) - self.x_pos;
- let mut intersect_y = (pos.y + CUBE_SIZE) - self.y_pos;
- //Im getting the intersect from the bottom of the cube, meaning that the top of the cube may still be intersected
- if intersect_x > CUBE_SIZE && intersect_x < 2 * CUBE_SIZE {
- intersect_x = CUBE_SIZE - (intersect_x - CUBE_SIZE);
- dest_x = pos.x - CUBE_SIZE - 1;
- }
- if intersect_y > CUBE_SIZE && intersect_y < 2 * CUBE_SIZE {
- intersect_y = CUBE_SIZE - (intersect_y - CUBE_SIZE);
- dest_y = pos.y - CUBE_SIZE - 1;
- }
- if intersect_x > 0 && intersect_x < CUBE_SIZE && intersect_y > 0 && intersect_y < CUBE_SIZE {
- if intersect_x == intersect_y {//When intersections are the same, meaning that the cubes are colliding at 45 degrees to each other.
- self.x_dir *= -1;
- self.y_dir *= -1;
- self.x_pos = dest_x;
- self.y_pos = dest_y;
- } else if intersect_x > intersect_y {
- self.y_dir *= -1;
- self.y_pos = dest_y;
- } else {
- self.x_dir *= -1;
- self.x_pos = dest_x;
- }
- }
- }
- self.x_pos += self.x_dir;
- self.y_pos += self.y_dir;
- }
- pub fn get_position(&self) -> Position {
- Position {
- x: self.x_pos,
- y: self.y_pos
- }
- }
- }
Add Comment
Please, Sign In to add comment