首页 > 解决方案 > 在 pygame 中显示新项目时遇到问题

问题描述

我一直致力于在 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)

标签: pythonpygame

解决方案


您创建了很多日志。您为每个速度创建一个日志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)

        # [...]

推荐阅读