示例#1
0
文件: player.go 项目: sammcj/ssh-tron
// 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)
}
示例#2
0
文件: player.go 项目: sammcj/ssh-tron
			// 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 {