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"
|
||||
)
|
||||
|
||||
// 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
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.
|
||||
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
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user