Проблемы с отображением новых предметов в Pygame - PullRequest
1 голос
/ 14 апреля 2020

Я работал над кодированием игры типа «лягушонок» в pygame. Для этого мне нужно иметь логи / предметы, на которые игрок может приземлиться, чтобы пройти на другую сторону экрана. Я пытаюсь сделать так, чтобы эти журналы появлялись со случайной шириной 75, 150 или 225 пикселей. Левый механизм запуска работает, но, как ни странно, правый создает журналы, которые намного больше, чем то, что должно появляться. Любая помощь будет принята с благодарностью за то, как обеспечить появление этих журналов на правильной ширине.

Вот мой код:

import sys, pygame, random
from pygame.locals import *

pygame.init()
screen_height = 750
screen_width = 1200
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Frogger")
FPS = 200

player = pygame.image.load('frog.bmp')
player_rect = player.get_rect()
player_rect.left = 300 + 11
player_rect.top = screen_height - 68

not_in_ocean = False

#For player movement
up_movements = 0
down_movements = 0
left_movements = 0 
right_movements = 0
up_movement = False
down_movement = False
left_movement = False
right_movement = False

x_logs = [0, 600]
y_logs = [74, 149, 224, 299, 374, 449, 524, 599] 
list_log_width = [1, 2, 3]
log_height = 74
logs_created = []
log_speeds = []
for y in y_logs:
    log_speeds.append(random.randint(1,3))


class Log():

    def __init__(self, x, y, direction, log_width, speed):
        self.direction = direction
        self.drew_new_log = False
        self.log_width = log_width
        self.speed = speed
        self.log = pygame.Rect(x, y, log_width * 75, log_height)
        self.log_length = random.randint(0,2)
        self.y_index = y_logs.index(self.log.y)

    def move_log(self):
        if self.direction == 'right':
            self.log.x += self.speed
            self.log.right += self.speed
        if self.direction == 'left':
            self.log.x -= self.speed
            self.log.right -= self.speed

    def draw_log(self):
        pygame.draw.rect(screen, (153, 102, 0), self.log)


    def delete_log(self, item):
        logs_created.remove(item)

    def draw_new_logs(self): # To address the issue of infinitely spawning in logs, put the if statements in the main game loop and only have it run this method if it meets the requirements
        if self.direction == 'right' and self.drew_new_log == False:
            if self.log.right  > screen_width:
                logs_created.append(Log((-75 * list_log_width[self.log_length]) + 1, self.log.y, 'right', list_log_width[self.log_length], log_speeds[self.y_index]))
                self.drew_new_log = True
        if self.direction == 'left' and self.drew_new_log == False:
            if self.log.left < 0:
                logs_created.append(Log(screen_width - 1, self.log.y, 'left', list_log_width[self.log_length], log_speeds[self.y_index]))
                self.drew_new_log = True

for x in x_logs:
    for y in y_logs:
        for speed in log_speeds:
            log_length = random.randint(0, 2)
            if (y_logs.index(y) % 2) == 0: 
                logs_created.append(Log(x, y, 'left', list_log_width[log_length], log_speeds[y_logs.index(y)]))#list_log_width[log_length], speed))
            else:
                logs_created.append(Log(x, y, 'right', list_log_width[log_length], log_speeds[y_logs.index(y)])) #list_log_width[log_length], speed)) 


