more anim progress
This commit is contained in:
parent
f62e9833db
commit
a915310274
|
@ -13,7 +13,7 @@ const (
|
|||
right
|
||||
)
|
||||
|
||||
func doCommand(cmd command, s State, teamID int) State {
|
||||
func doCommand(cmd command, s State, sOld State, teamID int) State {
|
||||
da := 1
|
||||
da += rand.Intn(3) - 1
|
||||
|
||||
|
@ -35,5 +35,5 @@ func doCommand(cmd command, s State, teamID int) State {
|
|||
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
|
||||
|
||||
import (
|
||||
"log"
|
||||
)
|
||||
func UpdateState(s State, sOld State) State {
|
||||
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 {
|
||||
Teams []Team
|
||||
|
@ -10,6 +100,40 @@ type State struct {
|
|||
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 {
|
||||
var teams []Team
|
||||
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 (
|
||||
Steps = 50
|
||||
numBots = 5
|
||||
|
@ -179,10 +185,3 @@ const (
|
|||
maxA = 3
|
||||
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 {
|
||||
|
|
37
gfx/gfx.go
37
gfx/gfx.go
|
@ -17,32 +17,50 @@ type RenderState struct {
|
|||
frame int
|
||||
}
|
||||
|
||||
func Render(rs RenderState, s game.State, w *pixelgl.Window, d time.Duration) RenderState {
|
||||
//tween := float64(rs.frame) / float64(rs.Frames)
|
||||
func Render(rs RenderState, sOld, sNew game.State, w *pixelgl.Window, d time.Duration) RenderState {
|
||||
//log.Println("render")
|
||||
w.Clear(colornames.Peru)
|
||||
|
||||
colors := teamColors(s.Teams)
|
||||
renderBots(s, w, d, colors)
|
||||
renderObstacles(s, w)
|
||||
tween := float64(rs.frame) / float64(rs.Frames)
|
||||
|
||||
colors := teamColors(sNew.Teams)
|
||||
renderBots(sOld, sNew, tween, w, d, colors)
|
||||
renderObstacles(sNew, w)
|
||||
|
||||
rs.frame++
|
||||
//log.Println("frame", rs.frame)
|
||||
if rs.frame >= rs.Frames {
|
||||
rs.Animating = false
|
||||
}
|
||||
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()
|
||||
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 {
|
||||
c := colors[&s.Teams[i]]
|
||||
c := colors[&sNew.Teams[i]]
|
||||
c.R += 0.2 * float64(j)
|
||||
c.G -= 0.1 * float64(j)
|
||||
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)
|
||||
|
||||
|
@ -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 {
|
||||
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
|
||||
|
||||
import (
|
||||
"log"
|
||||
"math/rand"
|
||||
"relay/game"
|
||||
"relay/gfx"
|
||||
|
@ -29,23 +30,26 @@ func run() {
|
|||
|
||||
start := time.Now()
|
||||
|
||||
w.Clear(colornames.Peachpuff)
|
||||
for !w.Closed() && !s.GameOver {
|
||||
w.Clear(colornames.Peru)
|
||||
sOld := s
|
||||
|
||||
//sOld := s
|
||||
rs := gfx.RenderState{
|
||||
Animating: false,
|
||||
Frames: 3,
|
||||
}
|
||||
|
||||
switch {
|
||||
case w.JustPressed(pixelgl.KeyQ):
|
||||
return
|
||||
case w.JustPressed(pixelgl.KeySpace):
|
||||
s = game.UpdateState(s)
|
||||
}
|
||||
rs := gfx.RenderState{
|
||||
Animating: true,
|
||||
Frames: 10,
|
||||
rs.Animating = true
|
||||
s = game.UpdateState(s, sOld)
|
||||
}
|
||||
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()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue