~johanvandegriff/ruegolike

8cd12f13f12c02bd2b102b6bcc29052ee86c6f95 — Johan Vandegriff 11 months ago f2dd2fa master
level 2 complete (message system)
3 files changed, 143 insertions(+), 66 deletions(-)

M display.go
M main.go
A messages.go
M display.go => display.go +6 -9
@@ 310,10 310,7 @@ func Display(s tcell.Screen, playerPos Position, visible *[height][width]bool, e
	playerX := playerPos.x
	playerY := playerPos.y

	style1 := tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.ColorBlack)
	style2 := tcell.StyleDefault.Foreground(tcell.ColorDarkSlateGray).Background(tcell.ColorBlack)

	EmitStr(s, 0, 19, style1, fmt.Sprintf("coords:%02d,%02d,%02d", playerPos.x, playerPos.y, playerPos.z))
	EmitStr(s, 0, 19, StyleDefault, fmt.Sprintf("coords:%02d,%02d,%02d", playerPos.x, playerPos.y, playerPos.z))

	rangeLimit := -1
	shadowcast(playerX, playerY, rangeLimit, visible, explored1, level)


@@ 678,21 675,21 @@ func Display(s tcell.Screen, playerPos Position, visible *[height][width]bool, e
					char = '█'
				}
				if visible[y][x] {
					s.SetContent(x+offsetX, y+offsetY, char, nil, style1)
					s.SetContent(x+offsetX, y+offsetY, char, nil, StyleDefault)
				} else {
					s.SetContent(x+offsetX, y+offsetY, char, nil, style2)
					s.SetContent(x+offsetX, y+offsetY, char, nil, StyleNotVisible)
				}
			} else {
				if debug {
					s.SetContent(x+offsetX, y+offsetY, level.GetChar(Point{x, y}), nil, tcell.StyleDefault.Foreground(tcell.ColorDarkRed).Background(tcell.ColorBlack))
					s.SetContent(x+offsetX, y+offsetY, level.GetChar(Point{x, y}), nil, StyleDebug)
				} else {
					s.SetContent(x+offsetX, y+offsetY, ' ', nil, style2)
					s.SetContent(x+offsetX, y+offsetY, ' ', nil, StyleNotVisible)
				}
			}
		}
	}
	// s.SetContent(x, y, '@', nil, tcell.Style.Blink(style, true))
	s.SetContent(playerX+offsetX, playerY+offsetY, '@', nil, style1) //display the player
	s.SetContent(playerX+offsetX, playerY+offsetY, '@', nil, StyleDefault) //display the player
	s.ShowCursor(playerX+offsetX, playerY+offsetY)                   //highlight the player

	// s.SetContent(3, 7, tcell.RuneHLine, nil, style)

M main.go => main.go +80 -57
@@ 13,16 13,33 @@ const width, height, depth = 48, 16, 32
const offsetX, offsetY = 1, 2
const debug = false

//Screen - global reference to the text screen
var Screen tcell.Screen

//StyleDefault - the display colors for most items on screen
var StyleDefault tcell.Style

//StyleNotVisible - the display colors for things the player cannot currently see
var StyleNotVisible tcell.Style

//StyleDebug - the display colors for the unexplored portions, in debugging
var StyleDebug tcell.Style

//StyleInvert - the display colors for inverted text
var StyleInvert tcell.Style

