Initial commit

master
DustyP 6 years ago
commit 77b6918c9f

@ -0,0 +1,46 @@
package main
var nums = [][]byte{
{
1,1,1,
1,0,1,
1,0,1,
1,0,1,
1,1,1,
},
{
1,1,0,
0,1,0,
0,1,0,
0,1,0,
1,1,1,
},
{
1,1,1,
0,0,1,
1,1,1,
1,0,0,
1,1,1,
},
{
1,1,1,
0,0,1,
0,1,1,
0,0,1,
1,1,1,
},
{
1,0,1,
1,0,1,
1,1,1,
0,0,1,
0,0,1,
},
{
1,1,1,
1,0,0,
1,1,1,
0,0,1,
1,1,1,
},
}

@ -0,0 +1,50 @@
package main
import "github.com/veandco/go-sdl2/sdl"
func (p *paddle) draw(pixels []byte) {
startX := int(p.x - p.w / 2)
startY := int(p.y - p.h / 2)
for y := 0; y < int(p.h); y++ {
for x := 0; x < int(p.w); x++ {
setPixel(startX + x, startY + y, p.color, pixels)
}
}
numPos := pos{
x: lerp(p.x, getCenter().x, 0.2),
y: 50,
}
drawNumber(numPos, p.color, 10, p.score, pixels)
}
func (b *ball) draw(pixels []byte) {
for y := -b.radius; y < b.radius; y++ {
for x := -b.radius; x < b.radius; x++ {
if x * x + y * y < b.radius * b.radius {
setPixel(int(b.x+x), int(b.y+y), b.color, pixels)
}
}
}
}
func drawNumber(pos pos, color sdl.Color, size, num int, pixels []byte) {
startX := int(pos.x) - (size * 3) / 2
startY := int(pos.y) - (size * 5) / 2
for i, v := range nums[num] {
if v == 1 {
for y := startY; y < startY + size; y++ {
for x := startX; x < startX + size; x++ {
setPixel(x, y, color, pixels)
}
}
}
startX += size
if (i + 1) % 3 == 0 {
startY += size
startX -= size * 3
}
}
}

@ -0,0 +1,65 @@
package main
import (
"github.com/veandco/go-sdl2/sdl"
"log"
"time"
)
func gameLoop(pixels []byte, player1, player2 paddle, ball ball, renderer *sdl.Renderer, tex *sdl.Texture, keyState []uint8) {
var frameStart time.Time
var elapsedTime float32
for {
frameStart = time.Now()
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
switch event.(type) {
case *sdl.QuitEvent:
return
}
}
if err := renderer.Clear(); err != nil {
log.Fatal(err)
}
if state == play {
if player1.score == 5 || player2.score == 5 {
state = start
}
player1.update(keyState, elapsedTime)
player2.aiUpdate(&ball, elapsedTime)
ball.update(&player1, &player2, elapsedTime)
} else if state == start {
if keyState[sdl.SCANCODE_SPACE] != 0 {
player1.score = 0
player2.score = 0
resetBall(&ball)
state = play
}
} else if state == pause {
if keyState[sdl.SCANCODE_SPACE] != 0 {
resetBall(&ball)
state = play
}
}
clearScreen(pixels)
player1.draw(pixels)
player2.draw(pixels)
ball.draw(pixels)
if err := tex.Update(nil, pixels, winWidth*4); err != nil {
log.Fatal(err)
}
if err := renderer.Copy(tex, nil, nil); err != nil {
log.Fatal(err)
}
renderer.Present()
elapsedTime = float32(time.Since(frameStart).Seconds())
if elapsedTime < 0.005 {
sdl.Delay(5 - uint32(elapsedTime / 1000))
elapsedTime = float32(time.Since(frameStart).Seconds())
}
}
}

@ -0,0 +1,84 @@
package main
import (
"github.com/veandco/go-sdl2/sdl"
"log"
)
var (
winWidth = 800
winHeight = 600
state = start
)
func main() {
err := sdl.Init(sdl.INIT_EVERYTHING)
if err != nil {
log.Fatal(err)
}
defer sdl.Quit()
window, err := sdl.CreateWindow(
"PONG",
sdl.WINDOWPOS_CENTERED,
sdl.WINDOWPOS_CENTERED,
int32(winWidth),
int32(winHeight),
sdl.WINDOW_SHOWN)
if err != nil {
log.Fatal(err)
}
defer window.Destroy()
renderer, err := sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED)
if err != nil {
log.Fatal(err)
}
defer renderer.Destroy()
tex, err := renderer.CreateTexture(
sdl.PIXELFORMAT_ABGR8888,
sdl.TEXTUREACCESS_STREAMING,
int32(winWidth),
int32(winHeight))
if err != nil {
log.Fatal(err)
}
defer tex.Destroy()
player1 := paddle{
pos: pos{50, 300},
w: 20,
h: 100,
speed: 300,
score: 0,
color: sdl.Color{255, 0, 0, 255},
}
player2 := paddle{
pos: pos{750, 300},
w: 20,
h: 100,
speed: 300,
score: 0,
color: sdl.Color{0, 255, 0, 255},
}
ball := ball{
pos: pos{400, 300},
radius: 20,
dx: 400,
dy: 400,
color: sdl.Color{0, 0, 255, 255},
}
keyState := sdl.GetKeyboardState()
pixels := make([]byte, winHeight*winWidth*4)
resetBall(&ball)
gameLoop(pixels, player1, player2, ball, renderer, tex, keyState)
}

