From f13438951a4075998b959a95772c22686d79cbe0 Mon Sep 17 00:00:00 2001 From: gmzar Date: Fri, 19 Jul 2019 16:04:18 -0700 Subject: [PATCH] Part 4 6/6 need help --- mapping/gamemap.go | 68 +++++++++++++++++++++++++++++++++------------- mapping/tile.go | 11 ++++++-- render.go | 32 +++++++++++++--------- 3 files changed, 77 insertions(+), 34 deletions(-) diff --git a/mapping/gamemap.go b/mapping/gamemap.go index 0500dba..4c50dc9 100644 --- a/mapping/gamemap.go +++ b/mapping/gamemap.go @@ -6,38 +6,41 @@ import ( "steel/interfaces" ) -// GameMap is our map data type. +// GameMap is our map type for holding our tiles and dimensions. type GameMap struct { - Width, Height int - Tiles [][]Tile + width, height int + tiles [][]Tile } -// Initialize initializes a GameMap's Tiles to match its Width and Height. It also sets up some coordinates to block movement and sight. -func (g *GameMap) Initialize() { - g.Tiles = make([][]Tile, g.Width) +// NewGameMap initializes a GameMap's Tiles to match provided width and height and sets up a few tiles to block movement and sight. Returns a GameMap interface. +func NewGameMap(width, height int) interfaces.GameMap { + g := &GameMapmake{ + width: width, + height: height, + } + g.tiles = make([][]Tile, g.width) - for x := range g.Tiles { - g.Tiles[x] = make([]Tile, g.Height) - for y := range g.Tiles[x] { - g.Tiles[x][y] = Tile{ - BlockSight: true, - BlockMovement: true, - } + for x := range g.tiles { + g.tiles[x] = make([]Tile, g.height) + for y := range g.tiles[x] { + g.tiles[x][y].Flags = BlockMovement | BlockSight } } + + return g } // MakeMap creates a new randomized map. This is built according to the passed arguments. func (g *GameMap) MakeMap(maxRooms, roomMinSize, roomMaxSize int, player interfaces.Entity) { - var rooms []*Rect + var rooms []Rect for r := 0; r < maxRooms; r++ { // Generate a random width and height. width := roomMinSize + goro.Random.Intn(roomMaxSize) height := roomMinSize + goro.Random.Intn(roomMaxSize) // Generate a random position within the map boundaries. - x := goro.Random.Intn(g.Width - width - 1) - y := goro.Random.Intn(g.Height - height - 1) + x := goro.Random.Intn(g.width - width - 1) + y := goro.Random.Intn(g.height - height - 1) // Create a Rect according to our generated sizes. room := NewRect(x, y, width, height) @@ -77,7 +80,7 @@ func (g *GameMap) MakeMap(maxRooms, roomMinSize, roomMaxSize int, player interfa } // CreateRoom creates a room from a provided rect. -func (g *GameMap) CreateRoom(r *Rect) { +func (g *GameMap) CreateRoom(r Rect) { for x := r.X1 + 1; x < r.X2; x++ { for y := r.Y1 + 1; y < r.Y2; y++ { if g.InBounds(x, y) { @@ -105,18 +108,45 @@ func (g *GameMap) CreateVTunnel(y1, y2, x int) { } } +// Explored returns if the tile at x by y has been explored. +func (g *GameMap) Explored(x, y int) bool { + if g.InBounds(x, y) { + return g.tiles[x][y].Flags&Explored != 0 + } + return false +} + +// SetExplored sets the explored state of the tile at x and y to the passed explored bool. +func (g *GameMap) SetExplored(x, y int, explored bool) { + if g.InBounds(x, y) { + if explored { + g.tiles[x][y].Flags = g.tiles[x][y].Flags | Explored + } else { + g.tiles[x][y].Flags = g.tiles[x][y].Flags &^ Explored + } + } +} + // IsBlocked returns if the given coordinates are blocking movement. func (g *GameMap) IsBlocked(x, y int) bool { // Always block if ourside our GameMap's bounds. if !g.InBounds(x, y) { return true } - return g.Tiles[x][y].BlockMovement + return g.Tiles[x][y].Flags&BlockMovement != 0 +} + +// IsOpaque returns if the given coordinates are blocking sight. +func (g *GameMap) IsOpaque(x, y int) bool { + if !g.InBounds(x, y) { + return true + } + return g.tiles[x][y].Flags&BlockSight != 0 } // InBounds returns if the given coordinates are within the map's bounds. func (g *GameMap) InBounds(x, y int) bool { - if x < 0 || x >= g.Width || y < 0 || y >= g.Height { + if x < 0 || x >= g.width || y < 0 || y >= g.height { return false } return true diff --git a/mapping/tile.go b/mapping/tile.go index 267b6d3..53370ed 100644 --- a/mapping/tile.go +++ b/mapping/tile.go @@ -1,6 +1,13 @@ package mapping + // Tile represents the state of a given location in a GameMap. type Tile struct { - BlockMovement bool - BlockSight bool + Flags uint } + +// Our Tile's flags. +const ( + BlockMovement = 1 << iota + BlockSight + Explored +) diff --git a/render.go b/render.go index 7431fa6..bba4a6b 100644 --- a/render.go +++ b/render.go @@ -11,19 +11,20 @@ import ( // DrawAll draws all entities and the gameMap to the screen and flushes it. func DrawAll(screen *goro.Screen, entities []interfaces.Entity, gameMap mapping.GameMap, fovMap fov.Map, fovRecompute bool, colors map[string]goro.Color) { if fovRecompute { - // Draw all the riles in the game map. - for x, column := range gameMap.Tiles { - for y, tile := range column { + // Draw all the tiles in the game map. + for x := 0; x < gameMap.Width(); x++ { + for y := 0; y < gameMap.Height(); y++ { visible := fovMap.Visible(x, y) if visible { - if tile.BlockSight { + if gameMap.IsBlocked(x, y) { screen.SetBackground(x, y, colors["lightWall"]) } else { screen.SetBackground(x, y, colors["lightGround"]) } - } else { - if tile.BlockSight { + gameMap.SetExplored(x, y, true) + } else if gameMap.Explored(x, y) { + if gameMap.IsBlocked(x, y) { screen.SetBackground(x, y, colors["darkWall"]) } else { screen.SetBackground(x, y, colors["darkGround"]) @@ -35,24 +36,29 @@ func DrawAll(screen *goro.Screen, entities []interfaces.Entity, gameMap mapping. // Draw all the entities in the game map. for _, entity := range entities { - DrawEntity(screen, entity) + DrawEntity(screen, entity, fovMap) } screen.Flush() } // ClearAll clears all entities from the screen. -func ClearAll(screen *goro.Screen, entities []interfaces.Entity) { +func ClearAll(screen *goro.Screen, entities []interfaces.Entity, fovMap fov.Map) { for _, entity := range entities { - ClearEntity(screen, entity) + ClearEntity(screen, entity, fovMap) } } // DrawEntity draws a given entity to the screen. -func DrawEntity(screen *goro.Screen, e interfaces.Entity) { - screen.DrawRune(e.X(), e.Y(), e.Rune(), e.Style()) +func DrawEntity(screen *goro.Screen, e interfaces.Entity, fovMap fov.Map) { + if fovMap.Visible(e.X(), e.Y()) { + screen.SetRune(e.X()), e.Y(), e.Rune()) + screen.SetForeground(e.X(), e.Y(), e.Style().Foreground) + } } // ClearEntity clears a given entity from the screen. -func ClearEntity(screen *goro.Screen, e interfaces.Entity) { - screen.SetRune(e.X(), e.Y(), ' ') +func ClearEntity(screen *goro.Screen, e interfaces.Entity, fovMap fov.Map) { + if fovMap.Visible(e.X(), e.Y()) { + screen.SetRune(e.X(), e.Y(), ' ') + } }