All checks were successful
Dynamic Branch Deploy / build-and-deploy (push) Successful in 6m49s
185 lines
7.4 KiB
Go
185 lines
7.4 KiB
Go
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
|
||
DoubleJumpUsed bool `json:"double_jump_used"` // Wurde zweiter Sprung schon benutzt?
|
||
DoubleJumpRemainingSeconds float64 `json:"double_jump_remaining_seconds"` // Verbleibende Double-Jump-Zeit in Sekunden
|
||
HasGodMode bool `json:"has_godmode"` // Hat Godmode Powerup
|
||
GodModeRemainingSeconds float64 `json:"godmode_remaining_seconds"` // Verbleibende Godmode-Zeit in Sekunden
|
||
HasMagnet bool `json:"has_magnet"` // Hat Magnet Powerup
|
||
MagnetRemainingSeconds float64 `json:"magnet_remaining_seconds"` // Verbleibende Magnet-Zeit in Sekunden
|
||
}
|
||
|
||
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"`
|
||
}
|