- 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.
215 lines
4.7 KiB
Go
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
|
|
}
|