func (player *Player) Draw(s *tl.Screen) { screenWidthidth, screenh := s.Size() x := player.sprite.x + screenWidthidth/2 - 30 y := player.sprite.y + screenh - 25 bg := tl.NewRectangle(x, y, x+20, y+10, StatsBG) bg.Draw(s) health := tl.NewText(x+1, y+1, fmt.Sprintf("%3.f%% health", float32(player.health)/float32(player.maxHealth)*100), tl.ColorRed, StatsBG) health.Draw(s) mana := tl.NewText(x+27, y+1, fmt.Sprintf("%3.f%% mana", float32(player.mana)/float32(player.maxMana)*100), tl.ColorBlue, StatsBG) mana.Draw(s) gold := tl.NewText(x+1, y+12, fmt.Sprintf("%d gold", player.gold), tl.ColorYellow, StatsBG) gold.Draw(s) experience := tl.NewText(x+29, y+12, fmt.Sprintf("%3.f%% xp", float32(player.experience)/float32(player.experienceToLevel)*100), tl.ColorMagenta, StatsBG) experience.Draw(s) if player.isCasting { player.isCasting = false newSpellEffect := NewSpellEffect(player.sprite, player.spellCanvases[player.sprite.direction], player.sprite.level) player.sprite.level.AddEntity(newSpellEffect) } e := tl.NewEntityFromCanvas(x+12, y+1, *player.portrait) e.Draw(s) }
func newHud(com chan string, screen *tl.Screen) (h *hud) { h = &hud{ screen: screen, com: com, } h.header = tl.NewText(h.offsetX, h.offsetY, "Events:", Fg, Bg) h.header2 = tl.NewText(h.offsetX, h.offsetY, "--------------------------------------------------------------------------------", Fg, Bg) for k, _ := range h.toDisp { h.toDisp[k] = tl.NewText(h.offsetX, h.offsetY+k, "", Fg, Bg) } return h }
func main() { rand.Seed(time.Now().UTC().UnixNano()) game := tl.NewGame() level := tl.NewBaseLevel(tl.Cell{ Bg: tl.ColorWhite, }) for i := 0; i < 4; i++ { TilePos[i] = rand.Intn(4) level.AddEntity(&Tile{ r: tl.NewRectangle(X+TilePos[i]*(TileWidth+BorderWidth), Y-i*(TileHeight+BorderHeight), TileWidth, TileHeight, tl.ColorBlack), }) } level.AddEntity(tl.NewText(X+TileWidth/2-1, Y+TileHeight, "←", tl.ColorBlack, tl.ColorWhite)) level.AddEntity(tl.NewText(X+(TileWidth+BorderWidth)+TileWidth/2-1, Y+TileHeight, "↓", tl.ColorBlack, tl.ColorWhite)) level.AddEntity(tl.NewText(X+2*(TileWidth+BorderWidth)+TileWidth/2-1, Y+TileHeight, "↑", tl.ColorBlack, tl.ColorWhite)) level.AddEntity(tl.NewText(X+3*(TileWidth+BorderWidth)+TileWidth/2-1, Y+TileHeight, "→", tl.ColorBlack, tl.ColorWhite)) level.AddEntity(&RemainingTime{ r: tl.NewText(X+4*(TileWidth+BorderWidth), 0, fmt.Sprintf("%.3f", Time), tl.ColorRed, tl.ColorDefault), s: tl.NewText(0, 0, "0", tl.ColorRed, tl.ColorDefault), t: Time, m: tl.NewText(0, Y+TileHeight+1, "", tl.ColorRed, tl.ColorDefault), e: tl.NewText(X+4*(TileWidth+BorderWidth), Y+TileHeight+1, "", tl.ColorRed, tl.ColorDefault), }) game.Screen().SetLevel(level) game.Start() }
func (h *hud) Draw(screen *tl.Screen) { w, _ := screen.Size() h.offsetX = w - 80 mainLoop: for { select { case str := <-h.com: i := hudMem - 1 for i > 0 { h.toDisp[i] = h.toDisp[i-1] if h.toDisp[i] != nil { h.toDisp[i].SetPosition(h.offsetX, h.offsetY+i+2) } i-- } h.toDisp[0] = tl.NewText(h.offsetX, h.offsetY+2, str, Fg, Bg) default: break mainLoop } } for _, v := range h.toDisp { v.Draw(screen) } h.header.SetPosition(h.offsetX, h.offsetY) h.header2.SetPosition(h.offsetX, h.offsetY+1) h.header.Draw(screen) h.header2.Draw(screen) }
// TODO need to be able to build multiple levels // maybe look at adding a 'R' key during debug to reload/refresh level func BuildLevel(g *tl.Game, w, h, score int) { maze := generateMaze(w, h) l := tl.NewBaseLevel(tl.Cell{}) l.SetOffset(30, 15) g.Screen().SetLevel(l) g.Log("Building level with width %d and height %d", w, h) scoretext := tl.NewText(0, 1, "Pengo", tl.ColorWhite, tl.ColorBlack) g.Screen().AddEntity(scoretext) for i, row := range maze { for j, path := range row { if path == '*' { // check if the iceblock is a wall and set its color to white. var blockcolor = tl.ColorBlue if (i <= 1 || j <= 1) || (i >= 15 || j >= 17) { blockcolor = tl.ColorWhite } l.AddEntity(NewIceBlock(i, j, g, blockcolor)) } else if path == 'P' { // it's Pengo l.AddEntity(NewPengo(i, j, g)) } else if path == 'S' { // it's a Snobee l.AddEntity(NewSnobee(i, j, g)) } // 'R' it's a Diamond iceblock // 's' it's a snobee egg iceblock } } }
func CreateSoundCtrl(filename string, loop bool) *SoundCtrl { a, err := tlx.InitAudio() chk(err) t1 := tl.NewText(1, 1, "Push the right arrow to play", tl.ColorWhite, 0) t2 := tl.NewText(1, 3, "Push the up arrow to pause", tl.ColorWhite, 0) t3 := tl.NewText(1, 5, "Push the left arrow to restart", tl.ColorWhite, 0) t4 := tl.NewText(1, 7, "Push the down arrow to stop", tl.ColorWhite, 0) text := []*tl.Text{t1, t2, t3, t4} track, err := a.LoadTrack(filename, loop) chk(err) return &SoundCtrl{ audio: a, track: track, text: text, } }
func GameOver() { end := tl.NewBaseLevel(tl.Cell{ Bg: tl.ColorRed, Fg: tl.ColorBlack, }) endText := StartLevel{ message: tl.NewText(0, 0, endMessage, tl.ColorGreen, tl.ColorBlack), instructions: tl.NewText(0, 0, endInstructions, tl.ColorGreen, tl.ColorBlack), instructions2: tl.NewText(0, 0, "", tl.ColorGreen, tl.ColorBlack), } end.AddEntity(&endText) firstPass = true game.Screen().SetLevel(end) }
func (l *storeLevel) refresh() { l.Level = tl.NewBaseLevel(tl.Cell{Bg: l.bg, Fg: l.fg}) l.gt.store.AddEntity(&l.gt.console) l.gt.console.SetText("") w, h := l.gt.g.Screen().Size() rect := tl.NewRectangle(10, 2, w-20, h-4, tl.ColorGreen) l.AddEntity(rect) store, _ := ioutil.ReadFile("data/store.txt") c := tl.CanvasFromString(string(store)) l.AddEntity(tl.NewEntityFromCanvas(w/2-len(c)/2, 4, c)) msg := "Up/Down(j/k), Enter to purchase, N to return to the game" l.AddEntity(tl.NewText(w/2-len(msg)/2, 10, msg, tl.ColorBlack, tl.ColorDefault)) msg = fmt.Sprintf("Cash: $%d", l.gt.stats.Dollars) l.AddEntity(tl.NewText(14, 11, msg, tl.ColorBlack, tl.ColorDefault)) y := 12 for idx, i := range l.items { i.Reset(l.gt) x := 14 fg := tl.ColorBlack if i.Price() > l.gt.stats.Dollars { fg = tl.ColorRed } var price string if l.currentItem == idx { price = ">" + i.PriceDesc() + "<" } else { price = " " + i.PriceDesc() } l.AddEntity(tl.NewText(x, y, price, fg, tl.ColorDefault)) x += len(i.PriceDesc()) + 4 l.AddEntity(tl.NewText(x, y, i.Name(), tl.ColorBlue, tl.ColorDefault)) y++ } desc := l.items[l.currentItem].Desc() l.AddEntity(tl.NewText(14, y+1, desc, tl.ColorBlue, tl.ColorDefault)) y = 12 x := w - 30 msg = fmt.Sprintf("Goroutines: %d", len(l.gt.items)) l.AddEntity(tl.NewText(x, y, msg, tl.ColorBlue, tl.ColorDefault)) y++ msg = fmt.Sprintf("CPU Upgrades: %d", l.gt.stats.CPUUpgrades) l.AddEntity(tl.NewText(x, y, msg, tl.ColorBlue, tl.ColorDefault)) y++ msg = fmt.Sprintf("Go Version: %0.1f", l.gt.stats.GoVersion) l.AddEntity(tl.NewText(x, y, msg, tl.ColorBlue, tl.ColorDefault)) y++ l.gt.g.Screen().SetLevel(l) }
func (g *Game) addChrome() { screen := g.game.Screen() screen.AddEntity(tl.NewText(offsetX, 0, " Number crusher! ", tl.ColorBlack, tl.ColorGreen)) x := 2*offsetX + (boardWidth * squareWidth) + (boardWidth * borderWidth) + borderWidth rules := tl.NewEntityFromCanvas(x, offsetY, tl.CanvasFromString(rules)) screen.AddEntity(rules) screen.AddEntity(g.status) }
func main() { if len(os.Args) < 2 { fmt.Println("Please provide a string as first argument") return } g := tl.NewGame() g.AddEntity(&MovingText{ text: tl.NewText(0, 0, os.Args[1], tl.ColorWhite, tl.ColorBlue), }) g.Start() }
func NewGame() *Game { game := &Game{ level: startLevel, game: tl.NewGame(), board: NewBoard(), status: tl.NewText(19, 0, "", tl.ColorWhite, tl.ColorBlack), } game.player = NewPlayer(game) game.updateStatus() return game }
func main() { game = tl.NewGame() game.SetDebugOn(false) start := tl.NewBaseLevel( tl.Cell{Bg: tl.ColorBlack, Fg: tl.ColorBlack, Ch: 'S'}, ) startText := StartLevel{ tl.NewText(0, 0, startMessage, tl.ColorGreen, tl.ColorBlack), tl.NewText(0, 0, instructions, tl.ColorGreen, tl.ColorBlack), tl.NewText(0, 0, instructions2, tl.ColorGreen, tl.ColorBlack), } start.AddEntity(&startText) game.Screen().SetLevel(start) firstPass = true game.Start() }
// NewCell creates a new cell. Accepts x and y coordinate parameters to // determine "isWave" state. Returns a new instance of Cell. func NewCell(x int, y int) Cell { cell := Cell{ entity: termloop.NewText(x, y, " ", termloop.ColorWhite, termloop.ColorCyan), isFlagged: false, isMine: false, isWave: (x%2 == 0 && y%2 == 0) || (x%2 != 0 && y%2 != 0), proximity: 0, isRevealed: false, } return cell }
func buildLevel(g *tl.Game, w, h, score int) { maze := generateMaze(w, h) l := tl.NewBaseLevel(tl.Cell{}) g.SetLevel(l) g.Log("Building level with width %d and height %d", w, h) scoretext := tl.NewText(0, 1, "Levels explored: "+strconv.Itoa(score), tl.ColorBlue, tl.ColorBlack) g.AddEntity(tl.NewText(0, 0, "Pyramid!", tl.ColorBlue, tl.ColorBlack)) g.AddEntity(scoretext) for i, row := range maze { for j, path := range row { if path == '*' { l.AddEntity(tl.NewRectangle(i, j, 1, 1, tl.ColorWhite)) } else if path == 'S' { l.AddEntity(NewBlock(i, j, tl.ColorRed, g, w, h, score, scoretext)) } else if path == 'L' { l.AddEntity(tl.NewRectangle(i, j, 1, 1, tl.ColorBlue)) } } } }
func (l *gameLevel) Activate() { l.Level = tl.NewBaseLevel(tl.Cell{Bg: l.bg, Fg: l.fg}) l.gt.stats.Garbage = 0 l.gt.game.AddEntity(&l.gt.console) l.gt.console.SetText("") numWords := l.gt.stats.LevelsCompleted + 1 w, h := l.gt.g.Screen().Size() l.words = []*word{} x := 0 y := 0 for i := 0; i < numWords; i++ { str := l.gt.wordList[rand.Intn(len(l.gt.wordList))] if len(str)+x > w { x = 0 y++ } w := newWord(x, y, str, tl.ColorRed, tl.ColorGreen, tl.ColorBlue, tl.ColorCyan) l.AddEntity(w) l.words = append(l.words, w) x += len(w.str) + 2 } l.currentWord = nil l.currentWordText = tl.NewText(0, h-1, "", tl.ColorRed, tl.ColorBlue) l.AddEntity(l.currentWordText) l.garbageText = tl.NewText(w, h-1, "", tl.ColorRed, tl.ColorBlue) l.AddEntity(l.garbageText) l.AddEntity(tl.NewText(0, h-2, strings.Repeat("*", w), tl.ColorBlack, tl.ColorDefault)) for _, i := range l.gt.items { i.Reset(l.gt) } l.gt.g.Screen().SetLevel(l) }
func (board *Board) build() { for i := 0; i <= 12; i++ { for j := 0; j <= 12; j++ { board.spots[i][j].outer = termloop.NewRectangle( i*pw, j*pl, pw, pl, termloop.ColorWhite) board.spots[i][j].inner = termloop.NewRectangle( i*pw+1, j*pl+1, pw-2, pl-2, termloop.ColorWhite) } } for i := 1; i <= 4; i++ { tltext := termloop.NewText(3, i, "", termloop.ColorWhite, termloop.ColorBlack) board.texts = append(board.texts, tltext) } }
func (l *endLevel) PrintStats(amt, x, y int) { msg := fmt.Sprintf("Levels Complete: %d", l.gt.stats.LevelsCompleted) text := tl.NewText(x-len(msg)/2, y, msg, tl.ColorBlack, tl.ColorDefault) l.AddEntity(text) y++ msg = fmt.Sprintf("Levels Attempted: %d", l.gt.stats.LevelsAttempted) text = tl.NewText(x-len(msg)/2, y, msg, tl.ColorBlack, tl.ColorDefault) l.AddEntity(text) y++ msg = fmt.Sprintf("Reward: $%d", amt) text = tl.NewText(x-len(msg)/2, y, msg, tl.ColorBlack, tl.ColorDefault) l.AddEntity(text) y++ msg = fmt.Sprintf("Balance: $%d", l.gt.stats.Dollars) text = tl.NewText(x-len(msg)/2, y, msg, tl.ColorBlack, tl.ColorDefault) l.AddEntity(text) y++ msg = fmt.Sprintf("Total Cash: $%d", l.gt.stats.TotalEarned) text = tl.NewText(x-len(msg)/2, y, msg, tl.ColorBlack, tl.ColorDefault) l.AddEntity(text) y++ msg = fmt.Sprintf("Lives Remaining: %d", l.gt.stats.Lives) text = tl.NewText(x-len(msg)/2, y, msg, tl.ColorBlack, tl.ColorDefault) l.AddEntity(text) y++ if l.win { msg = fmt.Sprintf("Press N for next level or S for store") } else if l.gt.stats.Lives > 0 { msg = fmt.Sprintf("Press R to retry level or S for store") } else { msg = fmt.Sprintf("Press Enter to quit or N for new game") } text = tl.NewText(x-len(msg)/2, y+1, msg, tl.ColorBlack, tl.ColorDefault) l.AddEntity(text) }
func (l *introLevel) refresh() { l.gt.intro.AddEntity(&l.gt.console) l.gt.console.SetText("") w, h := l.gt.g.Screen().Size() quarterH := h / 4 rect := tl.NewRectangle(10, 2, w-20, h-4, tl.ColorCyan) l.AddEntity(rect) logo, _ := ioutil.ReadFile("data/logo.txt") c := tl.CanvasFromString(string(logo)) logoEntity := tl.NewEntityFromCanvas(w/2-len(c)/2, quarterH, tl.CanvasFromString(string(logo))) l.AddEntity(logoEntity) msg := "Press any key to continue" l.pressAKeyText = tl.NewText(w/2-len(msg)/2, h/2, msg, tl.ColorBlue|tl.AttrReverse, tl.ColorDefault) l.AddEntity(l.pressAKeyText) instructions, _ := ioutil.ReadFile("data/instructions.txt") c = tl.CanvasFromString(string(instructions)) l.AddEntity(tl.NewEntityFromCanvas(w/2-len(c)/2, h/2+2, c)) l.needsRefresh = false }
func newWelcome(game *tl.Game) *welcome { c := [4]string{"HOTSEAT", "P1 vs AI", "AI vs P2", "AI vs AI"} hWidth := len(header[0]) hHeight := len(header) w := &welcome{ msg: tl.NewText(hWidth/2-(len(msg)/2), hHeight+1, msg, Fg, Bg), header: [12]*tl.Text{}, choices: [4]*tl.Text{ tl.NewText(5, hHeight+3, c[0], Fg, Bg), tl.NewText(hWidth/len(c)+5, hHeight+3, c[1], Fg, Bg), tl.NewText((hWidth/len(c))*2+5, hHeight+3, c[2], Fg, Bg), tl.NewText((hWidth/len(c))*3+5, hHeight+3, c[3], Fg, Bg), }, done: false, game: game, } for k, _ := range w.header { w.header[k] = tl.NewText(0, k, header[k], Fg, Bg) } return w }
func SetupUI() { game.Screen().AddEntity(termloop.NewText(0, 0, " MineSweeper ", termloop.ColorBlue, termloop.ColorBlack)) }
func UpdateUI() { _, screenH := game.Screen().Size() game.Screen().AddEntity(termloop.NewText(0, screenH-1, " Mines: "+strconv.Itoa(mineCount)+", Flags: "+strconv.Itoa(flags), termloop.ColorBlue, termloop.ColorBlack)) }
func (g *Game) gameOver() { g.game.Screen().Level().AddEntity(tl.NewText(28, 17, " GAME OVER ", tl.ColorBlack, tl.ColorRed)) }
func NewScoreText() *ScoreText { return &ScoreText{tl.NewText(0, 0, "Score: 0", tl.ColorYellow, tl.ColorBlue), 0} }
func NewLevelText() *LevelText { return &LevelText{tl.NewText(20, 0, "Level: 1", tl.ColorYellow, tl.ColorBlue), 1} }
func NewHealthText() *HealthText { return &HealthText{tl.NewText(40, 0, "Health: 100%", tl.ColorYellow, tl.ColorBlue), 100} }
func (d *TermloopDriver) OnInit(c *hachi.Chip8) { // hex keyboard with 16 keys. // 8, 4, 6 and 2 are typically used for directional input. d.keyMap = map[tl.Key]uint16{ tl.KeyTab: hachi.Key0, tl.KeyF2: hachi.Key1, tl.KeyF3: hachi.Key2, tl.KeyF4: hachi.Key3, tl.KeyF5: hachi.Key4, tl.KeyF6: hachi.Key5, tl.KeyF7: hachi.Key6, tl.KeyF8: hachi.Key7, tl.KeyF9: hachi.Key8, tl.KeyF10: hachi.Key9, tl.KeyCtrlA: hachi.KeyA, tl.KeyCtrlB: hachi.KeyB, tl.KeyCtrlC: hachi.KeyC, tl.KeyCtrlD: hachi.KeyD, tl.KeyCtrlE: hachi.KeyE, tl.KeyCtrlF: hachi.KeyF, tl.KeyArrowDown: hachi.Key2, tl.KeyArrowLeft: hachi.Key4, tl.KeyArrowRight: hachi.Key6, tl.KeyArrowUp: hachi.Key8, tl.KeyEnter: hachi.Key5, } // init termloop d.g = tl.NewGame() scr := d.g.Screen() scr.AddEntity(&inputHandler{c, d, make(map[uint16]time.Time)}) scr.AddEntity(tl.NewText(0, 0, "Stack Syscalls", tl.ColorDefault, tl.ColorDefault)) // stack d.stack = make([]*tl.Text, len(c.Stack)) for i := 0; i < len(d.stack); i++ { d.stack[i] = tl.NewText( 0, i+1, "", tl.ColorDefault, tl.ColorDefault) d.g.Screen().AddEntity(d.stack[i]) } // syscall log for i := 0; i < 10; i++ { d.syscalls[i] = tl.NewText( 8, i+1, "", tl.ColorDefault, tl.ColorDefault) d.g.Screen().AddEntity(d.syscalls[i]) } // chip info d.memory = tl.NewText(20, 0, "placeholder", tl.ColorDefault, tl.ColorDefault) scr.AddEntity(d.memory) d.registers = tl.NewText(20, 1, "placeholder", tl.ColorDefault, tl.ColorDefault) scr.AddEntity(d.registers) d.pointersAndTimers = tl.NewText(20, 2, "placeholder", tl.ColorDefault, tl.ColorDefault) scr.AddEntity(d.pointersAndTimers) d.devices = tl.NewText(20, 3, "placeholder", tl.ColorDefault, tl.ColorDefault) scr.AddEntity(d.devices) // screen preview at 20,5 d.screen = make([][]*tl.Rectangle, c.Width) color := tl.ColorWhite // foreground for i := uint8(0); i < c.Width; i++ { d.screen[i] = make([]*tl.Rectangle, c.Height) for j := uint8(0); j < c.Height; j++ { d.screen[i][j] = tl.NewRectangle( 20+int(i), 5+int(j), 1, 1, color, ) } } d.lastScreen = make([]byte, uint16(c.Width)*uint16(c.Height)/8) log.Println("TermloopDriver initialized") }