diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index e5b84ca..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,9 +0,0 @@
-MIT License
-
-Copyright (c) 2025 putschgi
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/PDA.tmpl b/PDA.tmpl
deleted file mode 100644
index ae511de..0000000
--- a/PDA.tmpl
+++ /dev/null
@@ -1,430 +0,0 @@
-
-
- {{cookiecutter.title}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AIO ⏏︎
- AIO ■
- AIO ▶
- Music ■
-
-
-
-
-
(battery level unknown)
-
(charging state unknown)
-
-
-
-
-
-
-
-
-
-
- Select files
-
-
-
-
-
-
-
-
diff --git a/images/background.png b/images/background.png
index 2835fdb..496dc0d 100644
Binary files a/images/background.png and b/images/background.png differ
diff --git a/images/case_w1_h1.png b/images/case_w1_h1.png
index 30ab4ef..1e8755b 100644
Binary files a/images/case_w1_h1.png and b/images/case_w1_h1.png differ
diff --git a/images/case_w1_h2.png b/images/case_w1_h2.png
index 63b709d..a045e40 100644
Binary files a/images/case_w1_h2.png and b/images/case_w1_h2.png differ
diff --git a/images/case_w1_h3.png b/images/case_w1_h3.png
index 15a9d3c..a3c2605 100644
Binary files a/images/case_w1_h3.png and b/images/case_w1_h3.png differ
diff --git a/images/case_w2_h1.png b/images/case_w2_h1.png
index b2b08ad..fe62f5d 100644
Binary files a/images/case_w2_h1.png and b/images/case_w2_h1.png differ
diff --git a/images/case_w2_h2.png b/images/case_w2_h2.png
index b41fc99..d9eb01a 100644
Binary files a/images/case_w2_h2.png and b/images/case_w2_h2.png differ
diff --git a/images/case_w2_h3.png b/images/case_w2_h3.png
index 4fb057f..bdf9373 100644
Binary files a/images/case_w2_h3.png and b/images/case_w2_h3.png differ
diff --git a/images/case_w3_h1.png b/images/case_w3_h1.png
index 60789ff..9423445 100644
Binary files a/images/case_w3_h1.png and b/images/case_w3_h1.png differ
diff --git a/images/case_w3_h2.png b/images/case_w3_h2.png
index 2561429..7713736 100644
Binary files a/images/case_w3_h2.png and b/images/case_w3_h2.png differ
diff --git a/images/case_w4_h1.png b/images/case_w4_h1.png
index 989498b..d38eabe 100644
Binary files a/images/case_w4_h1.png and b/images/case_w4_h1.png differ
diff --git a/images/case_w4_h2.png b/images/case_w4_h2.png
index 82317e4..f4f7a9a 100644
Binary files a/images/case_w4_h2.png and b/images/case_w4_h2.png differ
diff --git a/images/habegger_logo_goldbar_whitefont.png b/images/habegger_logo_goldbar_whitefont.png
index 62a1205..42f92c7 100644
Binary files a/images/habegger_logo_goldbar_whitefont.png and b/images/habegger_logo_goldbar_whitefont.png differ
diff --git a/images/tutorial.png b/images/tutorial.png
index 47c14db..be59bcb 100644
Binary files a/images/tutorial.png and b/images/tutorial.png differ
diff --git a/images/tutorial_controller.png b/images/tutorial_controller.png
deleted file mode 100644
index be59bcb..0000000
Binary files a/images/tutorial_controller.png and /dev/null differ
diff --git a/main.py b/main.py
deleted file mode 100644
index 71527b2..0000000
--- a/main.py
+++ /dev/null
@@ -1,805 +0,0 @@
-import asyncio
-import pygame
-import random
-import sys
-import os
-import time
-import re
-random.seed(time.time())
-
-
-from pygame import FULLSCREEN
-
-# === Konstanten ===
-SCREEN_WIDTH = 1920
-SCREEN_HEIGHT = 1080
-FPS = 60
-
-TOP_BAR_HEIGHT = SCREEN_HEIGHT // 8
-GAME_AREA_HEIGHT = SCREEN_HEIGHT // 1.6
-BOTTOM_BAR_HEIGHT = SCREEN_HEIGHT // 4
-
-TRAILER_WIDTH = int(SCREEN_WIDTH * 0.885416666667)
-TRAILER_HEIGHT = int(SCREEN_HEIGHT * 0.2778)
-TRAILER_X = (SCREEN_WIDTH - TRAILER_WIDTH) // 4
-TRAILER_Y = TOP_BAR_HEIGHT + 200
-
-CASE_SPEED_SLOW = 3
-CASE_SPEED_FAST = 8
-CASE_COLORS = [(200, 0, 0), (0, 200, 0), (0, 0, 200)]
-SNAP_THRESHOLD = 60
-FAST_TO_SLOW_DISTANCE = 120
-
-UNIT_LENGTH = TRAILER_HEIGHT // 3
-UNIT_HEIGHT = TRAILER_HEIGHT // 3
-
-# === Globale Variablen ===
-current_case_visible = True
-transition_fps = 60
-transition_counter = 0
-collision_x = TRAILER_X
-stacked_cases = []
-case_sequence = []
-case_index = 0
-current_case = None
-next_queue = []
-running = True
-can_use_tilt = True
-can_use_on_top = True
-game_finished = False
-shake_timer = 0
-state = 1 # PLAYING
-prepared_form = None
-ready_to_submit = False
-touch_start = None
-touch_start_time = None
-
-def init_sounds():
- global sound_fail, sound_place, sound_roll, sound_tut1, sound_tut2, sound_tuuut, zip_sound
- pygame.mixer.init()
- sound_fail = pygame.mixer.Sound("sounds/fail.ogg")
- sound_fail.set_volume(0.6)
- sound_place = pygame.mixer.Sound("sounds/place.ogg")
- sound_place.set_volume(0.6)
- sound_roll = pygame.mixer.Sound("sounds/roll.ogg")
- sound_roll.set_volume(0.3)
- sound_tut1 = pygame.mixer.Sound("sounds/tut1.ogg")
- sound_tut1.set_volume(1)
- sound_tut2 = pygame.mixer.Sound("sounds/tut2.ogg")
- sound_tut2.set_volume(1)
- sound_tuuut = pygame.mixer.Sound("sounds/tuuut.ogg")
- sound_tuuut.set_volume(1)
- zip_sound = pygame.mixer.Sound("sounds/zip.ogg")
- zip_sound.set_volume(1)
- print("Sounds erfolgreich geladen.")
-
-case_images = {}
-
-def touch(event):
- global touch_start, touch_start_time
-
- if event.type == pygame.FINGERDOWN and not touch_start:
- touch_start = (event.x * SCREEN_WIDTH, event.y * SCREEN_HEIGHT)
- touch_start_time = time.time()
- print("touch_start")
- return False
-
- elif event.type == pygame.FINGERUP and touch_start:
- end = (event.x * SCREEN_WIDTH, event.y * SCREEN_HEIGHT)
- duration = time.time() - touch_start_time
- dx = end[0] - touch_start[0]
- dy = end[1] - touch_start[1]
- print("touch_end")
- print(f"Touch dx={dx}, dy={dy}, duration={duration}")
-
- touch_start = None
- touch_start_time = None
-
- if abs(dx) < 30 and abs(dy) < 30 and duration < 0.1:
- return "snap"
- elif dx < -50 and abs(dy) < 80 and duration > 0.08:
- return "tilt"
- elif dy < -50 and abs(dx) < 80 and duration > 0.08:
- return "ontop"
- else:
- print("touch probleeeeem")
- return False
- return False
-
-def is_SPACE_event(event):
-
- # Tastatur oder Joystick A
- if (event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE) or \
- (event.type == pygame.JOYBUTTONDOWN and event.button == 0):
- return True
-
- # Mausklick (nur Linksklick, für Desktop-Tests)
- if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
- return True
-
- return False
-
-def is_LEFT_event(event):
- # Tastatur oder Joystick links
- if ((event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT) or
- (event.type == pygame.JOYHATMOTION and event.value[0] == -1) or
- (event.type == pygame.JOYBUTTONDOWN and event.button == 2)):
- return True
-
- return False
-
-
-def is_UP_event(event):
- # Tastatur oder Joystick oben
- if ((event.type == pygame.KEYDOWN and event.key == pygame.K_UP) or
- (event.type == pygame.JOYHATMOTION and event.value[1] == 1) or
- (event.type == pygame.JOYBUTTONDOWN and event.button == 3)):
- return True
-
- return False
-
-async def init_game():
- global screen, clock, font, controls
- pygame.init()
- pygame.joystick.init()
- init_sounds()
-
- if pygame.joystick.get_count() > 0:
- joystick = pygame.joystick.Joystick(0)
- joystick.init()
- print(f"Controller erkannt: {joystick.get_name()}")
- controls = "tutorial_controller"
- else:
- controls = "tutorial"
- print("Kein Controller gefunden.")
-
- screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
- pygame.display.set_caption("Habegger Loader Game")
- clock = pygame.time.Clock()
- font = pygame.font.SysFont(None, 48)
-
-class Case:
- def __init__(self, size=None):
- global case_index
- self.rotated = False
- if not case_sequence:
- generate_fill_sequence()
- if size is None:
- size = case_sequence[case_index % len(case_sequence)]
- case_index += 1
- self.length_units, self.height_units = size['w'], size['h']
- if size['rotated']:
- self.length_units, self.height_units = self.height_units, self.length_units
- elif self.height_units * UNIT_LENGTH <= TRAILER_WIDTH and self.length_units * UNIT_HEIGHT <= TRAILER_HEIGHT and random.choice(
- [True, False]):
- self.length_units, self.height_units = self.height_units, self.length_units
- self.width = self.length_units * UNIT_LENGTH
- self.height = self.height_units * UNIT_HEIGHT
- self.x = SCREEN_WIDTH
- self.spawn_y = TRAILER_Y + TRAILER_HEIGHT - self.height
- self.y = self.spawn_y
- self.entry_angle = 0
- self.color = random.choice(CASE_COLORS)
- self.placed = False
- self.allow_snap = False
- self.snapped = False
- self.occupied = False
- self.rotated = False # <==== WICHTIG: HINZUFÜGEN!!!
- global current_case_visible
- current_case_visible = True
-
- def move(self):
- global collision_x
- if not self.placed and not pygame.mixer.Channel(1).get_busy():
- if sound_roll:
- pygame.mixer.Channel(1).play(sound_roll, loops=-1)
- distance_to_obstacle = self.x - collision_x
- speed = CASE_SPEED_FAST if distance_to_obstacle > FAST_TO_SLOW_DISTANCE else CASE_SPEED_SLOW
- self.x -= speed
- if self.x <= collision_x + SNAP_THRESHOLD:
- self.allow_snap = True
-
- async def fail_snap(self):
- global collision_x
- steps = 5
- bounce_distance = 20 # Pixel zurückspringen
-
- for _ in range(steps):
- self.x += bounce_distance / steps
- draw_game()
- pygame.display.flip()
- await asyncio.sleep(0)
-
- self.placed = True
- self.snapped = True
- collision_x = self.x + self.width
-
- def can_place_on_top(self):
- if self.placed:
- return False
- for base in reversed(stacked_cases):
- if base.y <= TRAILER_Y:
- continue
- height_ok = base.y - self.height >= TRAILER_Y
- width_ok = self.width <= base.width
- aligned_with_barrier = abs(base.x + base.width - collision_x) < 5
- space_free = all(not (
- other.y + other.height == base.y and
- other.x < base.x + base.width and
- other.x + other.width > base.x
- ) for other in stacked_cases)
- if height_ok and width_ok and aligned_with_barrier and space_free:
- return True
- return False
-
- def collides_with_barrier(self):
- return not self.snapped and self.x <= collision_x
-
- def draw(self, surface=None):
- global screen
- surface = surface or screen
- angle = getattr(self, 'entry_angle', 0)
- if self.rotated:
- key = f"case_w{self.height_units}_h{self.length_units}"
- else:
- key = f"case_w{self.length_units}_h{self.height_units}"
- image = case_images.get(key)
- if image:
- if self.rotated:
- image_to_draw = pygame.transform.scale(image, (self.height, self.width))
- else:
- image_to_draw = pygame.transform.scale(image, (self.width, self.height))
- if self.rotated:
- image_to_draw = pygame.transform.rotate(image_to_draw, 90)
- if angle != 0:
- image_to_draw = pygame.transform.rotate(image_to_draw, angle)
- rect = image_to_draw.get_rect(center=(self.x + self.width // 2, self.y + self.height // 3))
- surface.blit(image_to_draw, rect)
- else:
- surface.blit(image_to_draw, (self.x, self.y))
- else:
- pygame.draw.rect(surface, self.color, (self.x, self.y, self.width, self.height))
- async def animate_snap(self):
- if sound_roll:
- pygame.mixer.Channel(1).stop()
- global collision_x
- target_x = collision_x
- steps = 10
- delta = (self.x - target_x) / steps
- for _ in range(steps):
- self.x -= delta
- draw_game()
- pygame.display.flip()
- await asyncio.sleep(0)
- self.x = target_x
- self.placed = True
- self.snapped = True
- collision_x = self.x + self.width
-
- async def animate_tip(self):
- global current_case_visible
- current_case_visible = False
- key = f"case_w{self.length_units}_h{self.height_units}"
- image = case_images.get(key)
- if image:
- original = pygame.transform.scale(image, (self.width, self.height)).convert_alpha()
- else:
- original = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
- pygame.draw.rect(original, self.color, (0, 0, self.width, self.height))
- steps = 10
- for step in range(steps + 1):
- angle = step * (90 / steps)
- rotated = pygame.transform.rotate(original, angle)
- new_rect = rotated.get_rect(bottomleft=(self.x, self.y + self.height))
- draw_game()
- screen.blit(rotated, new_rect)
- pygame.display.flip()
- await asyncio.sleep(0)
- self.width, self.height = self.height, self.width
- self.length_units, self.height_units = self.height_units, self.length_units
- self.rotated = not getattr(self, 'rotated', False)
- self.x = max(collision_x + SNAP_THRESHOLD // 2, self.x)
- self.y = TRAILER_Y + TRAILER_HEIGHT - self.height
- current_case_visible = True
-
- async def animate_place_on_top(self):
- if sound_roll:
- pygame.mixer.Channel(1).stop()
- global current_case_visible, collision_x
- for base in reversed(stacked_cases):
- height_ok = base.y - self.height >= TRAILER_Y
- width_ok = self.width <= base.width
- space_free = all(not (
- other.y + other.height == base.y and
- other.x < base.x + base.width and
- other.x + other.width > base.x
- ) for other in stacked_cases)
- if height_ok and width_ok and space_free:
- start_y = self.y
- target_y = base.y - self.height
- steps = 10
- for step in range(steps):
- self.y = start_y - ((start_y - target_y) * (step + 1) / steps)
- draw_game()
- pygame.display.flip()
- await asyncio.sleep(0)
- self.y = target_y
- start_x = self.x
- target_x = base.x + base.width - self.width
- for step in range(steps):
- self.x = start_x - ((start_x - target_x) * (step + 1) / steps)
- draw_game()
- pygame.display.flip()
- await asyncio.sleep(0)
- self.x = target_x
- self.placed = True
- self.snapped = True
- collision_x = self.x + self.width
- return True
- current_case_visible = True
- return False
-
-def load_case_images():
- global case_images
- for w in range(1, 5):
- for h in range(1, 4):
- key = f"case_w{w}_h{h}"
- path = f"images/{key}.png"
- if os.path.exists(path):
- case_images[key] = pygame.image.load(path).convert_alpha()
-
-async def show_start_sequence():
- global zip_sound
- center_x = TRAILER_X + TRAILER_WIDTH // 2
- center_y = TRAILER_Y + TRAILER_HEIGHT // 2
- colors = [(255, 0, 0), (255, 200, 0), (0, 255, 0)]
- delays = [1000, 1000, 1000] # ms pro Punkt
- sounds = [sound_tut1, sound_tut2, sound_tuuut]
- radius = 90
-
- for i in range(3):
- await asyncio.sleep(0)
- draw_game(hide_trailer=True)
- pygame.draw.circle(screen, colors[i], (center_x, center_y), radius)
- sounds[i].play()
- pygame.display.flip()
- pygame.time.delay(delays[i])
-
- # Reißverschluss-Effekt
- zip_sound.play()
- duration = 200
- steps = 60
- for step in range(steps + 1):
- await asyncio.sleep(0)
- width = int(TRAILER_WIDTH * (step / steps))
- draw_game(hide_trailer=True)
- pygame.draw.rect(screen, (100, 100, 100), (TRAILER_X, TRAILER_Y, width, TRAILER_HEIGHT))
- pygame.display.flip()
- pygame.time.delay(duration // steps)
-
-def load_instruction_image():
- global controls
- try:
- image = pygame.image.load("images/"+controls+".png")
- return pygame.transform.scale(image, (SCREEN_WIDTH, SCREEN_HEIGHT))
- except:
- return None
-
-def load_background():
- try:
- image = pygame.image.load("images/background.png")
- return pygame.transform.scale(image, (SCREEN_WIDTH, GAME_AREA_HEIGHT))
- except:
- return None
-
-def draw_game(hide_trailer=False):
- global shake_timer
- offset_x = random.randint(-5, 5) if shake_timer > 0 else 0
- offset_y = random.randint(-5, 5) if shake_timer > 0 else 0
- if shake_timer > 0:
- shake_timer -= 1
- screen.fill((0, 0, 0))
- pygame.draw.rect(screen, (0, 0, 0), (0, 0, SCREEN_WIDTH, TOP_BAR_HEIGHT))
- title_font = pygame.font.SysFont(None, 64)
- title_surface = title_font.render("Habegger Loader Game", True, (255, 255, 255))
- screen.blit(title_surface, (50, 50))
-
- # === Ladebalken zeichnen ===
- percent_full = calculate_load_percent()
- bar_width = 400
- bar_height = 30
- bar_x = SCREEN_WIDTH - bar_width - 50
- bar_y = 50
- pygame.draw.rect(screen, (80, 80, 80), (bar_x, bar_y, bar_width, bar_height))
- pygame.draw.rect(screen, (0, 255, 0), (bar_x, bar_y, bar_width * (percent_full / 100), bar_height))
- bar_font = pygame.font.SysFont(None, 36)
- bar_text = bar_font.render(f"{int(percent_full)}% geladen", True, (255, 255, 255))
- screen.blit(bar_text, (bar_x + bar_width // 2 - bar_text.get_width() // 2, bar_y + bar_height // 2 - bar_text.get_height() // 2))
-
- # === Vorschau nächstes Case (nur Text) ===
- preview_box_width = 150
- preview_box_height = 80
- preview_box_x = (SCREEN_WIDTH - preview_box_width) // 2
- preview_box_y = SCREEN_HEIGHT - preview_box_height - 20
-
- # Grauer Hintergrundkasten
- pygame.draw.rect(screen, (80, 80, 80), (preview_box_x, preview_box_y, preview_box_width, preview_box_height),
- border_radius=12)
-
- # Überschrift: "B x H"
- title_font = pygame.font.SysFont(None, 28)
- title_surface = title_font.render("Next: (B x H)", True, (200, 200, 200))
- title_x = preview_box_x + (preview_box_width - title_surface.get_width()) // 2
- title_y = preview_box_y + 5
- screen.blit(title_surface, (title_x, title_y))
-
- # Text für nächstes Case (z.B. "2x1")
- if next_queue:
- next_case = next_queue[0]
- preview_text = f"{next_case['w']}x{next_case['h']}"
- preview_font = pygame.font.SysFont(None, 48)
- text_surface = preview_font.render(preview_text, True, (255, 255, 255))
- text_x = preview_box_x + (preview_box_width - text_surface.get_width()) // 2
- text_y = title_y + title_surface.get_height() + 5
- screen.blit(text_surface, (text_x, text_y))
-
- # === Echte Vorschau der nächsten 3 Cases (horizontal in Top-Bar) ===
- preview_start_x = 50
- preview_start_y = SCREEN_HEIGHT - 200
- spacing_between_cases = 80 # Fester Abstand zwischen den Vorschau-Cases
- title_next = title_font.render("Next 3:", True, (200, 200, 200))
- title_x = 50
- title_y = SCREEN_HEIGHT - 250
- screen.blit(title_next, (title_x, title_y))
-
- current_x = preview_start_x
-
- for i, case_data in enumerate(next_queue[:3]):
- preview_width = case_data['w'] * (UNIT_LENGTH // 2)
- preview_height = case_data['h'] * (UNIT_HEIGHT // 2)
- preview_case_surface = pygame.Surface((preview_width, preview_height), pygame.SRCALPHA)
-
- # Bild laden oder Rechteck zeichnen
- key = f"case_w{case_data['w']}_h{case_data['h']}"
- image = case_images.get(key)
-
- if image:
- image = pygame.transform.scale(image, (preview_width, preview_height))
- preview_case_surface.blit(image, (0, 0))
- else:
- pygame.draw.rect(preview_case_surface, (180, 180, 180), (0, 0, preview_width, preview_height))
-
- preview_y = preview_start_y
-
- # Blit auf Hauptscreen
- screen.blit(preview_case_surface, (current_x, preview_y))
-
- # Nächste X-Position anpassen
- current_x += preview_width + spacing_between_cases
-
- if background_image:
- screen.blit(background_image, (0, TOP_BAR_HEIGHT))
- else:
- pygame.draw.rect(screen, (0, 0, 0), (0, TOP_BAR_HEIGHT, SCREEN_WIDTH, GAME_AREA_HEIGHT))
- if not hide_trailer:
- pygame.draw.rect(screen, (100, 100, 100),
- (TRAILER_X + offset_x, TRAILER_Y + offset_y, TRAILER_WIDTH, TRAILER_HEIGHT))
- for c in stacked_cases:
- c.draw(screen)
- if current_case and current_case_visible:
- current_case.draw(screen)
-
-async def show_instruction_screen(image):
- if not image:
- return
- waiting = True
- while waiting:
- screen.blit(image, (0, 0))
- pygame.display.flip()
- await asyncio.sleep(0)
- for event in pygame.event.get():
- await asyncio.sleep(0)
- result = touch(event)
- if event.type == pygame.QUIT:
- pygame.quit()
- sys.exit()
- elif is_SPACE_event(event) or (result == "snap"):
- waiting = False
-
-async def fail_current_case():
- global can_use_tilt, can_use_on_top, game_finished, shake_timer
- if sound_fail:
- sound_fail.play()
- await current_case.fail_snap()
- if current_case.x + current_case.width > TRAILER_X + TRAILER_WIDTH:
- if stacked_cases and stacked_cases[-1] == current_case:
- stacked_cases.pop()
- else:
- stacked_cases.append(current_case)
- can_use_tilt = True
- can_use_on_top = True
- spawn_case_in_game()
- shake_timer = 10
-
-def generate_fill_sequence():
- global case_sequence
- try:
- with open("case_sequences.txt", "r") as f:
- sets = re.split(r"\r?\n\r?\n", f.read().strip())
- print(f"Anzahl erkannter Sets: {len(sets)}")
-
- index = random.randint(0, len(sets) - 1)
- print(f"Zufällig gewählter Index: {index}")
-
- chosen_raw = sets[index].strip()
- print("Erste Zeilen des gewählten Sets:")
- print("\n".join(chosen_raw.splitlines()[:3])) # Zeigt max. 3 Zeilen an
-
- chosen = chosen_raw.split("\n")
- sequence = []
- for line in chosen:
- parts = line.strip().split(",")
- if len(parts) == 3:
- w, h, rot = int(parts[0]), int(parts[1]), parts[2].strip().lower() == 'true'
- sequence.append({'w': w, 'h': h, 'rotated': rot})
- case_sequence = sequence
-
- except Exception as e:
- print("Fehler beim Laden der Sequenz:", e)
- case_sequence = [{'w': 2, 'h': 1, 'rotated': False}, {'w': 1, 'h': 2, 'rotated': False}]
-
-
-def spawn_case_in_game():
- global current_case, next_queue, case_index
- if not case_sequence:
- generate_fill_sequence()
-
- while len(next_queue) < 3:
- index = (case_index + len(next_queue)) % len(case_sequence)
- next_queue.append(case_sequence[index])
-
- if case_index >= len(case_sequence):
- current_case = None
- return
- case_data = case_sequence[case_index % len(case_sequence)]
- case_index += 1
-
- if next_queue:
- next_queue.pop(0)
- while len(next_queue) < 3:
- index = (case_index + len(next_queue)) % len(case_sequence)
- next_queue.append(case_sequence[index])
-
- current_case = Case(size=case_data)
-
-async def show_game_over(score):
- import sys
- import urllib.parse
-
- try:
- import js
- except ImportError:
- js = None
- username = "Spieler"
-
- try:
- query = js.window.location.search
- params = urllib.parse.parse_qs(query[1:])
- username = params.get("name", ["Spieler"])[0]
- except Exception:
- pass
-
- data = {
- "name": username,
- "score": int(score),
- "api_key": "hag-trailer-8051"
- }
-
- def is_browser():
- return sys.platform in ("emscripten", "wasi")
-
- if is_browser():
- global prepared_form, ready_to_submit
-
- if not is_browser() or js is None:
- return
-
- try:
- form = js.document.createElement("form")
- form.method = "POST"
- form.action = "https://hag-game.carabella.ch/submit_points.php"
-
- for key, value in data.items():
- input_field = js.document.createElement("input")
- input_field.type = "hidden"
- input_field.name = key
- input_field.value = str(value)
- form.appendChild(input_field)
-
- js.document.body.appendChild(form)
-
- prepared_form = form
- ready_to_submit = True
-
- print("Formular vorbereitet. Warten auf Bestätigung (SPACE oder Klick).")
-
- except Exception as e:
- print("Fehler beim Formular vorbereiten:", e)
-
-
- else:
- try:
- import urllib.request
- body = urllib.parse.urlencode(data).encode()
- req = urllib.request.Request(
- url="https://hag-game.carabella.ch/submit_points.php",
- data=body,
- method="POST",
- headers={
- "Content-Type": "application/x-www-form-urlencoded",
- }
- )
- with urllib.request.urlopen(req) as response:
- if response.getcode() != 200:
- raise Exception("HTTP error")
- print("Punkte erfolgreich lokal gesendet!")
- except Exception as e:
- print("Fehler beim lokalen Senden:", e)
-
- pygame.mixer.stop()
- overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
- overlay.set_alpha(220)
- overlay.fill((0, 0, 0))
- screen.blit(overlay, (0, 0))
- font_big = pygame.font.SysFont(None, 72)
- message = f"Spiel beendet! Punkte: {int(score)}%. Drücke die Leertaste um deine Punkte zu übermitteln."
- text = font_big.render(message, True, (255, 255, 255))
- screen.blit(text, (SCREEN_WIDTH // 2 - text.get_width() // 2, SCREEN_HEIGHT // 2 - text.get_height() // 2))
- pygame.display.flip()
-
- waiting = True
- while waiting:
- await asyncio.sleep(0)
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- pygame.quit()
- sys.exit()
- elif is_SPACE_event(event) or (touch(event) == "snap"):
- if ready_to_submit and prepared_form:
- print("Benutzer bestätigt, Punkte werden jetzt gesendet.")
- prepared_form.submit()
- pygame.quit()
- sys.exit()
-
-def calculate_load_percent():
- total_volume = TRAILER_WIDTH * TRAILER_HEIGHT
- used_volume = sum([c.width * c.height for c in stacked_cases])
- return min(100, (used_volume / total_volume) * 100)
-
-async def main():
- global running, can_use_tilt, can_use_on_top, game_finished
- global current_case, transition_counter, state
- global screen, clock, font, instruction_image, background_image
- global touch_start
-
- await init_game()
- load_case_images()
- instruction_image = load_instruction_image()
- background_image = load_background()
- generate_fill_sequence()
-
- await asyncio.sleep(1)
- await show_instruction_screen(instruction_image)
- await show_start_sequence()
- spawn_case_in_game()
-
- running = True
- can_use_tilt = True
- can_use_on_top = True
- game_finished = False
-
- while running:
- if not game_finished and collision_x > TRAILER_X + TRAILER_WIDTH:
- await show_game_over(calculate_load_percent())
- game_finished = True
- continue
- if not game_finished and current_case is None and case_index >= len(case_sequence):
- await show_game_over(calculate_load_percent())
- game_finished = True
- continue
-
- clock.tick(FPS)
- await asyncio.sleep(0)
-
- if transition_counter > 0:
- transition_counter -= 1
- draw_game()
- pygame.display.flip()
- await asyncio.sleep(0)
- continue
-
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- running = False
- elif event.type == pygame.KEYDOWN or event.type == pygame.JOYBUTTONDOWN or event.type == pygame.JOYHATMOTION or event.type == pygame.FINGERDOWN or touch_start or (event.type == pygame.MOUSEBUTTONDOWN and event.button == 1):
- if state == 1: # PLAYING
- result = "none"
- if event.type == pygame.FINGERUP and touch_start:
- result = touch(event)
- elif event.type == pygame.FINGERDOWN and not touch_start:
- touch(event)
- print(result)
- if is_LEFT_event(event) or (result == "ontop"):
- can_tip = current_case.length_units * UNIT_HEIGHT <= TRAILER_HEIGHT
- if current_case and current_case.allow_snap and can_use_tilt and can_tip:
- await current_case.animate_tip()
- can_use_tilt = False
- elif is_UP_event(event) or (result == "tilt"):
- if current_case and current_case.allow_snap and can_use_on_top and current_case.can_place_on_top():
- if await current_case.animate_place_on_top():
- transition_counter = transition_fps
- if sound_place:
- sound_place.play()
- stacked_cases.append(current_case)
- spawn_case_in_game()
- can_use_tilt = True
- can_use_on_top = True
- else:
- await current_case.fail_snap()
- if sound_place:
- sound_place.play()
- stacked_cases.append(current_case)
- spawn_case_in_game()
- shake_timer = 10
- elif is_SPACE_event(event) or (result == "snap"):
-
- if current_case and current_case.allow_snap:
- await current_case.animate_snap()
- can_use_tilt = True
- can_use_on_top = True
- if sound_place:
- sound_place.play()
- transition_counter = transition_fps
- stacked_cases.append(current_case)
- spawn_case_in_game()
-
- if state == 1: # PLAYING
- if current_case is None:
- continue
- if current_case:
- current_case.move()
- if current_case.collides_with_barrier():
- await fail_current_case()
- if not game_finished:
- can_tip = current_case.length_units * UNIT_HEIGHT <= TRAILER_HEIGHT
- if collision_x + current_case.width > TRAILER_X + TRAILER_WIDTH and not current_case.can_place_on_top() and not current_case.allow_snap and not can_tip:
- await show_game_over(calculate_load_percent())
- game_finished = True
- continue
- if calculate_load_percent() >= 99.9 and case_index >= len(case_sequence):
- await show_game_over(100)
- game_finished = True
- continue
- if not current_case.placed and current_case.collides_with_barrier():
- await current_case.fail_snap()
- if current_case.x + current_case.width > TRAILER_X + TRAILER_WIDTH:
- if stacked_cases and stacked_cases[-1] == current_case:
- stacked_cases.pop()
- else:
- stacked_cases.append(current_case)
- can_use_tilt = True
- can_use_on_top = True
- if sound_fail:
- sound_fail.play()
- spawn_case_in_game()
- shake_timer = 10
- draw_game()
-
- pygame.display.flip()
-
- pygame.quit()
- sys.exit()
-
-# === Spielstart ===
-if __name__ == "__main__":
- asyncio.run(main())
diff --git a/sounds/fail-pygbag.ogg b/sounds/fail-pygbag.ogg
deleted file mode 100644
index 5239ba7..0000000
Binary files a/sounds/fail-pygbag.ogg and /dev/null differ
diff --git a/sounds/fail.ogg b/sounds/fail.ogg
deleted file mode 100644
index f5fc68c..0000000
Binary files a/sounds/fail.ogg and /dev/null differ
diff --git a/sounds/place-pygbag.ogg b/sounds/place-pygbag.ogg
deleted file mode 100644
index 5fbc887..0000000
Binary files a/sounds/place-pygbag.ogg and /dev/null differ
diff --git a/sounds/place.ogg b/sounds/place.ogg
deleted file mode 100644
index 3a35499..0000000
Binary files a/sounds/place.ogg and /dev/null differ
diff --git a/sounds/roll-pygbag.ogg b/sounds/roll-pygbag.ogg
deleted file mode 100644
index 5cee11f..0000000
Binary files a/sounds/roll-pygbag.ogg and /dev/null differ
diff --git a/sounds/roll.ogg b/sounds/roll.ogg
deleted file mode 100644
index dcef05c..0000000
Binary files a/sounds/roll.ogg and /dev/null differ
diff --git a/sounds/tut1-pygbag.ogg b/sounds/tut1-pygbag.ogg
deleted file mode 100644
index 3273d5b..0000000
Binary files a/sounds/tut1-pygbag.ogg and /dev/null differ
diff --git a/sounds/tut1.ogg b/sounds/tut1.ogg
deleted file mode 100644
index c3dc9b1..0000000
Binary files a/sounds/tut1.ogg and /dev/null differ
diff --git a/sounds/tut2-pygbag.ogg b/sounds/tut2-pygbag.ogg
deleted file mode 100644
index 8694191..0000000
Binary files a/sounds/tut2-pygbag.ogg and /dev/null differ
diff --git a/sounds/tut2.ogg b/sounds/tut2.ogg
deleted file mode 100644
index 6b300af..0000000
Binary files a/sounds/tut2.ogg and /dev/null differ
diff --git a/sounds/tuuut-pygbag.ogg b/sounds/tuuut-pygbag.ogg
deleted file mode 100644
index 3f61ab5..0000000
Binary files a/sounds/tuuut-pygbag.ogg and /dev/null differ
diff --git a/sounds/tuuut.ogg b/sounds/tuuut.ogg
deleted file mode 100644
index 3bdbcdd..0000000
Binary files a/sounds/tuuut.ogg and /dev/null differ
diff --git a/sounds/zip-pygbag.ogg b/sounds/zip-pygbag.ogg
deleted file mode 100644
index b86f8b7..0000000
Binary files a/sounds/zip-pygbag.ogg and /dev/null differ
diff --git a/sounds/zip.ogg b/sounds/zip.ogg
deleted file mode 100644
index aa5237d..0000000
Binary files a/sounds/zip.ogg and /dev/null differ