fixes to viewport, config tuning
This commit is contained in:
parent
a91351d3dc
commit
c6c6b6254d
@ -5,6 +5,7 @@ import (
|
|||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
|
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
|
||||||
"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/types"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/ui"
|
"lab.zaar.be/thefish/alchemyst-go/ui"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/ui/mainwindow"
|
"lab.zaar.be/thefish/alchemyst-go/ui/mainwindow"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/util"
|
"lab.zaar.be/thefish/alchemyst-go/util"
|
||||||
@ -22,23 +23,6 @@ func init() {
|
|||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
}
|
}
|
||||||
|
|
||||||
type GameState struct {
|
|
||||||
mainfunc chan func()
|
|
||||||
exit chan struct{}
|
|
||||||
input chan string
|
|
||||||
rawInput chan int
|
|
||||||
}
|
|
||||||
|
|
||||||
// do runs f on the main thread.
|
|
||||||
func (*GameState) Do(f func()) {
|
|
||||||
done := make(chan struct{}, 1)
|
|
||||||
State.mainfunc <- func() {
|
|
||||||
f()
|
|
||||||
done <- struct{}{}
|
|
||||||
}
|
|
||||||
<-done
|
|
||||||
}
|
|
||||||
|
|
||||||
//we can run logic in separate goroutines
|
//we can run logic in separate goroutines
|
||||||
//
|
//
|
||||||
// go doSometing(State,...)
|
// go doSometing(State,...)
|
||||||
@ -52,11 +36,13 @@ func (*GameState) Do(f func()) {
|
|||||||
// ...
|
// ...
|
||||||
// }
|
// }
|
||||||
|
|
||||||
var State = GameState{
|
var State = types.GameState{
|
||||||
mainfunc: make(chan func()),
|
Mainfunc: make(chan func()),
|
||||||
exit: make(chan struct{}, 1),
|
Exit: make(chan struct{}, 1),
|
||||||
input: make(chan string, 1),
|
Input: make(chan string, 1),
|
||||||
rawInput: make(chan int, 1),
|
RawInput: make(chan int, 1),
|
||||||
|
FovRecompute: make(chan struct{},1),
|
||||||
|
Redraw: make(chan struct{},1),
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -72,35 +58,37 @@ func main() {
|
|||||||
|
|
||||||
setupLayers(mw)
|
setupLayers(mw)
|
||||||
|
|
||||||
level := gamemap.NewLevel(mainCtx, "test", 1)
|
level, rooms := mapgens.DefaultGen(gamemap.NewLevel(mainCtx, "test", 1))
|
||||||
level = mapgens.DefaultGen(level)
|
|
||||||
vp := mainwindow.NewViewPort(40, 0, 60, 47, level, mw.GetLayer("base"))
|
vp := mainwindow.NewViewPort(40, 0, 60, 47, level, mw.GetLayer("base"))
|
||||||
vp.Render()
|
vp.PlayerCoords = rooms[0].Center
|
||||||
|
vp.Render(State)
|
||||||
|
|
||||||
go decodeInput(mainCtx, mw.GetLayer("base"))
|
go decodeInput(mainCtx, mw.GetLayer("base"))
|
||||||
|
go vp.Listen(State)
|
||||||
|
|
||||||
//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
|
||||||
for !exit {
|
for !exit {
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case State.rawInput <- ui.ReadKeyCode():
|
case State.RawInput <- ui.ReadKeyCode():
|
||||||
break
|
break
|
||||||
case pressed := <-State.input:
|
case pressed := <-State.Input:
|
||||||
mw.GetLayer("base").ClearArea(0, 3, 40, 1)
|
mw.GetLayer("base").ClearArea(0, 3, 40, 1)
|
||||||
mw.GetLayer("base").Print(1, 3, "Key: "+pressed)
|
mw.GetLayer("base").Print(1, 3, "Key: "+pressed)
|
||||||
mw.GetLayer("base").Print(1, 6, "█")
|
mw.GetLayer("base").Print(1, 6, "█")
|
||||||
break
|
break
|
||||||
//case f := <-State.mainfunc:
|
//case f := <-State.mainfunc:
|
||||||
// f()
|
// f()
|
||||||
// break
|
// break
|
||||||
case <-State.exit:
|
case <-State.Exit:
|
||||||
mainCtx.Logger().Warn().Msg("quitting NOW")
|
mainCtx.Logger().Warn().Msg("quitting NOW")
|
||||||
exit = true
|
exit = true
|
||||||
break
|
break
|
||||||
// не оставляйте default в бесконесчном select {} - сожрет всё CPU
|
// не оставляйте default в бесконесчном select {} - сожрет всё CPU
|
||||||
default:
|
default:
|
||||||
vp.Render()
|
vp.Render(State)
|
||||||
blt.Refresh()
|
blt.Refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,20 +105,20 @@ func setupLayers(mainwindow *mainwindow.MainWindow) {
|
|||||||
func decodeInput(ctx util.ClientCtx, baseLayer *mainwindow.Layer) {
|
func decodeInput(ctx util.ClientCtx, baseLayer *mainwindow.Layer) {
|
||||||
var exit = false
|
var exit = false
|
||||||
var waitForWCspam = true
|
var waitForWCspam = true
|
||||||
for !exit{
|
for !exit {
|
||||||
select {
|
select {
|
||||||
case keycode := <-State.rawInput:
|
case keycode := <-State.RawInput:
|
||||||
if keycode == blt.TK_NONE {
|
if keycode == blt.TK_NONE {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if keycode == blt.TK_CLOSE && !waitForWCspam {
|
if keycode == blt.TK_CLOSE && !waitForWCspam {
|
||||||
ctx.Logger().Warn().Msg("exiting on window close...")
|
ctx.Logger().Warn().Msg("exiting on window close...")
|
||||||
State.exit <- struct{}{}
|
State.Exit <- struct{}{}
|
||||||
ctx.Logger().Warn().Msg("...done")
|
ctx.Logger().Warn().Msg("...done")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var pressed= ""
|
var pressed = ""
|
||||||
var isModifier, _= util.InArray(keycode, modifiers)
|
var isModifier, _ = util.InArray(keycode, modifiers)
|
||||||
if !isModifier {
|
if !isModifier {
|
||||||
|
|
||||||
pressed = ui.Scancodemap[keycode]
|
pressed = ui.Scancodemap[keycode]
|
||||||
@ -147,6 +135,7 @@ func decodeInput(ctx util.ClientCtx, baseLayer *mainwindow.Layer) {
|
|||||||
|
|
||||||
//global hotkeys
|
//global hotkeys
|
||||||
switch pressed {
|
switch pressed {
|
||||||
|
//fixme testing only
|
||||||
case "F10":
|
case "F10":
|
||||||
State.Do(func() {
|
State.Do(func() {
|
||||||
blt.Set("window: size=100x47; font: ./resources/fonts-ttf/UbuntuMono-R.ttf, size=11;")
|
blt.Set("window: size=100x47; font: ./resources/fonts-ttf/UbuntuMono-R.ttf, size=11;")
|
||||||
@ -155,13 +144,15 @@ func decodeInput(ctx util.ClientCtx, baseLayer *mainwindow.Layer) {
|
|||||||
fallthrough
|
fallthrough
|
||||||
case "Escape":
|
case "Escape":
|
||||||
ctx.Logger().Info().Msg("exiting on quit command...")
|
ctx.Logger().Info().Msg("exiting on quit command...")
|
||||||
State.exit <- struct{}{}
|
State.Exit <- struct{}{}
|
||||||
ctx.Logger().Info().Msg("...done")
|
ctx.Logger().Info().Msg("...done")
|
||||||
exit = true
|
exit = true
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
waitForWCspam = false;
|
if pressed != "" {
|
||||||
State.input <- pressed
|
waitForWCspam = false;
|
||||||
|
State.Input <- pressed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
"sizeX": 100,
|
"sizeX": 100,
|
||||||
"sizeY": 47,
|
"sizeY": 47,
|
||||||
"fpsLimit" : 60,
|
"fpsLimit" : 60,
|
||||||
"font": "./resources/fonts-ttf/LiberationMono-Bold.ttf",
|
"font": "./resources/fonts-ttf/UbuntuMono-R.ttf",
|
||||||
|
"fontSize": "12x16",
|
||||||
"verbosity": "debug"
|
"verbosity": "debug"
|
||||||
}
|
}
|
@ -7,8 +7,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
//fixme move to config
|
//fixme move to config
|
||||||
var mapWidth = 150
|
var mapWidth = 70
|
||||||
var mapHeight = 100
|
var mapHeight = 50
|
||||||
|
|
||||||
|
|
||||||
type Level struct {
|
type Level struct {
|
||||||
|
@ -11,7 +11,7 @@ var maxRoomSize = 22
|
|||||||
var maxrooms = 30
|
var maxrooms = 30
|
||||||
|
|
||||||
//fixme make closure to stack them
|
//fixme make closure to stack them
|
||||||
func DefaultGen(l *gamemap.Level) *gamemap.Level {
|
func DefaultGen(l *gamemap.Level) (*gamemap.Level, []*gamemap.Room) {
|
||||||
|
|
||||||
rng := util.NewRNG()
|
rng := util.NewRNG()
|
||||||
|
|
||||||
@ -56,6 +56,9 @@ func DefaultGen(l *gamemap.Level) *gamemap.Level {
|
|||||||
if !failed {
|
if !failed {
|
||||||
rooms = append(rooms, newRoom)
|
rooms = append(rooms, newRoom)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//addStairs(rooms)
|
||||||
|
//itemize(rooms)
|
||||||
}
|
}
|
||||||
|
|
||||||
//fillage := types.RectFill{
|
//fillage := types.RectFill{
|
||||||
@ -89,7 +92,7 @@ func DefaultGen(l *gamemap.Level) *gamemap.Level {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return l
|
return l, rooms
|
||||||
}
|
}
|
||||||
|
|
||||||
func connectRooms (l *gamemap.Level, room, otherRoom *gamemap.Room, fillage types.RectFill, toss int) {
|
func connectRooms (l *gamemap.Level, room, otherRoom *gamemap.Room, fillage types.RectFill, toss int) {
|
||||||
|
@ -1,69 +1,8 @@
|
|||||||
package gamemap
|
package gamemap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gammazero/deque"
|
. "lab.zaar.be/thefish/alchemyst-go/engine/types"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/util"
|
|
||||||
)
|
)
|
||||||
import blt "lab.zaar.be/thefish/bearlibterminal"
|
|
||||||
|
|
||||||
type ColorHolder interface {
|
|
||||||
GetColor() uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type cdeque struct {
|
|
||||||
deque.Deque
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *cdeque) Next() uint8 {
|
|
||||||
c.Rotate(1)
|
|
||||||
return c.Front().(uint8)
|
|
||||||
}
|
|
||||||
|
|
||||||
type DanceColorHolder struct {
|
|
||||||
A uint8
|
|
||||||
R *cdeque
|
|
||||||
G *cdeque
|
|
||||||
B *cdeque
|
|
||||||
}
|
|
||||||
|
|
||||||
func (chd *DanceColorHolder) GetColor() uint32 {
|
|
||||||
return blt.ColorFromARGB(
|
|
||||||
chd.A,
|
|
||||||
chd.R.Next(),
|
|
||||||
chd.G.Next(),
|
|
||||||
chd.B.Next(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
type PlainColorHolder struct {
|
|
||||||
A uint8
|
|
||||||
R uint8
|
|
||||||
G uint8
|
|
||||||
B uint8
|
|
||||||
}
|
|
||||||
|
|
||||||
func (chb *PlainColorHolder) GetColor() uint32 {
|
|
||||||
return blt.ColorFromARGB(
|
|
||||||
chb.A,
|
|
||||||
chb.R,
|
|
||||||
chb.G,
|
|
||||||
chb.B,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
type TileColorSet struct {
|
|
||||||
Fg ColorHolder
|
|
||||||
Bg ColorHolder
|
|
||||||
DarkFg ColorHolder
|
|
||||||
DarkBg ColorHolder
|
|
||||||
}
|
|
||||||
|
|
||||||
type Appearance struct {
|
|
||||||
Char string `json:"char"`
|
|
||||||
ColorSet *TileColorSet `json:"colorSet"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var crng = util.NewRNG()
|
|
||||||
|
|
||||||
type Tile struct {
|
type Tile struct {
|
||||||
*Appearance `json:"app"`
|
*Appearance `json:"app"`
|
||||||
@ -97,33 +36,6 @@ func (t *Tile) GetRawBgColor() uint32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func singleColorRing(colorValue uint8) *cdeque {
|
|
||||||
c := &cdeque{}
|
|
||||||
c.PushBack(colorValue)
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
func fillColorRing(colorValue uint8, minGlow, maxGlow, step int) *cdeque {
|
|
||||||
q := make([]uint8, 0)
|
|
||||||
color := int(colorValue)
|
|
||||||
for color < maxGlow {
|
|
||||||
q = append(q, uint8(color))
|
|
||||||
color = crng.Range(1, step) + color
|
|
||||||
}
|
|
||||||
color = crng.Range(0, step+minGlow)
|
|
||||||
q = append(q, uint8(color))
|
|
||||||
//for uint8(color) < uint8(colorValue) {
|
|
||||||
// q = append(q, uint8(color))
|
|
||||||
// color = crng.Range(1, step+minGlow)
|
|
||||||
//}
|
|
||||||
|
|
||||||
c := &cdeque{}
|
|
||||||
for _, v := range q {
|
|
||||||
c.PushBack(uint8(v))
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewWall() *Tile {
|
func NewWall() *Tile {
|
||||||
return &Tile{
|
return &Tile{
|
||||||
Name: "Wall",
|
Name: "Wall",
|
||||||
@ -178,14 +90,14 @@ func NewWaterTile() *Tile {
|
|||||||
Appearance: &Appearance{
|
Appearance: &Appearance{
|
||||||
Char: " ",
|
Char: " ",
|
||||||
ColorSet: &TileColorSet{
|
ColorSet: &TileColorSet{
|
||||||
Fg: &PlainColorHolder{255, 220, 220, 250},
|
Fg: &PlainColorHolder{255, 220, 220, 250},
|
||||||
Bg: &DanceColorHolder{
|
Bg: &DanceColorHolder{
|
||||||
255,
|
255,
|
||||||
singleColorRing(19),
|
SingleColorRing(19),
|
||||||
fillColorRing(19, 0, 15, 2),
|
FillColorRing(19, 0, 15, 2),
|
||||||
fillColorRing(70, 120, 220, 12),
|
FillColorRing(70, 120, 220, 12),
|
||||||
},
|
},
|
||||||
DarkFg: &PlainColorHolder{255, 30, 20, 50 },
|
DarkFg: &PlainColorHolder{255, 30, 20, 50},
|
||||||
DarkBg: &PlainColorHolder{255, 7, 7, 30},
|
DarkBg: &PlainColorHolder{255, 7, 7, 30},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -205,16 +117,16 @@ func NewDeepWaterTile() *Tile {
|
|||||||
Appearance: &Appearance{
|
Appearance: &Appearance{
|
||||||
Char: " ",
|
Char: " ",
|
||||||
ColorSet: &TileColorSet{
|
ColorSet: &TileColorSet{
|
||||||
Fg: &PlainColorHolder{255, 220, 220, 250},
|
Fg: &PlainColorHolder{255, 220, 220, 250},
|
||||||
Bg: &DanceColorHolder{
|
Bg: &DanceColorHolder{
|
||||||
255,
|
255,
|
||||||
singleColorRing(5),
|
SingleColorRing(5),
|
||||||
fillColorRing(2,2,42,4),
|
FillColorRing(2, 2, 42, 4),
|
||||||
fillColorRing(154, 150, 229, 12),
|
FillColorRing(154, 150, 229, 12),
|
||||||
},
|
},
|
||||||
DarkFg: &PlainColorHolder{255, 30, 20, 50},
|
DarkFg: &PlainColorHolder{255, 30, 20, 50},
|
||||||
DarkBg: &PlainColorHolder{255, 7, 7, 30},
|
DarkBg: &PlainColorHolder{255, 7, 7, 30},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
94
engine/types/appearance.go
Normal file
94
engine/types/appearance.go
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gammazero/deque"
|
||||||
|
"lab.zaar.be/thefish/alchemyst-go/util"
|
||||||
|
)
|
||||||
|
import blt "lab.zaar.be/thefish/bearlibterminal"
|
||||||
|
|
||||||
|
var crng = util.NewRNG()
|
||||||
|
|
||||||
|
type ColorHolder interface {
|
||||||
|
GetColor() uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type cdeque struct {
|
||||||
|
deque.Deque
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cdeque) Next() uint8 {
|
||||||
|
c.Rotate(1)
|
||||||
|
return c.Front().(uint8)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DanceColorHolder struct {
|
||||||
|
A uint8
|
||||||
|
R *cdeque
|
||||||
|
G *cdeque
|
||||||
|
B *cdeque
|
||||||
|
}
|
||||||
|
|
||||||
|
func (chd *DanceColorHolder) GetColor() uint32 {
|
||||||
|
return blt.ColorFromARGB(
|
||||||
|
chd.A,
|
||||||
|
chd.R.Next(),
|
||||||
|
chd.G.Next(),
|
||||||
|
chd.B.Next(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type PlainColorHolder struct {
|
||||||
|
A uint8
|
||||||
|
R uint8
|
||||||
|
G uint8
|
||||||
|
B uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
func (chb *PlainColorHolder) GetColor() uint32 {
|
||||||
|
return blt.ColorFromARGB(
|
||||||
|
chb.A,
|
||||||
|
chb.R,
|
||||||
|
chb.G,
|
||||||
|
chb.B,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type TileColorSet struct {
|
||||||
|
Fg ColorHolder
|
||||||
|
Bg ColorHolder
|
||||||
|
DarkFg ColorHolder
|
||||||
|
DarkBg ColorHolder
|
||||||
|
}
|
||||||
|
|
||||||
|
type Appearance struct {
|
||||||
|
Char string `json:"char"`
|
||||||
|
ColorSet *TileColorSet `json:"colorSet"`
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func SingleColorRing(colorValue uint8) *cdeque {
|
||||||
|
c := &cdeque{}
|
||||||
|
c.PushBack(colorValue)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func FillColorRing(colorValue uint8, minGlow, maxGlow, step int) *cdeque {
|
||||||
|
q := make([]uint8, 0)
|
||||||
|
color := int(colorValue)
|
||||||
|
for color < maxGlow {
|
||||||
|
q = append(q, uint8(color))
|
||||||
|
color = crng.Range(1, step) + color
|
||||||
|
}
|
||||||
|
color = crng.Range(0, step+minGlow)
|
||||||
|
q = append(q, uint8(color))
|
||||||
|
//for uint8(color) < uint8(colorValue) {
|
||||||
|
// q = append(q, uint8(color))
|
||||||
|
// color = crng.Range(1, step+minGlow)
|
||||||
|
//}
|
||||||
|
|
||||||
|
c := &cdeque{}
|
||||||
|
for _, v := range q {
|
||||||
|
c.PushBack(uint8(v))
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
20
engine/types/gamestate.go
Normal file
20
engine/types/gamestate.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
type GameState struct {
|
||||||
|
Mainfunc chan func()
|
||||||
|
Exit chan struct{}
|
||||||
|
Input chan string
|
||||||
|
RawInput chan int
|
||||||
|
FovRecompute chan struct{}
|
||||||
|
Redraw chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// do runs f on the main thread.
|
||||||
|
func (g *GameState) Do(f func()) {
|
||||||
|
done := make(chan struct{}, 1)
|
||||||
|
g.Mainfunc <- func() {
|
||||||
|
f()
|
||||||
|
done <- struct{}{}
|
||||||
|
}
|
||||||
|
<-done
|
||||||
|
}
|
@ -98,7 +98,7 @@ func (layer *Layer) Decorate(f func(args ...interface{})) func(args ...interface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (layer *Layer) Clear(r *types.Rect) {
|
func (layer *Layer) ClearRect(r *types.Rect) {
|
||||||
blt.ClearArea(r.X, r.Y, r.W, r.H)
|
blt.ClearArea(r.X, r.Y, r.W, r.H)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,13 +42,14 @@ func (mw *MainWindow) Open() {
|
|||||||
blt.Set(
|
blt.Set(
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
//"window: size=%dx%d, title='%s v%s'; font: ./resources/fonts-bitmap/ibmnew8x12.png, size=8x12;",
|
//"window: size=%dx%d, title='%s v%s'; font: ./resources/fonts-bitmap/ibmnew8x12.png, size=8x12;",
|
||||||
"window: size=%dx%d, title='%s v%s'; font: %s, size=8x16;",
|
"window: size=%dx%d, title='%s v%s'; font: %s, size=%s;",
|
||||||
//"window: size=%dx%d, title='%s v%s'",
|
//"window: size=%dx%d, title='%s v%s'",
|
||||||
config.MainWindowSizeX,
|
config.MainWindowSizeX,
|
||||||
config.MainWindowSizeY,
|
config.MainWindowSizeY,
|
||||||
config.Title,
|
config.Title,
|
||||||
config.Version,
|
config.Version,
|
||||||
config.Font,
|
config.Font,
|
||||||
|
config.FontSize,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package mainwindow
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"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/gamemap"
|
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
|
||||||
@ -10,15 +11,14 @@ import (
|
|||||||
|
|
||||||
var NotInViewError = errors.New("not in ViewPort")
|
var NotInViewError = errors.New("not in ViewPort")
|
||||||
|
|
||||||
const FPS_LIMIT = 60
|
|
||||||
|
|
||||||
type ViewPort struct {
|
type ViewPort struct {
|
||||||
*types.Rect
|
*types.Rect
|
||||||
|
cameraCoords types.Coords
|
||||||
level *gamemap.Level
|
level *gamemap.Level
|
||||||
layer *Layer
|
layer *Layer
|
||||||
Fov fov.Fov
|
Fov fov.Fov
|
||||||
playerCoords types.Coords
|
PlayerCoords types.Coords
|
||||||
playerTorchRadius int
|
PlayerTorchRadius int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewViewPort(x, y, w, h int, level *gamemap.Level, layer *Layer) *ViewPort {
|
func NewViewPort(x, y, w, h int, level *gamemap.Level, layer *Layer) *ViewPort {
|
||||||
@ -32,13 +32,13 @@ func NewViewPort(x, y, w, h int, level *gamemap.Level, layer *Layer) *ViewPort {
|
|||||||
Fov: fov,
|
Fov: fov,
|
||||||
}
|
}
|
||||||
|
|
||||||
vp.playerCoords = types.Coords{10, 10}
|
vp.PlayerCoords = types.Coords{10, 10}
|
||||||
vp.playerTorchRadius = 10
|
vp.PlayerTorchRadius = 10
|
||||||
|
|
||||||
return &vp
|
return &vp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vp *ViewPort) Move(c *types.Coords) {
|
func (vp *ViewPort) Move(c *types.Coords, state types.GameState) {
|
||||||
x := c.X - vp.Rect.W/2
|
x := c.X - vp.Rect.W/2
|
||||||
y := c.Y - vp.Rect.H/2
|
y := c.Y - vp.Rect.H/2
|
||||||
|
|
||||||
@ -49,22 +49,26 @@ func (vp *ViewPort) Move(c *types.Coords) {
|
|||||||
y = 0
|
y = 0
|
||||||
}
|
}
|
||||||
if x > vp.level.W-vp.W {
|
if x > vp.level.W-vp.W {
|
||||||
x = vp.level.W - vp.W
|
x = vp.level.W - vp.W - 1
|
||||||
}
|
}
|
||||||
if y > vp.level.H-vp.H {
|
if y > vp.level.H-vp.H {
|
||||||
x = vp.level.H - vp.H
|
x = vp.level.H - vp.H - 1
|
||||||
}
|
}
|
||||||
//if x != vp.X || y != vp.Y { State.FovRecompute <- struct{}{}}
|
if x != vp.cameraCoords.X || y != vp.cameraCoords.Y {
|
||||||
vp.X, vp.Y = x, y
|
state.FovRecompute <- struct{}{}
|
||||||
|
}
|
||||||
|
vp.cameraCoords.X = x
|
||||||
|
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.X, c.Y-vp.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}, NotInViewError
|
||||||
}
|
}
|
||||||
return &types.Coords{x, y}, nil
|
return types.Coords{x, y}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
////call only from main thread
|
////call only from main thread
|
||||||
@ -75,15 +79,15 @@ func (vp *ViewPort) ToVPCoords(c *types.Coords) (newCoords *types.Coords, err er
|
|||||||
// redraw := false
|
// redraw := false
|
||||||
// //fixme get player instance
|
// //fixme get player instance
|
||||||
//
|
//
|
||||||
// vp.Move(&vp.playerCoords)
|
// vp.Move(&vp.PlayerCoords)
|
||||||
// //fixme detect fovRecompute
|
// //fixme detect fovRecompute
|
||||||
// if fovRecompute {
|
// if fovRecompute {
|
||||||
// vp.layer.Clear(vp.Rect)
|
// vp.layer.ClearRect(vp.Rect)
|
||||||
// fovRecompute = false
|
// fovRecompute = false
|
||||||
// redraw = true
|
// redraw = true
|
||||||
// //fixme
|
// //fixme
|
||||||
//
|
//
|
||||||
// vp.Fov.ComputeFov(vp.level, vp.playerCoords, vp.playerTorchRadius)
|
// vp.Fov.ComputeFov(vp.level, vp.PlayerCoords, vp.PlayerTorchRadius)
|
||||||
// }
|
// }
|
||||||
// //increase ticker
|
// //increase ticker
|
||||||
// fpsTicker++
|
// fpsTicker++
|
||||||
@ -119,26 +123,54 @@ func (vp *ViewPort) ToVPCoords(c *types.Coords) (newCoords *types.Coords, err er
|
|||||||
var redraw = true
|
var redraw = true
|
||||||
var fovRecompute = true
|
var fovRecompute = true
|
||||||
|
|
||||||
func (vp *ViewPort) Render() {
|
func (vp *ViewPort) Listen(state types.GameState) {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-state.FovRecompute:
|
||||||
|
fovRecompute = true
|
||||||
|
case <-state.Redraw:
|
||||||
|
redraw = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vp *ViewPort) Render(state types.GameState) {
|
||||||
|
|
||||||
|
vp.Move(&vp.PlayerCoords, state)
|
||||||
|
|
||||||
if fovRecompute {
|
if fovRecompute {
|
||||||
vp.layer.Clear(vp.Rect)
|
vp.layer.ClearRect(vp.Rect)
|
||||||
fovRecompute = false
|
fovRecompute = false
|
||||||
redraw = true
|
redraw = true
|
||||||
vp.Fov.ComputeFov(vp.level, vp.playerCoords, vp.playerTorchRadius)
|
vp.Fov.ComputeFov(vp.level, vp.PlayerCoords, vp.PlayerTorchRadius)
|
||||||
}
|
}
|
||||||
|
|
||||||
if redraw {
|
if redraw {
|
||||||
|
//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++ {
|
||||||
mapCoords := types.Coords{vp.X + x, vp.Y + y}
|
mapCoords := types.Coords{vp.cameraCoords.X + x, vp.cameraCoords.Y + y}
|
||||||
|
|
||||||
tile := vp.level.GetTile(mapCoords)
|
if vp.level.InBounds(mapCoords) {
|
||||||
if tile.Explored || tile.MustDraw || tile.Visible {
|
tile := vp.level.GetTile(mapCoords)
|
||||||
vp.layer.PutToBase(mapCoords.X, mapCoords.Y, tile.GetChar(), tile.GetRawColor(), tile.GetRawBgColor())
|
if tile.Explored || tile.MustDraw || tile.Visible {
|
||||||
|
vp.layer.PutToBase(x + vp.X, y + vp.Y, tile.GetChar(), tile.GetRawColor(), tile.GetRawBgColor())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//mobs
|
||||||
|
pc,err := vp.ToVPCoords(vp.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
|
//redraw = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ type Config struct {
|
|||||||
MainWindowSizeX int `json:"sizeX"`
|
MainWindowSizeX int `json:"sizeX"`
|
||||||
MainWindowSizeY int `json:"sizeY"`
|
MainWindowSizeY int `json:"sizeY"`
|
||||||
Font string `json:"font"`
|
Font string `json:"font"`
|
||||||
|
FontSize string `json:"fontSize"` //format is "8x12"
|
||||||
Verbosity string `json:"verbosity"`
|
Verbosity string `json:"verbosity"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user