You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
5.7 KiB
145 lines
5.7 KiB
import pygame
|
|
import settings
|
|
from player import Player
|
|
from obstacle import Obstacle
|
|
import random
|
|
from item import Item
|
|
|
|
class World:
|
|
def __init__(self, screen, player_name=""):
|
|
|
|
self.start_ticks = pygame.time.get_ticks()
|
|
self.level_started = False
|
|
self.level_start_time = None
|
|
self.time_passed = 0
|
|
|
|
# Hindernisse
|
|
self.obstacles = []
|
|
|
|
while len(self.obstacles) < settings.world.obstacle.amount:
|
|
x = random.randint(500, 12500)
|
|
# 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):
|
|
self.obstacles.append(Obstacle(x, 500, settings.world.obstacle.box))
|
|
|
|
|
|
# ITEMS
|
|
self.items = []
|
|
|
|
while len(self.items) < settings.world.items.amount:
|
|
x = random.randint(200, 12800)
|
|
y = random.randint(100, 500)
|
|
# 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):
|
|
self.items.append(Item(x, y))
|
|
|
|
# Welt Generierung
|
|
self.screen = screen
|
|
self.background = pygame.image.load(settings.BACKGROUND_IMG).convert()
|
|
self.bg_width = self.background.get_width()
|
|
|
|
# Boden
|
|
self.ground_rect = pygame.Rect(0, 650, 5000 * 2.7, 80) # Boden
|
|
full_image = pygame.image.load(settings.world.ground.img).convert_alpha()
|
|
# --- Ausschneiden des Bereichs
|
|
cropped = pygame.Surface((settings.world.ground.crop_scale_right, settings.world.ground.crop_height), pygame.SRCALPHA)
|
|
cropped.blit(full_image, (0, 0), (0, settings.world.ground.crop_top, settings.world.ground.crop_scale_right, settings.world.ground.crop_height))
|
|
# --- Skalieren für Anzeige
|
|
self.ground_image = pygame.transform.scale(cropped, (settings.world.ground.scale_width, settings.world.ground.scale_height))
|
|
self.tile_width = self.ground_image.get_width()
|
|
|
|
# ZIEL FLAGGEN
|
|
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)
|
|
|
|
# Spieler
|
|
self.player = Player(200, 500) # Spieler
|
|
|
|
# SCORE
|
|
self.save_score = 0
|
|
|
|
# Spielername
|
|
self.player_name = player_name
|
|
|
|
def draw(self):
|
|
|
|
self.screen.fill((0, 0, 0)) # Bildschirm löschen, bevor gezeichnet wird
|
|
camera_offset = self.player.rect.centerx - settings.SCREEN_WIDTH // 2
|
|
world_width = max(self.bg_width, max([obs.rect.right for obs in self.obstacles] + [self.ground_rect.right]))
|
|
camera_offset = max(0, min(camera_offset, world_width - settings.SCREEN_WIDTH))
|
|
score = self.player.update(
|
|
ground_y=self.ground_rect.top,
|
|
obstacles=self.obstacles,
|
|
items=self.items,
|
|
score=0,
|
|
input_allowed=self.level_started
|
|
)
|
|
|
|
|
|
if score != 0:
|
|
self.save_score += 10
|
|
print(self.save_score) if settings.DEBUG else None
|
|
|
|
bg_offset = int(camera_offset * 0.3) # Parallax: langsamer bewegen
|
|
self.screen.blit(self.background, (-bg_offset, 0))
|
|
# Boden kacheln ohne Parallax
|
|
start_tile = (camera_offset // self.tile_width) * self.tile_width
|
|
end_x = camera_offset + settings.SCREEN_WIDTH
|
|
x = start_tile
|
|
while x < end_x:
|
|
screen_x = x - camera_offset
|
|
self.screen.blit(self.ground_image, (screen_x, self.ground_rect.top))
|
|
x += self.tile_width
|
|
|
|
for obs in self.obstacles:
|
|
obs.draw(self.screen, camera_offset)
|
|
|
|
for items in self.items:
|
|
items.draw(self.screen, camera_offset)
|
|
|
|
player_screen_x = self.player.rect.x - camera_offset
|
|
|
|
# ZIEL FLAGGEN BACK
|
|
self.screen.blit(self.goal_flag, (settings.world.goal.position_x - camera_offset, self.ground_rect.top-160))
|
|
|
|
# PLAYER
|
|
self.screen.blit(self.player.image, (player_screen_x, self.player.rect.y))
|
|
|
|
font = pygame.font.Font(settings.fonts.PressStart2P, 24)
|
|
name_surface = font.render(self.player_name, True, (255, 255, 255))
|
|
self.screen.blit(name_surface, (20, 20))
|
|
|
|
current_ticks = pygame.time.get_ticks()
|
|
elapsed_seconds = (current_ticks - self.start_ticks) // 1000
|
|
|
|
if not self.level_started:
|
|
countdown = max(0, settings.world.countdown - elapsed_seconds)
|
|
|
|
font = pygame.font.Font(settings.fonts.PressStart2P, 72)
|
|
if countdown > 0:
|
|
countdown_surface = font.render(str(countdown), True, (255, 255, 255))
|
|
else:
|
|
countdown_surface = font.render("GO!", True, (0, 255, 0))
|
|
|
|
text_rect = countdown_surface.get_rect(center=(settings.SCREEN_WIDTH // 2, settings.SCREEN_HEIGHT // 2))
|
|
self.screen.blit(countdown_surface, text_rect)
|
|
|
|
if countdown == 0:
|
|
if self.level_start_time is None:
|
|
self.level_start_time = pygame.time.get_ticks()
|
|
if elapsed_seconds >= settings.world.countdown:
|
|
self.level_started = True
|
|
return # Solange Countdown läuft, alles andere nicht zeichnen
|
|
else:
|
|
self.time_passed = (pygame.time.get_ticks() - self.level_start_time) / 1000 # in Sekunden
|
|
|
|
|
|
def handle_event(self, event):
|
|
if not self.level_started:
|
|
return None # Keine Events verarbeiten, solange Countdown läuft
|
|
if event.type == pygame.KEYDOWN:
|
|
if event.key == pygame.K_ESCAPE:
|
|
if settings.DEBUG:
|
|
print("ESC-Pressed")
|
|
return "menu"
|
|
return None |