func main() {
	rand.Seed(time.Now().UnixNano())

	// fmt.Println(NewLevel())

	dungeon, explored, playerPos := Generate()
	maxDepth := playerPos.z
	// time.Sleep(1 * time.Second)

	tcell.SetEncodingFallback(tcell.EncodingFallbackASCII)
	s, e := tcell.NewScreen()
	Screen = s
	// fmt.Println(s, e)
	if e != nil {
		fmt.Fprintf(os.Stderr, "%v\n", e)


@@ 35,13 52,13 @@ func main() {
		os.Exit(1)
	}

	style1 := tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.ColorBlack)
	// style2 := tcell.StyleDefault.Foreground(tcell.ColorDarkSlateGray).Background(tcell.ColorBlack)
	// style1 := tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.ColorRed)
	// style2 := tcell.StyleDefault.Foreground(tcell.ColorDarkGray).Background(tcell.ColorBlack)
	StyleDefault = tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.ColorBlack)
	StyleNotVisible = tcell.StyleDefault.Foreground(tcell.ColorDarkSlateGray).Background(tcell.ColorBlack)
	// StyleNotVisible = tcell.StyleDefault.Foreground(tcell.ColorDarkSlateBlue).Background(tcell.ColorBlack)
	// StyleNotVisible = tcell.StyleDefault.Foreground(tcell.ColorDarkGray).Background(tcell.ColorBlack)
	StyleDebug = tcell.StyleDefault.Foreground(tcell.ColorDarkRed).Background(tcell.ColorBlack)
	// style3 := tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.ColorDarkGray)

	// invert := tcell.StyleDefault.Foreground(tcell.ColorBlack).Background(tcell.ColorWhite)
	StyleInvert = tcell.StyleDefault.Foreground(tcell.ColorBlack).Background(tcell.ColorWhite)

	var visible [height][width]bool
	s.Clear()


@@ 56,59 73,65 @@ func main() {
				s.Fini()
				os.Exit(0)
			}
			EmitStr(s, 0, 0, style1, fmt.Sprintf("%c", ev.Rune()))
			EmitStr(s, 2, 0, style1, fmt.Sprintf("%s                   ", ev.Name()))
			processMoveEvent(ev.Name(), ev.Rune(), &playerPos, dungeon, s, style1)
		}
			if debug {
				EmitStr(s, 0, 1, StyleDefault, fmt.Sprintf("%c", ev.Rune()))
				EmitStr(s, 2, 1, StyleDefault, fmt.Sprintf("%s                   ", ev.Name()))
			}
			ClearMessage() // clear the messages when a key is pressed

		Display(s, playerPos, &visible, &explored[playerPos.z], dungeon.GetLevel(playerPos.z))
	}
}
			var deltaX, deltaY int
			if ev.Rune() == '1' || ev.Rune() == ';' {
				deltaX, deltaY = -1, 1
			} else if ev.Rune() == '2' || ev.Name() == "Down" {
				deltaX, deltaY = 0, 1
			} else if ev.Rune() == '3' || ev.Rune() == '\'' {
				deltaX, deltaY = 1, 1
			} else if ev.Rune() == '4' || ev.Name() == "Left" {
				deltaX, deltaY = -1, 0
			} else if ev.Rune() == '5' {
				// deltaX, deltaY = 0, 0 //TODO run
			} else if ev.Rune() == '6' || ev.Name() == "Right" {
				deltaX, deltaY = 1, 0
			} else if ev.Rune() == '7' || ev.Rune() == 'p' {
				deltaX, deltaY = -1, -1
			} else if ev.Rune() == '8' || ev.Name() == "Up" {
				deltaX, deltaY = 0, -1
			} else if ev.Rune() == '9' || ev.Rune() == '[' {
				deltaX, deltaY = 1, -1
			}
			if deltaX != 0 || deltaY != 0 {
				newPlayerX := playerPos.x + deltaX
				newPlayerY := playerPos.y + deltaY

func processMoveEvent(evName string, evRune rune, playerPos *Position, dungeon *Dungeon, s tcell.Screen, style1 tcell.Style) {
	var deltaX, deltaY int
	if evRune == '1' || evRune == ';' {
		deltaX, deltaY = -1, 1
	} else if evRune == '2' || evName == "Down" {
		deltaX, deltaY = 0, 1
	} else if evRune == '3' || evRune == '\'' {
		deltaX, deltaY = 1, 1
	} else if evRune == '4' || evName == "Left" {
		deltaX, deltaY = -1, 0
	} else if evRune == '5' {
		// deltaX, deltaY = 0, 0 //TODO run
	} else if evRune == '6' || evName == "Right" {
		deltaX, deltaY = 1, 0
	} else if evRune == '7' || evRune == 'p' {
		deltaX, deltaY = -1, -1
	} else if evRune == '8' || evName == "Up" {
		deltaX, deltaY = 0, -1
	} else if evRune == '9' || evRune == '[' {
		deltaX, deltaY = 1, -1
	}
	if deltaX != 0 || deltaY != 0 {
		newPlayerX := playerPos.x + deltaX
		newPlayerY := playerPos.y + deltaY

		if newPlayerX >= 0 && newPlayerX < width &&
			newPlayerY >= 0 && newPlayerY < height &&
			!dungeon.GetTile(Position{newPlayerX, newPlayerY, playerPos.z}).IsSolid() {
			playerPos.x = newPlayerX
			playerPos.y = newPlayerY
			EmitStr(s, 15, 0, style1, "    ")
		} else {
			EmitStr(s, 15, 0, style1, "oof!")
				if newPlayerX >= 0 && newPlayerX < width &&
					newPlayerY >= 0 && newPlayerY < height &&
					!dungeon.GetTile(Position{newPlayerX, newPlayerY, playerPos.z}).IsSolid() {
					playerPos.x = newPlayerX
					playerPos.y = newPlayerY
				} else {
					Message("OOF!! You ran into a wall.")
				}
			} else if playerPos.z < depth-1 && (ev.Rune() == '.' || ev.Rune() == '>') && (debug || dungeon.GetChar(playerPos) == '>') {
				playerPos.z++
				newPos := dungeon.GetLevel(playerPos.z).FindChar('<')
				playerPos.x = newPos.x
				playerPos.y = newPos.y
				Message("You walk down the stairs.")
				Display(s, playerPos, &visible, &explored[playerPos.z], dungeon.GetLevel(playerPos.z))
				if playerPos.z > maxDepth {
					maxDepth = playerPos.z
					Message("This level you have entered looks completely new to you! (temporary message to test the --more-- functionality)")
				}
			} else if playerPos.z > 0 && (ev.Rune() == '.' || ev.Rune() == '<') && (debug || dungeon.GetChar(playerPos) == '<') {
				playerPos.z--
				newPos := dungeon.GetLevel(playerPos.z).FindChar('>')
				playerPos.x = newPos.x
				playerPos.y = newPos.y
				Message("You walk up the stairs.")
			}
			//TODO fast travel command (or click mouse)
		}
	} else if playerPos.z < depth-1 && (evRune == '.' || evRune == '>') && (debug || dungeon.GetChar(*playerPos) == '>') {
		playerPos.z++
		newPos := dungeon.GetLevel(playerPos.z).FindChar('<')
		playerPos.x = newPos.x
		playerPos.y = newPos.y
	} else if playerPos.z > 0 && (evRune == '.' || evRune == '<') && (debug || dungeon.GetChar(*playerPos) == '<') {
		playerPos.z--
		newPos := dungeon.GetLevel(playerPos.z).FindChar('>')
		playerPos.x = newPos.x
		playerPos.y = newPos.y

		Display(s, playerPos, &visible, &explored[playerPos.z], dungeon.GetLevel(playerPos.z))
	}
	//TODO fast travel command (or click mouse)
}

