joelotter / termloop Goto Github PK
View Code? Open in Web Editor NEWTerminal-based game engine for Go, built on top of Termbox
License: Other
Terminal-based game engine for Go, built on top of Termbox
License: Other
I hit an existential chicken-egg issue. Is there a way to get the screen size before game.Start()? game.Screen().Size()
returns 0, 0
Probably using PortAudio for cross-platform compatibility. Should be able to:
GPM [1] provides mouse support for at least Linux terminals.
Do you think it would be possible to support GPM with termloop? It would enable some nice scenarios :)
After discussion with community members on Gitter, it was decided that this would be a very useful feature to have - for example, one would be able to reorder entities, thereby dictating which is drawn on top of which.
Hi! I am trying to learn some Go and love your terminal libraries for starting some fun projects. Thank You!
I am creating an entity that has different orientations depending on which direction it is facing. That entity has some transparent pixels on it. On loading the entity, I create a new canvas for every orientation and keep a pointer to them. If the orientation of my entity changes, I use ApplyCanvas()
to apply the according canvas to the underlying entity's canvas. Unfortunately, when the orientation changes, the transparent pixel won't apply, if there is already a color defined (renderCell()
in screen.go). So the previous color for that pixel shows up, where a transparent one should be.
I understand why it's necessary to do this when drawing on a background, but would it be possible to use another function, that applies all pixels (including transparent) when not rendering to the screen, but on an internal(~sprite) canvas? What I did as a workaround, is using a special "Sprite" render Method and use this in ApplyCanvas()
.
func renderSpriteCell(old, new_ *Cell) {
old.Ch = new_.Ch
old.Bg = new_.Bg
old.Fg = new_.Fg
}
func (e *Entity) ApplyCanvas(c *Canvas) {
for i := 0; i < min(len(e.canvas), len(*c)); i++ {
for j := 0; j < min(len(e.canvas[0]), len((*c)[0])); j++ {
renderSpriteCell(&e.canvas[i][j], &(*c)[i][j])
}
}
}
In a real solution you wold need to use that in all relevant functions, I guess. Unfortunately I don't understand the implications of such change and don't feel confident in supplying a pull request.
Greetings!
We don't really have any tests other than running the included examples. If anyone has any ideas about the best way to go about this, please say!
Defining entities cell-by-cell in code is irritating. Ideally, one should be able to provide a pre-made file, which Termloop could read and create entities from.
Possible asset types:
I want to create monsters randomly on the field. But game.Screen().Size() has zeros as width and height and I cannot call rand with width and height as parameters. They are get defined only after termbox.Init() and this is done in the Start() method, so I need to wait till game is started.
Is it made on purpose? Can we init term at the moment of game creation or split Start() method onto Init() and Run() ?
Is there any reason for newCanvas
not being exported?
#i have a program that changes some text's position, from a go routine, and occasionally i get this crash;
panic: runtime error: index out of range
goroutine 1 [running]:
github.com/JoelOtter/termloop.(*Text).Draw(0xc420014500, 0xc420092000)
/home/simon/gocode/src/github.com/JoelOtter/termloop/text.go:39 +0xdd
github.com/JoelOtter/termloop.(*Screen).Draw(0xc420092000)
/home/simon/gocode/src/github.com/JoelOtter/termloop/screen.go:54 +0xb9
github.com/JoelOtter/termloop.(*Game).Start(0xc420012510)
/home/simon/gocode/src/github.com/JoelOtter/termloop/game.go:115 +0x3f9
main.main()
/home/simon/Dropbox/github/working/moving/text.go:31 +0xfa
code.....
package main
import "github.com/JoelOtter/termloop"
import "github.com/splace/joysticks"
import "fmt"
func main() {
g := termloop.NewGame()
m:=termloop.NewText(60, 20, "<0,0>", termloop.ColorWhite, termloop.ColorBlue)
g.Screen().AddEntity(m)
go func(){
evtChans := joysticks.Capture(
joysticks.Channel{1, joysticks.HID.OnMove},
joysticks.Channel{1, joysticks.HID.OnClose},
)
pos:=joysticks.PositionFromVelocity(evtChans[0])
for{
select {
case evt:= <-pos:
posEvt:=evt.(joysticks.CoordsEvent)
m.SetText(fmt.Sprintf("<%1.2f,%1.2f>",posEvt.X,posEvt.Y))
m.SetPosition(int(posEvt.X*80+60), int(posEvt.Y*80+20))
case <-evtChans[1]:
return
}
}
}()
g.SetEndKey(termloop.KeyEnd)
g.Start()
}
Sometimes Termloop will simply stop, outputting no useful information, even if debugging is turned on.
If you've noticed this happening, please post your configuration as a comment. Here's mine:
OS: Mac OS X 10.10.5 (Yosemite)
Go version: 1.5
Terminal: iTerm2 + tmux
Having a weird issue.
I'm trying the examples on Linux. With collision.go, key events work. Esc exits, arrow keys move.
With movingtext.go however, I cannot exit with Esc, and arrow keys don't work. I'm also going through the tutorial, and there Esc doesn't exit either. It's as if the Entity's Tick never gets called.
I'm trying to implement a Day/Night cycle (right now by simply cycling green from 55 to 255), but it is unclear to me how to change the Background color.
This is my code currently (run as a goroutine), but unfortunately it does not work...
func DayNight(level tl.Level, l *tl.Cell, s *tl.Screen) { // "l" is the background for "level"
ticker := time.NewTicker(100 * time.Millisecond)
sunRise := true
sunSet := false
color := 55
for {
select {
case <- ticker.C:
if color >= 255 {
sunRise = false
sunSet = true
}
if color <= 55 {
sunRise = true
sunSet = false
}
if sunRise == true {
color = color + 1
}
if sunSet == true {
color = color - 1
}
l.Bg = tl.RgbTo256Color(0, color, 0)
level.DrawBackground(s)
}
}
}
func main() {
g := tl.NewGame()
levelCell := tl.Cell {
Bg: tl.RgbTo256Color(0, 51, 0),
Fg: tl.ColorBlack,
Ch: 'v',
}
level := tl.NewBaseLevel(levelCell)
go DayNight(level, &levelCell, g.Screen())
level.AddEntity(tl.NewRectangle(10, 10, 50, 20, tl.ColorBlue))
g.Screen().SetLevel(level)
g.Start()
}
Termbox has added support for additional mouse events, including mouse wheel and release detection.
Support for this should be added to Termloop - however, as these new features are currently not supported on Windows, it might be better to add them to termloop/extras, or simply wait.
when using the Text
component, if the text string is CJK, eg "你好啊", it will only show "你啊". As far as I understand, this is because CJK need two Cell
to render. if what i understand is right, i'll make a pull request to fix this.
Maybe just an issue with my code, but I seem to be getting 0 back for game.Screen().Size() both width, and height.
Haven't really tested Termloop with Go 1.7+.
I can't choose cell's foreground and background colors when loading canvas from string. Wouldn't it be interesting to add two colors arguments to the function ?
This is the current game loop for BaseLevel:
1. Tick
2. Check Collisions
3. Draw
However, Tick()
is only called if there is an event. This means I can not update the entity position based on frame time. For example, I want to move an entity forward every X frames. This would currently only be possible in Draw()
which is called after collision checks, so it is unsafe. Moving an entity inside Draw()
allows it to be inside another entity, although collision checks should prevent that.
Since BaseLevel has a lot of features I would like to use, I don't want to write my own. I think this should be fixed and BaseLevel should call Tick on all its entities on every frame and let the entity decide if it wants to react on keyboard input or just the frame being updated.
Same goes for Screen.Tick()
Is there any specific reason you drop all EventNone
events?
Termloop's performance is acceptable for most applications, but that doesn't mean we shouldn't try and make it better. Let's use this issue to track ideas for improving performance. A couple of potential things to investigate:
Feel free to add more in comments.
For example, let's assume we decode the following rune for a TREE and set it into a cell:
r, _ := utf8.DecodeRuneInString("\xF0\x9F\x8C\xB2")
cell = tl.Cell{Fg: tl.ColorWhite, Ch: r}
What happens is that the true will fill in two spaces horizontally. If you attempt to insert two trees next to one another you will only see the tree on the left. I think this has something to do with the code taking into account the length of the rune in bytes as opposed to the glyph. The later takes up only one location on the screen.
Incidentally I appreciate your work here. Great work. I just wanted you to know. Thanks you!
Is there a way to use Termbox Output256 or OutputRGB?
Hello,
I want to draw a border around the screen by using Rectangles. Depending on the screen size the rectangles have to be placed.
Because game.Screen().Size() returns (0,0) if it's called before game.start(), I have to add the Rectangles afterwards.
But the rectangles don't show up after I add them with AddEntity() to the level.
I also tried to call the Draw() method but it doesn't show any effect.
What is the correct way to draw new entities after game.Start() was called?
my code:
package main
import tl "github.com/JoelOtter/termloop"
import "fmt"
func main() {
game := tl.NewGame()
game.SetDebugOn(true)
level := tl.NewBaseLevel(tl.Cell{
Bg: tl.ColorBlack,
Fg: tl.ColorWhite,
})
game.Screen().SetLevel(level)
//x, y := game.Screen().Size()
//fmt.Printf("before start x: %v, y: %v\n", x, y)
game.Start()
x, y = game.Screen().Size()
//fmt.Printf("after start x: %v, y: %v\n", x, y)
r := tl.NewRectangle(x, y, 1, 1, tl.ColorRed)
level.AddEntity(r)
//r.Draw(game.Screen())
//game.Screen().Draw()
}
for me, go1.8, this doesn't stop when hitting esc key.
package main
import "github.com/JoelOtter/termloop"
func main() {
g := termloop.NewGame()
m:=termloop.NewText(0, 0, "<=0=>", termloop.ColorWhite, termloop.ColorBlue)
g.Screen().AddEntity(m)
g.Start()
}
The tutorial in the README, along with the GoDoc, serve as a reasonable introduction. However, I think it'd be useful to have some more comprehensive documentation written, along with several tutorials on how to use Termloop's perhaps more-obscure features. We could host on GitHub Pages, which would keep it as part of this repo (just uses a separate branch).
I'm trying to create an in-game hud using a Text
object that's position is always fixed to the top-left corner of the screen.
I can get the text to the correct position sorta but it will not be perfectly fixed. It moves to the desired position when the whole screen updates next but it creates this laggy looking effect where part of the grid coordinates gets cut off or appear off screen for a short time.
Here's what I got in code so far (its chopped out but here is the important bits):
type GridCoordinates struct {
*tl.Text
}
// positions the coords Text object in top-left.
func (m *GridCoordinates) Tick(ev tl.Event) {
// plr is the player object
mx, my := m.Position()
x, y := plr.Position()
sx, sy := game.Screen().Size()
finx := x - sx/2
finy := y - sy/2
if finx != mx || finy != my {
crd := "x" + strconv.Itoa(x) + ",y" + strconv.Itoa(y)
m.SetPosition(x-sx/2, y-sy/2)
m.SetText(crd)
}
}
GridText := tl.NewText(0, 0, "x0,y0", tl.ColorWhite, tl.ColorBlue)
coords = GridCoordinates{GridText}
level.AddEntity(&coords)
This is the visual result:
How could I get some Text to always stay fixed in the upper left hand corner?
As far as I understand, mouse event coordinates correspond to the terminal cell positions, and no support for pixel mode (where every terminal cell contains two pixels) was implemented. The problem can be observed buy enabling the pixel mode in the click.go example.
Is there a way to programatically stop a termloop Game object? There is a Start function but no stop far as I can tell. Only way is to press key so far.
panic: runtime error: index out of range
goroutine 1 [running]:
github.com/nsf/termbox-go.cell_to_char_info(0x59000000000000, 0x0)
C:/Users/#/Documents/GoProjects/src/github.com/nsf/termbox-go/termbox_windows.go:526 +0x18b
github.com/nsf/termbox-go.append_diff_line(0xe, 0x78)
C:/Users/#/Documents/GoProjects/src/github.com/nsf/termbox-go/termbox_windows.go:466 +0xe0
github.com/nsf/termbox-go.prepare_diff_messages()
C:/Users/#/Documents/GoProjects/src/github.com/nsf/termbox-go/termbox_windows.go:510 +0x265
github.com/nsf/termbox-go.Flush(0x0, 0x0)
C:/Users/#/Documents/GoProjects/src/github.com/nsf/termbox-go/api_windows.go:109 +0x42
github.com/JoelOtter/termloop.(*Screen).Draw(0xc082010090)
C:/Users/#/Documents/GoProjects/src/github.com/JoelOtter/termloop/screen.go:65 +0x32f
github.com/JoelOtter/termloop.(*Game).Start(0xc08204e4b0)
C:/Users/#/Documents/GoProjects/src/github.com/JoelOtter/termloop/game.go:115 +0x51f
main.main()
C:/Users/#/Documents/GoProjects/src/Delilah/main.go:54 +0x220
goroutine 13 [chan send]:
github.com/JoelOtter/termloop.poll(0xc082006740)
C:/Users/#/Documents/GoProjects/src/github.com/JoelOtter/termloop/input.go:33 +0x9a
created by github.com/JoelOtter/termloop.(*input).start
C:/Users/#/Documents/GoProjects/src/github.com/JoelOtter/termloop/input.go:19 +0x3c
Above Error encountered when running the image.go example. Used random png, jpeg files. Nothing worked. Thank you :)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.