Updated ball to have deflection and max speed.
Updated the ball to increment its speed on hit. Also to calc a better angle on hit to serve back. Also set a max speed.
This commit is contained in:
+44
-11
@@ -9,6 +9,7 @@ init_ball :: proc() -> Entity {
|
||||
active = true,
|
||||
pos = rl.Vector2{(VIEWPORT_W / 2), (VIEWPORT_H / 2)},
|
||||
speed = 500,
|
||||
max_speed = 800,
|
||||
vel = rl.Vector2{0,0},
|
||||
shape = .Circle,
|
||||
size = rl.Vector2{15, 15}
|
||||
@@ -25,6 +26,7 @@ serve_ball :: proc(ball: ^Entity) {
|
||||
reset_ball :: proc(ball: ^Entity) {
|
||||
ball.pos = rl.Vector2{(VIEWPORT_W / 2), (VIEWPORT_H / 2)}
|
||||
ball.vel = rl.Vector2{0,0}
|
||||
ball.speed = 500
|
||||
}
|
||||
|
||||
update_ball :: proc(ball: ^Entity, level: ^Level, dt: f32) {
|
||||
@@ -39,18 +41,14 @@ update_ball :: proc(ball: ^Entity, level: ^Level, dt: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
ball.pos += ball.vel * dt
|
||||
radius := ball.size.x
|
||||
field_bounds := level.field_bounds
|
||||
|
||||
// paddle collisions detection (player then enemy)
|
||||
if check_ball_paddle_collision(ball^, level.player) {
|
||||
ball.vel.x = abs(ball.vel.x)
|
||||
// stp stickiness
|
||||
ball.pos.x = level.player.pos.x + level.player.size.x + radius
|
||||
} else if check_ball_paddle_collision(ball^, level.opponent) {
|
||||
ball.vel.x = -abs(ball.vel.x)
|
||||
ball.pos.x = level.opponent.pos.x - radius
|
||||
if check_ball_paddle_collision(ball, level.player) {
|
||||
resolve_collision(ball, level.player, true)
|
||||
} else if check_ball_paddle_collision(ball, level.opponent) {
|
||||
resolve_collision(ball, level.opponent, false)
|
||||
}
|
||||
|
||||
// bounds collision detection
|
||||
@@ -68,9 +66,11 @@ update_ball :: proc(ball: ^Entity, level: ^Level, dt: f32) {
|
||||
reset_ball(ball)
|
||||
level.serve_timer = level.wait_time
|
||||
}
|
||||
|
||||
ball.pos += ball.vel * dt
|
||||
}
|
||||
|
||||
check_ball_paddle_collision :: proc(ball: Entity, paddle: Entity) -> bool {
|
||||
check_ball_paddle_collision :: proc(ball: ^Entity, paddle: Entity) -> bool {
|
||||
paddle_rec := rl.Rectangle{
|
||||
x = paddle.pos.x,
|
||||
y = paddle.pos.y,
|
||||
@@ -78,14 +78,47 @@ check_ball_paddle_collision :: proc(ball: Entity, paddle: Entity) -> bool {
|
||||
height = paddle.size.y,
|
||||
}
|
||||
collided := rl.CheckCollisionCircleRec(ball.pos, ball.size.x, paddle_rec)
|
||||
if collided do emit_event(Event{ type = .Ball_Collision })
|
||||
if collided do emit_event(.Ball_Collision)
|
||||
return collided
|
||||
}
|
||||
|
||||
increment_score :: proc(score_side: ^int, max_score: int, player: bool) {
|
||||
score_side^ += 1
|
||||
if score_side^ == max_score do emit_event(Game_Over_Data{player})
|
||||
}
|
||||
|
||||
if score_side^ == max_score do emit_event(Event{ .Game_Over, player })
|
||||
increment_speed :: proc(ball: ^Entity) {
|
||||
if ball.speed <= ball.max_speed {
|
||||
ball.speed += 100
|
||||
ball.vel = rl.Vector2Normalize({ball.vel.x, ball.vel.y}) * ball.speed
|
||||
}
|
||||
}
|
||||
|
||||
resolve_collision :: proc(ball: ^Entity, paddle: Entity, is_player: bool) {
|
||||
ball_center_y := ball.pos.y
|
||||
paddle_center_y := paddle.pos.y + (paddle.size.y / 2.0)
|
||||
local_y := ball_center_y - paddle_center_y
|
||||
half_height := paddle.size.y / 2.0
|
||||
|
||||
// check if we are in top or bottom half of paddle
|
||||
hit_t := clamp(local_y / half_height, -1.0, 1.0)
|
||||
|
||||
// direction is dependant of if its the player
|
||||
dir_x: f32 = is_player ? 1.0 : -1.0
|
||||
|
||||
// steer the angle by a value using its hit t value
|
||||
dir_y := hit_t * 1.3
|
||||
new_dir := rl.Vector2Normalize({dir_x, dir_y})
|
||||
|
||||
ball.vel = new_dir * ball.speed
|
||||
increment_speed(ball)
|
||||
|
||||
// Resolve overlap
|
||||
if is_player {
|
||||
ball.pos.x = paddle.pos.x + paddle.size.x + ball.size.x
|
||||
} else {
|
||||
ball.pos.x = paddle.pos.x - ball.size.x
|
||||
}
|
||||
}
|
||||
|
||||
render_ball :: proc(ball: Entity, field_bounds: rl.Rectangle) {
|
||||
|
||||
Reference in New Issue
Block a user