// every tick, based on player screen size - calculate, store and send screen deltas. func (p *Player) update() { if !p.ready { return } gb := p.g.board // center board with offset width and height ow := (p.w - p.g.w) / 2 oh := (p.h - p.g.h) / 2 // store the last rendered for network optimisation var lastw, lasth uint16 var r rune var c, lastc []byte // screen loop var u []byte for h := 0; h < p.g.h; h++ { for tw := 0; tw < p.g.w; tw++ { // rune and color at terminal w x h r = empty c = colours[blank] sidebar := false if tw < sidebarWidth { // calculate rune from sidebar if tw == 0 { r = filled } else if h == 0 { r = top } else if h == p.g.h-1 { r = bottom } else { rs := p.g.sidebar.runes if h-1 < len(rs) && tw-1 < len(rs[h-1]) { i := (h - 1) / sidebarEntryHeight if i < len(p.g.sidebar.ps) { p := p.g.sidebar.ps[i] c = colours[p.id] r = rs[h-1][tw-1] sidebar = true } } } } else { // calculate rune from game gw := tw - sidebarWidth h1 := h * 2 h2 := h1 + 1 // choose rune if gb[gw][h1] != blank && gb[gw][h2] != blank { r = filled } else if gb[gw][h1] != blank { r = top } else if gb[gw][h2] != blank { r = bottom } // choose color if gb[gw][h2] == blank { c = colours[gb[gw][h1]] } else { c = colours[gb[gw][h2]] } } cacheOverride := p.g.sidebar.changed && sidebar // player board is different? draw it if p.screen[tw][h] != r || cacheOverride { // p.logf("rune differs '%s' %dx%d (%v)", string(r), tw, h, cacheOverride) // skip if we only moved one space right nexth := uint16(h + 1 + oh) nextw := uint16(tw + 1 + ow) if nexth != lasth || nextw != lastw+1 { u = append(u, ansi.Goto(nexth, nextw)...) lasth = nexth lastw = nextw } // skip if we didnt change color if c != nil && bytes.Compare(c, lastc) != 0 { u = append(u, c...) lastc = c } // write rune u = append(u, []byte(string(r))...) // cache p.screen[tw][h] = r } } } if len(u) == 0 { return } // p.logf("send %d", len(u)) p.conn.Write(u) }
// while preventing player from moving into itself (odd<->even) ((d%2 == 0 && d-1 != b[2]) || ((d+1)%2 == 0 && d+1 != b[2])) { p.nextd = Direction(b[2]) continue } // respawn! if b[0] == 13 { p.respawn() continue } // p.logf("sent action %+v", b) } p.teardown() } var resizeTmpl = string(ansi.Goto(2, 5)) + string(ansi.Set(ansi.White)) + "Please resize your terminal to %dx%d (+%dx+%d)" func (p *Player) resizeWatch() { for r := range p.resizes { p.w = int(r.width) p.h = int(r.height) // fits? if p.w >= p.g.w && p.h >= p.g.h { p.conn.EraseScreen() p.resetScreen() // send updates! p.ready = true } else {