python - 在 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)
解决方案
您创建了很多日志。您为每个速度创建一个日志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)
# [...]
推荐阅读
- opencv - 如何创建球形图像?
- node.js - 即使在 Three.js 中单独导入 STLLoader 后也会出现类型错误
- reactjs - Material UI 持久抽屉防止在打开时调整右侧内容的大小
- javascript - 例外:参数(字符串)与 SpreadsheetApp.Sheet.activate 的方法签名不匹配
- python - 无法对我的数据使用 plt.subplots()
- java - 赋值,但仅当为正时 - 无条件
- pdftron - 线性化过程中发生了什么错误
- node.js - 特定域的 Nodemailer 主机和端口电子邮件地址
- r - 合并两个数据框 - ID 的联合,值上的“ANY”
- vue.js - Vuetify 相当于 UINavigationController