clean up slightly

This commit is contained in:
thefish 2019-11-14 21:14:52 +03:00
parent 0f367eaf96
commit 3560be99a1
10 changed files with 299 additions and 412 deletions

22
TODO
View File

@ -1,5 +1,5 @@
Basics:
- Items:
Items:
- place
- pickup
- drop
@ -8,7 +8,13 @@ Basics:
- Character Screen
- Common letter/string selector for menus to separate struct/file (use it in inventory, title at least)
- Move scrollBar ro separate struct/file/function
Mobs:
basic:
- place mobs
- move mobs
advanced:
- ai
- dijkstra maps
Assets and i18n:
- move tile settings to json, generate from there (part of prefabs)
@ -16,7 +22,7 @@ Assets and i18n:
- all texts (terrain, mobs, quests) also in at least 2 languages
ECS & engine:
- implement time queue (how to deal with closures?) (?) github.com/thefish/sheduleq - get rid od time.Now inside
- implement time queue (how to deal with closures?) (?) github.com/thefish/scheduleq - get rid od time.Now inside
- move all rendering to systems
- try to move input handling to systems
@ -30,7 +36,7 @@ Dungeon and branches:
+ compose from gens and prefabs
- editor for prefabs
Mapgen:
- use delaunay -> minimum spanning tree for room connection (Краскал в gonum)
+ use delaunay -> minimum spanning tree for room connection (Краскал в gonum)
github.com/algds/kruskals - MST
github.com/esimov/triangle - delaunay
- или граф относительных окрестностей (?)
@ -43,13 +49,7 @@ Combat:
- damage from skill / mass / speed / material density
- no hitpoints! blood is the life source
Mobs:
basic:
- place mobs
- move mobs
advanced:
- ai
- dijkstra maps
Quest engine:
- look at parsers like URQL etc

View File

