目前我花了大约半个小时试图找出如何更好地实现这个脚本。我尝试了一些方法,但它们并没有完全奏效。 当运行脚本时,播放器会出现故障,有时播放器只有在接触后才能移动到块中。
x = 64*3
y = 0
xvel = 0
yvel = 0
grounded = True
playerRect = pygame.Rect ((x, y, 64, 64))
collidelist = []
level = ["#=======##=========================",
"#=======#==========================",
"#==###############=========###=====",
"#===============#####==============",
"#==================================",
"###################################"]
def makelevel (level):
x = y = 0
def checkline (line, x, y):
for character in line:
if character == "#":
block = pygame.draw.rect (screen, (50, 50, 255), (x * 64, y * 64, 64, 64))
collidelist.append (block)
x += 1
for line in level:
checkline (line, x, y)
y += 1
def move (xvel, yvel):
global x
global y
global playerRect
global collideList
x += xvel
y += yvel
for block in collidelist:
if playerRect.colliderect(block):
x += -xvel * 2
y += -yvel * 2
break
makelevel (level)
while True:
screen.fill ([0, 0, 0])
makelevel (level)
playerRect = pygame.Rect ((x, y, 64, 64))
pygame.draw.rect (screen, (255, 255, 255), playerRect)
for event in pygame.event.get ():
if event.type == pygame.QUIT:
pygame.quit ()
sys.exit ()
exit ()
pressed = pygame.key.get_pressed ()
if pressed [pygame.K_RIGHT]:
move (5, 0)
if pressed [pygame.K_LEFT]:
move (-5, 0)
if pressed [pygame.K_UP]:
move (0, -5)
if pressed [pygame.K_DOWN]:
move (0, 5)
pygame.display.update ()
答案 0 :(得分:0)
要处理与墙壁的碰撞,最简单的解决方案是首先沿x轴移动播放器rect或sprite,检查它是否与墙壁碰撞,然后如果我们移动则设置其rect.right = block.left
向右或rect.left = block.right
如果我们向左移动。然后你用y轴做同样的事情。我们必须单独进行,否则我们不知道方向以及如何重置矩形的位置。
以下是一个例子:
import sys
import pygame
def makelevel(level):
collidelist = []
for y, line in enumerate(level):
for x, character in enumerate(line):
if character == "#":
block = pygame.Rect(x*64, y*64, 64, 64)
collidelist.append(block)
return collidelist
def move(xvel, yvel, player_rect, collideList):
# Move the rect along the x-axis first.
player_rect.x += xvel
# Check if it collides with a block.
for block in collidelist:
if player_rect.colliderect(block):
if xvel < 0: # We're moving to the left.
# Move the player out of the block.
player_rect.left = block.right
elif xvel > 0: # We're moving to the right.
player_rect.right = block.left
break
# Now do the same for the y-axis.
player_rect.y += yvel
for block in collidelist:
if player_rect.colliderect(block):
if yvel < 0:
player_rect.top = block.bottom
elif yvel > 0:
player_rect.bottom = block.top
break
pygame.init()
screen = pygame.display.set_mode((800, 600))
BLOCK_COLOR = (50, 50, 255)
BG_COLOR = (0, 0, 0)
level = ["#=======##=========================",
"#=======#==========================",
"#==###############=========###=====",
"#===============#####==============",
"#==================================",
"###################################",]
collidelist = makelevel(level)
player_rect = pygame.Rect((64*3, 0, 64, 64))
# A clock to limit the frame rate.
clock = pygame.time.Clock()
while True:
for event in pygame.event.get ():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
pressed = pygame.key.get_pressed()
if pressed[pygame.K_RIGHT]:
move(5, 0, player_rect, collidelist)
if pressed[pygame.K_LEFT]:
move(-5, 0, player_rect, collidelist)
if pressed[pygame.K_UP]:
move(0, -5, player_rect, collidelist)
if pressed[pygame.K_DOWN]:
move(0, 5, player_rect, collidelist)
# Draw everything.
screen.fill(BG_COLOR)
for rect in collidelist:
pygame.draw.rect(screen, BLOCK_COLOR, rect)
pygame.draw.rect(screen, (255, 255, 255), player_rect)
pygame.display.update()
clock.tick(30) # Limit frame rate to 30 fps.
我需要解决您的代码中的一些其他问题(即使codereview是offtopic(请查看http://codereview.stackexchange.com/)):
最严重的问题是您在主循环中调用makelevel
,因此您会向collidelist
添加越来越多的内容,直到内存不足为止。在此函数中创建列表,然后返回并将其分配给while循环上方的变量,然后重复使用它。
没有必要在checkline
内定义makelevel
功能。
全局变量会对代码的可理解性和可维护性产生不良影响。而是将所需的变量传递给需要它们的函数并返回结果。
使用enumerate
代替y
中的x
和makelevel
增加1。