terrain animation broken, mobs rendering right

This commit is contained in:
thefish 2019-11-16 04:31:57 +03:00
parent 7e9f7686a9
commit 0d8649498c
6 changed files with 128 additions and 139 deletions

View File

@ -81,7 +81,6 @@ func main() {
//Set up viewport //Set up viewport
vp := mainwindow.NewViewPort(sidebarWidth, 0, (mw.W - sidebarWidth), (mw.H - 0), mw.GetLayer("base")) vp := mainwindow.NewViewPort(sidebarWidth, 0, (mw.W - sidebarWidth), (mw.H - 0), mw.GetLayer("base"))
go vp.Listen(State)
//set up controller //set up controller

View File

@ -210,6 +210,13 @@ func (c *Controller) AddSystem(system System, priority int) {
} }
} }
func (c *Controller) GetSystem(systemType string) System {
if system, ok := c.systems[systemType]; ok {
return system
}
return nil
}
// Process kicks off system processing for all systems attached to the controller. Systems will be processed in the // Process kicks off system processing for all systems attached to the controller. Systems will be processed in the
// order they are found, or if they have a priority, in priority order. If there is a mix of systems with priority and // order they are found, or if they have a priority, in priority order. If there is a mix of systems with priority and
// without, systems with priority will be processed first (in order). // without, systems with priority will be processed first (in order).

View File

