├── Cargo.toml ├── README.md └── src └── main.rs /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pong" 3 | version = "0.1.0" 4 | authors = ["tensor-programming "] 5 | 6 | [dependencies] 7 | piston = "0.35.0" 8 | piston2d-graphics = "0.24.0" 9 | pistoncore-glutin_window = "0.43.0" 10 | piston2d-opengl_graphics = "0.50.0" -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rust Pong Game. 2 | 3 | # A simple Rust Pong game built in Piston. 4 | 5 | ## Run `cargo run` to run the app, run `cargo build` to build an executable file. 6 | 7 | ### Check out the Youtube Tutorial for this [Rust Tutorial](https://youtu.be/-JIlCYbpNnI). Here is our [Youtube Channel](https://www.youtube.com/channel/UCYqCZOwHbnPwyjawKfE21wg) Subscribe for more content. 8 | 9 | ### Check out our blog at [tensor-programming.com](http://tensor-programming.com/). 10 | 11 | ### Our [Twitter](https://twitter.com/TensorProgram), our [facebook](https://www.facebook.com/Tensor-Programming-1197847143611799/) and our [Steemit](https://steemit.com/@tensor). 12 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate glutin_window; 2 | extern crate graphics; 3 | extern crate opengl_graphics; 4 | extern crate piston; 5 | 6 | use std::process; 7 | use piston::window::WindowSettings; 8 | use piston::event_loop::{EventSettings, Events}; 9 | use piston::input::{Button, Key, PressEvent, ReleaseEvent, RenderArgs, RenderEvent, UpdateArgs, UpdateEvent}; 10 | use glutin_window::GlutinWindow; 11 | use opengl_graphics::{GlGraphics, OpenGL}; 12 | 13 | pub struct App { 14 | gl: GlGraphics, 15 | left_score: i32, 16 | left_pos: i32, 17 | left_vel: i32, 18 | right_score: i32, 19 | right_pos: i32, 20 | right_vel: i32, 21 | ball_x: i32, 22 | ball_y: i32, 23 | vel_x: i32, 24 | vel_y: i32, 25 | } 26 | 27 | impl App { 28 | fn render(&mut self, args: &RenderArgs) { 29 | use graphics::*; 30 | 31 | const BACKGROUND: [f32; 4] = [0.0, 0.5, 0.5, 1.0]; 32 | const FOREGROUND: [f32; 4] = [0.0, 0.0, 1.0, 1.0]; 33 | 34 | let left = rectangle::square(0.0, 0.0, 50.0); 35 | let left_pos = self.left_pos as f64; 36 | let right = rectangle::square(0.0, 0.0, 50.0); 37 | let right_pos = self.right_pos as f64; 38 | 39 | let ball = rectangle::square(0.0, 0.0, 10.0); 40 | let ball_x = self.ball_x as f64; 41 | let ball_y = self.ball_y as f64; 42 | 43 | self.gl.draw(args.viewport(), |c, gl| { 44 | clear(BACKGROUND, gl); 45 | rectangle(FOREGROUND, left, c.transform.trans(-40.0, left_pos), gl); 46 | rectangle( 47 | FOREGROUND, 48 | right, 49 | c.transform.trans(args.window_size[0] as f64 - 10.0, right_pos), 50 | gl, 51 | ); 52 | rectangle(FOREGROUND, ball, c.transform.trans(ball_x, ball_y), gl); 53 | }); 54 | } 55 | 56 | fn update(&mut self, _args: &UpdateArgs) { 57 | if (self.left_vel == 1 && self.left_pos < 291) 58 | || (self.left_vel == -1 && self.left_pos >= 1) 59 | { 60 | self.left_pos += self.left_vel; 61 | } 62 | if (self.right_vel == 1 && self.right_pos < 291) 63 | || (self.right_vel == -1 && self.right_pos >= 1) 64 | { 65 | self.right_pos += self.right_vel; 66 | } 67 | self.ball_x += self.vel_x; 68 | if self.ball_x > 502 { 69 | self.vel_x = -self.vel_x; 70 | if self.ball_y < self.right_pos || self.ball_y > self.right_pos + 50 { 71 | self.left_score += 1; 72 | if self.left_score >= 5 { 73 | println!("Left wins!"); 74 | process::exit(0); 75 | } 76 | self.ball_x = 256; 77 | self.ball_y = 171; 78 | } 79 | } 80 | if self.ball_x < 1 { 81 | self.vel_x = -self.vel_x; 82 | if self.ball_y < self.left_pos || self.ball_y > self.left_pos + 50 { 83 | self.right_score += 1; 84 | if self.right_score >= 5 { 85 | println!("Right wins!"); 86 | process::exit(0); 87 | } 88 | self.ball_x = 256; 89 | self.ball_y = 171; 90 | } 91 | } 92 | 93 | self.ball_y += self.vel_y; 94 | if self.ball_y > 332 || self.ball_y < 1 { 95 | self.vel_y = -self.vel_y; 96 | } 97 | } 98 | 99 | fn press(&mut self, args: &Button) { 100 | if let &Button::Keyboard(key) = args { 101 | match key { 102 | Key::Up => { 103 | self.right_vel = -1; 104 | } 105 | Key::Down => { 106 | self.right_vel = 1; 107 | } 108 | Key::W => { 109 | self.left_vel = -1; 110 | } 111 | Key::S => { 112 | self.left_vel = 1; 113 | } 114 | _ => {} 115 | } 116 | } 117 | } 118 | 119 | fn release(&mut self, args: &Button) { 120 | if let &Button::Keyboard(key) = args { 121 | match key { 122 | Key::Up => { 123 | self.right_vel = 0; 124 | } 125 | Key::Down => { 126 | self.right_vel = 0; 127 | } 128 | Key::W => { 129 | self.left_vel = 0; 130 | } 131 | Key::S => { 132 | self.left_vel = 0; 133 | } 134 | _ => {} 135 | } 136 | } 137 | } 138 | } 139 | 140 | fn main() { 141 | let opengl = OpenGL::V3_2; 142 | let mut window: GlutinWindow = WindowSettings::new("Pong", [512, 342]) 143 | /* .opengl(opengl) */ 144 | .exit_on_esc(true) 145 | .build() 146 | .unwrap(); 147 | 148 | let mut app = App { 149 | gl: GlGraphics::new(opengl), 150 | left_score: 0, 151 | left_pos: 1, 152 | left_vel: 0, 153 | right_score: 0, 154 | right_pos: 1, 155 | right_vel: 0, 156 | ball_x: 0, 157 | ball_y: 0, 158 | vel_x: 1, 159 | vel_y: 1, 160 | }; 161 | 162 | let mut events = Events::new(EventSettings::new()); 163 | while let Some(e) = events.next(&mut window) { 164 | if let Some(r) = e.render_args() { 165 | app.render(&r); 166 | } 167 | 168 | if let Some(u) = e.update_args() { 169 | app.update(&u); 170 | } 171 | 172 | if let Some(b) = e.press_args() { 173 | app.press(&b); 174 | } 175 | 176 | if let Some(b) = e.release_args() { 177 | app.release(&b); 178 | } 179 | } 180 | } --------------------------------------------------------------------------------