Created
April 11, 2016 11:47
-
-
Save vk2gpu/5a227983cb904a109721f44d1006ed1a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate sdl2; | |
use sdl2::pixels::Color; | |
use sdl2::event::Event; | |
use sdl2::keyboard::Keycode; | |
use sdl2::rect::Rect; | |
const BORDER: i32 = 32; | |
const WIDTH: i32 = 1024; | |
const HEIGHT: i32 = 768; | |
trait Drawable | |
{ | |
fn draw(&self, renderer: &mut sdl2::render::Renderer); | |
} | |
fn draw<T: Drawable>(t: &T, renderer: &mut sdl2::render::Renderer) | |
{ | |
t.draw(renderer); | |
} | |
/** | |
* Paddle. | |
*/ | |
struct Paddle | |
{ | |
x: f32, | |
y: f32, | |
width: f32, | |
height: f32 | |
} | |
impl Paddle | |
{ | |
fn new(x: f32, y: f32, width: f32, height: f32) -> Paddle | |
{ | |
Paddle | |
{ | |
x: x, | |
y: y, | |
width: width, | |
height: height | |
} | |
} | |
fn get_top(&self) -> f32 | |
{ | |
let half_h = self.height / 2.0; | |
return self.y - half_h; | |
} | |
fn get_bottom(&self) -> f32 | |
{ | |
let half_h = self.height / 2.0; | |
return self.y + half_h; | |
} | |
fn test_edge(&self, x: f32) -> bool | |
{ | |
let half_w = self.width / 2.0; | |
if self.x < ((WIDTH / 2) as f32) | |
{ | |
return x < (self.x + half_w); | |
} | |
return x > (self.x - half_w); | |
} | |
} | |
impl Drawable for Paddle | |
{ | |
fn draw(&self, renderer: &mut sdl2::render::Renderer) | |
{ | |
let half_w = self.width / 2.0; | |
let half_h = self.height / 2.0; | |
let draw_rect = Rect::new((self.x - half_w) as i32, (self.y - half_h) as i32, self.width as u32, self.height as u32); | |
renderer.set_draw_color(Color::RGB(0, 255, 0)); | |
match renderer.draw_rect(draw_rect) | |
{ | |
_ => {} | |
} | |
} | |
} | |
/** | |
* Ball. | |
*/ | |
struct Ball | |
{ | |
x: f32, | |
y: f32, | |
radius: f32, | |
dx: f32, | |
dy: f32, | |
} | |
impl Ball | |
{ | |
fn new(x: f32, y: f32, radius: f32) -> Ball | |
{ | |
Ball | |
{ | |
x: x, | |
y: y, | |
radius: radius, | |
dx: -1.0, | |
dy: 1.0, | |
} | |
} | |
} | |
impl Drawable for Ball | |
{ | |
fn draw(&self, renderer: &mut sdl2::render::Renderer) | |
{ | |
let draw_rect = Rect::new(self.x as i32, self.y as i32, self.radius as u32, self.radius as u32); | |
renderer.set_draw_color(Color::RGB(0, 255, 0)); | |
match renderer.draw_rect(draw_rect) | |
{ | |
_ => {} | |
} | |
} | |
} | |
fn main() | |
{ | |
let ctx = sdl2::init().unwrap(); | |
let video_ctx = ctx.video().unwrap(); | |
let window = match video_ctx.window("sdl2_test", WIDTH as u32, HEIGHT as u32).position_centered().opengl().build() | |
{ | |
Ok(window) => window, | |
Err(err) => panic!("Failed to create window: {}", err) | |
}; | |
let mut renderer = window.renderer().build().unwrap(); | |
renderer.set_draw_color(Color::RGB(0, 0, 0)); | |
renderer.clear(); | |
renderer.present(); | |
let mut event_pump = ctx.event_pump().unwrap(); | |
let mut test_ball = Ball::new((WIDTH / 2) as f32, (HEIGHT / 2) as f32, 8.0); | |
let mut test_paddles: [Paddle; 2] = | |
[ | |
Paddle::new(BORDER as f32, (HEIGHT / 2) as f32, 16.0, 64.0), | |
Paddle::new((WIDTH - BORDER) as f32, (HEIGHT / 2) as f32, 16.0, 64.0), | |
]; | |
let mut move_up = false; | |
let mut move_down = false; | |
'running: loop | |
{ | |
let paddle_player = 0; | |
let paddle_computer = 1; | |
for event in event_pump.poll_iter() | |
{ | |
match event | |
{ | |
Event::Quit {..} => break 'running, | |
Event::KeyDown { keycode: Some(Keycode::Escape), .. } => break 'running, | |
Event::KeyDown { keycode: Some(Keycode::Up), .. } => move_up = true, | |
Event::KeyDown { keycode: Some(Keycode::Down), .. } => move_down = true, | |
Event::KeyUp { keycode: Some(Keycode::Up), .. } => move_up = false, | |
Event::KeyUp { keycode: Some(Keycode::Down), .. } => move_down = false, | |
_ => {} | |
} | |
} | |
// Clear screen. | |
renderer.set_draw_color(Color::RGB(0, 0, 0)); | |
renderer.clear(); | |
// | |
let draw_rect = Rect::new(BORDER, BORDER, (WIDTH - BORDER * 2) as u32, (HEIGHT - BORDER * 2) as u32); | |
renderer.set_draw_color(Color::RGB(0, 255, 0)); | |
match renderer.draw_rect(draw_rect) | |
{ | |
_ => {} | |
} | |
// Update delta. | |
let delta = 1.0 / 60.0; | |
// Update paddle for player. | |
{ | |
let mut paddle = &mut test_paddles[paddle_player]; | |
if move_up | |
{ | |
if paddle.y > BORDER as f32 | |
{ | |
paddle.y -= delta; | |
} | |
} | |
if move_down | |
{ | |
if paddle.y < (HEIGHT - BORDER) as f32 | |
{ | |
paddle.y += delta; | |
} | |
} | |
} | |
// Update ball. | |
test_ball.x += test_ball.dx * delta; | |
test_ball.y += test_ball.dy * delta; | |
if test_ball.x > (WIDTH - BORDER) as f32 || test_ball.x < BORDER as f32 | |
{ | |
// Recreate ball. | |
test_ball = Ball::new((WIDTH / 2) as f32, (HEIGHT / 2) as f32, 8.0); | |
} | |
if test_ball.y > (HEIGHT - BORDER) as f32 || test_ball.y < BORDER as f32 | |
{ | |
test_ball.dy = -test_ball.dy; | |
} | |
// Paddle collision | |
for paddle in &test_paddles | |
{ | |
if test_ball.y > paddle.get_top() && test_ball.y < paddle.get_bottom() && paddle.test_edge(test_ball.x) | |
{ | |
test_ball.dx = -test_ball.dx | |
} | |
} | |
// Do draw. | |
draw(&test_ball, &mut renderer); | |
for paddle in &test_paddles | |
{ | |
draw(paddle, &mut renderer); | |
} | |
// Do present. | |
renderer.present(); | |
} | |
} |
I assume the same goes for:
match stdin.read_line(&mut user_input)
{
Err(error) => panic!("Failure reading line: {}", error),
_ => {}
}
Becomes:
stdin.read_line(&mut user_input).unwrap();
?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Some feedback:
You don't have to return, you can just have to last line without a semicolon - of course maybe you prefer return.
If you don't want to handle the Result returned by
draw_rect()
rather than an empty match you can just do:This will panic if there was an error.
Otherwise looks pretty Rusty!