youtube:sfml-pong
差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン前のリビジョン次のリビジョン | 前のリビジョン | ||
youtube:sfml-pong [2024/02/28 18:26] – 削除 - 外部編集 (不明な日付) 127.0.0.1 | youtube:sfml-pong [2024/02/29 11:49] (現在) – freemikan | ||
---|---|---|---|
行 1: | 行 1: | ||
+ | ====== Pong ====== | ||
+ | |||
+ | 作成日: 2022-12-07 (水) | ||
+ | |||
+ | {{: | ||
+ | |||
+ | src/main.rs | ||
+ | |||
+ | <file rust pong.rs> | ||
+ | use sfml:: | ||
+ | |||
+ | struct MoveFlags { | ||
+ | up: bool, | ||
+ | down: bool, | ||
+ | } | ||
+ | |||
+ | struct Game<' | ||
+ | window: RenderWindow, | ||
+ | paddle: RectangleShape<' | ||
+ | paddle_speed: | ||
+ | ball: CircleShape<' | ||
+ | ball_velocity: | ||
+ | move_flags: MoveFlags | ||
+ | } | ||
+ | |||
+ | impl<' | ||
+ | const FPS: f32 = 60.0; // Time:: | ||
+ | const WIDTH: u32 = 1000; | ||
+ | const HEIGHT: u32 = 800; | ||
+ | const PADDLE_SPEED: | ||
+ | const PADDLE_SIZE_X: | ||
+ | const PADDLE_SIZE_Y: | ||
+ | const BALL_SPEED: f32 = 400.0; | ||
+ | const BALL_RADIUS: | ||
+ | |||
+ | pub fn new() -> Game<' | ||
+ | let window = RenderWindow:: | ||
+ | (Self:: | ||
+ | "Pong with Rust and SFML", | ||
+ | Style:: | ||
+ | & | ||
+ | | ||
+ | let mut paddle = RectangleShape:: | ||
+ | paddle.set_position((Self:: | ||
+ | | ||
+ | let paddle_speed = Self:: | ||
+ | | ||
+ | let mut ball = CircleShape:: | ||
+ | ball.set_position((Self:: | ||
+ | ball.set_origin((Self:: | ||
+ | | ||
+ | let ball_velocity = Vector2f:: | ||
+ | | ||
+ | Game { | ||
+ | window, | ||
+ | paddle, | ||
+ | paddle_speed, | ||
+ | ball, | ||
+ | ball_velocity, | ||
+ | move_flags: MoveFlags { | ||
+ | up: false, | ||
+ | down: false, | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | pub fn run(& | ||
+ | let mut clock = Clock:: | ||
+ | let mut time_since_last_update = Time::ZERO; | ||
+ | let time_per_frame = Time:: | ||
+ | | ||
+ | while self.window.is_open() { | ||
+ | self.process_events(); | ||
+ | |||
+ | time_since_last_update += clock.restart(); | ||
+ | while time_since_last_update > time_per_frame { | ||
+ | time_since_last_update -= time_per_frame; | ||
+ | self.process_events(); | ||
+ | self.update(& | ||
+ | } | ||
+ | self.render(); | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | fn process_events(& | ||
+ | while let Some(event) = self.window.poll_event() { | ||
+ | match event { | ||
+ | Event:: | ||
+ | Event:: | ||
+ | if code == Key::Enter || code == Key::Escape { | ||
+ | self.window.close(); | ||
+ | } else { | ||
+ | self.handle_player_input(code, | ||
+ | }, | ||
+ | Event:: | ||
+ | self.handle_player_input(code, | ||
+ | _ => {} | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | fn update(& | ||
+ | // short names for readability | ||
+ | let paddle = &mut self.paddle; | ||
+ | let ball = &mut self.ball; | ||
+ | let ball_velocity = &mut self.ball_velocity; | ||
+ | |||
+ | // update paddle | ||
+ | let mut movement = Vector2f:: | ||
+ | | ||
+ | if self.move_flags.up { | ||
+ | if paddle.position().y > 0.0 { | ||
+ | movement.y -= self.paddle_speed; | ||
+ | } | ||
+ | } | ||
+ | if self.move_flags.down { | ||
+ | if paddle.position().y + paddle.size().y < Self:: | ||
+ | movement.y += self.paddle_speed; | ||
+ | } | ||
+ | } | ||
+ | paddle.move_(movement * delta_time.as_seconds()); | ||
+ | | ||
+ | // update ball | ||
+ | | ||
+ | // update ball x | ||
+ | ball.move_((ball_velocity.x * delta_time.as_seconds(), | ||
+ | |||
+ | if ball.position().x + ball.radius() > Self::WIDTH as f32 { | ||
+ | ball_velocity.x *= -1.0; | ||
+ | // align to left of paddle | ||
+ | ball.set_position((Self:: | ||
+ | } | ||
+ | | ||
+ | let paddle_rect = paddle.global_bounds(); | ||
+ | let mut ball_rect = ball.global_bounds(); | ||
+ | if ball_rect.intersection(& | ||
+ | ball.set_position((paddle_rect.left + paddle_rect.width + ball.radius(), | ||
+ | ball_velocity.x *= -1.0; | ||
+ | } | ||
+ | | ||
+ | // update ball y | ||
+ | ball.move_((0.0, | ||
+ | | ||
+ | if ball.position().y - ball.radius() < 0.0 { | ||
+ | ball_velocity.y *= -1.0; | ||
+ | ball.set_position((ball.position().x, | ||
+ | } | ||
+ | if ball.position().y + ball.radius() > Self:: | ||
+ | ball_velocity.y *= -1.0; | ||
+ | ball.set_position((ball.position().x, | ||
+ | } | ||
+ | | ||
+ | ball_rect = ball.global_bounds(); | ||
+ | if ball_rect.intersection(& | ||
+ | if ball_velocity.y > 0.0 { | ||
+ | // align to top of paddle | ||
+ | | ||
+ | } else { | ||
+ | // align to bottom of paddle | ||
+ | ball.set_position((ball.position().x, | ||
+ | } | ||
+ | | ||
+ | ball_velocity.y *= -1.0; | ||
+ | } | ||
+ | | ||
+ | assert!(ball.position().x + ball.radius() <= Self::WIDTH as f32); | ||
+ | } | ||
+ | | ||
+ | fn render(& | ||
+ | self.window.clear(Color:: | ||
+ | self.window.draw(& | ||
+ | self.window.draw(& | ||
+ | self.window.display(); | ||
+ | } | ||
+ | | ||
+ | fn handle_player_input(& | ||
+ | match code { | ||
+ | Key::W => self.move_flags.up = pressed, | ||
+ | Key::S => self.move_flags.down = pressed, | ||
+ | _ => {} | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | fn main() { | ||
+ | let mut game = Game:: | ||
+ | game.run(); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Cargo.toml | ||
+ | |||
+ | < | ||
+ | [package] | ||
+ | name = " | ||
+ | version = " | ||
+ | edition = " | ||
+ | |||
+ | # See more keys and their definitions at https:// | ||
+ | |||
+ | [dependencies] | ||
+ | sfml = " | ||
+ | </ | ||