Created
December 30, 2020 12:06
-
-
Save jsimmons/bcf1eaf7aa58d702ccea44965a5ea017 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
use sdl2::{event::Event, keyboard::Keycode}; | |
use slappy::{Colour, Draw, Input, Loop, TickState, Vec2}; | |
#[derive(Default)] | |
struct PongInput { | |
player_1_up: bool, | |
player_1_down: bool, | |
player_2_up: bool, | |
player_2_down: bool, | |
} | |
impl Input for PongInput { | |
fn process(&mut self, event: &Event) { | |
match event { | |
Event::KeyDown { keycode, .. } | Event::KeyUp { keycode, .. } => { | |
let is_key_down = match event { | |
Event::KeyDown { .. } => true, | |
_ => false, | |
}; | |
if keycode == &Some(Keycode::W) { | |
self.player_1_up = is_key_down; | |
} | |
if keycode == &Some(Keycode::S) { | |
self.player_1_down = is_key_down; | |
} | |
if keycode == &Some(Keycode::Up) { | |
self.player_2_up = is_key_down; | |
} | |
if keycode == &Some(Keycode::Down) { | |
self.player_2_down = is_key_down; | |
} | |
} | |
_ => {} | |
} | |
} | |
} | |
const BALL_INITIAL_POSITION: Vec2 = Vec2::new(400, 300); | |
const BALL_INITIAL_VELOCITY: Vec2 = Vec2::new(-2, 2); | |
struct Pong { | |
ball_position: Vec2, | |
ball_velocity: Vec2, | |
paddle_1: i32, | |
paddle_2: i32, | |
score_1: u32, | |
score_2: u32, | |
} | |
impl Default for Pong { | |
fn default() -> Self { | |
Self { | |
ball_position: BALL_INITIAL_POSITION, | |
ball_velocity: BALL_INITIAL_VELOCITY, | |
paddle_1: 400, | |
paddle_2: 100, | |
score_1: 0, | |
score_2: 0, | |
} | |
} | |
} | |
impl Loop<PongInput> for Pong { | |
const NAME: &'static str = "Pong"; | |
fn tick(&mut self, _frame: u64, input: &PongInput) -> TickState { | |
if input.player_1_up { | |
self.paddle_1 -= 4; | |
} else if input.player_1_down { | |
self.paddle_1 += 4; | |
} | |
if input.player_2_up { | |
self.paddle_2 -= 4; | |
} else if input.player_2_down { | |
self.paddle_2 += 4; | |
} | |
self.paddle_1 = self.paddle_1.clamp(100, 400); | |
self.paddle_2 = self.paddle_2.clamp(100, 400); | |
let mut velocity = self.ball_velocity; | |
'substep: while velocity != Vec2::zero() { | |
if velocity.x.abs() > velocity.y.abs() { | |
let sign = velocity.x.signum(); | |
self.ball_position.x += sign; | |
velocity.x -= sign; | |
} else { | |
let sign = velocity.y.signum(); | |
self.ball_position.y += sign; | |
velocity.y -= sign; | |
} | |
if self.ball_position.y > 500 - 8 { | |
self.ball_position.y = 500 - 8; | |
velocity.y = -velocity.y; | |
self.ball_velocity.y = -self.ball_velocity.y; | |
} | |
if self.ball_position.y < 100 + 8 { | |
self.ball_position.y = 100 + 8; | |
velocity.y = -velocity.y; | |
self.ball_velocity.y = -self.ball_velocity.y; | |
} | |
if self.ball_position.x < 120 | |
&& (self.ball_position.y - (self.paddle_1 + 50)).abs() < 50 | |
{ | |
self.ball_position.x = 120; | |
velocity.x = -velocity.x; | |
self.ball_velocity.x = -(self.ball_velocity.x + self.ball_velocity.x.signum()); | |
} | |
if self.ball_position.x > 680 | |
&& (self.ball_position.y - (self.paddle_2 + 50)).abs() < 50 | |
{ | |
self.ball_position.x = 680; | |
velocity.x = -velocity.x; | |
self.ball_velocity.x = -(self.ball_velocity.x + self.ball_velocity.x.signum()); | |
} | |
if self.ball_position.x == 700 { | |
self.score_1 += 1; | |
self.ball_position = BALL_INITIAL_POSITION; | |
self.ball_velocity = BALL_INITIAL_VELOCITY; | |
break 'substep; | |
} | |
if self.ball_position.x == 100 { | |
self.score_2 += 1; | |
self.ball_position = BALL_INITIAL_POSITION; | |
self.ball_velocity = BALL_INITIAL_VELOCITY; | |
break 'substep; | |
} | |
} | |
TickState::Continue | |
} | |
fn draw(&self, draw: &mut Draw) { | |
let bg = Colour::new(220, 220, 220, 255); | |
let board_color = Colour::new(240, 240, 240, 255); | |
let fg = Colour::new(20, 20, 20, 255); | |
draw.clear(bg); | |
draw.rectangle_fill(Vec2::new(100, 100), Vec2::new(600, 400), board_color); | |
draw.rectangle_fill(Vec2::new(100, self.paddle_1), Vec2::new(20, 100), fg); | |
draw.rectangle_fill(Vec2::new(680, self.paddle_2), Vec2::new(20, 100), fg); | |
draw.rectangle_fill( | |
Vec2::new(self.ball_position.x - 8, self.ball_position.y - 8), | |
Vec2::new(16, 16), | |
fg, | |
); | |
} | |
} | |
fn main() { | |
Pong::default().run() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment