Pygame sprites werden nicht gezeichnet

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
Fire Spike
User
Beiträge: 329
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

Hallo ich brauche bei meinem Spiel wieder Hilfe, denn ich versuche Sprites dynamisch zu erstellen und anzuzeigen, aber leider werden sie nicht angezeigt.
Das Problem liegt bei der Object Klasse.
Könnt ihr mir vielleicht helfen?

Code: Alles auswählen

#!/usr/bin/python3

#pygame.colordict.THECOLORS[example]
import time
import pygame
# from tools import cursors, levels

WINDOW_TITLE = "Game"

WHITE = (255, 255, 255, 255)
RED = (255, 0, 0, 255)
GREEN = (0, 255, 0, 255)
BLUE = (0, 0, 255, 0)

COLOR = RED
FPS = 60

WIDTH = 1600
HEIGHT = 1000

PLAYER_Y = HEIGHT / 2
PLAYER_SIZE = 30

LEVEL_DATA = [
    [
        {
            "type": "line",
            "start time": 0.0,
            "end time": 2.0,
            "values": {
                "coordinates": [[0, 100], [100, 100]],
                "color": [0, 255, 200],
                "ID": None
            },
            "name": "stone"
        },
        {
            "type": "line",
            "start time": 5.0,
            "end time": 8.5,
            "values": {
                "coordinates": [[0, 100], [100, 120]],
                "color": [20, 255, 200],
                "ID": None
            },
            "name": "stone"
        }
    ],
    [
        {
            "type": "trigger",
            "start time": 5.1,
            "values": {
                "mode": "move",
                "duration": 1.5,
                "target coordinates": [[14, 134], [1345, 457]],
                "ID": 1,
            }
        }
    ]
]

def calculate_min_and_max_coordinates(coordinates):
    x_coordinates = []
    y_coordinates = []
    for x, y in coordinates:
        x_coordinates.append(x)
        y_coordinates.append(y)

    x_littlest = min(x_coordinates)
    x_biggest = max(x_coordinates)
    y_littlest = min(y_coordinates)
    y_biggest = max(y_coordinates)
    return [x_littlest, x_biggest, y_littlest, y_biggest]

def calculate_surface_size(min_max_coordinates):
    x_littlest, x_biggest, y_littlest, y_biggest = min_max_coordinates
    return [x_biggest - x_littlest, y_biggest - y_littlest]

def calculate_relative_coordinates(coordinates, min_max_coordinates):
    x_littlest, _, y_littlest, _ = min_max_coordinates
    relative_coordinates = []
    for x, y in coordinates:
        relative_coordinates.append([x - x_littlest, y - y_littlest])

    return relative_coordinates

class Object(pygame.sprite.Sprite):
    def __init__(self, object):
        pygame.sprite.Sprite.__init__(self)
        self.object = object
        self.finish = False
        self.coordinates = self.object["values"]["coordinates"]
        self.min_max_coordinates = calculate_min_and_max_coordinates(self.coordinates)
        self.width, self.height = calculate_surface_size(self.min_max_coordinates)
        self.image = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
        self.rect = self.image.get_rect(center=(self.min_max_coordinates[0], self.min_max_coordinates[2]))

    def draw_object(self):
        if self.object["type"] == "line":
            pygame.draw.line(self.image, tuple(self.object["values"]["color"]), self.coordinates[0], self.coordinates[1], 30)
            self.mask = pygame.mask.from_surface(self.image)
            
    def blit(self, screen):
        screen.blit(self.image, self.rect)
        
class Trigger:
    def __init__(self, trigger):
        self.trigger = trigger
        self.finish = False

class Cube(pygame.sprite.Sprite):
    STEP = 7
    def __init__(self, x):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface([PLAYER_SIZE, PLAYER_SIZE])
        self.image.fill(COLOR)
        self.rect = self.image.get_rect(center=(x, PLAYER_Y))
        self.mask = pygame.mask.from_surface(self.image)

    def calculate_step(self, fps):
        return self.STEP * FPS / fps if fps > 0 else self.STEP

    def left(self, fps):
        self.rect.x -= round(self.calculate_step(fps))
        if self.rect.x < 0:
            self.rect.x = WIDTH - PLAYER_SIZE

    def right(self, fps):
        self.rect.x += round(self.calculate_step(fps))
        if self.rect.x > WIDTH - PLAYER_SIZE:
            self.rect.x = 0

    def up(self, fps):
        self.rect.y -= round(self.calculate_step(fps))
        if self.rect.y < 0:
            self.rect.y = HEIGHT - PLAYER_SIZE

    def down(self, fps):
        self.rect.y += round(self.calculate_step(fps))
        if self.rect.y > HEIGHT - PLAYER_SIZE:
            self.rect.y = 0

    def blit(self, screen):
        screen.blit(self.image, self.rect)

def main():
    pygame.init()
    pygame.display.set_caption(WINDOW_TITLE)
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    screen.fill(WHITE)

    clock = pygame.time.Clock()

#     cursor = cursors.compile_cursor("transparent_cursor_black")
#     pygame.mouse.set_cursor((24, 24), (0, 0), cursor[0], cursor[1])

#     pygame.mixer.music.load("data/sounds/Death-Moon.mp3")
#     pygame.mixer.music.play()

    level = LEVEL_DATA #levels.load()
    objects = pygame.sprite.Group()
    triggers = []

    player = Cube(WIDTH // 2)

    player_is_alive = True
    start_time = time.monotonic()
    while player_is_alive:
        current_time = time.monotonic()
        past_time = current_time - start_time
        fps = clock.get_fps()

        screen.fill(WHITE)
        for event in pygame.event.get():
            player_is_alive = not (
                event.type == pygame.KEYDOWN
                and event.key == pygame.K_ESCAPE
                or event.type == pygame.QUIT
            )

        pressed_keys = pygame.key.get_pressed()
        if pressed_keys[pygame.K_RIGHT]:
            player.right(fps)

        if pressed_keys[pygame.K_LEFT]:
            player.left(fps)

        if pressed_keys[pygame.K_UP]:
            player.up(fps)

        if pressed_keys[pygame.K_DOWN]:
            player.down(fps)

        current_time = time.monotonic()
        past_time = current_time - start_time
        
        player.blit(screen)
        for trigger in level[1]:
            if trigger["start time"] >= past_time:
                triggers.append(Trigger(trigger))

        for object in objects:
            if not object.finish:
                object.blit(screen)
                
            else:
                objects.remove(object)
                
        for object_data in level[0]:
#             print(object_data["start time"])
            print(current_time - start_time)
            if object_data["start time"] <= current_time - start_time:
                print(object_data)
                object = Object(object_data)
                object.draw_object()
                objects.add(object)
                level[0].remove(object_data)
                
        for trigger in triggers:
            if trigger.finish:
                triggers.remove([trigger])

#         for object in objects.sprites():
#             if pygame.sprite.collide_mask(object, player):
#                 player_is_alive = False
#                 break

        pygame.display.flip()
        clock.tick(FPS)

    pygame.mixer.music.stop()
    pygame.quit()

if __name__ == "__main__":
    main()
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Es gibt kein littlest, das heißt smallest. Listen, über die man irritiert darf man nicht ändern. Das machst du bei objects und bei triggers.
Bei triggers versuchst du auch, eine Liste zu entfernen, die gar nicht in triggers enthalten ist, das sollte einen Fehler melden.
Ok. Sprites.Group verhält sich seltsam, trotzdem solltest du das in zwei Schritten machen:

Code: Alles auswählen

objects.remove(object for object in objects if object.finish)
triggers = [trigger for trigger in triggers if not trigger.finished]
Antworten