done making opng

This commit is contained in:
2020-11-02 22:03:08 +01:00
parent a5b17e9e82
commit 348144472a
2 changed files with 91 additions and 3 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 583 B

+91 -3
View File
@@ -1,12 +1,16 @@
#!/usr/bin/env cargo run
use tetra::graphics::{self, Color, Texture};
use tetra::graphics::{self, Color, Rectangle, Texture};
use tetra::input::{self, Key};
use tetra::math::Vec2;
use tetra::window;
use tetra::{Context, ContextBuilder, State};
const WINDOW_WIDTH: f32 = 640.0;
const WINDOW_HEIGHT: f32 = 480.0;
const PADDLE_SPEED: f32 = 8.0;
const BALL_SPEED: f32 = 5.0;
const PADDLE_SPIN: f32 = 4.0;
const BALL_ACC: f32 = 0.05;
fn main() -> tetra::Result {
ContextBuilder::new("Pong", WINDOW_WIDTH as i32, WINDOW_HEIGHT as i32)
@@ -18,17 +22,49 @@ fn main() -> tetra::Result {
struct Entity {
texture: Texture,
position: Vec2<f32>,
velocity: Vec2<f32>,
}
impl Entity {
fn new(texture: Texture, position: Vec2<f32>) -> Entity {
Entity { texture, position }
Entity::with_velocity(texture, position, Vec2::zero())
}
fn with_velocity(texture: Texture, position: Vec2<f32>, velocity: Vec2<f32>) -> Entity {
Entity {
texture,
position,
velocity,
}
}
fn width(&self) -> f32 {
self.texture.width() as f32
}
fn height(&self) -> f32 {
self.texture.height() as f32
}
fn bounds(&self) -> Rectangle {
Rectangle::new(
self.position.x,
self.position.y,
self.width(),
self.height(),
)
}
fn centre(&self) -> Vec2<f32> {
Vec2::new(
self.position.x + (self.width() / 2.0),
self.position.y + (self.height() / 2.0),
)
}
}
struct GameState {
player1: Entity,
player2: Entity,
ball: Entity,
}
impl GameState {
@@ -45,9 +81,18 @@ impl GameState {
(WINDOW_HEIGHT - player2_texture.height() as f32) / 2.0,
);
let ball_texture = Texture::new(ctx, "./img/ball.png")?;
let ball_position = Vec2::new(
WINDOW_WIDTH / 2.0 - ball_texture.width() as f32 / 2.0,
WINDOW_HEIGHT / 2.0 - ball_texture.height() as f32 / 2.0,
);
let ball_velocity = Vec2::new(-BALL_SPEED, 0.0);
Ok(GameState {
player1: Entity::new(player1_texture, player1_position),
player2: Entity::new(player2_texture, player2_position),
ball: Entity::with_velocity(ball_texture, ball_position, ball_velocity),
})
}
}
@@ -70,14 +115,57 @@ impl State for GameState {
self.player2.position.y += PADDLE_SPEED;
}
self.ball.position += self.ball.velocity;
let player1_bounds = self.player1.bounds();
let player2_bounds = self.player2.bounds();
let ball_bounds = self.ball.bounds();
let paddle_hit = if ball_bounds.intersects(&player1_bounds) {
Some(&self.player1)
} else if ball_bounds.intersects(&player2_bounds) {
Some(&self.player2)
} else {
None
};
if let Some(paddle) = paddle_hit {
// Increase the ball's velocity, then flip it.
self.ball.velocity.x =
-(self.ball.velocity.x + (BALL_ACC * self.ball.velocity.x.signum()));
// Calculate the offset between the paddle and the ball, as a number between
// -1.0 and 1.0.
let offset = (paddle.centre().y - self.ball.centre().y) / paddle.height();
// Apply the spin to the ball.
self.ball.velocity.y += PADDLE_SPIN * -offset;
}
if self.ball.position.y <= 0.0 || self.ball.position.y + self.ball.height() >= WINDOW_HEIGHT
{
self.ball.velocity.y = -self.ball.velocity.y;
}
if self.ball.position.x < 0.0 {
window::quit(ctx);
println!("Player 2 wins!");
}
if self.ball.position.x > WINDOW_WIDTH {
window::quit(ctx);
println!("Player 1 wins!");
}
Ok(())
}
fn draw(&mut self, ctx: &mut Context) -> tetra::Result {
graphics::clear(ctx, Color::rgb(0.392, 0.584, 0.929));
graphics::clear(ctx, Color::rgb(0., 0., 0.));
graphics::draw(ctx, &self.player1.texture, self.player1.position);
graphics::draw(ctx, &self.player2.texture, self.player2.position);
graphics::draw(ctx, &self.ball.texture, self.ball.position);
Ok(())
}