move render loop to gfx package

This commit is contained in:
Luke Meyers 2020-02-08 22:50:33 -08:00
parent 60694107c3
commit 241028934b
2 changed files with 61 additions and 81 deletions

View File

@ -3,12 +3,12 @@ package gfx
import ( import (
"fmt" "fmt"
"image" "image"
"image/color"
_ "image/png" _ "image/png"
"math" "math"
"math/rand" "math/rand"
"os" "os"
"relay/game" "relay/game"
"time"
"github.com/faiface/pixel" "github.com/faiface/pixel"
"github.com/faiface/pixel/imdraw" "github.com/faiface/pixel/imdraw"
@ -16,7 +16,40 @@ import (
"golang.org/x/image/colornames" "golang.org/x/image/colornames"
) )
type RenderState struct { func RenderLoop(w *pixelgl.Window, s game.State, sOld game.State, stateC <-chan game.State, sb *SpriteBank) {
var (
frames = 0
second = time.Tick(time.Second)
rs = renderState{
Frames: 15,
}
)
for !w.Closed() {
if rs.Frame == rs.Frames {
select {
case ss := <-stateC:
sOld = s
s = ss
rs.Frame = 0
default:
}
}
rs = Render(rs, sOld, s, w, *sb)
w.Update()
frames++
select {
case <-second:
w.SetTitle(fmt.Sprintf("%s | FPS: %d", "Relay", frames))
frames = 0
default:
}
}
}
type renderState struct {
Frames int Frames int
Frame int Frame int
} }
@ -63,11 +96,18 @@ func loadPicture(path string) (pixel.Picture, error) {
return pixel.PictureDataFromImage(img), nil return pixel.PictureDataFromImage(img), nil
} }
func Render(rs RenderState, sOld, sNew game.State, w *pixelgl.Window, sb SpriteBank) RenderState { func Render(rs renderState, sOld, sNew game.State, w *pixelgl.Window, sb SpriteBank) renderState {
bgBatch := pixel.NewBatch(new(pixel.TrianglesData), nil) bgBatch := pixel.NewBatch(new(pixel.TrianglesData), nil)
renderBackground(w, bgBatch) renderBackground(w, bgBatch)
colors := teamColors(sNew.Teams) oBatch := pixel.NewBatch(new(pixel.TrianglesData), sb.obstacle)
renderObstacles(sNew, w, oBatch, sb.obstacle)
oBatch.Draw(w)
sBatch := pixel.NewBatch(new(pixel.TrianglesData), nil)
renderSpawnPoints(sBatch, sNew.SpawnPoints, w.Bounds())
sBatch.Draw(w)
ctx := context{ ctx := context{
sOld: sOld, sOld: sOld,
sNew: sNew, sNew: sNew,
@ -75,17 +115,9 @@ func Render(rs RenderState, sOld, sNew game.State, w *pixelgl.Window, sb SpriteB
w: w, w: w,
} }
rBatch := pixel.NewBatch(new(pixel.TrianglesData), sb.racer) rBatch := pixel.NewBatch(new(pixel.TrianglesData), sb.racer)
renderRacers(ctx, rBatch, colors, sb.racer) renderRacers(ctx, rBatch, sb.racer)
rBatch.Draw(w) rBatch.Draw(w)
oBatch := pixel.NewBatch(new(pixel.TrianglesData), sb.obstacle)
renderObstacles(sNew, w, oBatch, sb.obstacle)
oBatch.Draw(w)
sBatch := pixel.NewBatch(new(pixel.TrianglesData), nil)
renderSpawnPoints(sBatch, sNew.SpawnPoints, w.Bounds(), colors)
sBatch.Draw(w)
if rs.Frame < rs.Frames { if rs.Frame < rs.Frames {
rs.Frame++ rs.Frame++
} }
@ -121,9 +153,9 @@ func renderBackground(w *pixelgl.Window, batch *pixel.Batch) {
batch.Draw(w) batch.Draw(w)
} }
func renderRacers(ctx context, batch *pixel.Batch, colors map[int]pixel.RGBA, pic pixel.Picture) { func renderRacers(ctx context, batch *pixel.Batch, pic pixel.Picture) {
for i, t := range ctx.sNew.Teams { for i, t := range ctx.sNew.Teams {
c := colors[i] c := teamColors[i]
for j, racer := range t.Racers { for j, racer := range t.Racers {
oldRacer := ctx.sOld.Teams[i].Racers[j] oldRacer := ctx.sOld.Teams[i].Racers[j]
renderRacer(ctx, batch, oldRacer, racer, racer.ID == ctx.sOld.Teams[i].Baton.HolderID, c, pic) renderRacer(ctx, batch, oldRacer, racer, racer.ID == ctx.sOld.Teams[i].Baton.HolderID, c, pic)
@ -246,11 +278,11 @@ func renderObstacles(s game.State, w *pixelgl.Window, batch *pixel.Batch, pic pi
im.Draw(batch) im.Draw(batch)
} }
func renderSpawnPoints(b *pixel.Batch, sps map[int]game.SpawnPoint, bounds pixel.Rect, colors map[int]pixel.RGBA) { func renderSpawnPoints(b *pixel.Batch, sps map[int]game.SpawnPoint, bounds pixel.Rect) {
im := imdraw.New(nil) im := imdraw.New(nil)
for _, sp := range sps { for _, sp := range sps {
c := colors[sp.TeamID] c := teamColors[sp.TeamID]
c.R *= 0.5 c.R *= 0.5
c.G *= 0.5 c.G *= 0.5
c.B *= 0.5 c.B *= 0.5
@ -264,34 +296,16 @@ func renderSpawnPoints(b *pixel.Batch, sps map[int]game.SpawnPoint, bounds pixel
im.Draw(b) im.Draw(b)
} }
func teamColors(ts []game.Team) map[int]pixel.RGBA { var teamColors = map[int]pixel.RGBA{
m := make(map[int]pixel.RGBA) 0: pixel.ToRGBA(colornames.Palevioletred),
for i := range ts { 1: pixel.ToRGBA(colornames.Lime),
var c color.RGBA 2: pixel.ToRGBA(colornames.Cornflowerblue),
switch i { 3: pixel.ToRGBA(colornames.Magenta),
case 0: 4: pixel.ToRGBA(colornames.Cyan),
c = colornames.Palevioletred 5: pixel.ToRGBA(colornames.Yellow),
case 1: 6: pixel.ToRGBA(colornames.Blueviolet),
c = colornames.Lime 7: pixel.ToRGBA(colornames.Orange),
case 2: 8: pixel.ToRGBA(colornames.Coral),
c = colornames.Cornflowerblue
case 3:
c = colornames.Magenta
case 4:
c = colornames.Cyan
case 5:
c = colornames.Yellow
case 6:
c = colornames.Blueviolet
case 7:
c = colornames.Orange
case 8:
c = colornames.Coral
}
m[i] = pixel.ToRGBA(c)
}
return m
} }
const ( const (

38
main.go
View File

@ -1,7 +1,6 @@
package main package main
import ( import (
"fmt"
"log" "log"
"math/rand" "math/rand"
"relay/game" "relay/game"
@ -28,9 +27,6 @@ func run() error {
s := game.NewState() s := game.NewState()
rs := gfx.RenderState{
Frames: 15,
}
sb, err := gfx.NewSpriteBank() sb, err := gfx.NewSpriteBank()
if err != nil { if err != nil {
return err return err
@ -44,13 +40,13 @@ func run() error {
stateCA := make(chan game.State) stateCA := make(chan game.State)
stateCB := make(chan game.State) stateCB := make(chan game.State)
go renderLoop(w, rs, s, sOld, stateCA, sb) go gfx.RenderLoop(w, s, sOld, stateCA, sb)
for !w.Closed() { for !w.Closed() {
switch { switch {
case w.Pressed(pixelgl.KeyQ): case w.Pressed(pixelgl.KeyQ):
return nil return nil
case w.Pressed(pixelgl.KeySpace): case w.JustPressed(pixelgl.KeySpace) || true:
cmds := <-cmdC cmds := <-cmdC
s = game.UpdateState(s, sOld, cmds) s = game.UpdateState(s, sOld, cmds)
turn++ turn++
@ -81,33 +77,3 @@ func pixelRun() {
func main() { func main() {
pixelgl.Run(pixelRun) pixelgl.Run(pixelRun)
} }
func renderLoop(w *pixelgl.Window, rs gfx.RenderState, s game.State, sOld game.State, stateC <-chan game.State, sb *gfx.SpriteBank) {
var (
frames = 0
second = time.Tick(time.Second)
)
for !w.Closed() {
if rs.Frame == rs.Frames {
select {
case ss := <-stateC:
sOld = s
s = ss
rs.Frame = 0
default:
}
}
rs = gfx.Render(rs, sOld, s, w, *sb)
w.Update()
frames++
select {
case <-second:
w.SetTitle(fmt.Sprintf("%s | FPS: %d", "Relay", frames))
frames = 0
default:
}
}
}