@ -5,7 +5,7 @@ import (
"github.com/rs/zerolog/log"
"lab.zaar.be/thefish/alchemyst-go/engine/ecs"
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap/mapgens/delaunaymst"
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap/mapgens"
"lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
"lab.zaar.be/thefish/alchemyst-go/engine/mob"
"lab.zaar.be/thefish/alchemyst-go/engine/mob/movement"
@ -71,7 +71,7 @@ func main() {
//fixme set up (load / generate) level - move to game / enter or title / exit
//level, rooms := _default.DefaultGen(mainCtx, gamemap.NewLevel(mainCtx, "test", 1))
level, rooms := delaunaymst.DelaunayMstGen(mainCtx, gamemap.NewLevel(mainCtx, "test", 1))
level, rooms := mapgens.DelaunayMstGen(mainCtx, gamemap.NewLevel(mainCtx, "test", 1))
State.Level = level
sidebarWidth := 0

View File

@ -0,0 +1,176 @@
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"
"lab.zaar.be/thefish/alchemyst-go/util/appctx"
)
//fixme move to config
var minRoomSize = 5
var maxRoomSize = 25
var maxrooms = 200
var fges = map[int]types.RectFill{
1: types.RectFill{
Top: gamemap.NewWall,
Bottom: gamemap.NewWall,
Left: gamemap.NewWall,
Right: gamemap.NewWall,
BottomLeft: gamemap.NewWall,
BottomRight: gamemap.NewWall,
TopLeft: gamemap.NewWall,
TopRight: gamemap.NewWall,
Body: gamemap.NewFloor,
},
2: types.RectFill{
Top: gamemap.NewWaterTile,
Bottom: gamemap.NewWaterTile,
Left: gamemap.NewWaterTile,
Right: gamemap.NewWaterTile,
BottomLeft: gamemap.NewWaterTile,
BottomRight: gamemap.NewWaterTile,
TopLeft: gamemap.NewWaterTile,
TopRight: gamemap.NewWaterTile,
Body: gamemap.NewDeepWaterTile,
},
}
func GetRandomRoomList(ctx appctx.ClientCtx, rng *util.RNG, l *gamemap.Level, maxRooms, minRoomSize, maxRoomSize int, ) []gamemap.Room{
rooms := make([]gamemap.Room, 0)
pfLoader := gamemap.NewPrefabLoader(ctx)
pfRooms := pfLoader.PrefabRoomsList()
var fillage types.RectFill
prefabUsed := false
for i := 0; i < maxRooms; i++ {
failed := false
fillage = fges[rng.GetWeightedEntity(map[int]int{1: 10, 2: 1})]
var newRoom = gamemap.Room{}
if !prefabUsed || rng.Range(0, 5) > 3 {
//if prefabUsed {
//prefab
prefabUsed = true
r := pfRooms[rng.Range(0, len(pfRooms))] //copy to local scope
newRoom = gamemap.Room{
Rect: r.Rect,
Center: r.Center,
Geometry: r.Geometry,
Items: r.Items,
Mobs: r.Mobs,
Connectors: make([]types.Coords,0),
}
for _, coord := range r.Connectors {
newRoom.Connectors = append(newRoom.Connectors, coord)
}
} else {
newRoom = gamemap.NewRandomRectRoom(
rng,
rng.Range(minRoomSize, maxRoomSize),
rng.Range(minRoomSize, maxRoomSize),
fillage,
)
}
where := types.Coords{
rng.Range(1, l.W-2-newRoom.W),
rng.Range(1, l.H-2-newRoom.H),
}
newRoom.MoveToCoords(where)
for _, otherRoom := range rooms {
if otherRoom.Intersects(newRoom.Rect) {
failed = true
break
}
}
if failed {
continue
}
if len(newRoom.Connectors) > 0 {
rooms = append(rooms, newRoom)
}
}
return rooms
}
//delaunay helper funcs
func FindNearestConnector(midpoint types.Coords, room gamemap.Room) types.Coords {
var nearest types.Coords
for _, con := range room.Connectors {
if nearest.X == 0 {
nearest = con
continue
}
if midpoint.DistanceTo(con) < midpoint.DistanceTo(nearest) {
nearest = con
}
}
return nearest
}
func ConnectStraight(rng *util.RNG, l *gamemap.Level, from, to, midpoint types.Coords) {
toss := rng.Range(0, 1)
if toss == 0 {
DigHTunnel(l, from.X, midpoint.X, from.Y)
DigVTunnel(l, from.Y, to.Y, midpoint.X)
DigHTunnel(l, midpoint.X, to.X, to.Y)
} else {
DigVTunnel(l, from.Y, midpoint.Y, from.X)
DigHTunnel(l, from.X, to.X, midpoint.Y)
DigVTunnel(l, midpoint.Y, to.Y, to.X)
}
}
func DigHTunnel(l *gamemap.Level, x1, x2, y int) {
var start, finish int
if x1 < x2 {
start = x1
finish = x2
} else {
start = x2
finish = x1
}
for i := start; i <= finish; i++ {
if l.InBounds(types.Coords{i, y}) {
l.SetTileByXY(i, y, gamemap.NewFloor())
//l.Tiles[i][y] = gamemap.NewFloor()
}
}
}
func DigVTunnel(l *gamemap.Level, y1, y2, x int) {
var start, finish int
if y1 < y2 {
start = y1
finish = y2
} else {
start = y2
finish = y1
}
for i := start; i <= finish; i++ {
if l.InBounds(types.Coords{x, i}) {
l.SetTileByXY(x, i, gamemap.NewFloor())
}
}
}
//default helper
func ConnectRoomCenters(l *gamemap.Level, room, otherRoom gamemap.Room, toss int) {
if toss == 0 {
DigHTunnel(l, room.Center.X, otherRoom.Center.X, room.Center.Y)
DigVTunnel(l, room.Center.Y, otherRoom.Center.Y, otherRoom.Center.X)
} else {
DigVTunnel(l, room.Center.Y, otherRoom.Center.Y, room.Center.Y)
DigHTunnel(l, room.Center.X, otherRoom.Center.X, otherRoom.Center.Y)
}
}

View File

@ -0,0 +1,38 @@
package mapgens
import (
"fmt"
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
"lab.zaar.be/thefish/alchemyst-go/util"
"lab.zaar.be/thefish/alchemyst-go/util/appctx"
)
func DefaultGen(ctx appctx.ClientCtx,l *gamemap.Level) (*gamemap.Level, []gamemap.Room) {
rng := util.NewRNG()
//fill with walls
for i := 0; i < l.W; i ++ {
for j := 0; j < l.H; j++ {
l.SetTileByXY(i, j, gamemap.NewWall())
}
}
rooms := GetRandomRoomList(ctx, rng, l, maxrooms, minRoomSize, maxRoomSize)
for _, room := range rooms {
err := room.BlitToLevel(l)
if err != nil {
fmt.Printf("err: %v", err)
}
}
for idx, room := range rooms {
if idx > 0 {
ConnectRoomCenters(l, room, rooms[idx-1], rng.Range(0, 1))
}
}
return l, rooms
}

View File

@ -1,162 +0,0 @@
package _default
import (
"fmt"
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
"lab.zaar.be/thefish/alchemyst-go/engine/types"
"lab.zaar.be/thefish/alchemyst-go/util"
"lab.zaar.be/thefish/alchemyst-go/util/appctx"
)
//fixme move to config
var minRoomSize = 3
var maxRoomSize = 15
var maxrooms = 50
var fges = map[int]types.RectFill{
1: 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() },
},
2: types.RectFill{
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() },
},
}
func DefaultGen(ctx appctx.ClientCtx,l *gamemap.Level) (*gamemap.Level, []gamemap.Room) {
rng := util.NewRNG()
//load prefabs
pfLoader := gamemap.NewPrefabLoader(ctx)
pfRooms := pfLoader.PrefabRoomsList()
//fill with walls
for i := 0; i < l.W; i ++ {
for j := 0; j < l.H; j++ {
l.SetTileByXY(i, j, gamemap.NewWall())
}
}
rooms := make([]gamemap.Room, 0)
prefabUsed := false
for i := 0; i < maxrooms; i++ {
failed := false
var fillage types.RectFill
fillage = fges[rng.GetWeightedEntity(map[int]int{1: 10, 2: 1})]
var newRoom gamemap.Room
if !prefabUsed || rng.Range(0,5) > 3 {
//prefab
prefabUsed = true
r := pfRooms[rng.Range(0, len(pfRooms))] //copy to local scope
newRoom = r
} else {
newRoom = gamemap.NewRandomRectRoom(
rng,
rng.Range(minRoomSize, maxRoomSize),
rng.Range(minRoomSize, maxRoomSize),
fillage,
)
}
where := types.Coords{
rng.Range(1, l.W -2 - newRoom.W),
rng.Range(1, l.H - 2 - newRoom.H),
}
newRoom.MoveToCoords(where)
for _, otherRoom := range rooms {
if otherRoom.Intersects(newRoom.Rect) {
failed = true
break
}
}
if !failed {
rooms = append(rooms, newRoom)
}
//addStairs(rooms)
//itemize(rooms)
}
//build delannay graph from room center
//refine it to minimum spanning tree
//connect accordingly
for _, room := range rooms {
err := room.BlitToLevel(l)
if err != nil {
fmt.Printf("err: %v", err)
}
}
for idx, room := range rooms {
if idx > 0 {
connectRooms(l, room, rooms[idx-1], rng.Range(0, 1))
}
}
return l, rooms
}
func connectRooms(l *gamemap.Level, room, otherRoom gamemap.Room, toss int) {
if toss == 0 {
digHTunnel(l, room.Center.X, otherRoom.Center.X, room.Center.Y)
digVTunnel(l, room.Center.Y, otherRoom.Center.Y, otherRoom.Center.X)
} else {
digVTunnel(l, room.Center.Y, otherRoom.Center.Y, room.Center.Y)
digHTunnel(l, room.Center.X, otherRoom.Center.X, otherRoom.Center.Y)
}
}
func digHTunnel(l *gamemap.Level, x1, x2, y int) {
var start, finish int
if x1 < x2 {
start = x1
finish = x2
} else {
start = x2
finish = x1
}
for i := start; i <= finish; i++ {
if l.InBounds(types.Coords{i, y}) {
l.SetTileByXY(i, y, gamemap.NewFloor())
//l.Tiles[i][y] = gamemap.NewFloor()
}
}
}
func digVTunnel(l *gamemap.Level, y1, y2, x int) {
var start, finish int
if y1 < y2 {
start = y1
finish = y2
} else {
start = y2
finish = y1
}
for i := start; i <= finish; i++ {
if l.InBounds(types.Coords{x, i}) {
l.SetTileByXY(x, i, gamemap.NewFloor())
}
}
}

