Better commenting throughout

This commit is contained in:
2025-11-24 12:29:19 -07:00
parent 175479da69
commit 5e0413a259
14 changed files with 107 additions and 195 deletions

View File

@@ -17,6 +17,7 @@ import (
"github.com/atridad/LilGuy/internal/world"
)
// Screen and hero defaults
var (
backgroundColor = color.NRGBA{R: 135, G: 206, B: 235, A: 255}
saveNotificationColor = color.NRGBA{R: 50, G: 200, B: 50, A: 255}
@@ -38,13 +39,12 @@ var (
heroColor = color.NRGBA{R: 210, G: 220, B: 255, A: 255}
)
// HUD settings.
// HUD positioning and colors
const (
hudX = 960 - 220 // ScreenWidth - 220
hudX = 960 - 220
hudY = 20
)
// HUD colors.
var (
staminaNormalColor = color.NRGBA{R: 0, G: 255, B: 180, A: 255}
staminaLowColor = color.NRGBA{R: 255, G: 60, B: 60, A: 255}
@@ -53,6 +53,7 @@ var (
fpsPoorColor = color.NRGBA{R: 255, G: 120, B: 120, A: 255}
)
// FPS monitoring thresholds
const (
staminaLowThreshold = 0.2
fpsWarnThreshold = 0.85
@@ -61,7 +62,6 @@ const (
targetTPS = 60
)
// Player input for the gameplay screen.
type GameplayInput struct {
Left bool
Right bool
@@ -70,8 +70,6 @@ type GameplayInput struct {
Shoot bool
}
// Manages the main gameplay state including the hero, HUD, and game world.
// This is where the actual game logic and rendering happens during active play.
type GameplayScreen struct {
hero *hero.Hero
hud hud.Overlay
@@ -90,7 +88,6 @@ type GameplayScreen struct {
showSaveNotification bool
}
// Creates a new gameplay screen instance.
func NewGameplayScreen(screenWidth, screenHeight int, fpsEnabled *bool) *GameplayScreen {
w := world.NewWorld()
@@ -133,7 +130,6 @@ func NewGameplayScreen(screenWidth, screenHeight int, fpsEnabled *bool) *Gamepla
}
}
// Processes gameplay logic with the given input and delta time.
func (g *GameplayScreen) Update(input GameplayInput, delta time.Duration) {
dt := delta.Seconds()
@@ -166,7 +162,7 @@ func (g *GameplayScreen) Update(input GameplayInput, delta time.Duration) {
}
}
// Calculates the current FPS if FPS monitoring is enabled.
// FPS tracking
func (g *GameplayScreen) trackFPS(delta time.Duration) {
if g.fpsEnabled == nil || !*g.fpsEnabled {
return
@@ -182,7 +178,7 @@ func (g *GameplayScreen) trackFPS(delta time.Duration) {
}
}
// Renders the gameplay screen.
// Rendering
func (g *GameplayScreen) Draw(screen *ebiten.Image) {
screen.Fill(backgroundColor)
@@ -205,7 +201,6 @@ func (g *GameplayScreen) Draw(screen *ebiten.Image) {
meters := []status.Meter{staminaMeter}
if g.fpsEnabled != nil && *g.fpsEnabled {
// Color based on target FPS (60).
ratio := g.fpsValue / float64(targetTPS)
fpsColor := fpsGoodColor
switch {
@@ -217,7 +212,7 @@ func (g *GameplayScreen) Draw(screen *ebiten.Image) {
fpsMeter := status.Meter{
Label: fmt.Sprintf("Framerate: %3.0f FPS", g.fpsValue),
Base: -1, // Negative base means text-only display.
Base: -1,
Level: 0,
Color: fpsColor,
}
@@ -266,7 +261,7 @@ func (g *GameplayScreen) ShowSaveNotification() {
g.saveNotificationTimer = saveNotificationDuration
}
// Resets the gameplay screen to its initial state.
// State management
func (g *GameplayScreen) Reset() {
screenWidth := int(g.bounds.Width)
screenHeight := int(g.bounds.Height)
@@ -307,7 +302,6 @@ func (g *GameplayScreen) Reset() {
g.fpsValue = 0
}
// SaveState converts the current gameplay state to a saveable format.
func (g *GameplayScreen) SaveState() *save.GameState {
return &save.GameState{
HeroX: g.hero.X,
@@ -317,7 +311,6 @@ func (g *GameplayScreen) SaveState() *save.GameState {
}
}
// LoadState restores gameplay state from saved data.
func (g *GameplayScreen) LoadState(state *save.GameState) {
screenWidth := int(g.bounds.Width)
screenHeight := int(g.bounds.Height)

View File

@@ -8,39 +8,32 @@ import (
"github.com/hajimehoshi/ebiten/v2/text/v2"
)
// An interface for managing FPS cap settings.
// Settings interface
type FPSCapSetting interface {
String() string
Cycle()
}
// Displays and manages game settings like FPS monitor and FPS cap.
// This screen can be accessed from both the title screen and pause menu.
type SettingsScreen struct {
selectedIndex int
fpsMonitorValue *bool
fpsCapValue FPSCapSetting
}
// Creates a new settings screen instance.
func NewSettingsScreen() *SettingsScreen {
return &SettingsScreen{
selectedIndex: 0,
}
}
// Sets the FPS monitor toggle reference.
func (s *SettingsScreen) SetFPSMonitor(enabled *bool) {
s.fpsMonitorValue = enabled
}
// Sets the FPS cap setting reference.
func (s *SettingsScreen) SetFPSCap(cap FPSCapSetting) {
s.fpsCapValue = cap
}
// Processes settings screen input.
// Returns true if the user wants to go back.
func (s *SettingsScreen) Update() bool {
if inpututil.IsKeyJustPressed(ebiten.KeyEscape) {
return true
@@ -71,20 +64,19 @@ func (s *SettingsScreen) Update() bool {
return false
}
// Renders the settings screen.
// Rendering
func (s *SettingsScreen) Draw(screen *ebiten.Image, screenWidth, screenHeight int, title string) {
// Draw background
screen.Fill(color.RGBA{R: 20, G: 20, B: 30, A: 255})
// Draw title
titleX := (screenWidth / 2) - (len(title) * 7 / 2)
titleY := screenHeight/3 - 50
s.drawText(screen, title, color.White, titleX, titleY)
// Draw settings options
startY := screenHeight/2 - 20
leftMargin := screenWidth/2 - 120
// FPS monitor toggle
fpsMonitorText := "FPS Monitor: "
if s.fpsMonitorValue != nil && *s.fpsMonitorValue {
fpsMonitorText += "ON"
@@ -100,6 +92,7 @@ func (s *SettingsScreen) Draw(screen *ebiten.Image, screenWidth, screenHeight in
s.drawText(screen, fpsMonitorText, color.RGBA{R: 180, G: 180, B: 200, A: 255}, leftMargin, startY)
}
// FPS cap setting
fpsCapText := "FPS Cap: "
if s.fpsCapValue != nil {
fpsCapText += s.fpsCapValue.String()
@@ -116,7 +109,7 @@ func (s *SettingsScreen) Draw(screen *ebiten.Image, screenWidth, screenHeight in
s.drawText(screen, fpsCapText, color.RGBA{R: 180, G: 180, B: 200, A: 255}, leftMargin, capY)
}
// Draw hint text
// Instructions
hintText := "Enter/Space to toggle, ESC to go back"
hintX := (screenWidth / 2) - (len(hintText) * 7 / 2)
hintY := screenHeight - 50
@@ -130,7 +123,6 @@ func (s *SettingsScreen) drawText(screen *ebiten.Image, txt string, clr color.Co
text.Draw(screen, txt, basicFace, op)
}
// Resets the settings screen to its initial state.
func (s *SettingsScreen) Reset() {
s.selectedIndex = 0
}

View File

@@ -15,14 +15,14 @@ var (
basicFaceAscent = basicFace.Metrics().HAscent
)
// Timing
const (
splashDuration = 2 * time.Second
fadeInDuration = 500 * time.Millisecond
fadeOutDuration = 500 * time.Millisecond
)
// Displays the game title with fade in/out effects.
// This is typically the first screen shown when the game starts.
type SplashScreen struct {
startTime time.Time
fadeInEnd time.Time
@@ -30,7 +30,6 @@ type SplashScreen struct {
endTime time.Time
}
// Creates a new splash screen instance.
func NewSplashScreen() *SplashScreen {
now := time.Now()
return &SplashScreen{
@@ -41,15 +40,11 @@ func NewSplashScreen() *SplashScreen {
}
}
// Processes splash screen logic.
// Returns true when the splash screen should end and transition to the next screen.
func (s *SplashScreen) Update() bool {
// Return true if splash is complete
if time.Now().After(s.endTime) {
return true
}
// Allow skipping with any key
if inpututil.IsKeyJustPressed(ebiten.KeySpace) ||
inpututil.IsKeyJustPressed(ebiten.KeyEnter) ||
inpututil.IsKeyJustPressed(ebiten.KeyEscape) {
@@ -59,14 +54,14 @@ func (s *SplashScreen) Update() bool {
return false
}
// Renders the splash screen.
// Rendering
func (s *SplashScreen) Draw(screen *ebiten.Image, screenWidth, screenHeight int) {
screen.Fill(color.RGBA{R: 0, G: 0, B: 0, A: 255})
now := time.Now()
alpha := 1.0
// Calculate fade in/out
if now.Before(s.fadeInEnd) {
elapsed := now.Sub(s.startTime)
alpha = float64(elapsed) / float64(fadeInDuration)
@@ -81,10 +76,9 @@ func (s *SplashScreen) Draw(screen *ebiten.Image, screenWidth, screenHeight int)
alpha = 1
}
// Draw large game title
// Draw title
titleText := "LIL GUY"
// Calculate size for large text (scale up the basic font)
scale := 4.0
charWidth := 7.0 * scale
textWidth := float64(len(titleText)) * charWidth

View File

@@ -9,7 +9,7 @@ import (
"github.com/hajimehoshi/ebiten/v2/vector"
)
// Represents the options available on the title screen.
// Menu options
type TitleMenuOption int
const (
@@ -20,6 +20,7 @@ const (
titleOptionCount
)
// Screen modes
type titleScreenMode int
const (
@@ -27,8 +28,6 @@ const (
titleModeSettings
)
// Displays the main menu with Continue, New Game, Settings, and Quit options.
// This is shown after the splash screen and when returning from the pause menu.
type TitleScreen struct {
selectedIndex int
currentMode titleScreenMode
@@ -36,7 +35,6 @@ type TitleScreen struct {
hasSaveGame bool
}
// Creates a new title screen instance.
func NewTitleScreen() *TitleScreen {
return &TitleScreen{
selectedIndex: 0,
@@ -46,28 +44,22 @@ func NewTitleScreen() *TitleScreen {
}
}
// Sets the FPS monitor toggle reference for settings.
func (t *TitleScreen) SetFPSMonitor(enabled *bool) {
t.settingsScreen.SetFPSMonitor(enabled)
}
// Sets the FPS cap setting reference for settings.
func (t *TitleScreen) SetFPSCap(cap FPSCapSetting) {
t.settingsScreen.SetFPSCap(cap)
}
// Sets whether a saved game exists.
func (t *TitleScreen) SetHasSaveGame(hasSave bool) {
t.hasSaveGame = hasSave
// If no save game, skip Continue option
if !hasSave && t.selectedIndex == 0 {
t.selectedIndex = 1 // Move to New Game
t.selectedIndex = 1
}
}
// Processes title screen input and returns the selected option if any.
func (t *TitleScreen) Update() *TitleMenuOption {
// Handle settings screen
if t.currentMode == titleModeSettings {
if t.settingsScreen.Update() {
t.currentMode = titleModeMain
@@ -76,13 +68,11 @@ func (t *TitleScreen) Update() *TitleMenuOption {
return nil
}
// Handle main menu
if inpututil.IsKeyJustPressed(ebiten.KeyArrowUp) || inpututil.IsKeyJustPressed(ebiten.KeyW) {
t.selectedIndex--
if t.selectedIndex < 0 {
t.selectedIndex = int(titleOptionCount) - 1
}
// Skip Continue if no save exists
if t.selectedIndex == int(TitleOptionContinue) && !t.hasSaveGame {
t.selectedIndex--
if t.selectedIndex < 0 {
@@ -96,7 +86,6 @@ func (t *TitleScreen) Update() *TitleMenuOption {
if t.selectedIndex >= int(titleOptionCount) {
t.selectedIndex = 0
}
// Skip Continue if no save exists
if t.selectedIndex == int(TitleOptionContinue) && !t.hasSaveGame {
t.selectedIndex++
if t.selectedIndex >= int(titleOptionCount) {
@@ -118,18 +107,15 @@ func (t *TitleScreen) Update() *TitleMenuOption {
return nil
}
// Renders the title screen.
// Rendering
func (t *TitleScreen) Draw(screen *ebiten.Image, screenWidth, screenHeight int) {
// If in settings mode, draw settings screen
if t.currentMode == titleModeSettings {
t.settingsScreen.Draw(screen, screenWidth, screenHeight, "SETTINGS")
return
}
// Draw main menu
screen.Fill(color.RGBA{R: 20, G: 20, B: 30, A: 255})
// Draw game title
titleText := "LIL GUY"
scale := 3.0
charWidth := 7.0 * scale
@@ -144,12 +130,11 @@ func (t *TitleScreen) Draw(screen *ebiten.Image, screenWidth, screenHeight int)
op.ColorScale.ScaleWithColor(color.RGBA{R: 210, G: 220, B: 255, A: 255})
text.Draw(screen, titleText, basicFace, op)
// Draw menu options
// Draw menu
options := []string{"Continue", "New Game", "Settings", "Quit"}
startY := screenHeight/2 + 10
for i, option := range options {
// Skip Continue option if no save exists
if i == int(TitleOptionContinue) && !t.hasSaveGame {
continue
}
@@ -163,12 +148,10 @@ func (t *TitleScreen) Draw(screen *ebiten.Image, screenWidth, screenHeight int)
}
if i == t.selectedIndex {
// Draw selection indicator
indicatorX := optionX - 20
t.drawText(screen, ">", color.RGBA{R: 255, G: 200, B: 0, A: 255}, indicatorX, optionY)
t.drawText(screen, option, color.RGBA{R: 255, G: 255, B: 100, A: 255}, optionX, optionY)
// Draw selection box
boxPadding := float32(10.0)
boxWidth := float32(len(option)*7) + boxPadding*2
boxHeight := float32(20)
@@ -182,7 +165,7 @@ func (t *TitleScreen) Draw(screen *ebiten.Image, screenWidth, screenHeight int)
}
}
// Draw hint text
// Instructions
hintText := "Use Arrow Keys/WASD to navigate, Enter/Space to select"
hintX := (screenWidth / 2) - (len(hintText) * 7 / 2)
hintY := screenHeight - 50
@@ -196,9 +179,7 @@ func (t *TitleScreen) drawText(screen *ebiten.Image, txt string, clr color.Color
text.Draw(screen, txt, basicFace, op)
}
// Resets the title screen to its initial state.
func (t *TitleScreen) Reset() {
// Start at Continue if available, otherwise New Game
if t.hasSaveGame {
t.selectedIndex = 0
} else {