package game import "image/color" type Vec2 struct { X, Y float64 `json:"x,y"` } type Rect struct { OffsetX, OffsetY, W, H float64 Type string } // Type hinzugefügt aus letztem Schritt type HexColor struct { R, G, B, A uint8 `json:"r,g,b,a"` } func (h HexColor) ToRGBA() color.RGBA { if h.A == 0 { return color.RGBA{h.R, h.G, h.B, 255} } return color.RGBA{h.R, h.G, h.B, h.A} } // --- ASSETS & CHUNKS (Bleiben gleich) --- type AssetDefinition struct { ID, Type, Filename string Scale, ProcWidth, ProcHeight, DrawOffX, DrawOffY float64 Color HexColor Hitbox Rect } type AssetManifest struct { Assets map[string]AssetDefinition `json:"assets"` } type LevelObject struct { AssetID string X, Y float64 // Für bewegende Plattformen MovingPlatform *MovingPlatformData `json:"moving_platform,omitempty"` } type MovingPlatformData struct { StartX float64 `json:"start_x"` // Start-Position X (relativ zum Chunk) StartY float64 `json:"start_y"` // Start-Position Y EndX float64 `json:"end_x"` // End-Position X EndY float64 `json:"end_y"` // End-Position Y Speed float64 `json:"speed"` // Geschwindigkeit (Einheiten pro Sekunde) } type Chunk struct { ID string Width int Objects []LevelObject } type ActiveChunk struct { ChunkID string X float64 } // --- NETZWERK & GAMEPLAY --- // Login Request (Client -> Server beim Verbinden) type LoginPayload struct { Action string `json:"action"` // "CREATE" oder "JOIN" RoomID string `json:"room_id"` // Leer bei CREATE, Code bei JOIN Name string `json:"name"` // Spielername } // Input vom Spieler während des Spiels type ClientInput struct { Type string `json:"type"` // "STATE", "START", "SET_TEAM_NAME", etc. RoomID string `json:"room_id"` PlayerID string `json:"player_id"` Sequence uint32 `json:"sequence"` // Sequenznummer für Client Prediction TeamName string `json:"team_name,omitempty"` // Für SET_TEAM_NAME Input // Vollständiger Input-State (für TYPE="STATE") // Sendet den kompletten Zustand in einer Nachricht, verhindert stuck-Inputs durch Paketverlust InputLeft bool `json:"input_left,omitempty"` InputRight bool `json:"input_right,omitempty"` InputJump bool `json:"input_jump,omitempty"` InputDown bool `json:"input_down,omitempty"` InputJoyX float64 `json:"input_joy_x,omitempty"` } type JoinRequest struct { Name string `json:"name"` RoomID string `json:"room_id"` GameMode string `json:"game_mode"` // "solo" oder "coop" IsHost bool `json:"is_host"` TeamName string `json:"team_name"` PlayerCode string `json:"player_code"` // PlayerCode für Score-Tracking } type PlayerState struct { ID string `json:"id"` Name string `json:"name"` X float64 `json:"x"` Y float64 `json:"y"` VX float64 `json:"vx"` VY float64 `json:"vy"` State string `json:"state"` OnGround bool `json:"on_ground"` OnWall bool `json:"on_wall"` // Ist an einer Wand LastInputSeq uint32 `json:"last_input_seq"` // Letzte verarbeitete Input-Sequenz Score int `json:"score"` // Punkte des Spielers IsAlive bool `json:"is_alive"` // Lebt der Spieler noch? IsSpectator bool `json:"is_spectator"` // Ist im Zuschauer-Modus HasDoubleJump bool `json:"has_double_jump"` // Hat Double Jump Powerup HasGodMode bool `json:"has_godmode"` // Hat Godmode Powerup } type GameState struct { RoomID string `json:"room_id"` Players map[string]PlayerState `json:"players"` Status string `json:"status"` TimeLeft int `json:"time_left"` WorldChunks []ActiveChunk `json:"world_chunks"` HostID string `json:"host_id"` HostPlayerCode string `json:"host_player_code"` // PlayerCode des Hosts (für Coop-Score) TeamName string `json:"team_name"` // Team-Name (vom Host gesetzt) ScrollX float64 `json:"scroll_x"` CollectedCoins map[string]bool `json:"collected_coins"` // Welche Coins wurden eingesammelt (Key: ChunkID_ObjectIndex) CollectedPowerups map[string]bool `json:"collected_powerups"` // Welche Powerups wurden eingesammelt MovingPlatforms []MovingPlatformSync `json:"moving_platforms"` // Bewegende Plattformen Sequence uint32 `json:"sequence"` // Sequenznummer für Out-of-Order-Erkennung CurrentSpeed float64 `json:"current_speed"` // Aktuelle Scroll-Geschwindigkeit (für Client-Prediction) DifficultyFactor float64 `json:"difficulty_factor"` // 0.0 (Anfang) bis 1.0 (Maximum) – skaliert Gravitation & Air-Control } // MovingPlatformSync: Synchronisiert die Position einer bewegenden Plattform type MovingPlatformSync struct { ChunkID string `json:"chunk_id"` ObjectIdx int `json:"object_idx"` AssetID string `json:"asset_id"` X float64 `json:"x"` Y float64 `json:"y"` } // Leaderboard-Eintrag type LeaderboardEntry struct { PlayerName string `json:"player_name"` PlayerCode string `json:"player_code"` // Eindeutiger Code für Verifikation Score int `json:"score"` Timestamp int64 `json:"timestamp"` // Unix-Timestamp ProofCode string `json:"proof_code"` // Beweis-Code zum Verifizieren des Scores } // Score-Submission vom Client an Server type ScoreSubmission struct { PlayerName string `json:"player_name"` PlayerCode string `json:"player_code"` Score int `json:"score"` Name string `json:"name"` // Alternativer Name-Feld (für Kompatibilität) Mode string `json:"mode"` // "solo" oder "coop" TeamName string `json:"team_name"` // Team-Name für Coop-Mode } // Score-Submission Response vom Server an Client type ScoreSubmissionResponse struct { Success bool `json:"success"` ProofCode string `json:"proof_code"` Score int `json:"score"` } // Start-Request vom Client type StartRequest struct { RoomID string `json:"room_id"` PlayerID string `json:"player_id"` // Wer startet das Spiel } // Leaderboard-Request vom Client type LeaderboardRequest struct { Mode string `json:"mode"` // "solo" oder "coop" ResponseChannel string `json:"response_channel"` } // Leaderboard-Response vom Server type LeaderboardResponse struct { Entries []LeaderboardEntry `json:"entries"` }