while True:
    screen.fill((0, 119, 190))
    starting_area = pygame.draw.rect(screen, (32, 178, 170), (0, 675, screen_width, screen_height / 10))
    finish_area = pygame.draw.rect(screen, (32, 178, 170), (0,0, screen_width, screen_height / 10))
    ocean = pygame.draw.rect(screen, (0, 119, 190), (0, screen_height / 10, screen_width, screen_height *0.8))

    FPSCLOCK = pygame.time.Clock()

    not_in_ocean = False


    for log in logs_created:
        log.draw_log()
        log.move_log()
        log.draw_new_logs()
        print(log.log_width*75)


        if log.direction == 'right':
            if log.log.centerx - ((log.log_width * 75) / 2) > screen_width:
                log.delete_log(log)
        if log.direction == 'left':
            if (log.log.right) < 0:# + (log.log_width * 75)) < 0:
                log.delete_log(log)


        if player_rect.colliderect(log.log):
            not_in_ocean = True
            if log.log_width == 3:

                if abs(player_rect.centerx - log.log.right) > abs(player_rect.centerx - log.log.left) and abs(player_rect.centerx - log.log.left) < abs(player_rect.centerx - log.log.centerx):
                    #Put the player on the left side
                    player_rect.centerx = log.log.left + 37.5

                if abs(player_rect.centerx - log.log.centerx) < abs(player_rect.centerx - log.log.right) and abs(player_rect.centerx - log.log.centerx) < abs(player_rect.centerx - log.log.left):
                    #Put the player in the middle
                    player_rect.centerx = log.log.centerx

                if abs(player_rect.centerx - log.log.right) < abs(player_rect.centerx - log.log.left) and abs(player_rect.centerx - log.log.centerx) > abs(player_rect.centerx - log.log.right):
                    #Put the player on the right side
                    player_rect.centerx = log.log.right - 37.5

            if log.log_width == 2:
                if abs(player_rect.centerx - log.log.right) > abs(player_rect.centerx - log.log.left):
                    #Put the player on the left side
                    player_rect.centerx = log.log.left + 37.5

                if abs(player_rect.centerx - log.log.right) < abs(player_rect.centerx - log.log.left):
                    #Put the player on the right side
                    player_rect.centerx = log.log.right - 37.5

            if log.log_width == 1:
                player_rect.centerx = log.log.centerx

            for event in pygame.event.get():
                if event.type == KEYDOWN:
                    if event.key == K_RIGHT:
                        player_rect.centerx += 75
                    if event.key == K_LEFT:
                        player_rect.x -= 75
                    if event.key == K_UP:
                        player_rect.y -= 75
                    if event.key == K_DOWN:
                        player_rect.y += 75


            if log.direction == 'right':
                player_rect.x += log_speeds[log.y_index]
            if log.direction == 'left':
                player_rect.x -= log_speeds[log.y_index]
        elif starting_area.colliderect(player_rect) or finish_area.colliderect(player_rect):
            not_in_ocean = True

    #Gameover mechanism
    if not_in_ocean == False:
        player_rect.left = 300 + 11
        player_rect.top = screen_height - 68

    screen.blit(player, player_rect)

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

        elif event.type == KEYDOWN:
            if event.key == K_UP:
                up_movement = True
            elif event.key == K_DOWN:
                down_movement = True
            elif event.key == K_LEFT:
                left_movement = True
            elif event.key == K_RIGHT:
                right_movement = True

        #Movements
    if up_movement == True:
        if player_rect.top > 11:
            if up_movements < 75:
                player_rect.y -= 15
                up_movements += 15
            else:
                up_movements = 0
                up_movement = False
        else:
            up_movement = False
            up_movements = 0
    if down_movement == True:
        if player_rect.bottom <= screen_height - 11:
            if down_movements < 75:
                player_rect.y += 15
                down_movements += 15
            else:
                down_movements = 0
                down_movement = False
        else:
            down_movement = False
            down_movements = 0

    if left_movement == True:
        if player_rect.left > 11:
            if left_movements < 75:
                player_rect.x -= 15
                left_movements += 15
            else:
                left_movements = 0
                left_movement = False
    if right_movement == True:
        if player_rect.right <= screen_width - 11:
            if right_movements < 75:
                player_rect.x += 15
                right_movements += 15
            else:
                right_movements = 0
                right_movement = False

    if player_rect.left < 0 or player_rect.right > screen_width:
        #Gameover
        player_rect.left = 300 + 11
        player_rect.top = screen_height - 68


    pygame.display.update()
    FPSCLOCK.tick(FPS)

1 Ответ

1 голос
/ 14 апреля 2020

Вы создаете много журналов. Вы создаете один журнал для каждой скорости в log_speeds

for x in x_logs:
   for y in y_logs:
       for speed in log_speeds:
           # [...]

Используйте `` , чтобы выбрать случайный элемент из log_speeds:

for x in x_logs:
    for y in y_logs:
        speed = random.choice(log_speeds)
        log_length = random.randint(0, 2)
        if (y_logs.index(y) % 2) == 0: 
            logs_created.append(Log(x, y, 'left', list_log_width[log_length], log_speeds[y_logs.index(y)]))#list_log_width[log_length], speed))
        else:
            logs_created.append(Log(x, y, 'right', list_log_width[log_length], log_speeds[y_logs.index(y)])) #list_log_width[log_length], speed)) 

Не удаляйте элементы из списка во время итерации по списку. Итерация по копии списка (logs_created [:]). См. Структуры данных . но удалите элементы из исходного списка, когда прямоугольник полностью покинет экран:

while True:
    # [...]

    for log in logs_created[:]:
        log.draw_log()
        log.move_log()
        log.draw_new_logs()

        if log.direction == 'right':
            if log.log.left > screen_width:
                log.delete_log(log)
        if log.direction == 'left':
            if log.log.right < 0:
                log.delete_log(log)

        # [...]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...