Updated to track score, serve and reset.
This commit is contained in:
+61
-7
@@ -1,31 +1,85 @@
|
||||
package game
|
||||
|
||||
import "core:math/rand"
|
||||
import "core:log"
|
||||
import rl "vendor:raylib"
|
||||
|
||||
init_ball :: proc() -> Entity {
|
||||
ball_radius: f32 = 25
|
||||
|
||||
return Entity{
|
||||
type = .Ball,
|
||||
active = true,
|
||||
pos = rl.Vector2{(VIEWPORT_WIDTH / 2), (VIEWPORT_HEIGHT / 2) - (ball_radius / 2)},
|
||||
vel = rl.Vector2{400,0},
|
||||
pos = rl.Vector2{(VIEWPORT_W / 2), (VIEWPORT_H / 2)},
|
||||
speed = 500,
|
||||
vel = rl.Vector2{0,0},
|
||||
shape = .Circle,
|
||||
size = rl.Vector2{15, 15}
|
||||
}
|
||||
}
|
||||
|
||||
update_ball :: proc(ball: ^Entity, field_bounds: rl.Rectangle, dt: f32) {
|
||||
serve_ball :: proc(ball: ^Entity) {
|
||||
// Randomize initial direction: -1.0 or 1.0
|
||||
dir_x := f32(rand.float32() > 0.5 ? 1 : -1)
|
||||
dir_y := rand.choice([]f32{-0.1, 0.1}) // Slightly angled launch
|
||||
ball.vel = rl.Vector2Normalize({dir_x, dir_y}) * ball.speed
|
||||
}
|
||||
|
||||
reset_ball :: proc(ball: ^Entity) {
|
||||
ball.pos = rl.Vector2{(VIEWPORT_W / 2), (VIEWPORT_H / 2)}
|
||||
ball.vel = rl.Vector2{0,0}
|
||||
}
|
||||
|
||||
update_ball :: proc(ball: ^Entity, level: ^Level, dt: f32) {
|
||||
// first check the level timer are we waiting to serve?
|
||||
if level.serve_timer > 0 {
|
||||
level.serve_timer -= dt
|
||||
if level.serve_timer <= 0 {
|
||||
serve_ball(ball)
|
||||
}
|
||||
|
||||
// return early if timer still ticking
|
||||
return
|
||||
}
|
||||
|
||||
// serve_ball(ball)
|
||||
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.enemy) {
|
||||
ball.vel.x = -abs(ball.vel.x)
|
||||
ball.pos.x = level.enemy.pos.x - radius
|
||||
}
|
||||
|
||||
// bounds collision detection
|
||||
if ball.pos.y >= (field_bounds.y + field_bounds.height) - ball.size.x { ball.vel.y = -ball.vel.y }
|
||||
if ball.pos.y <= field_bounds.y + ball.size.x { ball.vel.y = -ball.vel.y }
|
||||
|
||||
if ball.pos.x >= (field_bounds.x + field_bounds.width) - ball.size.x {
|
||||
ball.vel.x = -ball.vel.x
|
||||
level.score_player += 1
|
||||
reset_ball(ball)
|
||||
level.serve_timer = level.wait_time
|
||||
}
|
||||
|
||||
if ball.pos.x <= field_bounds.x + ball.size.x {
|
||||
ball.vel.x = -ball.vel.x
|
||||
level.score_enemy += 1
|
||||
reset_ball(ball)
|
||||
level.serve_timer = level.wait_time
|
||||
}
|
||||
}
|
||||
|
||||
check_ball_paddle_collision :: proc(ball: Entity, paddle: Entity) -> bool {
|
||||
paddle_rec := rl.Rectangle{
|
||||
x = paddle.pos.x,
|
||||
y = paddle.pos.y,
|
||||
width = paddle.size.x,
|
||||
height = paddle.size.y,
|
||||
}
|
||||
return rl.CheckCollisionCircleRec(ball.pos, ball.size.x, paddle_rec)
|
||||
}
|
||||
|
||||
render_ball :: proc(ball: Entity, field_bounds: rl.Rectangle) {
|
||||
|
||||
Reference in New Issue
Block a user