View File

@ -0,0 +1,67 @@
package mapgens
import (
"fmt"
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
"lab.zaar.be/thefish/alchemyst-go/engine/types"
"lab.zaar.be/thefish/alchemyst-go/util"
"lab.zaar.be/thefish/alchemyst-go/util/appctx"
"lab.zaar.be/thefish/alchemyst-go/util/delaunay"
)
func DelaunayMstGen(ctx appctx.ClientCtx, l *gamemap.Level) (*gamemap.Level, []gamemap.Room) {
rng := util.NewRNG()
//fill with walls
for i := 0; i < l.W; i ++ {
for j := 0; j < l.H; j++ {
l.SetTileByXY(i, j, gamemap.NewWall())
}
}
rooms := GetRandomRoomList(ctx, rng, l, maxrooms, minRoomSize, maxRoomSize)
for _, room := range rooms {
err := room.BlitToLevel(l)
if err != nil {
fmt.Printf("err: %v", err)
}
}
centers := make([]types.Coords, 0)
for _, room := range rooms {
centers = append(centers, room.Center)
}
edges := delaunay.GetMst(centers, l.W, l.H)
for _, edge := range edges {
MedianStraight(rng, l, rooms, centers, edge)
}
return l, rooms
}
func MedianStraight(rng *util.RNG, l *gamemap.Level, rooms []gamemap.Room, centers []types.Coords, edge types.Edge) {
//find connected rooms
var fromRoom, toRoom gamemap.Room
for _, room := range rooms {
if room.Center == edge.From {
fromRoom = room
continue
}
if room.Center == edge.To {
toRoom = room
continue
}
if len(fromRoom.Connectors) > 0 && len(toRoom.Connectors) > 0 {
break
}
}
midpoint := edge.Midpoint()
fromConnector := FindNearestConnector(midpoint, fromRoom)
toConnector := FindNearestConnector(midpoint, toRoom)
ConnectStraight(rng, l, fromConnector, toConnector, midpoint)
}

