working prototype with ecs
This commit is contained in:
parent
096ff2b182
commit
a195e335eb
@ -9,6 +9,7 @@ import (
|
|||||||
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap/mapgens"
|
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap/mapgens"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
|
"lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/engine/mob"
|
"lab.zaar.be/thefish/alchemyst-go/engine/mob"
|
||||||
|
"lab.zaar.be/thefish/alchemyst-go/engine/mob/movement"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/engine/screens"
|
"lab.zaar.be/thefish/alchemyst-go/engine/screens"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/engine/types"
|
"lab.zaar.be/thefish/alchemyst-go/engine/types"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/ui"
|
"lab.zaar.be/thefish/alchemyst-go/ui"
|
||||||
@ -56,18 +57,29 @@ func main() {
|
|||||||
var logLevels = map[string]zerolog.Level{"debug": zerolog.DebugLevel, "info": zerolog.InfoLevel, "warn": zerolog.WarnLevel}
|
var logLevels = map[string]zerolog.Level{"debug": zerolog.DebugLevel, "info": zerolog.InfoLevel, "warn": zerolog.WarnLevel}
|
||||||
var logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339}).Level(logLevels[config.Verbosity])
|
var logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339}).Level(logLevels[config.Verbosity])
|
||||||
|
|
||||||
|
// set up context
|
||||||
mainCtx := util.NewClientContext(config, &logger)
|
mainCtx := util.NewClientContext(config, &logger)
|
||||||
|
|
||||||
|
|
||||||
|
//set up main window
|
||||||
mw := mainwindow.Init(mainCtx)
|
mw := mainwindow.Init(mainCtx)
|
||||||
defer mw.Close()
|
defer mw.Close()
|
||||||
|
|
||||||
setupLayers(mw)
|
setupLayers(mw)
|
||||||
|
|
||||||
//fixme
|
//set up input decoder
|
||||||
|
go decodeInput(mainCtx, mw.GetLayer("base"))
|
||||||
|
|
||||||
|
|
||||||
|
//fixme set up (load / generate) level
|
||||||
level, rooms := mapgens.DefaultGen(gamemap.NewLevel(mainCtx, "test", 1))
|
level, rooms := mapgens.DefaultGen(gamemap.NewLevel(mainCtx, "test", 1))
|
||||||
State.Level = level
|
State.Level = level
|
||||||
vp := mainwindow.NewViewPort(30, 0, 70, 47, mw.GetLayer("base"))
|
|
||||||
|
|
||||||
|
//Set up viewport
|
||||||
|
vp := mainwindow.NewViewPort(30, 0, 70, 47, mw.GetLayer("base"))
|
||||||
|
go vp.Listen(State)
|
||||||
|
|
||||||
|
//Set up Screen Manager
|
||||||
screenMgr := types.NewScreenManager(mainCtx)
|
screenMgr := types.NewScreenManager(mainCtx)
|
||||||
screenMgr.AddScreen("title", &screens.TitleScreen{})
|
screenMgr.AddScreen("title", &screens.TitleScreen{})
|
||||||
screenMgr.AddScreen("game", screens.NewGameScreen(mw, &State, vp))
|
screenMgr.AddScreen("game", screens.NewGameScreen(mw, &State, vp))
|
||||||
@ -92,15 +104,21 @@ func main() {
|
|||||||
//vp.PlayerCoords = player.Coords
|
//vp.PlayerCoords = player.Coords
|
||||||
//vp.Render(&State)
|
//vp.Render(&State)
|
||||||
|
|
||||||
go decodeInput(mainCtx, mw.GetLayer("base"))
|
//set up controller
|
||||||
go vp.Listen(State)
|
|
||||||
|
|
||||||
controller := ecs.NewController()
|
controller := ecs.NewController()
|
||||||
|
|
||||||
controller.MapComponentClass("coords", types.Coords{})
|
controller.MapComponentClass("coords", types.Coords{})
|
||||||
controller.MapComponentClass("appearance", types.Appearance{})
|
controller.MapComponentClass("appearance", types.Appearance{})
|
||||||
controller.MapComponentClass("mob", mob.Mob{})
|
controller.MapComponentClass("mob", mob.Mob{})
|
||||||
|
controller.MapComponentClass("moveable", movement.Moveable{})
|
||||||
|
|
||||||
|
moveable := movement.Moveable{
|
||||||
|
Controller: controller,
|
||||||
|
Level: level,
|
||||||
|
}
|
||||||
|
|
||||||
|
//fixme set up (load / generate) player
|
||||||
player := controller.CreateEntity([]ecs.Component{})
|
player := controller.CreateEntity([]ecs.Component{})
|
||||||
|
|
||||||
controller.AddComponent(player, &types.Appearance{
|
controller.AddComponent(player, &types.Appearance{
|
||||||
@ -111,13 +129,15 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
controller.AddComponent(player, rooms[0].Center) //implicit Coords
|
controller.AddComponent(player, rooms[0].Center) //implicit Coords
|
||||||
|
controller.AddComponent(player, moveable)
|
||||||
|
|
||||||
|
|
||||||
render := systems.MobRenderSystem{EntityController: controller}
|
render := systems.MobRenderSystem{EntityController: controller}
|
||||||
|
|
||||||
controller.AddSystem(render, 1)
|
controller.AddSystem(render, 1)
|
||||||
|
|
||||||
level.Player = player
|
State.Player = player
|
||||||
|
State.Controller = controller
|
||||||
|
|
||||||
//but every call to bearlibterminal must be wrapped to closure and passed to mainfunc
|
//but every call to bearlibterminal must be wrapped to closure and passed to mainfunc
|
||||||
var exit = false
|
var exit = false
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package gamestate
|
package gamestate
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"lab.zaar.be/thefish/alchemyst-go/engine/ecs"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
|
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -10,8 +11,10 @@ type GameState struct {
|
|||||||
Input chan string
|
Input chan string
|
||||||
RawInput chan int
|
RawInput chan int
|
||||||
FovRecompute chan struct{}
|
FovRecompute chan struct{}
|
||||||
Redraw chan struct{}
|
Redraw chan struct{}
|
||||||
|
Player ecs.Entity
|
||||||
Level *gamemap.Level
|
Level *gamemap.Level
|
||||||
|
Controller *ecs.Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
// do runs f on the main thread.
|
// do runs f on the main thread.
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package mob
|
package mob
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
|
|
||||||
"lab.zaar.be/thefish/alchemyst-go/engine/types"
|
"lab.zaar.be/thefish/alchemyst-go/engine/types"
|
||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
@ -13,26 +11,10 @@ type Mob struct {
|
|||||||
BlocksPass bool
|
BlocksPass bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mob) Walk(level *gamemap.Level, dx, dy int) {
|
|
||||||
newCoords := types.Coords{m.X + dx, m.Y + dy}
|
|
||||||
if level.GetTile(newCoords).BlocksPass {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
//fixme
|
|
||||||
//if level.Objects.At(newCoords).HasComponent("block_pass") {
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
fmt.Printf("new coords: %d, %d\n", m.Coords.X, m.Coords.Y)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Mob) Render() {
|
func (m *Mob) Render() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mob) MoveToCoords(c types.Coords) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mob Mob) TypeOf() reflect.Type {
|
func (mob Mob) TypeOf() reflect.Type {
|
||||||
return reflect.TypeOf(mob)
|
return reflect.TypeOf(mob)
|
||||||
}
|
}
|
50
engine/mob/movement/movement.go
Normal file
50
engine/mob/movement/movement.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package movement
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"lab.zaar.be/thefish/alchemyst-go/engine/ecs"
|
||||||
|
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
|
||||||
|
"lab.zaar.be/thefish/alchemyst-go/engine/mob"
|
||||||
|
"lab.zaar.be/thefish/alchemyst-go/engine/types"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Moveable struct {
|
||||||
|
Controller *ecs.Controller
|
||||||
|
Level *gamemap.Level
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (mov Moveable) Walk() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mov Moveable) IsBlocked(c types.Coords) bool {
|
||||||
|
if mov.Level.GetTile(c).BlocksPass == true {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
list := mov.Controller.GetEntitiesWithComponent(mob.Mob{}.TypeOf())
|
||||||
|
for idx, _ := range list {
|
||||||
|
coords := mov.Controller.GetComponent(list[idx], types.Coords{}.TypeOf())
|
||||||
|
if coords == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
coords = coords.(types.Coords)
|
||||||
|
if coords != c {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
m := mov.Controller.GetComponent(list[idx], mob.Mob{}.TypeOf())
|
||||||
|
if m == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if m.(mob.Mob).BlocksPass {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Printf("\nCoords %v do not block pass!", c)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mov Moveable) TypeOf() reflect.Type {
|
||||||
|
return reflect.TypeOf(mov)
|
||||||
|
}
|
@ -1,5 +0,0 @@
|
|||||||
package mob
|
|
||||||
|
|
||||||
type Player struct {
|
|
||||||
Mob
|
|
||||||
}
|
|
@ -2,6 +2,8 @@ package screens
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
|
"lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
|
||||||
|
"lab.zaar.be/thefish/alchemyst-go/engine/mob/movement"
|
||||||
|
"lab.zaar.be/thefish/alchemyst-go/engine/types"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/ui/mainwindow"
|
"lab.zaar.be/thefish/alchemyst-go/ui/mainwindow"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -21,28 +23,28 @@ func (ts *GameScreen) HandleInput(input string) {
|
|||||||
//ts.state.Do(func(){
|
//ts.state.Do(func(){
|
||||||
switch input {
|
switch input {
|
||||||
case "Up", "k", "8":
|
case "Up", "k", "8":
|
||||||
ts.state.Player.Walk(ts.state.Level, 0, -1)
|
ts.walk(ts.state, 0, -1)
|
||||||
break
|
break
|
||||||
case "Down", "j", "2":
|
case "Down", "j", "2":
|
||||||
ts.state.Player.Walk(ts.state.Level,0, 1)
|
ts.walk(ts.state,0, 1)
|
||||||
break
|
break
|
||||||
case "Left", "h", "4":
|
case "Left", "h", "4":
|
||||||
ts.state.Player.Walk(ts.state.Level,-1, 0)
|
ts.walk(ts.state,-1, 0)
|
||||||
break
|
break
|
||||||
case "Right", "l", "6":
|
case "Right", "l", "6":
|
||||||
ts.state.Player.Walk(ts.state.Level,1, 0)
|
ts.walk(ts.state,1, 0)
|
||||||
break
|
break
|
||||||
case "y", "7":
|
case "y", "7":
|
||||||
ts.state.Player.Walk(ts.state.Level,-1, -1)
|
ts.walk(ts.state,-1, -1)
|
||||||
break
|
break
|
||||||
case "u", "9":
|
case "u", "9":
|
||||||
ts.state.Player.Walk(ts.state.Level,1, -1)
|
ts.walk(ts.state,1, -1)
|
||||||
break
|
break
|
||||||
case "b", "1":
|
case "b", "1":
|
||||||
ts.state.Player.Walk(ts.state.Level,-1, 1)
|
ts.walk(ts.state,-1, 1)
|
||||||
break
|
break
|
||||||
case "n", "3":
|
case "n", "3":
|
||||||
ts.state.Player.Walk(ts.state.Level,1, 1)
|
ts.walk(ts.state,1, 1)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
ts.mw.GetLayer("base").ClearArea(0, 3, 40, 1)
|
ts.mw.GetLayer("base").ClearArea(0, 3, 40, 1)
|
||||||
@ -56,3 +58,18 @@ func (ts *GameScreen) Exit() {}
|
|||||||
func (ts *GameScreen) Render() {
|
func (ts *GameScreen) Render() {
|
||||||
ts.vp.Render(ts.state)
|
ts.vp.Render(ts.state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (ts *GameScreen) walk(state *gamestate.GameState, dx, dy int) {
|
||||||
|
controller := state.Controller
|
||||||
|
coords := controller.GetComponent(state.Player, types.Coords{}.TypeOf()).(types.Coords)
|
||||||
|
newCoords := types.Coords{coords.X + dx, coords.Y + dy}
|
||||||
|
movable := controller.GetComponent(state.Player, movement.Moveable{}.TypeOf()).(movement.Moveable)
|
||||||
|
|
||||||
|
if !movable.IsBlocked(newCoords) {
|
||||||
|
controller.UpdateComponent(state.Player, types.Coords{}.TypeOf(), newCoords)
|
||||||
|
}
|
||||||
|
|
||||||
|
state.Redraw <- struct{}{}
|
||||||
|
state.FovRecompute <- struct{}{}
|
||||||
|
}
|
@ -6,7 +6,6 @@ import (
|
|||||||
"lab.zaar.be/thefish/alchemyst-go/engine/fov"
|
"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/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/mob"
|
|
||||||
"lab.zaar.be/thefish/alchemyst-go/engine/types"
|
"lab.zaar.be/thefish/alchemyst-go/engine/types"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -18,7 +17,6 @@ type ViewPort struct {
|
|||||||
cameraCoords types.Coords
|
cameraCoords types.Coords
|
||||||
layer *Layer
|
layer *Layer
|
||||||
Fov fov.Fov
|
Fov fov.Fov
|
||||||
Player mob.Player
|
|
||||||
TorchRadius int
|
TorchRadius int
|
||||||
animateTiles *time.Ticker
|
animateTiles *time.Ticker
|
||||||
}
|
}
|
||||||
@ -44,12 +42,10 @@ func (vp *ViewPort) Close() {
|
|||||||
vp.animateTiles = nil //free pointer to ticker
|
vp.animateTiles = nil //free pointer to ticker
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vp *ViewPort) Move(state *gamestate.GameState) {
|
func (vp *ViewPort) Move(state *gamestate.GameState, newCoords types.Coords) {
|
||||||
|
|
||||||
c := &state.Level.Player.HasComponent(types.Coords{}).Coords
|
x := newCoords.X - vp.Rect.W/2
|
||||||
|
y := newCoords.Y - vp.Rect.H/2
|
||||||
x := c.X - vp.Rect.W/2
|
|
||||||
y := c.Y - vp.Rect.H/2
|
|
||||||
|
|
||||||
if x < 0 {
|
if x < 0 {
|
||||||
x = 0
|
x = 0
|
||||||
@ -98,16 +94,22 @@ func (vp *ViewPort) Listen(state gamestate.GameState) {
|
|||||||
|
|
||||||
func (vp *ViewPort) Render(state *gamestate.GameState) {
|
func (vp *ViewPort) Render(state *gamestate.GameState) {
|
||||||
|
|
||||||
vp.Move(state)
|
playerCoords := state.Controller.GetComponent(state.Player, types.Coords{}.TypeOf()).(types.Coords)
|
||||||
|
|
||||||
|
vp.Move(state, playerCoords)
|
||||||
|
|
||||||
if fovRecompute {
|
if fovRecompute {
|
||||||
vp.layer.ClearRect(vp.Rect)
|
vp.layer.ClearRect(vp.Rect)
|
||||||
fovRecompute = true
|
fovRecompute = false
|
||||||
redraw = true
|
redraw = true
|
||||||
vp.Fov.ComputeFov(state.Level, state.Level.Player.Coords, vp.TorchRadius)
|
vp.Fov.ComputeFov(state.Level, playerCoords, vp.TorchRadius)
|
||||||
}
|
}
|
||||||
|
|
||||||
//if redraw {
|
vp.layer.ClearArea(0, 7, 40, 1)
|
||||||
|
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 < vp.H; y++ {
|
||||||
for x := 0; x < vp.W; x++ {
|
for x := 0; x < vp.W; x++ {
|
||||||
@ -122,7 +124,7 @@ func (vp *ViewPort) Render(state *gamestate.GameState) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//mobs
|
//mobs
|
||||||
pc, err := vp.ToVPCoords(state.Level.Player.Coords)
|
pc, err := vp.ToVPCoords(playerCoords)
|
||||||
_ = pc
|
_ = pc
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("error on getting player position")
|
fmt.Println("error on getting player position")
|
||||||
@ -133,8 +135,7 @@ func (vp *ViewPort) Render(state *gamestate.GameState) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//redraw = true
|
//redraw = true
|
||||||
//redraw = false
|
redraw = false
|
||||||
|
}
|
||||||
//}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user