Files
Bjorn Blomberg ede03ad026 Update tileset and settings, enhance logging
- Updated tileset configuration in 'tileset.tsj' to include new tiles and adjust dimensions.
- Added 'settings.json' for key bindings related to climbing and movement actions.
- Enhanced game logging in 'game.log' to track game start events and map loading.
- Updated the game binary to the latest version.
2026-04-26 15:59:44 +02:00

215 lines
4.7 KiB
Go

package input
import (
"encoding/json"
"log"
"os"
"path/filepath"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/inpututil"
)
type Binding [][]ebiten.Key
const settingsFile = "assets/settings.json"
type InputManager struct {
Actions map[string]Binding
recordingAction string
recordingKeys []ebiten.Key
isRecording bool
}
var Manager *InputManager
func init() {
Manager = NewInputManager()
Manager.LoadSettings()
}
func NewInputManager() *InputManager {
return &InputManager{
Actions: make(map[string]Binding),
recordingKeys: make([]ebiten.Key, 0),
}
}
func (im *InputManager) LoadDefaultSettings() {
im.Actions = map[string]Binding{
"Run": {{ebiten.KeyControl}},
"ClimbMode": {{ebiten.KeyShift}},
"MoveLeft": {{ebiten.KeyA}, {ebiten.KeyLeft}},
"MoveRight": {{ebiten.KeyD}, {ebiten.KeyRight}},
"MoveUp": {{ebiten.KeyW}, {ebiten.KeyUp}},
"MoveDown": {{ebiten.KeyS}, {ebiten.KeyDown}},
"Jump": {{ebiten.KeySpace}},
"ClimbLeft": {{ebiten.KeyA}, {ebiten.KeyLeft}},
"ClimbRight": {{ebiten.KeyD}, {ebiten.KeyRight}},
"ClimbUp": {{ebiten.KeyW}},
"ClimbDown": {{ebiten.KeyS}},
"ClimbIn": {{ebiten.KeyUp}},
"ClimbOut": {{ebiten.KeyDown}},
}
}
func (im *InputManager) LoadSettings() {
im.LoadDefaultSettings() // Load defaults first
data, err := os.ReadFile(settingsFile)
if err != nil {
if os.IsNotExist(err) {
im.SaveSettings() // Create the file if it doesn't exist
} else {
log.Println("Error reading settings.json:", err)
}
return
}
var loadedActions map[string]Binding
if err := json.Unmarshal(data, &loadedActions); err != nil {
log.Println("Error unmarshaling settings.json:", err)
return
}
// Overwrite defaults with loaded ones
for k, v := range loadedActions {
im.Actions[k] = v
}
}
func (im *InputManager) SaveSettings() {
// Ensure directory exists
if err := os.MkdirAll(filepath.Dir(settingsFile), 0755); err != nil {
log.Println("Failed to create settings directory:", err)
return
}
data, err := json.MarshalIndent(im.Actions, "", " ")
if err != nil {
log.Println("Error marshaling settings:", err)
return
}
if err := os.WriteFile(settingsFile, data, 0644); err != nil {
log.Println("Error writing settings.json:", err)
}
}
func (im *InputManager) IsActionPressed(action string) bool {
bindings, ok := im.Actions[action]
if !ok {
return false
}
for _, combination := range bindings {
allPressed := true
for _, key := range combination {
if !ebiten.IsKeyPressed(key) {
allPressed = false
break
}
}
// Om alla tangenter i kombinationen är nedtryckta så triggas handlingen
if len(combination) > 0 && allPressed {
return true
}
}
return false
}
func (im *InputManager) IsActionJustPressed(action string) bool {
bindings, ok := im.Actions[action]
if !ok {
return false
}
for _, combination := range bindings {
allPressed := true
justPressedCount := 0
for _, key := range combination {
if !ebiten.IsKeyPressed(key) {
allPressed = false
break
}
if inpututil.IsKeyJustPressed(key) {
justPressedCount++
}
}
if len(combination) > 0 && allPressed && justPressedCount > 0 {
return true
}
}
return false
}
func (im *InputManager) StartRecording(action string) {
im.recordingAction = action
im.recordingKeys = []ebiten.Key{}
im.isRecording = true
}
// UpdateRecording called every frame while in settings to record inputs.
// Returns true when recording finished.
func (im *InputManager) UpdateRecording() bool {
if !im.isRecording {
return false
}
// Avbryt med ESC
if inpututil.IsKeyJustPressed(ebiten.KeyEscape) {
im.StopRecording()
return true
}
// Spara med Enter
if inpututil.IsKeyJustPressed(ebiten.KeyEnter) {
if len(im.recordingKeys) > 0 {
im.Actions[im.recordingAction] = Binding{im.recordingKeys}
im.SaveSettings()
}
im.isRecording = false
return true
}
pressedKeys := make([]ebiten.Key, 0)
for k := ebiten.KeyA; k <= ebiten.KeyMax; k++ {
if ebiten.IsKeyPressed(k) {
// Ignorera Escape och Enter från att bindas
if k == ebiten.KeyEscape || k == ebiten.KeyEnter {
continue
}
pressedKeys = append(pressedKeys, k)
}
}
// Limit to max 2 keys
if len(pressedKeys) > 2 {
pressedKeys = pressedKeys[:2]
}
// Uppdatera de lagrade tangenterna att visa i UI
if len(pressedKeys) > 0 {
im.recordingKeys = pressedKeys
}
return false
}
func (im *InputManager) StopRecording() {
im.isRecording = false
}
func (im *InputManager) IsRecording() bool {
return im.isRecording
}
func (im *InputManager) GetRecordingAction() string {
return im.recordingAction
}
func (im *InputManager) GetRecordingKeys() []ebiten.Key {
return im.recordingKeys
}