View File

@ -1,229 +0,0 @@
package delaunaymst
import (
"fmt"
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
"lab.zaar.be/thefish/alchemyst-go/engine/types"
"lab.zaar.be/thefish/alchemyst-go/util"
"lab.zaar.be/thefish/alchemyst-go/util/appctx"
"lab.zaar.be/thefish/alchemyst-go/util/delaunay"
)
//fixme move to config
var minRoomSize = 5
var maxRoomSize = 25
var maxrooms = 200
var fges = map[int]types.RectFill{
1: 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() },
},
2: types.RectFill{
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() },
},
}
func DelaunayMstGen(ctx appctx.ClientCtx, l *gamemap.Level) (*gamemap.Level, []gamemap.Room) {
rng := util.NewRNG()
//load prefabs
pfLoader := gamemap.NewPrefabLoader(ctx)
pfRooms := pfLoader.PrefabRoomsList()
//fill with walls
for i := 0; i < l.W; i ++ {
for j := 0; j < l.H; j++ {
l.SetTileByXY(i, j, gamemap.NewWall())
}
}
rooms := make([]gamemap.Room, 0)
prefabUsed := false
for i := 0; i < maxrooms; i++ {
failed := false
var fillage types.RectFill
fillage = fges[rng.GetWeightedEntity(map[int]int{1: 10, 2: 1})]
var newRoom = gamemap.Room{}
if !prefabUsed || rng.Range(0, 5) > 3 {
//if prefabUsed {
//prefab
prefabUsed = true
fmt.Printf("\n\n------USING PREFAB-----\n")
r := pfRooms[rng.Range(0, len(pfRooms))] //copy to local scope
newRoom = gamemap.Room{
Rect: r.Rect,
Center: r.Center,
Geometry: r.Geometry,
Items: r.Items,
Mobs: r.Mobs,
Connectors: make([]types.Coords,0),
}
for _, coord := range r.Connectors {
newRoom.Connectors = append(newRoom.Connectors, coord)
}
} else {
newRoom = gamemap.NewRandomRectRoom(
rng,
rng.Range(minRoomSize, maxRoomSize),
rng.Range(minRoomSize, maxRoomSize),
fillage,
)
}
where := types.Coords{
rng.Range(1, l.W-2-newRoom.W),
rng.Range(1, l.H-2-newRoom.H),
}
newRoom.MoveToCoords(where)
for _, otherRoom := range rooms {
if otherRoom.Intersects(newRoom.Rect) {
failed = true
break
}
}
if failed {
continue
}
if len(newRoom.Connectors) > 0 {
rooms = append(rooms, newRoom)
}
}
for _, room := range rooms {
err := room.BlitToLevel(l)
if err != nil {
fmt.Printf("err: %v", err)
}
}
centers := make([]types.Coords, 0)
for _, room := range rooms {
centers = append(centers, room.Center)
}
edges := delaunay.GetMst(centers, l.W, l.H)
fmt.Printf("edges: ", edges)
for _, edge := range edges {
MedianStraight(rng, l, rooms, centers, edge)
}
return l, rooms
}
func MedianStraight(rng *util.RNG, l *gamemap.Level, rooms []gamemap.Room, centers []types.Coords, edge types.Edge) {
//find connected rooms
var fromRoom, toRoom gamemap.Room
for _, room := range rooms {
if room.Center == edge.From {
fromRoom = room
continue
}
if room.Center == edge.To {
toRoom = room
continue
}
if len(fromRoom.Connectors) > 0 && len(toRoom.Connectors) > 0 {
break
}
}
midpoint := edge.Midpoint()
fromConnector := findNearestCoonector(midpoint, fromRoom)
toConnector := findNearestCoonector(midpoint, toRoom)
if (!l.InBounds(midpoint)) {
//fmt.Printf("rooms: ", rooms)
fmt.Printf("\nedges: ", edge)
fmt.Printf("\nmidpoint: ", midpoint)
panic(fmt.Errorf("midpoint out of level bounds!"))
}
if (!l.InBounds(fromConnector)) {
fmt.Printf("\nfrom room: ", fromRoom.String())
fmt.Printf("\nedges: ", edge)
fmt.Printf("\nfromConnector: ", fromConnector)
panic(fmt.Errorf("fromConnector out of level bounds!"))
}
if (!l.InBounds(toConnector)) {
fmt.Printf("\nto room: ", toRoom.String())
fmt.Printf("\nedges: ", edge)
fmt.Printf("\ntoConnector: ", toConnector)
panic(fmt.Errorf("toConnector out of level bounds!"))
}
connectStraight(rng, l, fromConnector, toConnector, midpoint)
}
func findNearestCoonector(midpoint types.Coords, room gamemap.Room) types.Coords {
var nearest types.Coords
for _, con := range room.Connectors {
if nearest.X == 0 {
nearest = con
continue
}
if midpoint.DistanceTo(con) < midpoint.DistanceTo(nearest) {
nearest = con
}
}
return nearest
}
func connectStraight(rng *util.RNG, l *gamemap.Level, from, to, midpoint types.Coords) {
toss := rng.Range(0, 1)
if toss == 0 {
digHTunnel(l, from.X, midpoint.X, from.Y)
digVTunnel(l, from.Y, to.Y, midpoint.X)
digHTunnel(l, midpoint.X, to.X, to.Y)
} else {
digVTunnel(l, from.Y, midpoint.Y, from.X)
digHTunnel(l, from.X, to.X, midpoint.Y)
digVTunnel(l, midpoint.Y, to.Y, to.X)
}
}
func digHTunnel(l *gamemap.Level, x1, x2, y int) {
var start, finish int
if x1 < x2 {
start = x1
finish = x2
} else {
start = x2
finish = x1
}
for i := start; i <= finish; i++ {
if l.InBounds(types.Coords{i, y}) {
l.SetTileByXY(i, y, gamemap.NewFloor())
//l.Tiles[i][y] = gamemap.NewFloor()
}
}
}
func digVTunnel(l *gamemap.Level, y1, y2, x int) {
var start, finish int
if y1 < y2 {
start = y1
finish = y2
} else {
start = y2
finish = y1
}
for i := start; i <= finish; i++ {
if l.InBounds(types.Coords{x, i}) {
l.SetTileByXY(x, i, gamemap.NewFloor())
}
}
}

