JoelOtter / termloop

Terminal-based game engine for Go, built on top of Termbox
Other
1.42k stars 83 forks source link

Not possible to get screen width and height before game.Start() is called #30

Closed kirhgoff closed 7 years ago

kirhgoff commented 7 years ago

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() ?

kirhgoff commented 7 years ago

Another problem with width and height is that if I have monsters moving over level independently, changing their coordinates in gouroutines, there is no information about screen size. Level is infinite and I want not to allow monsters to go off the screen. Should I extend Level and add border collision functionality? What would you recommend?

JoelOtter commented 7 years ago

The Init vs Run idea is interesting - let me mull that one over a bit. 😄 As for Goroutines - Termloop is explicitly single-threaded, so I've not really tried running entities in separate threads. I guess adding that functionality to Level could work, though that seems like the wrong approach - perhaps your entities could hold a pointer to some central thing that they can query for information like frame time and screen size.

domdom82 commented 7 years ago

hi, I am struggling with the same issue. I need to place the player in the middle of the screen for which I need the screen dimensions before calling Start(). I think it would also be possible to handle in the Tick() somehow but rather complicated.

I carefully disagree on @kirhgoff second point using goroutines to move monsters. Usually games have a single "main loop" during which stuff like keyboard input, sound, rendering and movement are processed. Unless your monsters have some very sophisticated AI logic that requires massive CPU cycles to compute, there is not much benefit in splitting them into goroutines but you have major pain in synchronizing everything back shoehorning it into the single-thread main loop again.

So there should be just one step like "moveMonsters()" that happens on every loop cycle and moves every monster according to its logic for this very frame.

JoelOtter commented 7 years ago

OK, so we shouldn't need an Init function - you don't want to place your player in the center of the screen, you want to render your screen relative to the position of the player. BaseLevel includes a function called SetOffset which you can use. It's in the tutorial.

kirhgoff commented 7 years ago

@domdom82 in my case I was planning to have complicated long-running logic, hopefully, goroutines easy the pain of synchronization.