progress in part 5, but unresolved problems with flags
This commit is contained in:
parent
696ccd216e
commit
733ffe3380
|
@ -6,20 +6,23 @@ import (
|
||||||
"github.com/kettek/goro"
|
"github.com/kettek/goro"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 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
|
||||||
|
name string
|
||||||
|
flags uint
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEntity returns a pointer to a newly created Entity.
|
// NewEntity returns an interface to a new populated Entity.
|
||||||
func NewEntity(x int, y int, r rune, s goro.Style) interfaces.Entity {
|
func NewEntity(x int, y int, r rune, style goro.Style, name string, flags Flags) interfaces.Entity {
|
||||||
return &Entity{
|
return &Entity{
|
||||||
x: x,
|
x: x,
|
||||||
y: y,
|
y: y,
|
||||||
rune: r,
|
rune: r,
|
||||||
style: s,
|
style: style,
|
||||||
|
name: name,
|
||||||
|
flags: flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +37,7 @@ func (e *Entity) X() int {
|
||||||
return e.x
|
return e.x
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetX sets the entity's X value
|
// SetX sets the entity's x value
|
||||||
func (e *Entity) SetX(x int) {
|
func (e *Entity) SetX(x int) {
|
||||||
e.x = x
|
e.x = x
|
||||||
}
|
}
|
||||||
|
@ -65,6 +68,36 @@ func (e *Entity) Style() goro.Style {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetStyle sets the entity's style.
|
// SetStyle sets the entity's style.
|
||||||
func (e *Entity) SetStyle(s goro.Style) {
|
func (e *Entity) SetStyle(style goro.Style) {
|
||||||
e.style = s
|
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
6
entity/flags.go
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
package entity
|
||||||
|
|
||||||
|
// Our entity flags.
|
||||||
|
const (
|
||||||
|
BlockMovement uint = 1 << iota
|
||||||
|
)
|
10
gamestate.go
Normal file
10
gamestate.go
Normal 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
38
main.go
|
@ -27,6 +27,8 @@ func main() {
|
||||||
// Our initial variables.
|
// Our initial variables.
|
||||||
mapWidth, mapHeight := 80, 40
|
mapWidth, mapHeight := 80, 40
|
||||||
maxRooms, roomMinSize, roomMaxSize := 30, 6, 10
|
maxRooms, roomMinSize, roomMaxSize := 30, 6, 10
|
||||||
|
maxMonstersPerRoom := 3
|
||||||
|
gameState := PlayerTurnState
|
||||||
|
|
||||||
fovRadius := 10
|
fovRadius := 10
|
||||||
fovRecompute := true
|
fovRecompute := true
|
||||||
|
@ -38,17 +40,15 @@ func main() {
|
||||||
"lightGround": goro.Color{R: 150, G: 150, B: 150, A: 255},
|
"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})
|
player := entity.NewEntity(0, 0, '@', goro.Style{Foreground: goro.ColorWhite}, "Player", entity.BlockMovement)
|
||||||
npc := entity.NewEntity(screen.Columns/2-5, screen.Rows/2, '@', goro.Style{Foreground: goro.ColorYellow})
|
|
||||||
|
|
||||||
entities := []interfaces.Entity{
|
entities := []interfaces.Entity{
|
||||||
player,
|
player,
|
||||||
npc,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gameMap := mapping.NewGameMap(mapWidth, mapHeight)
|
gameMap := mapping.NewGameMap(mapWidth, mapHeight)
|
||||||
|
|
||||||
gameMap.MakeMap(maxRooms, roomMinSize, roomMaxSize, player)
|
gameMap.MakeMap(maxRooms, roomMinSize, roomMaxSize, &entities, maxMonstersPerRoom)
|
||||||
|
|
||||||
fovMap := InitializeFoV(gameMap)
|
fovMap := InitializeFoV(gameMap)
|
||||||
|
|
||||||
|
@ -70,16 +70,36 @@ 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 gameState == PlayerTurnState {
|
||||||
player.Move(action.X, action.Y)
|
x := player.X() + action.X
|
||||||
fovRecompute = true
|
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:
|
gameState = NPCTurnState
|
||||||
goro.Quit()
|
|
||||||
}
|
}
|
||||||
|
case ActionQuit:
|
||||||
|
goro.Quit()
|
||||||
|
}
|
||||||
case goro.EventQuit:
|
case goro.EventQuit:
|
||||||
return
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package mapping
|
package mapping
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/kettek/goro"
|
"steel/entity"
|
||||||
|
|
||||||
"steel/interfaces"
|
"steel/interfaces"
|
||||||
|
|
||||||
|
"github.com/kettek/goro"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GameMap is our map type for holding our tiles and dimensions.
|
// 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.
|
// 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
|
var rooms []Rect
|
||||||
|
|
||||||
for r := 0; r < maxRooms; r++ {
|
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.
|
// Always place the player in the center of the first room.
|
||||||
if len(rooms) == 0 {
|
if len(rooms) == 0 {
|
||||||
player.SetX(roomCenterX)
|
(*entities)[0].SetX(roomCenterX)
|
||||||
player.SetY(roomCenterY)
|
(*entities)[0].SetY(roomCenterY)
|
||||||
} else {
|
} else {
|
||||||
prevCenterX, prevCenterY := rooms[len(rooms)-1].Center()
|
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)
|
g.CreateHTunnel(prevCenterX, roomCenterX, roomCenterY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Place random monsters in the room.
|
||||||
|
g.PlaceEntities(room, entities, maxMonsters)
|
||||||
|
|
||||||
// Append our new room to our rooms list.
|
// Append our new room to our rooms list.
|
||||||
rooms = append(rooms, room)
|
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.
|
// Explored returns if the tile at x by y has been explored.
|
||||||
func (g *GameMap) Explored(x, y int) bool {
|
func (g *GameMap) Explored(x, y int) bool {
|
||||||
if g.InBounds(x, y) {
|
if g.InBounds(x, y) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user