Skip to content

Commit

Permalink
Move tunel's decorations to Tunel, update README
Browse files Browse the repository at this point in the history
  • Loading branch information
juchiast committed Mar 18, 2017
1 parent 8f16317 commit b3633e8
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 79 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This game was written with hope to be a good example of game development in Rust

Download binary (64-bit Windows and Linux) here: https://github.com/juchiast/boxcrash/releases

This code should be compiled with the latest stable version of Rust (1.15.1 as of this writing).
This code should be compiled with the latest stable version of Rust (1.16.0 as of this writing).

Almost all game's constants are configurable via `resources/config.json`.
You should edit the screen size details to match your monitor.
Expand Down Expand Up @@ -38,7 +38,7 @@ This seem to be a piston\_window's bug.
- Write an article about the writing of this code.
- Fix some known bugs.
- Test game on more machines.
- Write a GUI to configure and restart game.
- ~~Write a GUI to configure and restart game~~ (Done).
- Draw more details of box and the road.
- Add crashing animations.
- Add some sounds.
Expand Down
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ mod bot;
mod game;
mod ui;

type Rendered = Vec<([cgmath::Vector2<f64>; 2], color::Color)>;

// Pixel present a point in the window and window's size
#[derive(Clone, Serialize, Deserialize)]
pub struct Pixel {
Expand Down
78 changes: 74 additions & 4 deletions src/tunel.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cgmath::{Vector2, Vector3};
use cgmath::{Vector2, Vector3, vec3};
use color::*;
use camera::Camera;

Expand All @@ -8,13 +8,23 @@ pub struct Tunel {
pub size: Vector3<f64>,
// Color to draw tunel
pub color: Color,
// Road's dividers
pub divider: Vector2<f64>,
pub divider_state: f64,
// Tunel's decorations
pub decor_distance: f64,
pub decor_state: f64,
}

impl Tunel {
pub fn new(size: [f64; 3]) -> Tunel {
pub fn new(config: &::game::GameConfig) -> Tunel {
Tunel {
size: size.into(),
size: config.tunel_size.into(),
color: BLUE,
divider: config.divider_size.into(),
divider_state: config.divider_size[1],
decor_distance: config.decor_distance,
decor_state: config.decor_distance,
}
}

Expand All @@ -25,6 +35,66 @@ impl Tunel {
((0., self.size.y, 0.), (0., self.size.y, self.size.z)),
((self.size.x, self.size.y, 0.), (self.size.x, self.size.y, self.size.z)),
].into_iter().map(|(a, b)| camera.render_line(&a.into(), &b.into()))
.filter_map(|x| x.map(|x| (x, self.color))).collect()
.filter_map(|x| x.map(|x| (x, self.color)))
.chain(self.divider_render(camera))
.chain(self.decor_render(camera))
.collect()
}

pub fn update(&mut self, dt: f64, speed: f64) {
self.divider_state -= dt*speed;
if self.divider_state < 0. {
self.divider_state += 2.*self.divider.y;
}
self.decor_state -= dt*speed;
if self.decor_state < 0. {
self.decor_state += self.decor_distance;
}
}

fn divider_render(&self, camera: &Camera) -> ::Rendered {
let mut points = [vec3(self.size.x/2., 0., self.divider_state); 4];
points[2].z -= self.divider.y; points[3].z -= self.divider.y;
points[0].x -= self.divider.x/2.; points[3].x -= self.divider.x/2.;
points[1].x += self.divider.x/2.; points[2].x += self.divider.x/2.;

let mut ret = Vec::new();
{
let mut r = |p: &[Vector3<f64>; 4]| {
let iter = p.iter().zip(p.iter().cycle().skip(1))
.map(|(x, y)| camera.render_line(x, y))
.filter_map(|x| x.map(|x| (x, self.color)));
ret.append(&mut iter.collect());
};
while points[0].z <= self.size.z {
r(&points);
for p in &mut points {
p.z += 2.*self.divider.y;
}
}
r(&points);
}
ret
}
fn decor_render(&self, camera: &Camera) -> ::Rendered {
let mut data = [
vec3(0., 0., self.decor_state),
vec3(0., self.size.y, self.decor_state),
vec3(self.size.x, self.size.y, self.decor_state),
vec3(self.size.x, 0., self.decor_state),
];
let mut ret = Vec::new();
while data[0].z <= self.size.z {
for (x, y) in data.iter().zip(data.iter().skip(1)) {
if let Some(rendered) = camera.render_line(x, y) {
ret.push((rendered, self.color));
}
}
for x in &mut data {
x.z += self.decor_distance;
}
}
ret
}

}
84 changes: 11 additions & 73 deletions src/world.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use tunel::Tunel;
use car::*;
use color::*;
use cgmath::{Vector2, Vector3, vec3};
use cgmath::{Vector3, vec3};
use cgmath::prelude::*;
use game::GameConfig;
use camera::Camera;
Expand All @@ -11,64 +11,9 @@ pub struct World {
pub tunel: Tunel,
pub player: BoxCar,
pub bots: Vec<Bot>,
pub divider: Vector2<f64>,
pub decor_distance: f64,
pub divider_state: f64,
pub decor_state: f64,
pub bullets: Vec<[Vector3<f64>; 3]>,
}
type Rendered = Vec<([Vector2<f64>; 2], Color)>;
impl World {
fn divider_render(&self, camera: &Camera) -> Rendered {
let mut points = [vec3(self.tunel.size.x/2., 0., self.divider_state); 4];
points[2].z -= self.divider.y; points[3].z -= self.divider.y;
points[0].x -= self.divider.x/2.; points[3].x -= self.divider.x/2.;
points[1].x += self.divider.x/2.; points[2].x += self.divider.x/2.;

let mut ret = Vec::new();
{
let mut r = |p: &[Vector3<f64>; 4]| {
let iter = p.iter().zip(p.iter().cycle().skip(1))
.map(|(x, y)| camera.render_line(x, y))
.filter_map(|x| x.map(|x| (x, self.tunel.color)));
ret.append(&mut iter.collect());
};
while points[0].z <= self.tunel.size.z {
r(&points);
for p in &mut points {
p.z += 2.*self.divider.y;
}
}
r(&points);
}
ret
}
fn decor_render(&self, camera: &Camera) -> Rendered {
let mut data = [
vec3(0., 0., self.decor_state),
vec3(0., self.tunel.size.y, self.decor_state),
vec3(self.tunel.size.x, self.tunel.size.y, self.decor_state),
vec3(self.tunel.size.x, 0., self.decor_state),
];
let mut ret = Vec::new();
while data[0].z <= self.tunel.size.z {
for (x, y) in data.iter().zip(data.iter().skip(1)) {
if let Some(rendered) = camera.render_line(x, y) {
ret.push((rendered, self.tunel.color));
}
}
for x in &mut data {
x.z += self.decor_distance;
}
}
ret
}
fn bullets_render(&self, camera: &Camera) -> Rendered {
self.bullets.iter().filter_map(|x| {
camera.render_line(&x[0], &(x[0]+x[1])).map(|x| (x, self.player.color))
}).collect()
}

pub fn new(config: &GameConfig) -> World {
let player = BoxCar {
size: config.player_size.into(),
Expand All @@ -84,38 +29,25 @@ impl World {
};

World {
tunel: Tunel::new(config.tunel_size),
tunel: Tunel::new(&config),
player: player,
bots: Vec::new(),
divider: config.divider_size.into(),
divider_state: config.divider_size[1],
decor_distance: config.decor_distance,
decor_state: config.decor_distance,
bullets: Vec::new(),
}
}

pub fn render(&self, camera: &Camera) -> Rendered {
pub fn render(&self, camera: &Camera) -> ::Rendered {
Vec::new().into_iter()
.chain(self.tunel.render(camera))
.chain(self.divider_render(camera))
.chain(self.decor_render(camera))
.chain(self.player.render(camera))
.chain(self.bots.iter().flat_map(|x| x.render(camera)))
.chain(self.bullets_render(camera))
.collect()
}
pub fn update(&mut self, dt: f64, game_speed: f64) {
self.player.update_jump(dt);
let speed = game_speed + self.player.speed;
self.divider_state -= dt*speed;
if self.divider_state < 0. {
self.divider_state += 2.*self.divider.y;
}
self.decor_state -= dt*speed;
if self.decor_state < 0. {
self.decor_state += self.decor_distance;
}
self.player.update_jump(dt);
self.tunel.update(dt, speed);
for x in &mut self.bots {
x.drive(dt);
x.forward(dt, speed);
Expand Down Expand Up @@ -168,4 +100,10 @@ impl World {
direction,
]);
}

fn bullets_render(&self, camera: &Camera) -> ::Rendered {
self.bullets.iter().filter_map(|x| {
camera.render_line(&x[0], &(x[0]+x[1])).map(|x| (x, self.player.color))
}).collect()
}
}

0 comments on commit b3633e8

Please sign in to comment.