Add sounds and Function with controller

main
Samuel Zielke 7 months ago
parent 14414ab17a
commit d94f1bab5e

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,68 @@
import pygame
import settings
from settings import MyColors
class GameOver:
def __init__(self, screen):
self.screen = screen
self.background = pygame.image.load(settings.BACKGROUND_IMG_COMP).convert_alpha()
icon_controller_retry = pygame.image.load(settings.icons.controller.viereck).convert_alpha()
self.icon_controller_retry = pygame.transform.scale(icon_controller_retry, (50, 48))
icon_controller_menu = pygame.image.load(settings.icons.controller.dreieck).convert_alpha()
self.icon_controller_menu = pygame.transform.scale(icon_controller_menu, (50, 48))
self.font = pygame.font.Font(settings.fonts.PressStart2P, 60)
self.small_font = pygame.font.Font(settings.fonts.PressStart2P, 24)
self.retry_button = pygame.Rect(390, 400, 200, 50)
self.menu_button = pygame.Rect(690, 400, 200, 50)
def draw(self):
# self.screen.blit(self.background, (0, 0))
overlay = pygame.Surface((settings.SCREEN_WIDTH, settings.SCREEN_HEIGHT)) # Neues Surface in Bildschirmgröße
overlay.set_alpha(50) # 0 = komplett durchsichtig, 255 = komplett undurchsichtig
overlay.fill((0, 0, 0)) # Schwarz färben
self.screen.blit(overlay, (0, 0)) # Overlay auf
# Score-Text
score_text = self.font.render(f"GAME OVER", True, (255, 255, 255)) # z.B. Gold
self.screen.blit(score_text, (settings.SCREEN_WIDTH // 2 - score_text.get_width() // 2, 200))
time_text = self.small_font.render(f"Das wird schon wieder", True, (255, 255, 255))
self.screen.blit(time_text, (settings.SCREEN_WIDTH // 2 - time_text.get_width() // 2, 300))
pygame.draw.rect(self.screen, MyColors.yellow, self.retry_button)
pygame.draw.rect(self.screen, MyColors.yellow, self.menu_button)
nochmal_text = self.small_font.render("Nochmal", True, MyColors.brown)
menu_text = self.small_font.render("Menü", True, MyColors.brown)
self.screen.blit(nochmal_text, (self.retry_button.x + 15, self.retry_button.y + 10))
self.screen.blit(menu_text, (self.menu_button.x + 50, self.menu_button.y + 10))
self.screen.blit(self.icon_controller_retry, (self.retry_button.x + 70, self.retry_button.y + 40))
self.screen.blit(self.icon_controller_menu, ((self.menu_button.x + 70), self.menu_button.y + 40))
return self.retry_button, self.menu_button
def handle_event(self, event):
if event.type == pygame.MOUSEBUTTONDOWN:
print("MOUSEBUTTONDOWN") if settings.DEBUG else None
if self.retry_button.collidepoint(event.pos):
return "retry"
elif self.menu_button.collidepoint(event.pos):
return "menu"
if event.type == pygame.MOUSEBUTTONUP:
if self.retry_button.collidepoint(event.pos):
return "retry"
elif self.menu_button.collidepoint(event.pos):
return "menu"
if event.type == pygame.JOYBUTTONDOWN:
if event.button == 3:
return "menu"
elif event.button == 2:
return "retry"
return None

Binary file not shown.

@ -1,11 +1,13 @@
import pygame import pygame
import settings import settings
from settings import MyColors from settings import MyColors
import sqlite3
class Endscreen: class Endscreen:
def __init__(self, screen, score, time_passed=0): def __init__(self, screen, score=0, time_passed=0, player_name="Spieler1"):
self.screen = screen self.screen = screen
self.score = score self.score = score
self.player_name = player_name
self.background = pygame.image.load(settings.BACKGROUND_IMG_COMP).convert_alpha() self.background = pygame.image.load(settings.BACKGROUND_IMG_COMP).convert_alpha()
icon_controller_retry = pygame.image.load(settings.icons.controller.viereck).convert_alpha() icon_controller_retry = pygame.image.load(settings.icons.controller.viereck).convert_alpha()
@ -21,6 +23,29 @@ class Endscreen:
self.time_passed = time_passed self.time_passed = time_passed
self.save_score_to_db()
def save_score_to_db(self):
connection = sqlite3.connect('highscores.db')
cursor = connection.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS highscores (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
score INTEGER NOT NULL,
time REAL NOT NULL
)
''')
cursor.execute('''
INSERT INTO highscores (name, score, time)
VALUES (?, ?, ?)
''', (self.player_name, self.score, self.time_passed))
connection.commit()
connection.close()
def draw(self): def draw(self):
self.screen.blit(self.background, (0, 0)) self.screen.blit(self.background, (0, 0))

@ -5,6 +5,7 @@ from menu import Menu # Menü importieren
import settings import settings
from world import World from world import World
from level_complete_screen import Endscreen from level_complete_screen import Endscreen
from gameover import GameOver
def main(): def main():
pygame.joystick.init() pygame.joystick.init()
@ -58,13 +59,28 @@ def main():
menu.ready_to_start_game = False menu.ready_to_start_game = False
menu.player_name = "" menu.player_name = ""
if current_scene == "gameover":
action = endscreen.handle_event(event)
if action == "retry":
world = World(screen, menu.player_name)
current_scene = "world"
elif action == "menu":
current_scene = "menu"
menu.input_active = False
menu.show_main_buttons = True
menu.ready_to_start_game = False
menu.player_name = ""
if current_scene == "menu": if current_scene == "menu":
menu.draw() menu.draw()
elif current_scene == "world": elif current_scene == "world":
if not world.player.game_paused: if not world.player.game_paused and not world.player.gameOver:
world.draw() world.draw()
elif world.player.gameOver:
gameover = GameOver(screen)
current_scene = "gameover"
else: else:
endscreen = Endscreen(screen, world.save_score, world.time_passed) endscreen = Endscreen(screen, world.save_score, world.time_passed, world.player_name)
current_scene = "endscreen" current_scene = "endscreen"
if settings.DEBUG and not hasattr(world, 'level_end_printed'): if settings.DEBUG and not hasattr(world, 'level_end_printed'):
print("Level beendet!") print("Level beendet!")
@ -72,6 +88,9 @@ def main():
elif current_scene == "endscreen": elif current_scene == "endscreen":
endscreen.draw() endscreen.draw()
elif current_scene == "gameover":
gameover.draw()
pygame.display.flip() pygame.display.flip()
clock.tick(60) clock.tick(60)

@ -85,6 +85,21 @@ class Menu:
if settings.DEBUG: if settings.DEBUG:
print(f"Spielstart mit Spielername: {self.player_name}") print(f"Spielstart mit Spielername: {self.player_name}")
if event.type == pygame.JOYBUTTONDOWN:
if event.button == 2: # Button 2 auf den meisten Controllern ist Index 1
if self.show_main_buttons:
self.input_active = True
self.show_main_buttons = False
if settings.DEBUG:
print("Start gedrückt mit Controller")
elif self.input_active:
if self.player_name: # Name muss eingegeben sein
self.input_active = False
self.show_main_buttons = False
self.ready_to_start_game = True
if settings.DEBUG:
print(f"Spielstart mit Controller: {self.player_name}")
if event.type == pygame.KEYDOWN and self.input_active: if event.type == pygame.KEYDOWN and self.input_active:
if event.key == pygame.K_RETURN: if event.key == pygame.K_RETURN:
if self.player_name: # Nur wenn ein Name eingegeben wurde if self.player_name: # Nur wenn ein Name eingegeben wurde

@ -1,10 +1,18 @@
import pygame import pygame
import settings import settings
import random
class Obstacle: class Obstacle:
def __init__(self, x, y, image_path): def __init__(self, x):
self.image = pygame.image.load(image_path).convert_alpha() type = random.randint(1,2)
self.image = pygame.transform.scale(self.image, (400, 150)) # Größe anpassen if type == 1:
self.image = pygame.image.load(settings.world.obstacle.box).convert_alpha()
self.image = pygame.transform.scale(self.image, (400, 120)) # Größe anpassen
y = 530
if type == 2:
self.image = pygame.image.load(settings.world.obstacle.stone).convert_alpha()
self.image = pygame.transform.scale(self.image, (90, 80)) # Größe anpassen
y = 575
self.rect = self.image.get_rect(topleft=(x, y)) self.rect = self.image.get_rect(topleft=(x, y))
def draw(self, screen, camera_offset): def draw(self, screen, camera_offset):

@ -1,6 +1,11 @@
import pygame import pygame
import settings import settings
# Sound für das Einsammeln von Items laden
pygame.mixer.init()
pickup_sound = pygame.mixer.Sound("../assets/sounds/coin.mp3")
pickup_sound.set_volume(0.5)
class Player: class Player:
def __init__(self, x, y): def __init__(self, x, y):
# PLAYER BILDER # PLAYER BILDER
@ -21,6 +26,7 @@ class Player:
self.on_ground = False self.on_ground = False
self.game_paused = False self.game_paused = False
self.gameOver = False
self.broken_bones = 0 self.broken_bones = 0
self.last_collision_obstacle = None self.last_collision_obstacle = None
@ -35,61 +41,61 @@ class Player:
# Controller-Eingaben prüfen # Controller-Eingaben prüfen
for joystick in joysticks: for joystick in joysticks:
if joystick.get_axis(0) < -0.5: # Linker Stick links if joystick.get_axis(0) < -0.5:
move_left = True move_left = True
if joystick.get_axis(0) > 0.5: # Linker Stick rechts if joystick.get_axis(0) > 0.5:
move_right = True move_right = True
if joystick.get_button(0): # X-Button if joystick.get_button(0):
jump = True jump = True
# Bewegung seitlich # --- Horizontale Bewegung
dx = 0
if move_left and input_allowed: if move_left and input_allowed:
self.rect.x -= settings.player.speed dx = -settings.player.speed
if move_right and input_allowed: if move_right and input_allowed:
self.rect.x += settings.player.speed dx = settings.player.speed
self.rect.x += dx
# Springen for obs in obstacles:
if self.rect.colliderect(obs.get_rect()):
if dx > 0: # Bewegung nach rechts
self.rect.right = obs.get_rect().left - 10
if self.last_collision_obstacle != obs:
self.broken_bones += 1
self.last_collision_obstacle = obs
elif dx < 0: # Bewegung nach links
self.rect.left = obs.get_rect().right - 10
if self.last_collision_obstacle != obs:
self.broken_bones += 1
self.last_collision_obstacle = obs
# --- Vertikale Bewegung
if jump and self.on_ground and input_allowed: if jump and self.on_ground and input_allowed:
self.velocity_y = self.jump_strength self.velocity_y = self.jump_strength
self.on_ground = False self.on_ground = False
# Gravitation self.velocity_y += self.gravity
self.velocity_y += settings.player.gravity
self.rect.y += self.velocity_y self.rect.y += self.velocity_y
self.on_ground = False # zurücksetzen self.on_ground = False
# HINDERNISSE-KOLLISION
for obs in obstacles: for obs in obstacles:
if self.rect.colliderect(obs.get_rect()): if self.rect.colliderect(obs.get_rect()):
if self.velocity_y > 0 and self.rect.bottom - self.velocity_y < obs.get_rect().top: if self.velocity_y > 0: # Fallend
# Fred landet oben auf der Kiste
self.rect.bottom = obs.get_rect().top self.rect.bottom = obs.get_rect().top
self.velocity_y = 0 self.velocity_y = 0
self.on_ground = True self.on_ground = True
self.last_collision_obstacle = None self.last_collision_obstacle = None
else: elif self.velocity_y < 0: # Aufsteigend
# Seitenkollision - Fred wird blockiert UND Knochenbruch zählen self.rect.top = obs.get_rect().bottom
if abs(self.rect.right - obs.get_rect().left) < abs(settings.player.speed): self.velocity_y = 0
if self.last_collision_obstacle != obs:
self.broken_bones += 1
self.last_collision_obstacle = obs
self.rect.right = obs.get_rect().left # WICHTIG: stoppen!
elif abs(self.rect.left - obs.get_rect().right) < abs(settings.player.speed):
if self.last_collision_obstacle != obs:
self.broken_bones += 1
self.last_collision_obstacle = obs
self.rect.left = obs.get_rect().right # WICHTIG: stoppen!
else:
# Keine Kollision mehr → Reset
if self.last_collision_obstacle == obs:
self.last_collision_obstacle = None
# ITEM-KOLLISION # ITEM-KOLLISION
for item in items[:]: for item in items[:]:
if self.rect.colliderect(item.get_rect()): if self.rect.colliderect(item.get_rect()):
items.remove(item) items.remove(item)
score += 10 # Beispiel: 10 Punkte pro eingesammeltem Item score += 10
pickup_sound.play()
# Boden-Kollision # Boden-Kollision
if self.rect.bottom >= ground_y: if self.rect.bottom >= ground_y:
@ -97,16 +103,20 @@ class Player:
self.velocity_y = 0 self.velocity_y = 0
self.on_ground = True self.on_ground = True
# ZIEL FLAGGEN ACTION # Ziel-Flagge erreicht
if not self.game_paused and self.rect.left > settings.world.goal.position_x: if not self.game_paused and self.rect.left > settings.world.goal.position_x:
self.game_paused = True self.game_paused = True
# Bildlogik # CANCEL nach zu vielen Brüche
if self.broken_bones == 5:
self.gameOver = True
# Bild-Logik
if not self.on_ground: if not self.on_ground:
self.image = self.image_jump self.image = self.image_jump
elif keys[pygame.K_LEFT]: elif keys[pygame.K_LEFT] or move_left:
self.image = self.image_left self.image = self.image_left
elif keys[pygame.K_RIGHT]: elif keys[pygame.K_RIGHT] or move_right:
self.image = self.image_normal self.image = self.image_normal
else: else:
self.image = self.image_normal self.image = self.image_normal

@ -4,11 +4,11 @@ import random
SCREEN_WIDTH = 1280 SCREEN_WIDTH = 1280
SCREEN_HEIGHT = 720 SCREEN_HEIGHT = 720
FPS = 60 FPS = 60
DEBUG = True DEBUG = False
DEBUG_KEY_INPUT = False DEBUG_KEY_INPUT = False
DEBUG_ENDSCREEN = False DEBUG_ENDSCREEN = False
Mute = True Mute = True
START_POINT = "endscreen" # world, menu START_POINT = "menu" # world, menu
BACKGROUND_IMG = "../assets/backgrounds/background_III.png" BACKGROUND_IMG = "../assets/backgrounds/background_III.png"
BACKGROUND_IMG_COMP = "../assets/backgrounds/background-complete.png" BACKGROUND_IMG_COMP = "../assets/backgrounds/background-complete.png"
@ -18,8 +18,8 @@ class fonts:
class player: class player:
size = (110, 200) size = (110, 200)
speed = 25 if DEBUG else 18 speed = 25 if DEBUG else 17
gravity = 1.5 gravity = 1.7
jump_strength = -30 jump_strength = -30
class fred: class fred:
@ -29,6 +29,7 @@ class player:
class world: class world:
countdown = 3 #sekunden countdown = 3 #sekunden
brokenBone_image = "../assets/images/broken_bone.png"
class ground: class ground:
img = "../assets/world/ground_II.png" img = "../assets/world/ground_II.png"
crop_top = 500 crop_top = 500
@ -38,11 +39,12 @@ class world:
crop_scale_right = 1400 crop_scale_right = 1400
class obstacle: class obstacle:
amount = random.randint(4, 8) amount = 15
box = "../assets/obstacles/box.png" box = "../assets/obstacles/box.png"
stone = "../assets/obstacles/stone.png"
class items: class items:
amount = 15 amount = 23
class beer: class beer:
img = "../assets/images/items/bier.png" img = "../assets/images/items/bier.png"
size = (70, 85) size = (70, 85)
@ -50,7 +52,7 @@ class world:
class goal: class goal:
img = "../assets/world/GoalFlag.png" img = "../assets/world/GoalFlag.png"
size = (110,160) size = (110,160)
position_x = 13130 position_x = 29800
class icons: class icons:

@ -17,18 +17,18 @@ class World:
self.obstacles = [] self.obstacles = []
while len(self.obstacles) < settings.world.obstacle.amount: while len(self.obstacles) < settings.world.obstacle.amount:
x = random.randint(500, 12500) x = random.randint(500, 29500)
# Prüfen, ob der neue x weit genug entfernt ist von bestehenden Hindernissen # Prüfen, ob der neue x weit genug entfernt ist von bestehenden Hindernissen
if all(abs(x - obs.rect.x) > 800 for obs in self.obstacles): if all(abs(x - obs.rect.x) > 800 for obs in self.obstacles):
self.obstacles.append(Obstacle(x, 500, settings.world.obstacle.box)) self.obstacles.append(Obstacle(x))
# ITEMS # ITEMS
self.items = [] self.items = []
while len(self.items) < settings.world.items.amount: while len(self.items) < settings.world.items.amount:
x = random.randint(200, 12800) x = random.randint(200, 29500)
y = random.randint(100, 500) y = random.randint(100, 480)
# Prüfen, ob der neue x weit genug entfernt ist von bestehenden Hindernissen # Prüfen, ob der neue x weit genug entfernt ist von bestehenden Hindernissen
if all(abs(x - item.rect.x) > 200 for item in self.items): if all(abs(x - item.rect.x) > 200 for item in self.items):
self.items.append(Item(x, y)) self.items.append(Item(x, y))
@ -39,7 +39,7 @@ class World:
self.bg_width = self.background.get_width() self.bg_width = self.background.get_width()
# Boden # Boden
self.ground_rect = pygame.Rect(0, 650, 5000 * 2.7, 80) # Boden self.ground_rect = pygame.Rect(0, 650, 5000 * 6, 80) # Boden
full_image = pygame.image.load(settings.world.ground.img).convert_alpha() full_image = pygame.image.load(settings.world.ground.img).convert_alpha()
# --- Ausschneiden des Bereichs # --- Ausschneiden des Bereichs
cropped = pygame.Surface((settings.world.ground.crop_scale_right, settings.world.ground.crop_height), pygame.SRCALPHA) cropped = pygame.Surface((settings.world.ground.crop_scale_right, settings.world.ground.crop_height), pygame.SRCALPHA)
@ -52,6 +52,9 @@ class World:
goal_flag_image = pygame.image.load(settings.world.goal.img).convert_alpha() goal_flag_image = pygame.image.load(settings.world.goal.img).convert_alpha()
self.goal_flag = pygame.transform.scale(goal_flag_image, settings.world.goal.size) self.goal_flag = pygame.transform.scale(goal_flag_image, settings.world.goal.size)
# Knochenbrüche
brokenBone_image = pygame.image.load(settings.world.brokenBone_image).convert_alpha()
self.brokeBoneImage = pygame.transform.scale(brokenBone_image, (50,50))
# Spieler # Spieler
self.player = Player(200, 500) # Spieler self.player = Player(200, 500) # Spieler
@ -80,7 +83,7 @@ class World:
self.save_score += 10 self.save_score += 10
print(self.save_score) if settings.DEBUG else None print(self.save_score) if settings.DEBUG else None
bg_offset = int(camera_offset * 0.3) # Parallax: langsamer bewegen bg_offset = int(camera_offset * 0.125) # Parallax: langsamer bewegen
self.screen.blit(self.background, (-bg_offset, 0)) self.screen.blit(self.background, (-bg_offset, 0))
# Boden kacheln ohne Parallax # Boden kacheln ohne Parallax
start_tile = (camera_offset // self.tile_width) * self.tile_width start_tile = (camera_offset // self.tile_width) * self.tile_width
@ -106,13 +109,24 @@ class World:
self.screen.blit(self.player.image, (player_screen_x, self.player.rect.y)) self.screen.blit(self.player.image, (player_screen_x, self.player.rect.y))
# ANZEIGE # ANZEIGE
font = pygame.font.Font(settings.fonts.PressStart2P, 24) font = pygame.font.Font(settings.fonts.PressStart2P, 32)
name_surface = font.render(self.player_name, True, (255, 255, 255)) name_surface = font.render(self.player_name, True, (255, 255, 255))
score_surface = font.render(f"{self.save_score}", True, (255,255,0))
self.screen.blit(name_surface, (20, 20)) self.screen.blit(name_surface, (20, 20))
self.screen.blit(score_surface, (20, 120))
# KNOCHENBRÜCHE # KNOCHENBRÜCHE
bones_text = font.render(f"Schaden: {self.player.broken_bones}", True, (255, 255, 255)) if self.player.broken_bones < 5:
self.screen.blit(bones_text, (20, 60)) self.screen.blit(self.brokeBoneImage, (20, 50))
if self.player.broken_bones < 4:
self.screen.blit(self.brokeBoneImage, (70, 50))
if self.player.broken_bones < 3:
self.screen.blit(self.brokeBoneImage, (120, 50))
if self.player.broken_bones < 2:
self.screen.blit(self.brokeBoneImage, (170, 50))
if self.player.broken_bones < 1:
self.screen.blit(self.brokeBoneImage, (220, 50))
current_ticks = pygame.time.get_ticks() current_ticks = pygame.time.get_ticks()
elapsed_seconds = (current_ticks - self.start_ticks) // 1000 elapsed_seconds = (current_ticks - self.start_ticks) // 1000

Loading…
Cancel
Save

Powered by TurnKey Linux.