basic mapgen

This commit is contained in:
thefish 2019-10-27 01:08:06 +03:00
parent ec9d3d9a73
commit b8c8a65fa7
6 changed files with 154 additions and 36 deletions

View File

@ -2,59 +2,51 @@ package gamemap
import (
"lab.zaar.be/thefish/alchemyst-go/engine/ecs"
"lab.zaar.be/thefish/alchemyst-go/engine/types"
"lab.zaar.be/thefish/alchemyst-go/util"
)
var maxrooms = 100
//fixme move to config
var mapWidth = 150
var mapHeight = 100
type Level struct {
*types.Rect
ctx util.ClientCtx
Name string
Branch string
Depth int
MaxRooms int
Width int
Height int
Objects []ecs.Entity
Tiles [][]*Tile
}
func (l *Level) Put (x, y int, tileFunc interface{}) {
tf := tileFunc.(func() *Tile)()
if tf == nil {
l.ctx.Logger().Fatal().Msgf("Got non-tile type to put into level: %v", tf)
}
l.Tiles[x][y] = tf
}
func NewLevel(ctx util.ClientCtx, branch string, depth int) *Level {
l := &Level{
Name: branch + string(depth),
Depth: depth,
MaxRooms: maxrooms,
Width: mapWidth,
Height: mapHeight,
Rect: types.NewRect(0,0, mapWidth, mapHeight),
}
l.Tiles = make([][]*Tile, l.Width)
l.Tiles = make([][]*Tile, l.W)
for i := range l.Tiles {
l.Tiles[i] = make([]*Tile, l.Height)
}
return l
}
func Generate(l *Level) (l *Level) {
for i := 0; i < l.MaxRooms; i++ {
l.Tiles[i] = make([]*Tile, l.H)
}
return l
}
type Room struct {
x, y, w, h int
}
func (self *Room) intersects(other *Room) bool {
if self.x <= (other.x+other.w) &&
(self.x+self.w) >= other.x &&
self.y <= (other.y+other.h) &&
(self.y+self.h) >= other.y {
}
}
*types.Rect
Center *types.Coords
}

View File

@ -0,0 +1,108 @@
package mapgens
import (
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
"lab.zaar.be/thefish/alchemyst-go/engine/types"
"lab.zaar.be/thefish/alchemyst-go/util"
)
//fixme move to config
var maxrooms = 100
var minRoomSize = 3
var maxRoomSize = 11
func DefaultGen(l *gamemap.Level) *gamemap.Level {
rng := util.NewRNG()
//fill with walls
for i := 0; i < l.W; i ++ {
for j := 0; j < l.H; j++ {
l.Tiles[i][j] = gamemap.NewWall()
}
}
rooms := make([]*gamemap.Room, maxrooms)
for i := 0; i < l.MaxRooms; i++ {
newRoom := &gamemap.Room{
Rect: types.NewRect(
rng.Range(l.X, l.W),
rng.Range(l.Y, l.H),
rng.Range(minRoomSize, maxRoomSize),
rng.Range(minRoomSize, maxRoomSize),
)}
newRoom.Center.X = newRoom.X + newRoom.W / 2
newRoom.Center.Y = newRoom.Y + newRoom.H / 2
failed := false
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()},
}
for idx, room := range rooms {
room.Blit(fillage, l)
if idx > 0 {
connectRooms(l, room, rooms[idx-1], fillage, rng.Range(0,1))
}
}
return l
}
func connectRooms (l *gamemap.Level, room, otherRoom *gamemap.Room, fillage types.RectFill, toss int) {
if toss == 0 {
digHTunnel(l, room.Center.X,otherRoom.Center.X,room.Center.Y, fillage)
digVTunnel(l, room.Center.Y,otherRoom.Center.Y,otherRoom.Center.X, fillage)
} else {
digVTunnel(l, room.Center.Y, otherRoom.Center.Y, room.Center.Y, fillage)
digHTunnel(l, room.Center.X, otherRoom.Center.X, otherRoom.Center.Y, fillage)
}
}
func digHTunnel(l *gamemap.Level, x1,x2,y int, fillage types.RectFill) {
var start, finish int
if x1 > x2 {
start = x1
finish = x2
} else {
start = x2
finish = x1
}
for i := start; i <= finish; i++ {
l.Tiles[i][y] = fillage.Body.(func() *gamemap.Tile)()
}
}
func digVTunnel(l *gamemap.Level, y1,y2,x int, fillage types.RectFill) {
var start, finish int
if y1 > y2 {
start = y1
finish = y2
} else {
start = y2
finish = y1
}
for i := start; i <= finish; i++ {
l.Tiles[x][i] = fillage.Body.(func() *gamemap.Tile)()
}
}

View File

@ -1,5 +0,0 @@
package gamemap
type Coords struct {
x, y int
}

9
engine/types/coords.go Normal file
View File

@ -0,0 +1,9 @@
package types
type Coords struct {
X, Y int
}
func (c *Coords) Get() (int,int) {
return c.X,c.Y
}

View File

@ -12,7 +12,7 @@ func NewRect(x, y, w, h int) *Rect {
return &Rect{x, y, w, h}
}
func (r *Rect) RenderToLayer(fillage RectFill, layer Putable) {
func (r *Rect) Blit(fillage RectFill, layer Putable) {
if fillage.Body != "" {
for i := r.X + 1; i < r.X+r.W; i++ {
@ -45,3 +45,17 @@ func (r *Rect) RenderToLayer(fillage RectFill, layer Putable) {
//lii.Put(X+W, Y-1, "L");
layer.Put(r.X+r.W, r.Y+r.H, fillage.BottomRight)
}
func (self *Rect) Intersects(other *Rect) bool {
if self.X <= (other.X+other.W) &&
(self.X+self.W) >= other.X &&
self.Y <= (other.Y+other.Y) &&
(self.Y+self.H) >= other.Y {
return true
}
return false
}
func (r *Rect) InBounds (x,y int) bool {
return x >= r.X && x <= (r.X + r.W) && y >= r.Y && y <= (r.Y + r.H)
}

View File

@ -51,15 +51,15 @@ func (layer *Layer) NewWindow(x, y, w, h int) *UiWindow {
}
func (uiw *UiWindow) NoBorder() {
uiw.RenderToLayer(noborder, uiw.layer)
uiw.Blit(noborder, uiw.layer)
}
func (uiw *UiWindow) Splash() {
uiw.RenderToLayer(splash, uiw.layer)
uiw.Blit(splash, uiw.layer)
}
func (uiw *UiWindow) DoubleBordered(title string) {
uiw.RenderToLayer(doubleBorder, uiw.layer)
uiw.Blit(doubleBorder, uiw.layer)
if len(title) > (uiw.W - 2) {
title = title[:(uiw.W - 2)]
}