progress in part 5, but unresolved problems with flags

This commit is contained in:
gmzar 2019-07-24 17:03:53 -07:00
parent 696ccd216e
commit 733ffe3380
5 changed files with 116 additions and 21 deletions

View File

@ -6,20 +6,23 @@ import (
"github.com/kettek/goro"
)
// Entity is a type that represents an active entity in the world.
type Entity struct {
x, y int
rune rune
style goro.Style
name string
flags uint
}
// NewEntity returns a pointer to a newly created Entity.
func NewEntity(x int, y int, r rune, s goro.Style) interfaces.Entity {
// NewEntity returns an interface to a new populated Entity.
func NewEntity(x int, y int, r rune, style goro.Style, name string, flags Flags) interfaces.Entity {
return &Entity{
x: x,
y: y,
rune: r,
style: s,
style: style,
name: name,
flags: flags,
}
}
@ -34,7 +37,7 @@ func (e *Entity) X() int {
return e.x
}
// SetX sets the entity's X value
// SetX sets the entity's x value
func (e *Entity) SetX(x int) {
e.x = x
}
@ -65,6 +68,36 @@ func (e *Entity) Style() goro.Style {
}
// SetStyle sets the entity's style.
func (e *Entity) SetStyle(s goro.Style) {
e.style = s
func (e *Entity) SetStyle(style goro.Style) {
e.style = style
}
// Name gets the entity's name.
func (e *Entity) Name() string {
return e.name
}
// SetName sets the entity's name.
func (e *Entity) SetName(n string) {
e.name = n
}
// Flags gets the entity's flags.
func (e *Entity) Flags() uint {
return e.flags
}
// SetFlags sets the entity's flags.
func (e *Entity) SetFlags(f uint) {
e.flags = f
}
// FindEntityAtLocation finds and returns the first entity at x and y matching the provided flags. If none exists, it returns nil.
func FindEntityAtLocation(entities []interfaces.Entity, x, y int, checkMask uint, matchFlags uint) interfaces.Entity {
for _, e := range entities {
if (e.Flags()&checkMask) == matchFlags && e.X() == x && e.Y() == y {
return e
}
}
return nil
}

6
entity/flags.go Normal file
View File

@ -0,0 +1,6 @@
package entity
// Our entity flags.
const (
BlockMovement uint = 1 << iota
)

10
gamestate.go Normal file
View File

@ -0,0 +1,10 @@
package main
// GameState is a numerical representation of a game state.
type GameState = uint8
// Our various game states.
const (
PlayerTurnState GameState = iota
NPCTurnState
)

38
main.go
View File

@ -27,6 +27,8 @@ func main() {
// Our initial variables.
mapWidth, mapHeight := 80, 40
maxRooms, roomMinSize, roomMaxSize := 30, 6, 10
maxMonstersPerRoom := 3
gameState := PlayerTurnState
fovRadius := 10
fovRecompute := true
@ -38,17 +40,15 @@ func main() {
"lightGround": goro.Color{R: 150, G: 150, B: 150, A: 255},
}
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})
player := entity.NewEntity(0, 0, '@', goro.Style{Foreground: goro.ColorWhite}, "Player", entity.BlockMovement)
entities := []interfaces.Entity{
player,
npc,
}
gameMap := mapping.NewGameMap(mapWidth, mapHeight)
gameMap.MakeMap(maxRooms, roomMinSize, roomMaxSize, player)
gameMap.MakeMap(maxRooms, roomMinSize, roomMaxSize, &entities, maxMonstersPerRoom)
fovMap := InitializeFoV(gameMap)
@ -70,16 +70,36 @@ func main() {
case goro.EventKey:
switch action := handleKeyEvent(event).(type) {
case ActionMove:
if !gameMap.IsBlocked(player.X()+action.X, player.Y()+action.Y) {
player.Move(action.X, action.Y)
fovRecompute = true
if gameState == PlayerTurnState {
x := player.X() + action.X
y := player.Y() + action.Y
if !gameMap.IsBlocked(x, y) {
otherEntity := entity.FindEntityAtLocation(entities, x, y, entity.BlockMovement, entity.BlockMovement)
if otherEntity != nil {
fmt.Printf("You lick the %s in the shins, much to its enjoyment!\n", otherEntity.Name())
} else {
player.Move(action.X, action.Y)
forRecompute = true
}
}
case ActionQuit:
goro.Quit()
gameState = NPCTurnState
}
case ActionQuit:
goro.Quit()
}
case goro.EventQuit:
return
}
// Handle entity updates.
if gameState == NPCTurnState {
for i, e := range entities {
if i > 0 {
fmt.Printf("The &s punders.\n", e.Name())
}
}
gameState = PlayerTurnState
}
}
})
}

View File

@ -1,9 +1,10 @@
package mapping
import (
"github.com/kettek/goro"
"steel/entity"
"steel/interfaces"
"github.com/kettek/goro"
)
// GameMap is our map type for holding our tiles and dimensions.
@ -31,7 +32,7 @@ func NewGameMap(width, height int) interfaces.GameMap {
}
// 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) {
func (g *GameMap) MakeMap(maxRooms, roomMinSize, roomMaxSize int, entities *[]interfaces.Entity, maxMonsters int) {
var rooms []Rect
for r := 0; r < maxRooms; r++ {
@ -59,8 +60,8 @@ func (g *GameMap) MakeMap(maxRooms, roomMinSize, roomMaxSize int, player interfa
// Always place the player in the center of the first room.
if len(rooms) == 0 {
player.SetX(roomCenterX)
player.SetY(roomCenterY)
(*entities)[0].SetX(roomCenterX)
(*entities)[0].SetY(roomCenterY)
} else {
prevCenterX, prevCenterY := rooms[len(rooms)-1].Center()
@ -73,6 +74,9 @@ func (g *GameMap) MakeMap(maxRooms, roomMinSize, roomMaxSize int, player interfa
g.CreateHTunnel(prevCenterX, roomCenterX, roomCenterY)
}
}
// Place random monsters in the room.
g.PlaceEntities(room, entities, maxMonsters)
// Append our new room to our rooms list.
rooms = append(rooms, room)
}
@ -108,6 +112,28 @@ func (g *GameMap) CreateVTunnel(y1, y2, x int) {
}
}
// PlaceEntities places 0 to maxMonsters monster entities in the provided room.
func (g *GameMap) PlaceEntities(room Rect, entities *[]interfaces.Entity, maxMonsters int) {
monstersCount := goro.Random.Intn(maxMonsters)
for i := 0; i < monstersCount; i++ {
var monster interfaces.Entity
// Acquire a random location within the room.
x := (1 + room.X1) + goro.Random.Intn(room.X2-room.X1-1)
y := (1 + room.Y1) + goro.Random.Intn(room.Y2-room.Y1-1)
if entity.FindEntityAtLocation(*entities, x, y, 0, 0) == nil {
// Generate an orc with 80% probably or a troll with 20%.
if goro.Random.Intn(100) < 80 {
monster = entity.NewEntity(x, y, 'o', goro.Style{Foreground: goro.ColorLime}, "Orc", entity.BlockMovement)
} else {
monster = entity.NewEntity(x, y, 'T', goro.Style{Foreground: goro.ColorGreen}, "Troll", entity.BlockMovement)
}
*entities = append(*entities, monster)
}
}
}
// 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) {