View File

@ -2,7 +2,6 @@ package gamemap
import (
"encoding/json"
"fmt"
"io/ioutil"
"lab.zaar.be/thefish/alchemyst-go/engine/items"
"lab.zaar.be/thefish/alchemyst-go/engine/mob"
@ -113,8 +112,6 @@ func (pfbl PrefabLoader) PrefabRoomsList() []Room {
}
}
//add room to list
fmt.Printf("PREFAB room append: ", room.String())
rooms = append(rooms, room)
}
return rooms

View File

@ -60,8 +60,6 @@ func (room *Room) BlitToLevel(l *Level) error {
}
func (room *Room) MoveToCoords(where types.Coords) *Room {
fmt.Printf("\n MOVING room :", room.String())
fmt.Printf("\nmovin room to %v", where)
//update room coords?
room.X = where.X
room.Y = where.Y
@ -70,14 +68,11 @@ func (room *Room) MoveToCoords(where types.Coords) *Room {
room.Center.Y = room.Center.Y + where.Y
//update connector?
for i, coords := range room.Connectors {
fmt.Printf("\nupdating coords ", coords)
coords.X = coords.X + where.X
coords.Y = coords.Y + where.Y
fmt.Printf("\nupdated coords ", coords)
room.Connectors[i] = coords
}
fmt.Printf("\nROOM MOVED to %v \n\n", room)
return room
}

View File

@ -169,4 +169,9 @@ func (tr *TerrainRender) Render() {
**вдвое**. Это удобная штука, не спорю, но пользоваться ей надо при загрузке ресурсов, при сохранении/загрузке состояния
приложения - т.е. при разовых операциях. Как оказалось, она _очень_ дорогая по CPU. Кто пользоуется ей в main loop, ORM
и прочих нагруженных местах - да будет предан анафеме.
Обратить внимание
===
При казалось бы передаче по значению слайсы - всё равно передаются по ссылке! (пример с комнатами и выходами)