A messages.go => messages.go +57 -0
@@ 0,0 1,57 @@
package main

import (
	"strings"

	"github.com/gdamore/tcell"
)

const more = "--more--"
const messageAndMoreWidth = 80 //width + 2
const messageWidth = messageAndMoreWidth - len(more) - 1

var x int = 0

//Message - display a message to the player at the top of the screen, managing messages that are too long with --more--
func Message(m string) {
	if len(m) > messageWidth {
		for i := 0; i < len(m); i += messageWidth {
			end := i + messageWidth
			if end > len(m) {
				end = len(m)
			}
			Message(m[i:end])
		}
		return
	}
	if x != 0 { //if not at beginning of line (so some text is showing)
		EmitStr(Screen, x+1, 0, StyleInvert, more)
		x += len(more)
		Screen.Show()
		WaitForSpace()
		ClearMessage()
	}
	EmitStr(Screen, x, 0, StyleDefault, m)
	Screen.Show()
	x += len(m)
}

//ClearMessage - clear the message part of the screen (such as when the player takes an action, or when the next message needs to be displayed)
func ClearMessage() {
	EmitStr(Screen, 0, 0, StyleDefault, strings.Repeat(" ", messageAndMoreWidth))
	Screen.Show()
	x = 0
}

//WaitForSpace - wait for the space key to be pressed
func WaitForSpace() {
	for {
		ev := Screen.PollEvent()
		switch ev := ev.(type) {
		case *tcell.EventKey:
			if ev.Rune() == ' ' {
				return
			}
		}
	}
}