more anim progress
This commit is contained in:
parent
f62e9833db
commit
a915310274
|
@ -13,7 +13,7 @@ const (
|
||||||
right
|
right
|
||||||
)
|
)
|
||||||
|
|
||||||
func doCommand(cmd command, s State, teamID int) State {
|
func doCommand(cmd command, s State, sOld State, teamID int) State {
|
||||||
da := 1
|
da := 1
|
||||||
da += rand.Intn(3) - 1
|
da += rand.Intn(3) - 1
|
||||||
|
|
||||||
|
@ -35,5 +35,5 @@ func doCommand(cmd command, s State, teamID int) State {
|
||||||
b.Lane--
|
b.Lane--
|
||||||
}
|
}
|
||||||
|
|
||||||
return updateBot(s, teamID, *b)
|
return updateBot(s, sOld, teamID, *b)
|
||||||
}
|
}
|
||||||
|
|
255
game/game.go
255
game/game.go
|
@ -1,8 +1,98 @@
|
||||||
package game
|
package game
|
||||||
|
|
||||||
import (
|
func UpdateState(s State, sOld State) State {
|
||||||
"log"
|
for i := range s.Teams {
|
||||||
)
|
s = doCommand(chooseCommand(s, i), s, sOld, i)
|
||||||
|
if b := activeBot(s.Teams[i]); b != nil {
|
||||||
|
s = moveBot(s, i, *b)
|
||||||
|
}
|
||||||
|
s = maybePassBaton(s, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, t := range s.Teams {
|
||||||
|
if b := activeBot(t); b != nil && won(*b, s) {
|
||||||
|
s.GameOver = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func maybePassBaton(s State, teamID int) State {
|
||||||
|
t := s.Teams[teamID]
|
||||||
|
h := activeBot(t)
|
||||||
|
if h == nil {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, b := range t.Bots {
|
||||||
|
if h.ID >= b.ID || h.Lane != b.Lane {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if abs(b.Pos-h.Pos) <= passDistance {
|
||||||
|
h.v = 0
|
||||||
|
h.a = 0
|
||||||
|
s = updateBot(s, s, teamID, *h)
|
||||||
|
newH := t.Bots[i]
|
||||||
|
newH.a = baseAccel
|
||||||
|
t.Baton.HolderID = newH.ID
|
||||||
|
s = updateTeam(s, t)
|
||||||
|
return updateBot(s, s, teamID, newH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func activeBot(t Team) *Bot {
|
||||||
|
for _, b := range t.Bots {
|
||||||
|
if b.ID == t.Baton.HolderID {
|
||||||
|
return &b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateBot(s State, sOld State, teamID int, b Bot) State {
|
||||||
|
t := s.Teams[teamID]
|
||||||
|
for i, bb := range t.Bots {
|
||||||
|
if bb.ID == b.ID {
|
||||||
|
bots := append([]Bot{}, t.Bots[:i]...)
|
||||||
|
bots = append(bots, b)
|
||||||
|
bots = append(bots, t.Bots[i+1:]...)
|
||||||
|
t.Bots = bots
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s = updateTeam(s, t)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateTeam(s State, t Team) State {
|
||||||
|
s.Teams = append(s.Teams[:t.id], append([]Team{t}, s.Teams[t.id+1:]...)...)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func won(b Bot, s State) bool {
|
||||||
|
return b.Pos >= Steps
|
||||||
|
}
|
||||||
|
|
||||||
|
func gameOver(s State) bool {
|
||||||
|
for _, t := range s.Teams {
|
||||||
|
if t.won {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func abs(n int) int {
|
||||||
|
if n < 0 {
|
||||||
|
return -n
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
type State struct {
|
type State struct {
|
||||||
Teams []Team
|
Teams []Team
|
||||||
|
@ -10,6 +100,40 @@ type State struct {
|
||||||
GameOver bool
|
GameOver bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Team struct {
|
||||||
|
id int
|
||||||
|
Bots []Bot
|
||||||
|
Baton Baton
|
||||||
|
won bool
|
||||||
|
Lane int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t Team) BatonHolder() *Bot {
|
||||||
|
for _, b := range t.Bots {
|
||||||
|
if b.ID == t.Baton.HolderID {
|
||||||
|
return &b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Bot struct {
|
||||||
|
ID int
|
||||||
|
Lane int
|
||||||
|
Pos int
|
||||||
|
v int
|
||||||
|
a int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Baton struct {
|
||||||
|
HolderID int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Obstacle struct {
|
||||||
|
Lane int
|
||||||
|
Pos int
|
||||||
|
}
|
||||||
|
|
||||||
func NewState() State {
|
func NewState() State {
|
||||||
var teams []Team
|
var teams []Team
|
||||||
for i := 0; i < NumTeams; i++ {
|
for i := 0; i < NumTeams; i++ {
|
||||||
|
@ -53,124 +177,6 @@ func NewState() State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Team struct {
|
|
||||||
id int
|
|
||||||
Bots []Bot
|
|
||||||
Baton Baton
|
|
||||||
won bool
|
|
||||||
Lane int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t Team) BatonHolder() *Bot {
|
|
||||||
for _, b := range t.Bots {
|
|
||||||
if b.ID == t.Baton.HolderID {
|
|
||||||
return &b
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type Bot struct {
|
|
||||||
ID int
|
|
||||||
Lane int
|
|
||||||
Pos int
|
|
||||||
v int
|
|
||||||
a int
|
|
||||||
}
|
|
||||||
|
|
||||||
type Baton struct {
|
|
||||||
HolderID int
|
|
||||||
}
|
|
||||||
|
|
||||||
type Obstacle struct {
|
|
||||||
Lane int
|
|
||||||
Pos int
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdateState(s State) State {
|
|
||||||
for i, t := range s.Teams {
|
|
||||||
s = doCommand(chooseCommand(s, i), s, i)
|
|
||||||
if b := activeBot(t); b != nil {
|
|
||||||
s = moveBot(s, i, *b)
|
|
||||||
}
|
|
||||||
s = maybePassBaton(s, i)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, t := range s.Teams {
|
|
||||||
if b := activeBot(t); b != nil && won(*b, s) {
|
|
||||||
s.GameOver = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func maybePassBaton(s State, teamID int) State {
|
|
||||||
t := s.Teams[teamID]
|
|
||||||
h := activeBot(t)
|
|
||||||
if h == nil {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, b := range t.Bots {
|
|
||||||
if h.ID >= b.ID || h.Lane != b.Lane {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if abs(b.Pos-h.Pos) <= passDistance {
|
|
||||||
log.Printf("team %v pass from %v to %v!", teamID, h.ID, b.ID)
|
|
||||||
h.v = 0
|
|
||||||
h.a = 0
|
|
||||||
s = updateBot(s, teamID, *h)
|
|
||||||
newH := t.Bots[i]
|
|
||||||
newH.a = baseAccel
|
|
||||||
t.Baton.HolderID = newH.ID
|
|
||||||
s = updateTeam(s, t)
|
|
||||||
return updateBot(s, teamID, newH)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func activeBot(t Team) *Bot {
|
|
||||||
for _, b := range t.Bots {
|
|
||||||
if b.ID == t.Baton.HolderID {
|
|
||||||
return &b
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateBot(s State, teamID int, b Bot) State {
|
|
||||||
t := s.Teams[teamID]
|
|
||||||
for i, bb := range t.Bots {
|
|
||||||
if bb.ID == b.ID {
|
|
||||||
t.Bots = append(t.Bots[:i], append([]Bot{b}, t.Bots[i+1:]...)...)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return updateTeam(s, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateTeam(s State, t Team) State {
|
|
||||||
s.Teams = append(s.Teams[:t.id], append([]Team{t}, s.Teams[t.id+1:]...)...)
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func won(b Bot, s State) bool {
|
|
||||||
return b.Pos >= Steps
|
|
||||||
}
|
|
||||||
|
|
||||||
func gameOver(s State) bool {
|
|
||||||
for _, t := range s.Teams {
|
|
||||||
if t.won {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Steps = 50
|
Steps = 50
|
||||||
numBots = 5
|
numBots = 5
|
||||||
|
@ -179,10 +185,3 @@ const (
|
||||||
maxA = 3
|
maxA = 3
|
||||||
maxV = 10
|
maxV = 10
|
||||||
)
|
)
|
||||||
|
|
||||||
func abs(n int) int {
|
|
||||||
if n < 0 {
|
|
||||||
return -n
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
|
@ -26,7 +26,8 @@ func moveBot(s State, teamID int, b Bot) State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return updateBot(s, teamID, b)
|
s = updateBot(s, s, teamID, b)
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func collide(pos, lane int, s State) bool {
|
func collide(pos, lane int, s State) bool {
|
||||||
|
|
37
gfx/gfx.go
37
gfx/gfx.go
|
@ -17,32 +17,50 @@ type RenderState struct {
|
||||||
frame int
|
frame int
|
||||||
}
|
}
|
||||||
|
|
||||||
func Render(rs RenderState, s game.State, w *pixelgl.Window, d time.Duration) RenderState {
|
func Render(rs RenderState, sOld, sNew game.State, w *pixelgl.Window, d time.Duration) RenderState {
|
||||||
//tween := float64(rs.frame) / float64(rs.Frames)
|
//log.Println("render")
|
||||||
|
w.Clear(colornames.Peru)
|
||||||
|
|
||||||
colors := teamColors(s.Teams)
|
tween := float64(rs.frame) / float64(rs.Frames)
|
||||||
renderBots(s, w, d, colors)
|
|
||||||
renderObstacles(s, w)
|
colors := teamColors(sNew.Teams)
|
||||||
|
renderBots(sOld, sNew, tween, w, d, colors)
|
||||||
|
renderObstacles(sNew, w)
|
||||||
|
|
||||||
rs.frame++
|
rs.frame++
|
||||||
|
//log.Println("frame", rs.frame)
|
||||||
if rs.frame >= rs.Frames {
|
if rs.frame >= rs.Frames {
|
||||||
rs.Animating = false
|
rs.Animating = false
|
||||||
}
|
}
|
||||||
return rs
|
return rs
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderBots(s game.State, w *pixelgl.Window, d time.Duration, colors map[*game.Team]pixel.RGBA) {
|
func renderBots(sOld, sNew game.State, tween float64, w *pixelgl.Window, d time.Duration, colors map[*game.Team]pixel.RGBA) {
|
||||||
bounds := w.Bounds()
|
bounds := w.Bounds()
|
||||||
im := imdraw.New(nil)
|
im := imdraw.New(nil)
|
||||||
|
|
||||||
for i, t := range s.Teams {
|
//log.Println("sOld.Teams:", sOld.Teams)
|
||||||
|
|
||||||
|
for i, t := range sNew.Teams {
|
||||||
for j, bot := range t.Bots {
|
for j, bot := range t.Bots {
|
||||||
c := colors[&s.Teams[i]]
|
c := colors[&sNew.Teams[i]]
|
||||||
c.R += 0.2 * float64(j)
|
c.R += 0.2 * float64(j)
|
||||||
c.G -= 0.1 * float64(j)
|
c.G -= 0.1 * float64(j)
|
||||||
im.Color = c
|
im.Color = c
|
||||||
|
|
||||||
pos := lanePos(bot.Pos, bot.Lane, botWidth, bounds)
|
oldBot := sOld.Teams[i].Bots[j]
|
||||||
|
// log.Println("oldBot:", oldBot)
|
||||||
|
// log.Println("bot:", bot)
|
||||||
|
oldPos := lanePos(oldBot.Pos, oldBot.Lane, botWidth, bounds)
|
||||||
|
newPos := lanePos(bot.Pos, bot.Lane, botWidth, bounds)
|
||||||
|
|
||||||
|
// log.Println("oldPos:", oldPos)
|
||||||
|
// log.Println("newPos:", newPos)
|
||||||
|
|
||||||
|
pos := pixel.Vec{
|
||||||
|
X: oldPos.X + tween*(newPos.X-oldPos.X),
|
||||||
|
Y: oldPos.Y + tween*(newPos.Y-oldPos.Y),
|
||||||
|
}
|
||||||
|
|
||||||
im.Push(pos)
|
im.Push(pos)
|
||||||
|
|
||||||
|
@ -53,6 +71,7 @@ func renderBots(s game.State, w *pixelgl.Window, d time.Duration, colors map[*ga
|
||||||
if t.Bots[j].ID == t.Baton.HolderID {
|
if t.Bots[j].ID == t.Baton.HolderID {
|
||||||
renderBaton(pos, w)
|
renderBaton(pos, w)
|
||||||
}
|
}
|
||||||
|
//log.Println("sOld.Teams[i].Bots[j]:", sOld.Teams[i].Bots[j])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
20
main.go
20
main.go
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"relay/game"
|
"relay/game"
|
||||||
"relay/gfx"
|
"relay/gfx"
|
||||||
|
@ -29,23 +30,26 @@ func run() {
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
|
w.Clear(colornames.Peachpuff)
|
||||||
for !w.Closed() && !s.GameOver {
|
for !w.Closed() && !s.GameOver {
|
||||||
w.Clear(colornames.Peru)
|
sOld := s
|
||||||
|
|
||||||
//sOld := s
|
rs := gfx.RenderState{
|
||||||
|
Animating: false,
|
||||||
|
Frames: 3,
|
||||||
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case w.JustPressed(pixelgl.KeyQ):
|
case w.JustPressed(pixelgl.KeyQ):
|
||||||
return
|
return
|
||||||
case w.JustPressed(pixelgl.KeySpace):
|
case w.JustPressed(pixelgl.KeySpace):
|
||||||
s = game.UpdateState(s)
|
rs.Animating = true
|
||||||
}
|
s = game.UpdateState(s, sOld)
|
||||||
rs := gfx.RenderState{
|
|
||||||
Animating: true,
|
|
||||||
Frames: 10,
|
|
||||||
}
|
}
|
||||||
for rs.Animating {
|
for rs.Animating {
|
||||||
rs = gfx.Render(rs, s, w, time.Since(start))
|
log.Println("anim loop")
|
||||||
|
rs = gfx.Render(rs, sOld, s, w, time.Since(start))
|
||||||
|
w.Update()
|
||||||
}
|
}
|
||||||
w.Update()
|
w.Update()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue