colordance

This commit is contained in:
2019-10-31 00:55:51 +03:00
parent ffe658e90e
commit 8dd242b242
9 changed files with 185 additions and 86 deletions

View File

@ -1,10 +1,13 @@
package basic
import (
"github.com/jcerise/gogue/gamemap"
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
"lab.zaar.be/thefish/alchemyst-go/engine/types"
"math"
)
//fixme store separate FovMap, add method IsInMap to it
type FieldOfVision struct {
cosTable map[int]float64
sinTable map[int]float64
@ -31,15 +34,15 @@ func (f *FieldOfVision) SetTorchRadius(radius int) {
}
}
func (f *FieldOfVision) SetAllInvisible(gameMap *gamemap.Map) {
for x := 0; x < gameMap.Width; x++ {
for y := 0; y < gameMap.Height; y++ {
gameMap.Tiles[x][y].Visible = false
func (f *FieldOfVision) SetAllInvisible(level *gamemap.Level) {
for x := 0; x < level.W; x++ {
for y := 0; y < level.H; y++ {
level.Tiles[x][y].Visible = false
}
}
}
func (f *FieldOfVision) RayCast(playerX, playerY int, gameMap *gamemap.Map) {
func (f *FieldOfVision) RayCast(playerCoords types.Coords, level *gamemap.Level) {
// Cast out rays each degree in a 360 circle from the player. If a ray passes over a floor (does not block sight)
// tile, keep going, up to the maximum torch radius (view radius) of the player. If the ray intersects a wall
// (blocks sight), stop, as the player will not be able to see past that. Every visible tile will get the Visible
@ -50,11 +53,11 @@ func (f *FieldOfVision) RayCast(playerX, playerY int, gameMap *gamemap.Map) {
ax := f.sinTable[i]
ay := f.cosTable[i]
x := float64(playerX)
y := float64(playerY)
x := float64(playerCoords.X)
y := float64(playerCoords.Y)
// Mark the players current position as explored
tile := gameMap.Tiles[playerX][playerY]
tile := level.Tiles[playerCoords.X][playerCoords.Y]
tile.Explored = true
tile.Visible = true
@ -65,17 +68,17 @@ func (f *FieldOfVision) RayCast(playerX, playerY int, gameMap *gamemap.Map) {
roundedX := int(Round(x))
roundedY := int(Round(y))
if x < 0 || x > float64(gameMap.Width-1) || y < 0 || y > float64(gameMap.Height-1) {
if x < 0 || x > float64(level.W -1) || y < 0 || y > float64(level.H -1) {
// If the ray is cast outside of the gamemap, stop
break
}
tile := gameMap.Tiles[roundedX][roundedY]
tile := level.Tiles[roundedX][roundedY]
tile.Explored = true
tile.Visible = true
if gameMap.Tiles[roundedX][roundedY].BlocksSight == true {
if level.Tiles[roundedX][roundedY].BlocksSight == true {
// The ray hit a wall, go no further
break
}
@ -85,4 +88,4 @@ func (f *FieldOfVision) RayCast(playerX, playerY int, gameMap *gamemap.Map) {
func Round(f float64) float64 {
return math.Floor(f + .5)
}
}

View File

@ -37,7 +37,7 @@ CurrentShade variable with the contents of the NextShade variable.
If the tested cell is opaque for each angle in the range occludedAngles by the cell, place a 1 at the position
determined by angle%360 in the NextShade string.
For each angle in the range occludedAngles by the cell, add 1 to the shade value for that cell for each 0 encountered
For each angle in the range occludedAngles by the cell, add 1 to the lit value for that cell for each 0 encountered
at the position determined by angle%360 in the CurrentShade string.
Notes
@ -75,7 +75,8 @@ type Cell struct {
types.Coords
distance float64
occludedAngles []int //indexes of cells in CellList
shade int //shade value
lit int //lit value
wasOccluded bool
}
type CellList []*Cell
@ -116,7 +117,7 @@ func (ps *precomputedShade) IsInFov(coords types.Coords) bool {
if err != nil {
return false
}
return cell.shade > 0
return cell.lit > 0
}
func (ps *precomputedShade) SetLightWalls(value bool) {
@ -141,7 +142,7 @@ func (ps *precomputedShade) PrecomputeFovMap() {
iterCoords := types.Coords{x, y}
distance := zeroCoords.DistanceTo(iterCoords)
if distance <= float64(max) {
ps.CellList = append(ps.CellList, &Cell{iterCoords, distance, nil, 0})
ps.CellList = append(ps.CellList, &Cell{iterCoords, distance, nil, 0, false})
}
}
}
@ -223,19 +224,22 @@ func (ps *precomputedShade) recalc(level *gamemap.Level, initCoords types.Coords
}
//fmt.Printf("\n level coords: %v", lc)
if level.Tiles[lc.X][lc.Y].BlocksSight {
level.Tiles[lc.X][lc.Y].Visible = true
for _, angle := range cell.occludedAngles {
for _, angle := range cell.occludedAngles {
if level.Tiles[lc.X][lc.Y].BlocksSight {
nextShade[angle] = 1
}
}
for _, angle := range cell.occludedAngles {
if currentShade[angle] == 0 {
cell.shade = cell.shade + 1
cell.lit = cell.lit + 1
}
}
if level.Tiles[lc.X][lc.Y].BlocksSight {
level.Tiles[lc.X][lc.Y].Visible = true
}
}
}
@ -244,8 +248,8 @@ func (ps *precomputedShade) ComputeFov(level *gamemap.Level, initCoords types.Co
ps.recalc(level, initCoords, radius)
for _, cell := range ps.CellList {
//fmt.Printf("\n coords: %v, distance: %f, shade: %d", cell.Coords, cell.distance, cell.shade)
if cell.shade > 0 {
//fmt.Printf("\n coords: %v, distance: %f, lit: %d", cell.Coords, cell.distance, cell.lit)
if cell.lit > 0 {
cs, err := ps.toLevelCoords(level, initCoords, cell.Coords)
if err != nil {
continue

View File

@ -59,7 +59,7 @@ func TestPrecompShade(t *testing.T) {
level.Tiles[10][11] = gamemap.NewWall()
level.Tiles[11][10] = gamemap.NewWall()
ppFov.ComputeFov(level, playerCoords, 15)
ppFov.ComputeFov(level, playerCoords, 12)
fmt.Printf("\n\n")

View File

@ -7,8 +7,8 @@ import (
)
//fixme move to config
var minRoomSize = 3
var maxRoomSize = 11
var maxrooms = 100
var maxRoomSize = 22
var maxrooms = 30
//fixme make closure to stack them
func DefaultGen(l *gamemap.Level) *gamemap.Level {
@ -35,27 +35,51 @@ func DefaultGen(l *gamemap.Level) *gamemap.Level {
newRoom.Center = types.Coords{newRoom.X + newRoom.W / 2, newRoom.Y + newRoom.H / 2}
failed := false
for _, otherRoom := range rooms {
if otherRoom.Intersects(newRoom.Rect) {
failed = true
break
if !l.InBounds(types.Coords{newRoom.X, newRoom.Y}) {
failed = true
}
if !failed && !l.InBounds(types.Coords{newRoom.X + newRoom.W, newRoom.Y + newRoom.H}) {
failed = true
}
if !failed {
for _, otherRoom := range rooms {
if otherRoom.Intersects(newRoom.Rect) {
failed = true
break
}
}
}
if !failed {
rooms = append(rooms, newRoom)
}
}
//fillage := types.RectFill{
// Top: func() *gamemap.Tile {return gamemap.NewWall()},
// Bottom: func() *gamemap.Tile {return gamemap.NewWall()},
// Left: func() *gamemap.Tile {return gamemap.NewWall()},
// Right: func() *gamemap.Tile {return gamemap.NewWall()},
// BottomLeft: func() *gamemap.Tile {return gamemap.NewWall()},
// BottomRight: func() *gamemap.Tile {return gamemap.NewWall()},
// TopLeft: func() *gamemap.Tile {return gamemap.NewWall()},
// TopRight: func() *gamemap.Tile {return gamemap.NewWall()},
// Body: func() *gamemap.Tile {return gamemap.NewFloor()},
//}
fillage := types.RectFill{
Top: func() *gamemap.Tile {return gamemap.NewWall()},
Bottom: func() *gamemap.Tile {return gamemap.NewWall()},
Left: func() *gamemap.Tile {return gamemap.NewWall()},
Right: func() *gamemap.Tile {return gamemap.NewWall()},
BottomLeft: func() *gamemap.Tile {return gamemap.NewWall()},
BottomRight: func() *gamemap.Tile {return gamemap.NewWall()},
TopLeft: func() *gamemap.Tile {return gamemap.NewWall()},
TopRight: func() *gamemap.Tile {return gamemap.NewWall()},
Body: func() *gamemap.Tile {return gamemap.NewFloor()},
Top: func() *gamemap.Tile {return gamemap.NewWaterTile()},
Bottom: func() *gamemap.Tile {return gamemap.NewWaterTile()},
Left: func() *gamemap.Tile {return gamemap.NewWaterTile()},
Right: func() *gamemap.Tile {return gamemap.NewWaterTile()},
BottomLeft: func() *gamemap.Tile {return gamemap.NewWaterTile()},
BottomRight: func() *gamemap.Tile {return gamemap.NewWaterTile()},
TopLeft: func() *gamemap.Tile {return gamemap.NewWaterTile()},
TopRight: func() *gamemap.Tile {return gamemap.NewWaterTile()},
Body: func() *gamemap.Tile {return gamemap.NewDeepWaterTile()},
}
for idx, room := range rooms {
@ -80,28 +104,33 @@ func connectRooms (l *gamemap.Level, room, otherRoom *gamemap.Room, fillage type
func digHTunnel(l *gamemap.Level, x1,x2,y int, fillage types.RectFill) {
var start, finish int
if x1 > x2 {
if x1 < x2 {
start = x1
finish = x2
} else {
start = x2
finish = x1
}
for i := start; i <= finish - 1; i++ {
l.Tiles[i][y] = fillage.Body.(func() *gamemap.Tile)()
for i := start; i <= finish; i++ {
if l.InBounds(types.Coords{i, y}) {
l.Tiles[i][y] = fillage.Body.(func() *gamemap.Tile)()
//l.Tiles[i][y] = gamemap.NewFloor()
}
}
}
func digVTunnel(l *gamemap.Level, y1,y2,x int, fillage types.RectFill) {
var start, finish int
if y1 > y2 {
if y1 < y2 {
start = y1
finish = y2
} else {
start = y2
finish = y1
}
for i := start; i <= finish - 1; i++ {
l.Tiles[x][i] = fillage.Body.(func() *gamemap.Tile)()
for i := start; i <= finish; i++ {
if l.InBounds(types.Coords{x, i}) {
l.Tiles[x][i] = fillage.Body.(func() *gamemap.Tile)()
}
}
}

View File

@ -39,8 +39,8 @@ type Tile struct {
BlocksPass bool
BlocksSight bool
Explored bool
Visible bool
MustDraw bool
Visible bool
Colordance bool
}
@ -94,8 +94,9 @@ func NewWaterTile() *Tile {
Explored: false,
MustDraw: true, //fixme debug
Colordance: true,
Appearance: &Appearance{
Char: ".",
Char: " ",
ColorSet: &TileColorSet{
current: ch,
Fg: func() uint32 { return blt.ColorFromARGB(255, 220, 220, 250) },
@ -103,19 +104,20 @@ func NewWaterTile() *Tile {
return blt.ColorFromARGB(
255,
ch.R,
colordance(ch.G, 2, 42, 4),
colordance(ch.B, 180, 229, 12),
colordance(ch.G, 0, 15, 2),
colordance(ch.B, 120, 220, 12),
)
},
DarkFg: func() uint32 { return blt.ColorFromARGB(255, 30, 20, 50) },
DarkBg: func() uint32 { return blt.ColorFromARGB(255, 7, 7, 30) },
},
},
}
}
func NewDeepWaterTile() *Tile {
ch := &ColorHolder{5, 2, 154}
ch := &ColorHolder{5, 2, 122}
return &Tile{
Name: "Deep Water",
Description: "Deep water",
@ -133,8 +135,8 @@ func NewDeepWaterTile() *Tile {
return blt.ColorFromARGB(
255,
ch.R,
colordance(ch.G, 0, 15, 2),
colordance(ch.B, 120, 180, 5),
colordance(ch.G, 2, 42, 4),
colordance(ch.B, 180, 229, 12),
)
},
DarkFg: func() uint32 { return blt.ColorFromARGB(255, 30, 20, 50) },

25
engine/mob/mob.go Normal file
View File

@ -0,0 +1,25 @@
package mob
import (
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
"lab.zaar.be/thefish/alchemyst-go/engine/types"
)
type Mob struct {
*gamemap.Appearance
*types.Coords
BlocksPass bool
}
func (m *Mob) Walk(dx, dy int) {
}
func (m *Mob) Render() {
}
func (m *Mob) MoveToCoords(c types.Coords) {
}

5
engine/mob/player.go Normal file
View File

@ -0,0 +1,5 @@
package mob
type Player struct {
*Mob
}