Private
Public Access
1
0

fix game
Some checks failed
Dynamic Branch Deploy / build-and-deploy (push) Failing after 8m17s

This commit is contained in:
Sebastian Unterschütz
2026-03-21 20:32:53 +01:00
parent f7df54431c
commit 188e9c2cc2
6 changed files with 420 additions and 101 deletions

View File

@@ -39,27 +39,27 @@ func (g *Game) UpdateGame() {
// --- 4. INPUT STATE ERSTELLEN ---
joyDir := 0.0
if g.joyActive {
maxDist := g.joyRadius
if maxDist == 0 {
maxDist = 60.0 // Fallback
}
diffX := g.joyStickX - g.joyBaseX
maxDist := 60.0 // Muss mit handleTouchInput() übereinstimmen
// Analoger Wert zwischen -1.0 und 1.0
joyDir = diffX / maxDist
// Clamp zwischen -1 und 1
if joyDir < -1.0 {
joyDir = -1.0
}
if joyDir > 1.0 {
joyDir = 1.0
}
// Deadzone für bessere Kontrolle
// Deadzone
if joyDir > -0.15 && joyDir < 0.15 {
joyDir = 0
}
}
isJoyDown := g.joyActive && (g.joyStickY-g.joyBaseY) > 40
// Down: Joystick nach unten ziehen ODER Down-Button
isJoyDown := g.joyActive && (g.joyStickY-g.joyBaseY) > g.joyRadius*0.5
// Input State zusammenbauen
input := InputState{
@@ -67,10 +67,11 @@ func (g *Game) UpdateGame() {
Left: keyLeft || joyDir < -0.1,
Right: keyRight || joyDir > 0.1,
Jump: keyJump || g.btnJumpActive,
Down: keyDown || isJoyDown,
JoyX: joyDir, // Analoge X-Achse speichern
Down: keyDown || isJoyDown || g.btnDownActive,
JoyX: joyDir,
}
g.btnJumpActive = false
g.btnDownActive = false
// --- 4. INPUT SENDEN (MIT CLIENT PREDICTION) ---
if g.connected {
@@ -130,13 +131,32 @@ func (g *Game) UpdateGame() {
func (g *Game) handleTouchInput() {
touches := ebiten.TouchIDs()
// WICHTIG: Joystick-Base-Position wird jetzt beim Rendering gesetzt (DrawGame)
// um sicherzustellen dass die gleiche Canvas-Höhe verwendet wird!
// Wir verwenden hier nur die gecachte Position.
// Linke Hälfte = Joystick-Zone (55% der Breite, damit auf schmalen Screens etwas Platz bleibt)
halfW := float64(g.lastCanvasWidth) * 0.55
if halfW == 0 {
halfW = float64(ScreenWidth) * 0.55 // Fallback
}
// Reset, wenn keine Finger mehr auf dem Display sind
joyRadius := g.joyRadius
if joyRadius == 0 {
joyRadius = 60.0 // Fallback
}
// Vorab: alle gerade neu gedrückten Touch-IDs sammeln
justPressed := inpututil.JustPressedTouchIDs()
isJustPressed := func(id ebiten.TouchID) bool {
for _, j := range justPressed {
if id == j {
return true
}
}
return false
}
// Reset wenn alle Finger weg
if len(touches) == 0 {
g.joyActive = false
g.btnJumpPressed = false
g.joyStickX = g.joyBaseX
g.joyStickY = g.joyBaseY
return
@@ -148,55 +168,56 @@ func (g *Game) handleTouchInput() {
x, y := ebiten.TouchPosition(id)
fx, fy := float64(x), float64(y)
// 1. RECHTE SEITE: JUMP BUTTON
// Alles rechts der Bildschirmmitte ist "Springen"
if fx > ScreenWidth/2 {
// Prüfen, ob dieser Touch gerade NEU dazu gekommen ist
for _, justID := range inpututil.JustPressedTouchIDs() {
if id == justID {
g.btnJumpActive = true
break
if fx >= halfW {
// ── RECHTE SEITE: Jump und Down ──────────────────────────────────────
g.btnJumpPressed = true // visuelles Feedback solange Finger drauf
if isJustPressed(id) {
// Down-Button: Prüfen ob Finger in der Nähe des Down-Buttons
if g.downBtnR > 0 {
dx := fx - g.downBtnX
dy := fy - g.downBtnY
if dx*dx+dy*dy < g.downBtnR*g.downBtnR*1.5 {
g.btnDownActive = true
continue
}
}
// Sonst: Sprung
g.btnJumpActive = true
}
continue
}
// 2. LINKE SEITE: JOYSTICK
// Wenn wir noch keinen Joystick-Finger haben, prüfen wir, ob dieser Finger startet
// ── LINKE SEITE: Floating Joystick ───────────────────────────────────
// Floating = Basis springt zu der Stelle wo der Finger aufsetzt.
// Kein fester Ausgangspunkt nötig → komfortabler auf allen Screen-Größen.
if !g.joyActive {
// Prüfen ob Touch in der Nähe der Joystick-Basis ist (Radius 150 Toleranz)
dist := math.Sqrt(math.Pow(fx-g.joyBaseX, 2) + math.Pow(fy-g.joyBaseY, 2))
if dist < 150 {
g.joyActive = true
g.joyTouchID = id
}
g.joyActive = true
g.joyTouchID = id
g.joyBaseX = fx
g.joyBaseY = fy
g.joyStickX = fx
g.joyStickY = fy
}
// Wenn das der Joystick-Finger ist -> Stick bewegen
if g.joyActive && id == g.joyTouchID {
joyFound = true
// Vektor berechnen (Wie weit ziehen wir weg?)
dx := fx - g.joyBaseX
dy := fy - g.joyBaseY
dist := math.Sqrt(dx*dx + dy*dy)
maxDist := 60.0 // Maximaler Radius des Sticks
// Begrenzen auf Radius
if dist > maxDist {
scale := maxDist / dist
if dist > joyRadius {
scale := joyRadius / dist
dx *= scale
dy *= scale
}
g.joyStickX = g.joyBaseX + dx
g.joyStickY = g.joyBaseY + dy
}
}
// Wenn der Joystick-Finger losgelassen wurde, Joystick resetten
if !joyFound {
g.joyActive = false
g.btnJumpPressed = false
g.joyStickX = g.joyBaseX
g.joyStickY = g.joyBaseY
}
@@ -460,40 +481,74 @@ func (g *Game) DrawGame(screen *ebiten.Image) {
// 8. TOUCH CONTROLS OVERLAY (nur wenn Tastatur nicht benutzt wurde)
if !g.keyboardUsed {
canvasW, canvasH := screen.Size()
tcW, tcH := screen.Size()
// Cache Canvas-Höhe für Touch-Input (wird in UpdateGame/handleTouchInput verwendet)
g.lastCanvasHeight = canvasH
// Canvas-Größe cachen (für handleTouchInput im nächsten Frame)
g.lastCanvasHeight = tcH
g.lastCanvasWidth = tcW
// A) Joystick Base (unten links, über dem Boden positioniert)
// WICHTIG: Verwende die gleiche Berechnung wie in handleTouchInput()!
g.joyBaseX = 150.0
floorY := GetFloorYFromHeight(canvasH)
g.joyBaseY = floorY - 50.0 // 50px über dem Boden (sichtbar über der Erde)
floorY := GetFloorYFromHeight(tcH)
// Wenn Joystick nicht aktiv, Stick = Base
// Proportionale Größen: basiert auf der kleineren Screen-Dimension
refDim := math.Min(float64(tcW), float64(tcH))
joyR := refDim * 0.13 // Joystick-Außenring (13% der kleineren Dimension)
knobR := joyR * 0.48 // Knob ~halber Joystick-Radius
jumpR := refDim * 0.11 // Sprung-Button
downR := refDim * 0.08 // Down-Button (kleiner)
// Werte für Input-Verarbeitung cachen
g.joyRadius = joyR
// ── A) Floating Joystick ─────────────────────────────────────────────
// Wenn inaktiv: Basis an Default-Position (unten links) zeigen
if !g.joyActive {
g.joyBaseX = float64(tcW) * 0.18
g.joyBaseY = floorY - joyR - 12
g.joyStickX = g.joyBaseX
g.joyStickY = g.joyBaseY
}
baseCol := color.RGBA{80, 80, 80, 50}
vector.DrawFilledCircle(screen, float32(g.joyBaseX), float32(g.joyBaseY), 60, baseCol, false)
vector.StrokeCircle(screen, float32(g.joyBaseX), float32(g.joyBaseY), 60, 2, color.RGBA{100, 100, 100, 100}, false)
// B) Joystick Knob (relativ zu Base)
knobCol := color.RGBA{100, 100, 100, 80}
// Joystick-Ring (halb transparent, nur wenn aktiv sichtbarer)
ringAlpha := uint8(40)
if g.joyActive {
knobCol = color.RGBA{100, 255, 100, 120}
ringAlpha = 70
}
vector.DrawFilledCircle(screen, float32(g.joyStickX), float32(g.joyStickY), 30, knobCol, false)
vector.DrawFilledCircle(screen, float32(g.joyBaseX), float32(g.joyBaseY), float32(joyR), color.RGBA{80, 80, 80, ringAlpha}, false)
vector.StrokeCircle(screen, float32(g.joyBaseX), float32(g.joyBaseY), float32(joyR), 2, color.RGBA{120, 120, 120, 90}, false)
// C) Jump Button (unten rechts, über dem Boden positioniert)
jumpX := float32(canvasW) - 150
jumpY := float32(floorY) - 50 // 50px über dem Boden
vector.DrawFilledCircle(screen, jumpX, jumpY, 50, color.RGBA{255, 0, 0, 50}, false)
vector.StrokeCircle(screen, jumpX, jumpY, 50, 2, color.RGBA{255, 0, 0, 100}, false)
text.Draw(screen, "JUMP", basicfont.Face7x13, int(jumpX)-15, int(jumpY)+5, color.RGBA{255, 255, 255, 150})
// Joystick-Knob
knobCol := color.RGBA{180, 180, 180, 100}
if g.joyActive {
knobCol = color.RGBA{80, 220, 80, 160}
}
vector.DrawFilledCircle(screen, float32(g.joyStickX), float32(g.joyStickY), float32(knobR), knobCol, false)
// ── B) Jump Button (rechts) ──────────────────────────────────────────
jumpX := float64(tcW)*0.82
jumpY := floorY - jumpR - 12
jumpFill := color.RGBA{220, 50, 50, 60}
jumpStroke := color.RGBA{255, 80, 80, 130}
if g.btnJumpPressed {
jumpFill = color.RGBA{255, 80, 80, 130} // heller wenn gedrückt
jumpStroke = color.RGBA{255, 160, 160, 200}
}
vector.DrawFilledCircle(screen, float32(jumpX), float32(jumpY), float32(jumpR), jumpFill, false)
vector.StrokeCircle(screen, float32(jumpX), float32(jumpY), float32(jumpR), 2.5, jumpStroke, false)
text.Draw(screen, "JUMP", basicfont.Face7x13,
int(jumpX)-14, int(jumpY)+5, color.RGBA{255, 255, 255, 180})
// ── C) Down/FastFall Button (links vom Jump) ─────────────────────────
downX := float64(tcW)*0.62
downY := floorY - downR - 12
g.downBtnX = downX
g.downBtnY = downY
g.downBtnR = downR
vector.DrawFilledCircle(screen, float32(downX), float32(downY), float32(downR), color.RGBA{50, 120, 220, 55}, false)
vector.StrokeCircle(screen, float32(downX), float32(downY), float32(downR), 2, color.RGBA{80, 160, 255, 120}, false)
text.Draw(screen, "▼", basicfont.Face7x13,
int(downX)-4, int(downY)+5, color.RGBA{200, 220, 255, 180})
}
}