@ -0,0 +1,32 @@
package main
import "github.com/veandco/go-sdl2/sdl"
type pos struct {
x, y float32
}
type ball struct {
pos
radius float32
dx float32
dy float32
color sdl.Color
}
type paddle struct {
pos
w float32
h float32
speed float32
score int
color sdl.Color
}
type gameState int
const (
start gameState = iota
play
pause
end
)

@ -0,0 +1,63 @@
package main
import (
"github.com/veandco/go-sdl2/sdl"
"math"
)
func (p *paddle) update(keyState []uint8, et float32) {
if keyState[sdl.SCANCODE_UP] != 0 && p.y - p.h / 2 > 0 {
p.y -= p.speed * et
}
if keyState[sdl.SCANCODE_DOWN] != 0 && p.y + p.h / 2 < float32(winHeight) {
p.y += p.speed * et
}
}
func (p *paddle) aiUpdate(ball *ball, et float32) {
if ball.y + p.h / 2 < float32(winHeight) && ball.y - p.h / 2 > 0 {
p.y = ball.y
}
}
func (b *ball) update(p1, p2 *paddle, et float32) {
if detectCollision(b, p1) {
if b.y < p1.y+p1.h/2 && b.y > p1.y-p1.h/2 && b.dx < 0{
b.dx = -b.dx
} else if b.x < p1.x + p1.w / 2 && b.x > p1.x - p1.w / 2 {
b.dy = -b.dy
} else {
testX, testY := closestCorner(b, p1)
vx, vy := testX - b.x, testY - b.y
vd := float32(math.Sqrt(float64(vx * vx + vy * vy)))
ux, uy := vx / vd, vy / vd
b.x, b.y = testX - b.radius * ux, testY - b.radius * uy
q := -(2 * (b.dx * (b.x - testX) + b.dy * (b.y - testY)) / (b.radius * b.radius))
b.dx = b.dx + q * (b.x - testX)
b.dy = b.dy + q * (b.y - testY)
}
}
b.x += b.dx * et
b.y += b.dy * et
if b.y - b.radius < 1 || b.y + b.radius > float32(winHeight) - 1 {
b.dy = -b.dy
}
if b.x - b.radius < 0 {
p2.score++
b.pos = getCenter()
state = pause
} else if b.x + b.radius > float32(winWidth) {
p1.score++
b.pos = getCenter()
state = pause
}
if b.x + b.radius >= p2.x - p2.w / 2 && b.dx > 0{
if b.y < p2.y+p2.h/2 && b.y > p2.y-p2.h/2 {
b.dx = -b.dx
}
}
}

@ -0,0 +1,63 @@
package main
import (
"github.com/veandco/go-sdl2/sdl"
"math/rand"
"time"
)
func closestCorner(b *ball, p *paddle) (float32, float32) {
testX := b.x
testY := b.y
if b.x < p.x - p.w / 2 {
testX = p.x - p.w / 2
} else if b.x > p.x + p.w / 2 {
testX = p.x + p.w / 2
}
if b.y < p.y - p.h / 2 {
testY = p.y - p.h / 2
} else if b.y > p.y + p.h / 2 {
testY = p.y + p.h / 2
}
return testX, testY
}
func detectCollision(b *ball, p *paddle) bool {
testX, testY := closestCorner(b, p)
sideX := b.x - testX
sideY := b.y - testY
return b.radius * b.radius >= sideX * sideX + sideY * sideY
}
func setPixel(x, y int, c sdl.Color, pixels []byte) {
index := (y*winWidth + x) * 4
if index < len(pixels) - 4 && index >= 0 {
pixels[index] = c.R
pixels[index+1] = c.G
pixels[index+2] = c.B
//pixels[index+3] = c.A
}
}
func clearScreen(pixels []byte) {
for i := range pixels {
pixels[i] = 0
}
}
func getCenter() pos {
return pos{float32(winWidth) / 2, float32(winHeight) / 2}
}
func lerp(a, b, pct float32) float32 {
return a + pct * (b - a)
}
func resetBall(b *ball) {
choices := []float32{-400, -200, 200, 400}
s := rand.NewSource(time.Now().Unix())
r := rand.New(s)
b.dy = choices[r.Intn(len(choices))]
b.dx = choices[r.Intn(len(choices))]
}
Loading…
Cancel
Save