Converted to use entity interfaces
This commit is contained in:
parent
eea1fa9388
commit
085b1078d4
|
@ -1,25 +1,70 @@
|
||||||
package entity
|
package entity
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"steel/interfaces"
|
||||||
|
|
||||||
"github.com/kettek/goro"
|
"github.com/kettek/goro"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Entity is a type that represents an active entity in the world.
|
// Entity is a type that represents an active entity in the world.
|
||||||
type Entity struct {
|
type Entity struct {
|
||||||
X, Y int
|
x, y int
|
||||||
Rune rune
|
rune rune
|
||||||
Style goro.Style
|
style goro.Style
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewEntity returns a pointer to a newly created Entity.
|
||||||
|
func NewEntity(x int, y int, r rune, s goro.Style) interfaces.Entity {
|
||||||
|
return &Entity{
|
||||||
|
x: x,
|
||||||
|
y: y,
|
||||||
|
rune: r,
|
||||||
|
style: s,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Move moves the entity by a given amount.
|
// Move moves the entity by a given amount.
|
||||||
func (e *Entity) Move(x, y int) {
|
func (e *Entity) Move(x, y int) {
|
||||||
e.X += x
|
e.x += x
|
||||||
e.Y += y
|
e.y += y
|
||||||
|
}
|
||||||
|
|
||||||
|
// X returns the entity's X value.
|
||||||
|
func (e *Entity) X() int {
|
||||||
|
return e.x
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetX sets the entity's X value
|
||||||
|
func (e *Entity) SetX(x int) {
|
||||||
|
e.x = x
|
||||||
|
}
|
||||||
|
|
||||||
|
// Y returns the entity's Y value.
|
||||||
|
func (e *Entity) Y() int {
|
||||||
|
return e.y
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetY sets the entity's Y value
|
||||||
|
func (e *Entity) SetY(y int) {
|
||||||
|
e.y = y
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rune returns the entity's rune.
|
||||||
|
func (e *Entity) Rune() rune {
|
||||||
|
return e.rune
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRune sets the entity's rune.
|
||||||
|
func (e *Entity) SetRune(r rune) {
|
||||||
|
e.rune = r
|
||||||
|
}
|
||||||
|
|
||||||
|
// Style returns the entity's style.
|
||||||
|
func (e *Entity) Style() goro.Style {
|
||||||
|
return e.style
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStyle sets the entity's style.
|
||||||
|
func (e *Entity) SetStyle(s goro.Style) {
|
||||||
|
e.style = s
|
||||||
}
|
}
|
||||||
// NewEntity returns a pointer to a newly created Entity.
|
|
||||||
func NewEntity(x int, y int, r rune, s goro.Style) *Entity {
|
|
||||||
return &Entity{
|
|
||||||
X: x,
|
|
||||||
Y: y,
|
|
||||||
Rune: r,
|
|
||||||
Style: s,
|
|
||||||
}
|
|
||||||
}
|
|
17
interfaces/entity.go
Normal file
17
interfaces/entity.go
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package interfaces
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kettek/goro"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Entity interface {
|
||||||
|
X() int
|
||||||
|
SetX(int)
|
||||||
|
Y() int
|
||||||
|
SetY(int)
|
||||||
|
Rune() rune
|
||||||
|
SetRune(rune)
|
||||||
|
Style() goro.Style
|
||||||
|
SetStyle(goro.Style)
|
||||||
|
Move(int, int)
|
||||||
|
}
|
7
main.go
7
main.go
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"steel/entity"
|
"steel/entity"
|
||||||
|
"steel/interfaces"
|
||||||
"steel/mapping"
|
"steel/mapping"
|
||||||
|
|
||||||
"github.com/kettek/goro"
|
"github.com/kettek/goro"
|
||||||
|
@ -40,7 +41,7 @@ func main() {
|
||||||
player := entity.NewEntity(screen.Columns/2, screen.Rows/2+5, '@', goro.Style{Foreground: goro.ColorWhite})
|
player := entity.NewEntity(screen.Columns/2, screen.Rows/2+5, '@', goro.Style{Foreground: goro.ColorWhite})
|
||||||
npc := entity.NewEntity(screen.Columns/2-5, screen.Rows/2, '@', goro.Style{Foreground: goro.ColorYellow})
|
npc := entity.NewEntity(screen.Columns/2-5, screen.Rows/2, '@', goro.Style{Foreground: goro.ColorYellow})
|
||||||
|
|
||||||
entities := []*entity.Entity{
|
entities := []interfaces.Entity{
|
||||||
player,
|
player,
|
||||||
npc,
|
npc,
|
||||||
}
|
}
|
||||||
|
@ -59,7 +60,7 @@ func main() {
|
||||||
for {
|
for {
|
||||||
|
|
||||||
if fovRecompute {
|
if fovRecompute {
|
||||||
RecomputeFov(fovMap, player.X, player.Y, fovRadius, fov.Light{})
|
RecomputeFov(fovMap, player.X(), player.Y(), fovRadius, fov.Light{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw screen.
|
// Draw screen.
|
||||||
|
@ -74,7 +75,7 @@ func main() {
|
||||||
case goro.EventKey:
|
case goro.EventKey:
|
||||||
switch action := handleKeyEvent(event).(type) {
|
switch action := handleKeyEvent(event).(type) {
|
||||||
case ActionMove:
|
case ActionMove:
|
||||||
if !gameMap.IsBlocked(player.X+action.X, player.Y+action.Y) {
|
if !gameMap.IsBlocked(player.X()+action.X, player.Y()+action.Y) {
|
||||||
player.Move(action.X, action.Y)
|
player.Move(action.X, action.Y)
|
||||||
fovRecompute = true
|
fovRecompute = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,13 @@ package mapping
|
||||||
import (
|
import (
|
||||||
"github.com/kettek/goro"
|
"github.com/kettek/goro"
|
||||||
|
|
||||||
"steel/entity"
|
"steel/interfaces"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GameMap is our map data type.
|
// GameMap is our map data type.
|
||||||
type GameMap struct {
|
type GameMap struct {
|
||||||
Width, Height int
|
Width, Height int
|
||||||
Tiles [][]Tile
|
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.
|
// Initialize initializes a GameMap's Tiles to match its Width and Height. It also sets up some coordinates to block movement and sight.
|
||||||
|
@ -20,15 +20,15 @@ func (g *GameMap) Initialize() {
|
||||||
g.Tiles[x] = make([]Tile, g.Height)
|
g.Tiles[x] = make([]Tile, g.Height)
|
||||||
for y := range g.Tiles[x] {
|
for y := range g.Tiles[x] {
|
||||||
g.Tiles[x][y] = Tile{
|
g.Tiles[x][y] = Tile{
|
||||||
BlockSight: true,
|
BlockSight: true,
|
||||||
BlockMovement: true,
|
BlockMovement: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeMap creates a new randomized map. This is built according to the passed arguments.
|
// MakeMap creates a new randomized map. This is built according to the passed arguments.
|
||||||
func (g *GameMap) MakeMap(maxRooms, roomMinSize, roomMaxSize int, player *entity.Entity) {
|
func (g *GameMap) MakeMap(maxRooms, roomMinSize, roomMaxSize int, player interfaces.Entity) {
|
||||||
var rooms []*Rect
|
var rooms []*Rect
|
||||||
|
|
||||||
for r := 0; r < maxRooms; r++ {
|
for r := 0; r < maxRooms; r++ {
|
||||||
|
@ -40,7 +40,7 @@ func (g *GameMap) MakeMap(maxRooms, roomMinSize, roomMaxSize int, player *entity
|
||||||
y := goro.Random.Intn(g.Height - height - 1)
|
y := goro.Random.Intn(g.Height - height - 1)
|
||||||
// Create a Rect according to our generated sizes.
|
// Create a Rect according to our generated sizes.
|
||||||
room := NewRect(x, y, width, height)
|
room := NewRect(x, y, width, height)
|
||||||
|
|
||||||
// Iterate through our existing rooms to check for intersection with our new room.
|
// Iterate through our existing rooms to check for intersection with our new room.
|
||||||
intersects := false
|
intersects := false
|
||||||
for _, otherRoom := range rooms {
|
for _, otherRoom := range rooms {
|
||||||
|
@ -54,22 +54,22 @@ func (g *GameMap) MakeMap(maxRooms, roomMinSize, roomMaxSize int, player *entity
|
||||||
g.CreateRoom(room)
|
g.CreateRoom(room)
|
||||||
roomCenterX, roomCenterY := room.Center()
|
roomCenterX, roomCenterY := room.Center()
|
||||||
|
|
||||||
// Always place the player in the center of the first room.
|
// Always place the player in the center of the first room.
|
||||||
if len(rooms) == 0 {
|
if len(rooms) == 0 {
|
||||||
player.X = roomCenterX
|
player.SetX(roomCenterX)
|
||||||
player.Y = roomCenterY
|
player.SetY(roomCenterY)
|
||||||
} else {
|
|
||||||
prevCenterX, prevCenterY := rooms[len(rooms)-1].Center()
|
|
||||||
|
|
||||||
// Flip a coin if we should tunnel horizontally or vertically first.
|
|
||||||
if goro.Random.Intn(1) == 1 {
|
|
||||||
g.CreateHTunnel(prevCenterX, roomCenterX, prevCenterY)
|
|
||||||
g.CreateVTunnel(prevCenterY, roomCenterY, roomCenterX)
|
|
||||||
} else {
|
} else {
|
||||||
g.CreateVTunnel(prevCenterY, roomCenterY, prevCenterX)
|
prevCenterX, prevCenterY := rooms[len(rooms)-1].Center()
|
||||||
g.CreateHTunnel(prevCenterX, roomCenterX, roomCenterY)
|
|
||||||
|
// Flip a coin if we should tunnel horizontally or vertically first.
|
||||||
|
if goro.Random.Intn(1) == 1 {
|
||||||
|
g.CreateHTunnel(prevCenterX, roomCenterX, prevCenterY)
|
||||||
|
g.CreateVTunnel(prevCenterY, roomCenterY, roomCenterX)
|
||||||
|
} else {
|
||||||
|
g.CreateVTunnel(prevCenterY, roomCenterY, prevCenterX)
|
||||||
|
g.CreateHTunnel(prevCenterX, roomCenterX, roomCenterY)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Append our new room to our rooms list.
|
// Append our new room to our rooms list.
|
||||||
rooms = append(rooms, room)
|
rooms = append(rooms, room)
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ func (g *GameMap) CreateHTunnel(x1, x2, y int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateVTunnel creates a vertical tunnel from y1 to/from y2 starting at x.
|
// CreateVTunnel creates a vertical tunnel from y1 to/from y2 starting at x.
|
||||||
func (g *GameMap) CreateVTunnel(y1, y2, x int) {
|
func (g *GameMap) CreateVTunnel(y1, y2, x int) {
|
||||||
for y := goro.MinInt(y1, y2); y <= goro.MaxInt(y1, y2); y++ {
|
for y := goro.MinInt(y1, y2); y <= goro.MaxInt(y1, y2); y++ {
|
||||||
if g.InBounds(x, y) {
|
if g.InBounds(x, y) {
|
||||||
|
@ -115,7 +115,7 @@ func (g *GameMap) IsBlocked(x, y int) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// InBounds returns if the given coordinates are within the map's bounds.
|
// InBounds returns if the given coordinates are within the map's bounds.
|
||||||
func (g *GameMap) InBounds (x, y int) bool {
|
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 false
|
||||||
}
|
}
|
||||||
|
|
14
render.go
14
render.go
|
@ -4,12 +4,12 @@ import (
|
||||||
"github.com/kettek/goro"
|
"github.com/kettek/goro"
|
||||||
"github.com/kettek/goro/fov"
|
"github.com/kettek/goro/fov"
|
||||||
|
|
||||||
"steel/entity"
|
"steel/interfaces"
|
||||||
"steel/mapping"
|
"steel/mapping"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DrawAll draws all entities and the gameMap to the screen and flushes it.
|
// DrawAll draws all entities and the gameMap to the screen and flushes it.
|
||||||
func DrawAll(screen *goro.Screen, entities []*entity.Entity, gameMap mapping.GameMap, fovMap fov.Map, fovRecompute bool, colors map[string]goro.Color) {
|
func DrawAll(screen *goro.Screen, entities []interfaces.Entity, gameMap mapping.GameMap, fovMap fov.Map, fovRecompute bool, colors map[string]goro.Color) {
|
||||||
if fovRecompute {
|
if fovRecompute {
|
||||||
// Draw all the riles in the game map.
|
// Draw all the riles in the game map.
|
||||||
for x, column := range gameMap.Tiles {
|
for x, column := range gameMap.Tiles {
|
||||||
|
@ -41,18 +41,18 @@ func DrawAll(screen *goro.Screen, entities []*entity.Entity, gameMap mapping.Gam
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearAll clears all entities from the screen.
|
// ClearAll clears all entities from the screen.
|
||||||
func ClearAll(screen *goro.Screen, entities []*entity.Entity) {
|
func ClearAll(screen *goro.Screen, entities []interfaces.Entity) {
|
||||||
for _, entity := range entities {
|
for _, entity := range entities {
|
||||||
ClearEntity(screen, entity)
|
ClearEntity(screen, entity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DrawEntity draws a given entity to the screen.
|
// DrawEntity draws a given entity to the screen.
|
||||||
func DrawEntity(screen *goro.Screen, e *entity.Entity) {
|
func DrawEntity(screen *goro.Screen, e interfaces.Entity) {
|
||||||
screen.DrawRune(e.X, e.Y, e.Rune, e.Style)
|
screen.DrawRune(e.X(), e.Y(), e.Rune(), e.Style())
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearEntity clears a given entity from the screen.
|
// ClearEntity clears a given entity from the screen.
|
||||||
func ClearEntity(screen *goro.Screen, e *entity.Entity) {
|
func ClearEntity(screen *goro.Screen, e interfaces.Entity) {
|
||||||
screen.SetRune(e.X, e.Y, ' ')
|
screen.SetRune(e.X(), e.Y(), ' ')
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user