@ -1,7 +1,9 @@
package systems package systems
import ( import (
"fmt"
"lab.zaar.be/thefish/alchemyst-go/engine/ecs" "lab.zaar.be/thefish/alchemyst-go/engine/ecs"
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
"lab.zaar.be/thefish/alchemyst-go/engine/types" "lab.zaar.be/thefish/alchemyst-go/engine/types"
"lab.zaar.be/thefish/alchemyst-go/ui/mainwindow" "lab.zaar.be/thefish/alchemyst-go/ui/mainwindow"
) )
@ -10,6 +12,7 @@ type MobRenderSystem struct {
Controller *ecs.Controller Controller *ecs.Controller
Layer *mainwindow.Layer Layer *mainwindow.Layer
Viewport *mainwindow.ViewPort Viewport *mainwindow.ViewPort
*gamemap.Level
} }
func (mrs MobRenderSystem) Process(){ func (mrs MobRenderSystem) Process(){
@ -30,8 +33,25 @@ func (mrs MobRenderSystem) Process(){
//} //}
//fixme //fixme
mrs.Layer.WithRawColor(appearance.ColorSet.Fg.GetColor()).Put(pos.X, pos.Y, appearance.Glyph.GetGlyph()) //for y := 0; y < mrs.Viewport.H; y++ {
mrs.Layer.WithRawColor(appearance.ColorSet.Fg.GetColor()).Put(pos.X, pos.Y, appearance.Glyph.GetGlyph()) // for x := 0; x < mrs.Viewport.W; x++ {
// mapCoords := types.Coords{mrs.Viewport.CameraCoords.X + x, mrs.Viewport.CameraCoords.Y + y}
// if mrs.Level.InBounds(mapCoords) {
// mrs.Layer.WithRawColor(appearance.ColorSet.Fg.GetColor()).Put(
// x+mrs.Viewport.X,
// y+mrs.Viewport.Y,
// appearance.Glyph.GetGlyph(),
// )
// }
// }
//}
vpc, err := mrs.Viewport.ToVPCoords(pos)
if err != nil {
fmt.Printf("Err: " , err)
}
mrs.Layer.WithRawColor(appearance.ColorSet.Fg.GetColor()).Put(vpc.X, vpc.Y, appearance.Glyph.GetGlyph())
//gogue.PrintGlyph(pos.X, pos.Y, appearance.Glyph, "", appearance.Layer) //gogue.PrintGlyph(pos.X, pos.Y, appearance.Glyph, "", appearance.Layer)
//} //}

View File

@ -2,64 +2,105 @@ package systems
import ( import (
"lab.zaar.be/thefish/alchemyst-go/engine/ecs" "lab.zaar.be/thefish/alchemyst-go/engine/ecs"
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap" "lab.zaar.be/thefish/alchemyst-go/engine/fov"
"lab.zaar.be/thefish/alchemyst-go/engine/fov/precomputed_shade"
"lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
"lab.zaar.be/thefish/alchemyst-go/engine/types" "lab.zaar.be/thefish/alchemyst-go/engine/types"
"lab.zaar.be/thefish/alchemyst-go/ui/mainwindow" "lab.zaar.be/thefish/alchemyst-go/ui/mainwindow"
"time"
) )
type TerrainRenderSystem struct { type TerrainRenderSystem struct {
Viewport mainwindow.ViewPort Viewport *mainwindow.ViewPort
Level gamemap.Level state *gamestate.GameState
layer *mainwindow.Layer
animateTiles *time.Ticker
fov fov.Fov
TorchRadius int
redraw bool
fovRecompute bool
}
func NewTerrainRenderSystem(
state *gamestate.GameState,
vp *mainwindow.ViewPort,
layer *mainwindow.Layer,
) TerrainRenderSystem {
trs := TerrainRenderSystem{
Viewport:vp,
layer: layer,
state: state,
redraw: true,
fovRecompute: true,
}
computedFov := precomputed_shade.NewPrecomputedShade(15)
computedFov.Init()
trs.TorchRadius = 12 //fixme move to sight component
trs.animateTiles = time.NewTicker(time.Second / 12)
trs.fov = computedFov
return trs
}
//fixme add to screens/game Exit()
func (trs TerrainRenderSystem) Close() {
trs.animateTiles.Stop()
trs.animateTiles = nil //zero pointer to ticker
}
func (trs TerrainRenderSystem) Listen() {
for {
select {
case <-trs.state.FovRecompute:
trs.fovRecompute = true
case <-trs.state.Redraw:
trs.redraw = true
case <-trs.animateTiles.C:
trs.redraw = true
}
}
} }
func (trs TerrainRenderSystem) Process() { func (trs TerrainRenderSystem) Process() {
playerCoords := state.Controller.GetComponent(state.Player, ecs.CoordsComponent).(types.Coords) playerCoords := trs.state.Controller.GetComponent(trs.state.Player, ecs.CoordsComponent).(types.Coords)
vp.Move(state, playerCoords) trs.Viewport.Move(trs.state, playerCoords)
if fovRecompute { if trs.fovRecompute {
vp.layer.ClearRect(vp.Rect) trs.layer.ClearRect(trs.Viewport.Rect)
fovRecompute = false trs.fovRecompute = false
redraw = true trs.redraw = true
vp.Fov.ComputeFov(state.Level, playerCoords, vp.TorchRadius) trs.fov.ComputeFov(trs.state.Level, playerCoords, trs.TorchRadius)
} }
//vp.layer.ClearArea(0, 7, 20, 1) if trs.redraw {
//vp.layer.Print(0,7, fmt.Sprintf("pcds: %v", playerCoords))
if redraw {
//terrain //terrain
for y := 0; y < vp.H; y++ { for y := 0; y < trs.Viewport.H; y++ {
for x := 0; x < vp.W; x++ { for x := 0; x < trs.Viewport.W; x++ {
mapCoords := types.Coords{vp.cameraCoords.X + x, vp.cameraCoords.Y + y} mapCoords := types.Coords{trs.Viewport.CameraCoords.X + x, trs.Viewport.CameraCoords.Y + y}
if state.Level.InBounds(mapCoords) { if trs.state.Level.InBounds(mapCoords) {
tile := state.Level.GetTile(mapCoords) tile := trs.state.Level.GetTile(mapCoords)
if tile.Explored || tile.Visible { if tile.Explored || tile.Visible {
vp.layer.PutToBase(x+vp.X, y+vp.Y, tile.GetChar(), tile.GetRawColor(), tile.GetRawBgColor()) trs.layer.PutToBase(
x+trs.Viewport.X,
y+trs.Viewport.Y,
tile.GetChar(),
tile.GetRawColor(),
tile.GetRawBgColor(),
)
} }
} }
} }
} }
/* trs.redraw = false
//mobs
pc, err := vp.ToVPCoords(playerCoords)
_ = pc
if err != nil {
fmt.Println("error on getting player position")
} else {
vp.layer.WithColor("white").Put(pc.X+vp.X, pc.Y+vp.Y, "@")
//mw.GetLayer("base").WithColor("white").Put(42, 10, "B")
//mw.GetLayer("overlay").WithColor("white").Put(59, 10, "O")
}
*/
//redraw = true
redraw = false
} }
} }
func (trs TerrainRenderSystem) Type() string { func (trs TerrainRenderSystem) SystemType() string {
return ecs.TerrainRenderSystem return ecs.TerrainRenderSystem
} }

View File

@ -19,8 +19,17 @@ type GameScreen struct {
func NewGameScreen(mw *mainwindow.MainWindow, state *gamestate.GameState, viewPort *mainwindow.ViewPort, controller *ecs.Controller, scm *types.ScreenManager) *GameScreen { func NewGameScreen(mw *mainwindow.MainWindow, state *gamestate.GameState, viewPort *mainwindow.ViewPort, controller *ecs.Controller, scm *types.ScreenManager) *GameScreen {
ts := &GameScreen{mw: mw, state: state, vp: viewPort, controller: controller, scm: scm} ts := &GameScreen{mw: mw, state: state, vp: viewPort, controller: controller, scm: scm}
renderMobs := systems.MobRenderSystem{Controller: ts.controller, Layer: ts.mw.GetLayer("base"), Viewport: ts.vp} renderMobs := systems.MobRenderSystem{
ts.controller.AddSystem(renderMobs, 1) Controller: ts.controller,
Layer: ts.mw.GetLayer("base"),
Viewport: ts.vp,
Level: state.Level,
}
ts.controller.AddSystem(renderMobs, 10)
renderTerrain := systems.NewTerrainRenderSystem(state, viewPort, ts.mw.GetLayer("base"))
go renderTerrain.Listen()
ts.controller.AddSystem(renderTerrain, 5)
return ts return ts
} }
@ -31,6 +40,8 @@ func (ts *GameScreen) Enter() {
Print(1, ts.mw.H-2, "Press [color=white]?[/color] for help") Print(1, ts.mw.H-2, "Press [color=white]?[/color] for help")
} }
func (ts *GameScreen) Exit() { func (ts *GameScreen) Exit() {
//trs := ts.controller.GetSystem(ecs.TerrainRenderSystem)
//trs.(systems.TerrainRenderSystem).Close()
ts.mw.GetLayer("overlay").ClearArea(0, ts.mw.H-3, 30, 3) ts.mw.GetLayer("overlay").ClearArea(0, ts.mw.H-3, 30, 3)
//remove what we dont need //remove what we dont need
} }
@ -81,6 +92,6 @@ func (ts *GameScreen) HandleInput(input string) {
} }
func (ts *GameScreen) Render() { func (ts *GameScreen) Render() {
ts.vp.Render(ts.state) //ts.vp.Render(ts.state)
ts.controller.Process([]string{}) ts.controller.Process([]string{})
} }

View File

@ -1,47 +1,23 @@
package mainwindow package mainwindow
import ( import (
"errors" "fmt"
"lab.zaar.be/thefish/alchemyst-go/engine/ecs"
"lab.zaar.be/thefish/alchemyst-go/engine/fov"
"lab.zaar.be/thefish/alchemyst-go/engine/fov/precomputed_shade"
"lab.zaar.be/thefish/alchemyst-go/engine/gamestate" "lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
"lab.zaar.be/thefish/alchemyst-go/engine/types" "lab.zaar.be/thefish/alchemyst-go/engine/types"
"time"
) )
var NotInViewError = errors.New("not in ViewPort")
type ViewPort struct { type ViewPort struct {
types.Rect types.Rect
cameraCoords types.Coords CameraCoords types.Coords
layer *Layer
Fov fov.Fov
TorchRadius int
animateTiles *time.Ticker
} }
func NewViewPort(x, y, w, h int, layer *Layer) *ViewPort { func NewViewPort(x, y, w, h int, layer *Layer) *ViewPort {
computedFov := precomputed_shade.NewPrecomputedShade(15)
computedFov.Init()
vp := ViewPort{ vp := ViewPort{
Rect: types.Rect{x, y, w, h}, Rect: types.Rect{x, y, w, h},
layer: layer,
Fov: computedFov,
} }
vp.TorchRadius = 12
vp.animateTiles = time.NewTicker(time.Second / 12)
return &vp return &vp
} }
func (vp *ViewPort) Close() {
vp.animateTiles.Stop()
vp.animateTiles = nil //zero pointer to ticker
}
func (vp *ViewPort) Move(state *gamestate.GameState, newCoords types.Coords) { func (vp *ViewPort) Move(state *gamestate.GameState, newCoords types.Coords) {
x := newCoords.X - vp.Rect.W/2 x := newCoords.X - vp.Rect.W/2
@ -59,85 +35,20 @@ func (vp *ViewPort) Move(state *gamestate.GameState, newCoords types.Coords) {
if y > state.Level.H-vp.H - 1 { if y > state.Level.H-vp.H - 1 {
y = state.Level.H - vp.H y = state.Level.H - vp.H
} }
if x != vp.cameraCoords.X || y != vp.cameraCoords.Y { if x != vp.CameraCoords.X || y != vp.CameraCoords.Y {
state.FovRecompute <- struct{}{} state.FovRecompute <- struct{}{}
} }
vp.cameraCoords.X = x vp.CameraCoords.X = x
vp.cameraCoords.Y = y vp.CameraCoords.Y = y
} }
func (vp *ViewPort) ToVPCoords(c types.Coords) (newCoords types.Coords, err error) { func (vp *ViewPort) ToVPCoords(c types.Coords) (newCoords types.Coords, err error) {
//coords on map to coords on vp //coords on map to coords on vp
x, y := c.X-vp.cameraCoords.X, c.Y-vp.cameraCoords.Y x, y := c.X-vp.CameraCoords.X, c.Y-vp.CameraCoords.Y
if x < 0 || y < 0 || x > vp.W || y > vp.H { if x < 0 || y < 0 || x > vp.W || y > vp.H {
return types.Coords{-1, -1}, NotInViewError return types.Coords{-1, -1}, fmt.Errorf("Not in viewport: {%d, %d}", x, y)
} }
return types.Coords{x, y}, nil return types.Coords{x, y}, nil
} }
var redraw = true
var fovRecompute = true
func (vp *ViewPort) Listen(state gamestate.GameState) {
for {
select {
case <-state.FovRecompute:
fovRecompute = true
case <-state.Redraw:
redraw = true
case <-vp.animateTiles.C:
redraw = true
}
}
}
func (vp *ViewPort) Render(state *gamestate.GameState) {
playerCoords := state.Controller.GetComponent(state.Player, ecs.CoordsComponent).(types.Coords)
vp.Move(state, playerCoords)
if fovRecompute {
vp.layer.ClearRect(vp.Rect)
fovRecompute = false
redraw = true
vp.Fov.ComputeFov(state.Level, playerCoords, vp.TorchRadius)
}
//vp.layer.ClearArea(0, 7, 20, 1)
//vp.layer.Print(0,7, fmt.Sprintf("pcds: %v", playerCoords))
if redraw {
//terrain
for y := 0; y < vp.H; y++ {
for x := 0; x < vp.W; x++ {
mapCoords := types.Coords{vp.cameraCoords.X + x, vp.cameraCoords.Y + y}
if state.Level.InBounds(mapCoords) {
tile := state.Level.GetTile(mapCoords)
if tile.Explored || tile.Visible {
vp.layer.PutToBase(x+vp.X, y+vp.Y, tile.GetChar(), tile.GetRawColor(), tile.GetRawBgColor())
}
}
}
}
/*
//mobs
pc, err := vp.ToVPCoords(playerCoords)
_ = pc
if err != nil {
fmt.Println("error on getting player position")
} else {
vp.layer.WithColor("white").Put(pc.X+vp.X, pc.Y+vp.Y, "@")
//mw.GetLayer("base").WithColor("white").Put(42, 10, "B")
//mw.GetLayer("overlay").WithColor("white").Put(59, 10, "O")
}
*/
//redraw = true
redraw = false
}
}