Skip to content

Instantly share code, notes, and snippets.

@LLBlumire
Created December 22, 2015 21:48
Show Gist options
  • Save LLBlumire/ea09341418803a527a10 to your computer and use it in GitHub Desktop.
Save LLBlumire/ea09341418803a527a10 to your computer and use it in GitHub Desktop.
A simple implementation of Pong, NOTE: Collision engine not written
// piston_window is our game engine
extern crate piston_window;
// rand is for random number generation
extern crate rand;
// Lets us do custom implementations of the `+` function.
use std::ops::Add;
// Bring all of our game engine stuff into scope
use piston_window::*;
// Bring our randon number gerneration into scope
use rand::{Rng, thread_rng};
// PI. Because PI
use std::f64::consts::PI;
fn main() {
// Our viewport
let mut viewport: [u32; 2] = [800, 600];
// The game window
let window: PistonWindow = WindowSettings::new("My First Game", viewport).build().unwrap();
// Our paddles
let mut paddles: [Paddle; 2] = build_paddles(viewport);
// The Ball
let mut ball = generate_ball(viewport);
// Poll events from our window, loading the window
for event in window {
// If it's a render event, do the following
if let Some(render) = event.render_args() {
// Draw to the screen
event.draw_2d(|c, g| {
// Clear the screen
clear([0.0, 0.0, 0.0, 1.0], g);
// For both our paddles
for paddle in paddles.iter() {
// Draw the paddle rectangle
rectangle([1.0; 4],
[0.0, 0.0, paddle.size[0], paddle.size[1]],
c.transform.trans(
paddle.center_coord.0 - paddle.size[0]/2.0,
paddle.center_coord.1 - paddle.size[1]/2.0),
g);
}
// Draw the ball rectangle
rectangle([1.0; 4],
[0.0, 0.0, ball.size[0], ball.size[1]],
c.transform.trans(
ball.center_coord.0 - ball.size[0]/2.0,
ball.center_coord.1 - ball.size[1]/2.0),
g);
});
}
// If it's a key press event, do the following
if let Some(Button::Keyboard(key)) = event.press_args() {
// Check which key it is, change the movement variable accordingly
match key {
Key::A => paddles[0].left = true,
Key::D => paddles[0].right = true,
Key::J => paddles[1].left = true,
Key::L => paddles[1].right = true,
_ => {}
}
}
// If it's a key release event, do the following
if let Some(Button::Keyboard(key)) = event.release_args() {
// Check which key it is, change the movement variable accordingly
match key {
Key::A => paddles[0].left = false,
Key::D => paddles[0].right = false,
Key::J => paddles[1].left = false,
Key::L => paddles[1].right = false,
_ => {}
}
}
// If it's an update event, do the following
if let Some(update) = event.update_args() {
// Foe each of our paddles
for paddle in paddles.iter_mut() {
// Move the paddle 3/5ths of the way across the screen in the active key direction
// each second.
paddle.center_coord.0 += update.dt *
(viewport[0] as f64 * 3.0 / 5.0) *
(paddle.right as u8 as f64);
paddle.center_coord.0 -= update.dt *
(viewport[0] as f64 * 3.0 / 5.0) *
(paddle.left as u8 as f64);
}
// Move the ball half way across the screen each second
ball.center_coord = update.dt
ball.center_coord + (viewport[0]*0.5*ball.bearing.cos(),
viewport[1]*0.5*ball.bearing.sin());
}
// If it's a resize event, do the following
if let Some(resize) = event.resize_args() {
// Resize the screen
viewport = resize;
// Reset the paddles
paddles = build_paddles(viewport);
// Reset the ball
ball = generate_ball(viewport);
}
}
}
/// Build a new paddle
fn build_paddles(viewport: [u32; 2]) -> [Paddle; 2] {
[Paddle::new(Point(viewport[0] as f64/2.0, viewport[1] as f64/10.0), viewport),
Paddle::new(Point(viewport[0] as f64/2.0, viewport[1] as f64 * 9.0 / 10.0), viewport)]
}
/// Generate a new ball
fn generate_ball(viewport: [u32; 2]) -> Ball {
Ball::new(viewport)
}
/// A point on the screen
struct Point(f64, f64);
impl Add<(f64, f64)> for Point {
type Output = Point;
/// Add a tuple to our point, Point(a, b) + (c, d) = Point(a+c, b+d)
fn add(self, rhs: (f64, f64)) -> Self::Output {
Point(self.0 + rhs.0, self.1 + rhs.1)
}
}
/// A paddle
struct Paddle {
center_coord: Point,
size: [f64; 2],
left: bool,
right: bool
}
impl Paddle {
/// Build a new paddle
fn new(center_coord: Point, viewport: [u32; 2]) -> Self {
Paddle {
center_coord: center_coord,
size: [(viewport[0] / 7) as f64, (viewport[1] / 20) as f64],
left: false,
right: false
}
}
}
/// the ball
struct Ball {
center_coord: Point,
size: [f64; 2],
bearing: f64 // Radians, Bearing
}
impl Ball {
/// Build a new ball
fn new(viewport: [u32; 2]) -> Self {
Ball {
center_coord: Point(viewport[0] as f64/2.0, viewport[1] as f64/2.0),
size: [viewport[0] as f64/50.0, viewport[1] as f64/50.0],
bearing: thread_rng().gen_range(0.0, PI * 2.0)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment