rust-pilot/src/game/mod.rs

114 lines
3.2 KiB
Rust

mod controls;
mod bullet;
mod ship;
mod camera;
mod map;
use piston_window::*;
use piston_window::math::*;
use piston_window::draw_state::Blend;
use self::ship::Ship;
use self::bullet::Bullet;
use self::camera::Camera;
use self::map::Map;
use self::controls::Controls;
const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];
const RED: [f32; 4] = [1.0, 0.0, 0.0, 1.0];
const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
pub struct Game {
player: Ship,
bullets: Vec<Bullet>,
map: Map,
camera: Camera,
pub controls: Controls
}
fn draw_background<G>(g: &mut G) where G: Graphics {
clear(BLACK, g);
}
fn draw_player<G>(player: &Ship, ds: &DrawState, trans: Matrix2d, g: &mut G)
where G: Graphics {
let trans = trans
.append_transform(translate(player.position))
.rot_rad(player.rotation);
Polygon::new(RED).draw(player.geometry, ds, trans, g);
}
fn draw_bullet<G>(bullet: &Bullet, ds: &DrawState, trans: Matrix2d, g: &mut G)
where G: Graphics {
let trans = trans
.append_transform(translate(bullet.position));
Polygon::new(WHITE).draw(bullet.geometry, &ds, trans, g);
}
impl Game {
pub fn new(width: Scalar, height: Scalar) -> Self {
let new_map = Map::new(10000.0, 10000.0);
let center = new_map.center();
Game {
player: Ship::new(center),
bullets: Vec::new(),
map: new_map,
camera: Camera::new(center, width, height),
controls: Controls::new()
}
}
pub fn render<GE>(&mut self, args: RenderArgs, w: &mut PistonWindow, e: &GE) where
GE: GenericEvent
{
w.draw_2d(e, |context, gl| {
draw_background(gl);
let ds = context.draw_state.blend(Blend::Alpha);
/* Make the camera coordinate origin the center of the window */
let ct = context.transform.trans(Scalar::from(args.width / 2),
Scalar::from(args.height / 2));
let cam_pos = self.camera.position;
let cam_size= [self.camera.width, self.camera.height];
/* Transform world coordinates to camera-relative coordinates */
let cam_trans = ct.append_transform(translate(mul_scalar(cam_pos, -1.0)));
self.map.draw_grid(cam_pos, cam_size, &ds, cam_trans, gl);
for bullet in &self.bullets {
draw_bullet(&bullet, &ds, cam_trans, gl);
}
draw_player(&self.player, &ds, cam_trans, gl);
});
}
pub fn update(&mut self, args: UpdateArgs) {
let thr = self.controls.thrust_control();
let rot = self.controls.rotation_control();
let firing = self.controls.fire_control();
self.player.update(thr, rot, args.dt, &self.map);
for bullet in &mut self.bullets { bullet.update(args.dt); }
self.bullets.retain(|bullet| bullet.ttl > 0.0);
if firing {
let (nose, dir, vel) = self.player.trajectory();
let bul = Bullet::new(nose, add(vel, mul_scalar(dir, 3.0)), 2.0);
self.bullets.push(bul);
}
self.camera.follow(self.player.position, &self.map);
}
pub fn input(&mut self, inp: &Event) {
self.controls.update(inp);
}
}