fix game
Some checks failed
Dynamic Branch Deploy / build-and-deploy (push) Failing after 8m17s
Some checks failed
Dynamic Branch Deploy / build-and-deploy (push) Failing after 8m17s
This commit is contained in:
@@ -27,6 +27,22 @@ type WebSocketMessage struct {
|
||||
Payload interface{} `json:"payload"`
|
||||
}
|
||||
|
||||
// disconnectFromServer trennt die bestehende WebSocket-Verbindung sauber
|
||||
func (g *Game) disconnectFromServer() {
|
||||
if g.wsConn != nil {
|
||||
// stopChan schließen ohne Panic falls schon geschlossen
|
||||
select {
|
||||
case <-g.wsConn.stopChan:
|
||||
// bereits geschlossen
|
||||
default:
|
||||
close(g.wsConn.stopChan)
|
||||
}
|
||||
g.wsConn.conn.Close()
|
||||
g.wsConn = nil
|
||||
}
|
||||
g.connected = false
|
||||
}
|
||||
|
||||
// connectToServer verbindet sich über WebSocket mit dem Gateway (Native Desktop)
|
||||
func (g *Game) connectToServer() {
|
||||
serverURL := "ws://localhost:8080/ws"
|
||||
|
||||
@@ -25,6 +25,15 @@ type wsConn struct {
|
||||
connected bool
|
||||
}
|
||||
|
||||
// disconnectFromServer trennt die bestehende WebSocket-Verbindung sauber
|
||||
func (g *Game) disconnectFromServer() {
|
||||
if g.wsConn != nil {
|
||||
g.wsConn.ws.Call("close")
|
||||
g.wsConn = nil
|
||||
}
|
||||
g.connected = false
|
||||
}
|
||||
|
||||
// connectToServer verbindet sich über WebSocket mit dem Gateway
|
||||
func (g *Game) connectToServer() {
|
||||
// Automatisch die richtige WebSocket-URL basierend auf der aktuellen Domain
|
||||
|
||||
@@ -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})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -126,9 +126,15 @@ type Game struct {
|
||||
joyStickX, joyStickY float64
|
||||
joyActive bool
|
||||
joyTouchID ebiten.TouchID
|
||||
joyRadius float64 // Joystick-Radius (skaliert mit Screen)
|
||||
btnJumpActive bool
|
||||
keyboardUsed bool // Wurde Tastatur benutzt?
|
||||
lastCanvasHeight int // Cache der Canvas-Höhe für Touch-Input
|
||||
btnJumpPressed bool // Jump wird gerade gehalten (visuelles Feedback)
|
||||
btnDownActive bool // Down/FastFall-Button gedrückt
|
||||
keyboardUsed bool // Wurde Tastatur benutzt?
|
||||
lastCanvasHeight int // Cache der Canvas-Höhe für Touch-Input
|
||||
lastCanvasWidth int // Cache der Canvas-Breite für Touch-Input
|
||||
downBtnX, downBtnY float64 // Zentrum des Down-Buttons
|
||||
downBtnR float64 // Radius des Down-Buttons
|
||||
|
||||
// Debug Stats
|
||||
showDebug bool // Debug-Overlay anzeigen (F3 zum Umschalten)
|
||||
@@ -844,13 +850,61 @@ func generateRoomCode() string {
|
||||
return string(code)
|
||||
}
|
||||
|
||||
func (g *Game) connectAndStart() {
|
||||
// Initiale predicted Position
|
||||
// resetForNewGame setzt den gesamten Spiel-State zurück ohne die Seite neu zu laden.
|
||||
// Muss vor jeder neuen Verbindung aufgerufen werden.
|
||||
func (g *Game) resetForNewGame() {
|
||||
// Alte Verbindung sauber trennen
|
||||
g.disconnectFromServer()
|
||||
|
||||
// Prediction-State zurücksetzen
|
||||
g.predictionMutex.Lock()
|
||||
g.pendingInputs = make(map[uint32]InputState)
|
||||
g.inputSequence = 0
|
||||
g.lastServerSeq = 0
|
||||
g.predictedX = 100
|
||||
g.predictedY = 200
|
||||
g.predictedVX = 0
|
||||
g.predictedVY = 0
|
||||
g.predictedGround = false
|
||||
g.predictedOnWall = false
|
||||
g.currentSpeed = 0
|
||||
g.correctionOffsetX = 0
|
||||
g.correctionOffsetY = 0
|
||||
g.predictionMutex.Unlock()
|
||||
|
||||
// KRITISCH: lastRecvSeq zurücksetzen!
|
||||
// Ohne diesen Reset ignoriert die Out-of-Order-Prüfung alle Nachrichten
|
||||
// des neuen Spiels (neue Sequenzen < alter lastRecvSeq).
|
||||
g.lastRecvSeq = 0
|
||||
|
||||
// Spieler-State zurücksetzen
|
||||
g.scoreSubmitted = false
|
||||
g.lastStatus = ""
|
||||
g.correctionCount = 0
|
||||
g.outOfOrderCount = 0
|
||||
g.totalUpdates = 0
|
||||
|
||||
// GameState leeren
|
||||
g.stateMutex.Lock()
|
||||
g.gameState = game.GameState{Players: make(map[string]game.PlayerState)}
|
||||
g.stateMutex.Unlock()
|
||||
|
||||
// Leaderboard leeren
|
||||
g.leaderboardMutex.Lock()
|
||||
g.leaderboard = make([]game.LeaderboardEntry, 0)
|
||||
g.leaderboardMutex.Unlock()
|
||||
|
||||
// Partikel leeren
|
||||
g.particlesMutex.Lock()
|
||||
g.particles = nil
|
||||
g.particlesMutex.Unlock()
|
||||
g.lastCollectedCoins = make(map[string]bool)
|
||||
g.lastCollectedPowerups = make(map[string]bool)
|
||||
g.lastPlayerStates = make(map[string]game.PlayerState)
|
||||
}
|
||||
|
||||
func (g *Game) connectAndStart() {
|
||||
g.resetForNewGame()
|
||||
|
||||
// Verbindung über plattformspezifische Implementierung
|
||||
g.connectToServer()
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
<div class="legal-bar" style="margin-top: 10px;">
|
||||
<button class="legal-btn" onclick="showImpressum()">📄 IMPRESSUM</button>
|
||||
<button class="legal-btn" onclick="showDatenschutz()">🔒 DATENSCHUTZ</button>
|
||||
<button class="legal-btn" onclick="showSprueche()">💬 SPRÜCHE</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -227,6 +228,16 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SPRÜCHE MENU -->
|
||||
<div id="spruecheMenu" class="overlay-screen hidden">
|
||||
<div class="center-box" style="max-width: 900px; width: 95%;">
|
||||
<h1>💬 LEGENDÄRE SPRÜCHE</h1>
|
||||
<p style="font-size: 12px; color: #888; margin: -10px 0 15px;">Aus dem Schulalltag – gesammelt von Schülern</p>
|
||||
<div id="spruecheList" class="leaderboard-box" style="max-height: 60vh; overflow-y: auto; text-align: left; padding: 10px;"></div>
|
||||
<button class="back-btn" onclick="showMainMenu()">← ZURÜCK</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- LOBBY SCREEN (CO-OP WAITING ROOM) -->
|
||||
<div id="lobbyScreen" class="overlay-screen hidden">
|
||||
<div class="center-box">
|
||||
@@ -288,6 +299,128 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sprüche Logic -->
|
||||
<script>
|
||||
const SPRUECHE = [
|
||||
{ text: "Mobbing ist besser als gar keine sozialen Kontakte.", author: "Ein Lehrer" },
|
||||
{ text: "Ein Lehrer kauft sich ein Auto, weil ihm die Farbe gefallen hat.", author: "Schulflur-Legende" },
|
||||
{ text: "Was heißt Strafe auf Englisch? „Richard"?", author: "Ein Lehrer", ctx: "Während er versucht, einem Schüler etwas auf Englisch zu erklären" },
|
||||
{ text: "Heute ist [alles in der Anwesenheitsliste] richtig eingetragen.", author: "Eine Lehrerin", ctx: "Am Montagmorgen. Ein paar Stunden später fehlte trotzdem jemand in der Liste." },
|
||||
{ text: "Verstehen Sie überhaupt die Prüfungsfragen? Neh, ach …", author: "Ein Lehrer", ctx: "An einen Schüler" },
|
||||
{ text: "Tut mir leid, dass ich Sie damit nerve, aber … [erzählt 10 Minuten über seine Weiterbildung zu Courage und Rechtsextremismus]. Ein Schüler meldet sich. – Ist das eine rechtsextreme Handlung?!", author: "Ein Lehrer" },
|
||||
{ text: "Können wir nochmal eine LK über Straßennamen schreiben? – Ja klar, wenn du das willst.", author: "Schüler & Lehrerin", ctx: "Richard zur Deutschlehrerin im 3. Lehrjahr" },
|
||||
{ text: "Mitten im WiKu-Unterricht betritt eine Lehrerin den Raum, schaut sich kurz um, schnappt sich den versteckten Wasserkocher vom Fensterstock und geht wieder. Ist das gerade wirklich passiert?", author: "Augenzeugen" },
|
||||
{ text: "Neues Lieblingswort: „Hanebüchen"", author: "Ein Lehrer" },
|
||||
{ text: "Einem Lehrer fällt die Kinnlade runter, als Reda chinesisch mit den chinesischen Lehrkräften spricht – und diese es verstehen.", author: "Augenzeugen" },
|
||||
{ text: "Ich bin mit dem Staat verheiratet. … Ich hab das nur wegen der Pension gemacht.", author: "Ein Lehrer (Lehrer aus Überzeugung)" },
|
||||
{ text: "Ich hab 'nen Freund, [Schüler]! – Das ist egal.", author: "Eine Lehrerin & Schüler" },
|
||||
{ text: "Beschreibungen im Unterricht u.a.: Slavenhändler, Mafia, Kopfgeld, Knebelverträge, Voodoo-Zauber (bei Physik und Frontend), Menschen quälen mit Aufgaben, goldene Balkone bauen, geklauter Code … und ein Ast als Zeigestock, mit dem er auf die Tastatur haut.", author: "Ein Lehrer" },
|
||||
{ text: "Ein Kollege hat vorgeschlagen, bei der Hitze schon um 6:40 Uhr anzufangen. Ich meinte, um diese Zeit ist noch niemand da, nicht einmal ich selber. Dann meinte ich, wir sollten lieber 5:40 Uhr anfangen. Dann kommen noch welche von ihrem Heimweg vorbei.", author: "Ein Lehrer" },
|
||||
{ text: "Nachdem wir in ihrem Kreuzworträtsel etwa 10 Fehler gefunden haben, gibt sie zu, dass sie es bei einem Gläschen Wein erstellt hat. 1A Unterrichtsvorbereitung.", author: "Eine Lehrerin" },
|
||||
{ text: "Die „Katastrophenprüfung" im Sommer 2023 – und die „Entschuldigungsprüfung" im Sommer 2024.", author: "Ein Lehrer" },
|
||||
{ text: "Das „Pippi"-Diagramm: das UML-Sequenzdiagramm.", author: "Ein Lehrer" },
|
||||
{ text: "Und wo ist euer Klassenbuch? Mit wem hattet ihr gestern zuletzt Unterricht? – Mit [dem Lehrer]. – Ah ja. – Der hat das gegessen.", author: "Eine Lehrerin" },
|
||||
{ text: "Cool! Ich hab einen Klassensatz Bücher bestellt bekommen!", author: "Eine Lehrerin", ctx: "Freut sich wie ein Kind" },
|
||||
{ text: "Ich hör viel zu viel Deutsch… Das ist nicht rassistisch gemeint. … Äh … Redet gefälligst in Englisch!", author: "Eine Lehrerin", ctx: "Im Englischunterricht" },
|
||||
{ text: "Itze! Äh, äh, nowe! … Yes, this is good so.", author: "Eine Lehrerin" },
|
||||
{ text: "Die anderen listen carefully, bitte.", author: "Eine Lehrerin" },
|
||||
{ text: "Was mit Beschiss? Mit Beschiss kann ich. […] Ich hab den König gekrönt vom Bescheissen.", author: "Ein Lehrer" },
|
||||
{ text: "Ein Lehrer erzählt uns die Geschichte von dem Huhn, das aggro wurde, als es einen Waschbären traf – das jetzt so viel wert ist wie seine neue Brille.", author: "Schulflur-Legende" },
|
||||
{ text: "EPK ist BPMN auf Steroiden.", author: "Ein Lehrer" },
|
||||
{ text: "Richard ist heute nicht da. – Was!? Dann wird das ja heute richtig still im Raum. Geil. Das hab ich jetzt nicht gesagt.", author: "Schüler & Lehrerin" },
|
||||
{ text: "Zu Hausmeistern habe ich immer noch das beste Verhältnis – im Gegensatz zu manchen anderen.", author: "Ein Lehrer" },
|
||||
{ text: "Ein Kollege hat das bestimmt entspannter gemacht. Ich mag Menschen quälen.", author: "Ein Lehrer", ctx: "Zu LF 3" },
|
||||
{ text: "Morgen sind Schüler unserer polnischen Partnerschule mit in unserem Unterricht. Die wollen von dem Besten lernen – also von mir.", author: "Ein Lehrer" },
|
||||
{ text: "Zwei Lehrer haben sich beim Kaffeetrinken über die Notengebung geeinigt. „[Der Kollege] ist da sehr entspannt, weil er Richard nur noch zwei Stunden die Woche hat."", author: "Schulflur-Legende" },
|
||||
{ text: "Ich bräuchte jetzt wirklich einen Kaffee oder ein Bier. Aber bietet mir bloß nicht was aus eurem Kofferraum an! Nur weil manche Schüler das schon gemacht haben…", author: "Eine Lehrerin", ctx: "Nach ausführlicher Diskussion über Englisch-Noten in der 9. Stunde" },
|
||||
{ text: "Unterrichtsvorbereitung: „Ich werde es Ihnen beweisen. Hoffentlich habe ich keine zu große Klappe…"", author: "Ein Lehrer" },
|
||||
{ text: "Ein Facharzt? Das ist ne echt gute Ausrede. Verdammte Scheiße…", author: "Ein Lehrer", ctx: "Zum Schüler, der früher gehen musste" },
|
||||
{ text: "Scheiße, darauf kann ich nicht rumschreiben!", author: "Ein Lehrer", ctx: "Als er mit dem Tablet-Stift auf den Fernseher zugeht" },
|
||||
{ text: "Can you read number 4? – Which number? – Please pay a little bit more attension to the lesson!", author: "Richard", ctx: "Während er versucht, die Klasse auf Englisch zu unterrichten, weil die Lehrerin noch nicht da war. Gelächter, weil er selbst sonst nur zu selten aufpasst." },
|
||||
{ text: "Warum muss ich jetzt wieder Scheiße erklären, die ich net verzapft hab. Lasst mich doch in Ruhe.", author: "Ein Lehrer", ctx: "Als die Klasse mal wieder abschweift" },
|
||||
{ text: "Dann können Rollstuhlfahrer gleich mit in den Krieg ziehen.", author: "Ein Lehrer" },
|
||||
{ text: "Mobbing ist 3 Monate durchgängig. Ich kann sie also nicht gar nicht mobben, weil sie immer weg sind.", author: "Ein Lehrer" },
|
||||
{ text: "Ich spiele kein Schach mehr, seit ich gegen ein (Klein-)Kind verloren hab.", author: "Ein Lehrer" },
|
||||
{ text: "Sind denn alle schon da? Es sind so wenig gerade. – Es sind ja auch nur die A- und C-Klasse da. Vermisst du etwa Richard?", author: "Samuel & Mitschüler" },
|
||||
{ text: "Spielen Sie „God of War"? So sehen sie auch aus.", author: "Ein Lehrer", ctx: "Zu einem Schüler in der ersten Reihe" },
|
||||
{ text: "Ich hab gesehen, dass jetzt sogar Spiele aus dem Microsoft Store hier funktionieren. Kaum zu glauben.", author: "Ein Lehrer", ctx: "Über die Schultechnik" },
|
||||
{ text: "Die Antwort soll „ja" sein. Mit genug Reden kann man auch das Gegenteil argumentieren. Mit viel Liebe, ja.", author: "Ein Lehrer", ctx: "Beim Auflösen einer Aufgabe" },
|
||||
{ text: "Hallo, [Herr Lehrer]! – Was macht ihr denn jetzt? – Wir gehen auf's Klo. – Was macht [Richard] jetzt? Sich ein Loch graben?", author: "Richard, David & ein Lehrer" },
|
||||
{ text: "Offiziell gibt's das Notenbuch gar nicht. – Der könnte von mir sein.", author: "Sebastian & ein Lehrer", ctx: "Über eigenmächtige Eintragungen" },
|
||||
{ text: "Nicht richtig, aber auch nicht zielführend. – Richard: In der Prüfung… Aber wenn das nicht die Antwort ist, kann ich doch die IHK verklagen?", author: "Eine Lehrerin & Richard" },
|
||||
{ text: "Wollen Sie jetzt damit sagen, dass Stuttgart keinen Bahnhof braucht? – Nein, aber net so ein Ding. Hätten sie mal lieber die halbe Stadt weggesprengt und einen richtigen Bahnhof hingebaut.", author: "Ein Lehrer" },
|
||||
{ text: "Es geht darum, Sie drei Jahre hinzuhalten – und dann sind Sie eh weg.", author: "Ein Lehrer", ctx: "Zum Prinzip Berufsschule" },
|
||||
{ text: "Diesen Workaround gibt es hier nicht. Es gibt hier gar kein Problem. Am Tag darauf: Es gibt *** nochmal keine Probleme!", author: "Ein Lehrer", ctx: "Zu den „Problemchen" der IT-Infrastruktur" },
|
||||
{ text: "Wenn man seine Kommentare aus dem Kontext reißt: „Ich denke immer, ich bin doof. Aber das ist so."", author: "Ein Lehrer" },
|
||||
{ text: "Wollen Sie etwas Lustiges hören? Nein? Dann eben etwas Trauriges…", author: "Ein Lehrer", ctx: "Freitagmorgen" },
|
||||
{ text: "Ein Lehrer schickt einen Schüler, ein Messer aus dem Lehrerzimmer zu holen – Tür extra offengelassen. Der Schüler kommt mit Messer heraus, begegnet zwei verdutzt schauenden Lehrern, grüßt freundlichst und geht weiter, als ob er das jeden Tag machen würde.", author: "Schulflur-Legende" },
|
||||
{ text: "Warum wollen Sie die Schule versichern? Die können Sie sowieso nicht verklagen.", author: "Ein Lehrer" },
|
||||
{ text: "Das ist das Beste, das uns passieren kann. Dann können wir von null anfangen.", author: "Ein Lehrer", ctx: "Falls der einzige IT-Administrator-Lehrer mal nicht mehr da sein sollte" },
|
||||
{ text: "Haltet euch sklavisch an die Notation!", author: "Ein Lehrer" },
|
||||
{ text: "Nur die Paranoiden werden überleben.", author: "Ein Lehrer" },
|
||||
{ text: "Ein Lehrer wünscht sich, dass die Schüler mehr Angst haben. Aber nicht, dass den Schülern Angst gemacht wird.", author: "Schulflur-Legende" },
|
||||
{ text: "Ich bin gerade im Größenwahn und es wird immer verrückter.", author: "Ein Lehrer", ctx: "Mitten im Unterricht" },
|
||||
{ text: "Und was haben Sie heute gemacht? – Nichts. – Und was soll ich jetzt darauf antworten? Wenn Sie einmal einen Yachthafen haben, …", author: "Ein Lehrer", ctx: "Am Ende des Unterrichts" },
|
||||
{ text: "Die Schüler haben mich genötigt durchzumachen (damit sie eher gehen können).", author: "Ein Lehrer", ctx: "Nach der Mittagspause" },
|
||||
{ text: "Programmieren kann so ekelhaft sein, wenn man sich wirklich damit beschäftigt.", author: "Ein Lehrer" },
|
||||
{ text: "Vorsicht, sauer. Hab ich meinen Kindern geklaut.", author: "Ein Lehrer", ctx: "Beim Austeilen von sauren Gummischlangen" },
|
||||
{ text: "[Herr Lehrer], Sie sind mein absoluter Lieblingslehrer, … – Mit was habe ich Ihre Anwesenheit verdient?", author: "Richard & ein Lehrer" },
|
||||
{ text: "Die Beitragsätze der Sozialversicherungen haben sich geändert. Und ich muss nur kurz mein Auto aufsperren.", author: "Eine Lehrerin", ctx: "Im neuen Kalenderjahr" },
|
||||
{ text: "Es gibt eine große Zeitspanne, in der quasi keine Lehrer ausgebildet wurden. – Und dann gibt es noch solche von der Resterampe wie mich.", author: "Ein Lehrer" },
|
||||
{ text: "Ja. So viel Pech im Denken kann man gar nicht haben.", author: "Ein Lehrer", ctx: "Als ihn ein Schüler fragte, mit wem er Spaß bei Sinusfunktionen hatte" },
|
||||
{ text: "Richard; bei dir, das hab ich gleich gelassen und gar keine Note drunter geschrieben.", author: "Eine Lehrerin", ctx: "Beim Zurückgeben freiwilliger Aufgaben" },
|
||||
{ text: "Die Noten der letzten LK konnten nicht eingetragen werden, weil die Notenbücher verschwunden sind. Reaktion: „Die tauchen irgendwann schon wieder auf."", author: "Eine Lehrerin" },
|
||||
{ text: "Ein Lehrer kommt random in der Mittagspause ins Zimmer und erzählt von seinen kulinarischen Abenteuern – u.a. Gammelfisch am Wochenende.", author: "Zeugen" },
|
||||
{ text: "Samuel: Ich hab für den Weg zum Netto länger gebraucht als die WiKu-LK gerade.", author: "Samuel" },
|
||||
{ text: "[Schüler], waren Sie gestern da? – Nein, ich war krank. Warum? – Weil ein Kollege drauf gewettet hat, dass Sie nicht da sind. Ich hab die Wette verloren.", author: "Ein Lehrer" },
|
||||
{ text: "[Herr Lehrer], wie heißen Sie eigentlich mit Vornamen? – „Unwichtig." – Aha, „Unwichtig [Nachname]." – Wie würden Sie sich nennen, wenn Sie sich einen Namen aussuchen könnten? – „Ich-hab-zu-tun,-Geh-weg."", author: "Richard & ein Lehrer" },
|
||||
{ text: "Der Assi = der Assistenzarzt. „Hat der Assi Sie gut behandelt?"", author: "Ein Lehrer" },
|
||||
{ text: "Dass ihr mal wisst, wie eine Prüfung physisch aussieht – hier die vom Sommer '26. – Die nehmen wir gerne! – Nein! Die vom Sommer '25.", author: "Ein Lehrer & Schüler" },
|
||||
{ text: "Ich kenn einen Autor vom Westermann; der schimpft eigentlich nur.", author: "Ein Lehrer" },
|
||||
{ text: "[Herr Lehrer], haben Sie ein Messer dabei? – Nein, leider nicht.", author: "Schüler & ein Lehrer" },
|
||||
{ text: "Sag mal, die Amok-Läufer; das sind doch immer Schüler, oder?", author: "Ein Lehrer", ctx: "Zu einem Kollegen" },
|
||||
{ text: "Das werdet ihr nicht mehr erleben mit den elektronischen Tafeln…", author: "Eine Lehrerin" },
|
||||
{ text: "Ich darf mich doch, während ich die Aufgabe mache, umentscheiden. – Ich muss Sie aber verstehen. Denken Sie doch mal an mich!", author: "Schüler & ein Lehrer" },
|
||||
{ text: "Wir schauen uns eine Aufgabe aus der Prüfung der Systemintegratoren an. Wir haben ja einen Experten hier sitzen. Richard: So einfach?! – Mehr trauen sie Euch nicht zu.", author: "Ein Lehrer & Richard", ctx: "Richard hatte sich in seiner Freistunde in den Unterricht gesetzt" },
|
||||
{ text: "[Schüler], du hast leider eine 2 in der Arbeit… Haben wir uns trotzdem noch lieb?", author: "Ein Lehrer" },
|
||||
{ text: "Kann ich Sie ihrem elendigem Schicksal überlassen? (= Bitte gehen Sie.)", author: "Ein Lehrer", ctx: "Zum Stundenbeginn" },
|
||||
{ text: "Ich war leider zu spät. – Zu spät zum Unterricht, oder für was? – Zu spät zum Gaffen.", author: "Ein Lehrer", ctx: "Am Tag nach einem Unfall auf der Reichenbacher Straße" },
|
||||
{ text: "Da wäre ich fast ausm Schlüpper geflogen!", author: "Eine Lehrerin" },
|
||||
{ text: "Was stört sich die Eiche, wenn sich ein Schwein daran wälzt.", author: "Ein Lehrer" },
|
||||
{ text: "Ich habe nichts verstanden. – Hättest du auch nicht, wenn Ton da gewesen wäre.", author: "Leon & ein Lehrer", ctx: "Bei einem Video mit Tonproblemen" },
|
||||
{ text: "Ein Lehrer greift an eine gerissene Achillissehne (einer anderen Person), nur um zu wissen, wie sich das anfühlt: „Wie Matsch."", author: "Augenzeugen" },
|
||||
{ text: "Wo ist Sebastian? – Krank. Wo ist euer Klassenbuch? – Krank.", author: "Reda" },
|
||||
{ text: "„W"-Fragen sind verpönt! Das geht gar nicht!", author: "Ein Lehrer" },
|
||||
{ text: "Wenn Richard im Unterricht keine Zeit hat, mit Mitschülern zu reden – dann muss eine Lehrerin daran glauben…", author: "Schulflur-Legende" },
|
||||
{ text: "Jetzt muss ich mir schon die Musterlösung schönsaufen.", author: "Ein Lehrer" },
|
||||
{ text: "Ich muss die Prüfung nicht schreiben!", author: "Ein Lehrer", ctx: "Bei der Prüfungsvorbereitung" },
|
||||
{ text: "Werd ich echt alt?", author: "Ein Lehrer", ctx: "Nachdem er die Anfänge von Wörtern nicht mehr gut verstand" },
|
||||
{ text: "Bei euch hab ich ein gutes Gefühl. Apropos – wo ist denn Leon?", author: "Ein Lehrer", ctx: "Als die Prüfung näher rückte" },
|
||||
{ text: "Ein Lehrer kennt leider alle Bibi & Tina-Filme und erkennt für die Hälfte der Folgen den Titel am Titelbild.", author: "Schulflur-Legende" },
|
||||
{ text: "Die Geißel Gottes. Ich freue mich, Sie zu sehen…!", author: "Ein Lehrer", ctx: "Zu Richard" },
|
||||
{ text: "Ja, wir haben ein Kind. Meine Frau war da mehr beteiligt als ich.", author: "Ein Lehrer" },
|
||||
{ text: "Kind kriegen ist glaub ich schon geiler als auf'm Mount Everest zu steigen.", author: "Ein Lehrer" },
|
||||
{ text: "Ein Lehrer setzt Richard nach einem unruhigen Stundenstart nach vorne und fordert ihn zur Mitarbeit auf. Danach hat er im Unterricht niemanden mehr, den er rügen konnte.", author: "Augenzeugen" },
|
||||
{ text: "„Mach nicht den Reda!" = In einen Raum gehen, vor dem Schüler warten, und ihnen noch zurufen, dass da eine andere Klasse drin ist – in dem Moment hat er die Tür schon aufgemacht und blickt in die verwirrten Gesichter der fremden Klasse.", author: "Schulflur-Legende" },
|
||||
];
|
||||
|
||||
function showSprueche() {
|
||||
document.querySelectorAll('.overlay-screen').forEach(el => el.classList.add('hidden'));
|
||||
document.getElementById('spruecheMenu').classList.remove('hidden');
|
||||
|
||||
// Shuffle quotes
|
||||
const shuffled = [...SPRUECHE].sort(() => Math.random() - 0.5);
|
||||
const container = document.getElementById('spruecheList');
|
||||
container.innerHTML = shuffled.map((q, i) => `
|
||||
<div style="background: rgba(255,255,255,0.05); border-left: 3px solid #fc0; margin: 8px 0; padding: 12px 15px; border-radius: 3px;">
|
||||
<p style="margin: 0 0 6px; font-family: sans-serif; font-size: 14px; color: #eee; line-height: 1.5;">${q.text.replace(/</g,'<').replace(/>/g,'>')}</p>
|
||||
${q.ctx ? `<p style="margin: 0 0 4px; font-size: 11px; color: #888; font-style: italic;">${q.ctx.replace(/</g,'<').replace(/>/g,'>')}</p>` : ''}
|
||||
<p style="margin: 0; font-size: 12px; color: #fc0;">— ${q.author}</p>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- WASM Execution -->
|
||||
<script>
|
||||
// Cache-Busting für JavaScript-Dateien (wird beim Build aktualisiert)
|
||||
|
||||
Reference in New Issue
Block a user