Created
June 19, 2025 23:49
-
-
Save naranyala/7da12c5cd0a38ed0b5e4f08c30ca7350 to your computer and use it in GitHub Desktop.
pong game in odin code using raylib
This file contains hidden or 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
package main | |
import "core:fmt" | |
import rl "vendor:raylib" | |
// Constants | |
WINDOW_WIDTH :: 800 | |
WINDOW_HEIGHT :: 600 | |
PADDLE_SPEED :: f32(300.0) | |
BALL_SPEED :: f32(200.0) | |
BALL_MAX_SPEED :: f32(400.0) | |
BALL_RADIUS :: f32(10.0) | |
main :: proc() { | |
rl.InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Pong") | |
defer rl.CloseWindow() | |
rl.SetTargetFPS(60) | |
// Game objects | |
left_paddle := rl.Rectangle{50, 250, 20, 100} | |
right_paddle := rl.Rectangle{730, 250, 20, 100} | |
ball := rl.Vector2{400, 300} | |
ball_velocity := rl.Vector2{BALL_SPEED, BALL_SPEED} | |
left_score: i32 = 0 | |
right_score: i32 = 0 | |
for !rl.WindowShouldClose() { | |
dt := rl.GetFrameTime() | |
handle_input(&left_paddle, &right_paddle, dt) | |
update_ball(&ball, &ball_velocity, &left_paddle, &right_paddle, dt, &left_score, &right_score) | |
draw_game(left_paddle, right_paddle, ball, left_score, right_score) | |
} | |
} | |
handle_input :: proc( | |
left: ^rl.Rectangle, | |
right: ^rl.Rectangle, | |
dt: f32, | |
) { | |
if rl.IsKeyDown(.W) && left.y > 0 { | |
left.y -= PADDLE_SPEED * dt | |
} else if rl.IsKeyDown(.S) && left.y < f32(WINDOW_HEIGHT) - left.height { | |
left.y += PADDLE_SPEED * dt | |
} | |
if rl.IsKeyDown(.UP) && right.y > 0 { | |
right.y -= PADDLE_SPEED * dt | |
} else if rl.IsKeyDown(.DOWN) && right.y < f32(WINDOW_HEIGHT) - right.height { | |
right.y += PADDLE_SPEED * dt | |
} | |
} | |
update_ball :: proc( | |
ball: ^rl.Vector2, | |
velocity: ^rl.Vector2, | |
left: ^rl.Rectangle, | |
right: ^rl.Rectangle, | |
dt: f32, | |
left_score: ^i32, | |
right_score: ^i32, | |
) { | |
ball.x += velocity.x * dt | |
ball.y += velocity.y * dt | |
// Top/Bottom wall collision | |
if ball.y <= BALL_RADIUS || ball.y >= f32(WINDOW_HEIGHT) - BALL_RADIUS { | |
velocity.y *= -1 | |
} | |
// Left paddle collision | |
if rl.CheckCollisionCircleRec(ball^, BALL_RADIUS, left^) { | |
velocity.x *= -1 | |
velocity.y += (ball.y - (left.y + left.height / 2)) * 2 | |
velocity.y = clamp(velocity.y, -BALL_MAX_SPEED, BALL_MAX_SPEED) | |
ball.x = left.x + left.width + BALL_RADIUS | |
} | |
// Right paddle collision | |
if rl.CheckCollisionCircleRec(ball^, BALL_RADIUS, right^) { | |
velocity.x *= -1 | |
velocity.y += (ball.y - (right.y + right.height / 2)) * 2 | |
velocity.y = clamp(velocity.y, -BALL_MAX_SPEED, BALL_MAX_SPEED) | |
ball.x = right.x - BALL_RADIUS | |
} | |
// Score logic | |
if ball.x < 0 { | |
right_score^ += 1 | |
reset_ball(ball, velocity) | |
} else if ball.x > f32(WINDOW_WIDTH) { | |
left_score^ += 1 | |
reset_ball(ball, velocity) | |
} | |
} | |
reset_ball :: proc(ball: ^rl.Vector2, velocity: ^rl.Vector2) { | |
ball.x = 400 | |
ball.y = 300 | |
velocity.x = BALL_SPEED if rl.GetRandomValue(0, 1) == 0 else -BALL_SPEED | |
velocity.y = BALL_SPEED | |
} | |
clamp :: proc(value, min, max: f32) -> f32 { | |
if value < min do return min | |
if value > max do return max | |
return value | |
} | |
draw_game :: proc( | |
left, right: rl.Rectangle, | |
ball: rl.Vector2, | |
left_score, right_score: i32, | |
) { | |
rl.BeginDrawing() | |
rl.ClearBackground(rl.BLACK) | |
rl.DrawRectangleRec(left, rl.WHITE) | |
rl.DrawRectangleRec(right, rl.WHITE) | |
rl.DrawCircleV(ball, BALL_RADIUS, rl.WHITE) | |
left_text := fmt.ctprintf("Left: %d", left_score) | |
right_text := fmt.ctprintf("Right: %d", right_score) | |
rl.DrawText(left_text, 10, 10, 20, rl.WHITE) | |
rl.DrawText(right_text, 700, 10, 20, rl.WHITE) | |
rl.DrawText("W/S: Left | UP/DOWN: Right", 10, 550, 16, rl.GRAY) | |
rl.EndDrawing() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment