commit
e6017e5fc4
1 changed files with 175 additions and 0 deletions
175
examples/games/pong/main.go
Normal file
175
examples/games/pong/main.go
Normal file
|
@ -0,0 +1,175 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
// Game settings
|
||||
const (
|
||||
screenWidth = 800
|
||||
screenHeight = 600
|
||||
)
|
||||
|
||||
// Paddle struct
|
||||
type Paddle struct {
|
||||
Pos rl.Vector2
|
||||
Width float32
|
||||
Height float32
|
||||
Speed float32
|
||||
}
|
||||
|
||||
// Ball struct
|
||||
type Ball struct {
|
||||
Pos rl.Vector2
|
||||
Speed rl.Vector2
|
||||
Radius float32
|
||||
}
|
||||
|
||||
// Game struct
|
||||
type Game struct {
|
||||
paddle1 Paddle
|
||||
paddle2 Paddle
|
||||
ball Ball
|
||||
player1Score int
|
||||
player2Score int
|
||||
}
|
||||
|
||||
// Check for collision between ball and paddle, and determine side
|
||||
func CheckCollisionSide(ball Ball, paddle Paddle) string {
|
||||
closestX := rl.Clamp(ball.Pos.X, paddle.Pos.X, paddle.Pos.X+paddle.Width)
|
||||
closestY := rl.Clamp(ball.Pos.Y, paddle.Pos.Y, paddle.Pos.Y+paddle.Height)
|
||||
|
||||
dx := ball.Pos.X - closestX
|
||||
dy := ball.Pos.Y - closestY
|
||||
|
||||
distanceSq := dx*dx + dy*dy
|
||||
radiusSq := ball.Radius * ball.Radius
|
||||
|
||||
if distanceSq <= radiusSq {
|
||||
// Determine where it hit
|
||||
if closestX == paddle.Pos.X || closestX == paddle.Pos.X+paddle.Width {
|
||||
return "side"
|
||||
}
|
||||
if closestY == paddle.Pos.Y || closestY == paddle.Pos.Y+paddle.Height {
|
||||
return "topbottom"
|
||||
}
|
||||
return "side" // fallback
|
||||
}
|
||||
|
||||
return "none"
|
||||
}
|
||||
|
||||
|
||||
// Initialize the game state
|
||||
func (g *Game) Init() {
|
||||
g.paddle1 = Paddle{
|
||||
Pos: rl.NewVector2(30, float32(screenHeight/2-50)),
|
||||
Width: 10,
|
||||
Height: 100,
|
||||
Speed: 5,
|
||||
}
|
||||
|
||||
g.paddle2 = Paddle{
|
||||
Pos: rl.NewVector2(float32(screenWidth-40), float32(screenHeight/2-50)),
|
||||
Width: 10,
|
||||
Height: 100,
|
||||
Speed: 5,
|
||||
}
|
||||
|
||||
g.ball = Ball{
|
||||
Pos: rl.NewVector2(float32(screenWidth/2), float32(screenHeight/2)),
|
||||
Speed: rl.NewVector2(5, 4),
|
||||
Radius: 10,
|
||||
}
|
||||
|
||||
g.player1Score = 0
|
||||
g.player2Score = 0
|
||||
}
|
||||
|
||||
// Game update logic
|
||||
func (g *Game) Update() {
|
||||
// Player 1 - W/S
|
||||
if rl.IsKeyDown(rl.KeyW) && g.paddle1.Pos.Y > 0 {
|
||||
g.paddle1.Pos.Y -= g.paddle1.Speed
|
||||
}
|
||||
if rl.IsKeyDown(rl.KeyS) && g.paddle1.Pos.Y < screenHeight-g.paddle1.Height {
|
||||
g.paddle1.Pos.Y += g.paddle1.Speed
|
||||
}
|
||||
|
||||
// Player 2 - Up/Down
|
||||
if rl.IsKeyDown(rl.KeyUp) && g.paddle2.Pos.Y > 0 {
|
||||
g.paddle2.Pos.Y -= g.paddle2.Speed
|
||||
}
|
||||
if rl.IsKeyDown(rl.KeyDown) && g.paddle2.Pos.Y < screenHeight-g.paddle2.Height {
|
||||
g.paddle2.Pos.Y += g.paddle2.Speed
|
||||
}
|
||||
|
||||
// Ball movement
|
||||
g.ball.Pos.X += g.ball.Speed.X
|
||||
g.ball.Pos.Y += g.ball.Speed.Y
|
||||
|
||||
// Ball bounce off top/bottom walls
|
||||
if g.ball.Pos.Y <= g.ball.Radius || g.ball.Pos.Y >= float32(screenHeight)-g.ball.Radius {
|
||||
g.ball.Speed.Y *= -1
|
||||
}
|
||||
|
||||
// Ball collisions with paddle sides only
|
||||
if CheckCollisionSide(g.ball, g.paddle1) == "side" {
|
||||
g.ball.Speed.X *= -1
|
||||
// Reposition ball outside paddle1
|
||||
g.ball.Pos.X = g.paddle1.Pos.X + g.paddle1.Width + g.ball.Radius
|
||||
}
|
||||
|
||||
if CheckCollisionSide(g.ball, g.paddle2) == "side" {
|
||||
g.ball.Speed.X *= -1
|
||||
// Reposition ball outside paddle2
|
||||
g.ball.Pos.X = g.paddle2.Pos.X - g.ball.Radius
|
||||
}
|
||||
|
||||
|
||||
// Scoring
|
||||
if g.ball.Pos.X < 0 {
|
||||
g.player2Score++
|
||||
g.ball.Pos = rl.NewVector2(float32(screenWidth/2), float32(screenHeight/2))
|
||||
g.ball.Speed.X *= -1
|
||||
}
|
||||
if g.ball.Pos.X > float32(screenWidth) {
|
||||
g.player1Score++
|
||||
g.ball.Pos = rl.NewVector2(float32(screenWidth/2), float32(screenHeight/2))
|
||||
g.ball.Speed.X *= -1
|
||||
}
|
||||
}
|
||||
|
||||
// Draw game elements
|
||||
func (g *Game) Draw() {
|
||||
// Draw paddles
|
||||
rl.DrawRectangleV(g.paddle1.Pos, rl.NewVector2(g.paddle1.Width, g.paddle1.Height), rl.Black)
|
||||
rl.DrawRectangleV(g.paddle2.Pos, rl.NewVector2(g.paddle2.Width, g.paddle2.Height), rl.Black)
|
||||
|
||||
// Draw ball
|
||||
rl.DrawCircleV(g.ball.Pos, g.ball.Radius, rl.Black)
|
||||
|
||||
// Draw scores
|
||||
rl.DrawText(fmt.Sprintf("Player 1 : %d", g.player1Score), 20, 20, 20, rl.DarkGray)
|
||||
rl.DrawText(fmt.Sprintf("Player 2 : %d", g.player2Score), screenWidth-140, 20, 20, rl.DarkGray)
|
||||
}
|
||||
|
||||
func main() {
|
||||
rl.InitWindow(screenWidth, screenHeight, "Pong in Go!")
|
||||
rl.SetTargetFPS(60)
|
||||
|
||||
var game Game
|
||||
game.Init()
|
||||
|
||||
for !rl.WindowShouldClose() {
|
||||
game.Update()
|
||||
|
||||
rl.BeginDrawing()
|
||||
rl.ClearBackground(rl.RayWhite)
|
||||
game.Draw()
|
||||
rl.EndDrawing()
|
||||
}
|
||||
|
||||
rl.CloseWindow()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue