我正在使用Pygame创建一个基本的乒乓式游戏,而且我已经移动了桨。我的代码可以防止拨片移动超出屏幕边缘,但如果玩家按住一个移动键,则拨片稍微移动到屏幕边缘。一旦玩家释放钥匙,桨就会快速回到它应该停止的位置。
我对Python和编码有点新手,所以我的代码可能不是最整洁或最有效的。虽然这个问题可能根本不会影响游戏玩法,但我想知道它为什么会这样,以及如何将其改变为我想要的方式。
我的代码是:
import random
import pygame
from pygame.locals import *
from sys import exit
screen_size = 600, 600
w,h = screen_size
screen = pygame.display.set_mode(screen_size)
clock = pygame.time.Clock()
pic = pygame.image.load
class paddle(pygame.sprite.Sprite):
def __init__(self, pos):
pygame.sprite.Sprite.__init__(self)
self.pos = pos
self.posx, self.posy = self.pos
self.width = 10
self.height = 100
self.image = pygame.Surface((self.width, self.height))
self.image.fill((255,255,255))
self.rect = pygame.Rect((0,0), self.image.get_size())
self.speed = 150
def update(self, mov, tp):
self.posy += mov * self.speed * tp
self.rect.center = self.posx, self.posy
class box(pygame.sprite.Sprite):
def __init__(self, pos):
pygame.sprite.Sprite.__init__(self)
self.pos = pos
self.posx, self.posy = self.pos
self.width = 10
self.height = 10
self.image = pygame.Surface((self.width, self.height))
self.image.fill((255,255,255))
self.rect = pygame.Rect((0,0), self.image.get_size())
self.speed = 300
self.directionx = 0
self.directiony = 0
def update(self, mov, tp):
self.posx += mov[0] * self.speed * tp
self.posy += mov[1] * self.speed * tp
self.rect.center = self.posx, self.posy
reset = True
done = False
while done == False:
if reset == True:
p1 = paddle((0,0))
p1 = paddle((20,(h-p1.height)/2))
p2 = paddle((0,0))
p2 = paddle((w-20,(h-p2.height)/2))
paddle_group = pygame.sprite.Group()
paddle_group.add(p1)
paddle_group.add(p2)
ball = box(((w/2)-10,h/2))
ball_group = pygame.sprite.Group(ball)
reset = False
else:
pass
time_passed = clock.tick(60)
time_passed_seconds = time_passed/1000.0
for event in pygame.event.get():
if event.type == QUIT:
done = True
p1_movey = 0
p2_movey = 0
pressed_keys = pygame.key.get_pressed()
pressed_mb = pygame.mouse.get_pressed()
if pressed_keys[K_ESCAPE]:
done = True
if pressed_keys[K_w]:
p1_movey = -2
elif pressed_keys[K_s]:
p1_movey = +2
if pressed_keys[K_UP]:
p2_movey = -2
elif pressed_keys[K_DOWN]:
p2_movey = +2
p1.update(p1_movey, time_passed_seconds)
p2.update(p2_movey, time_passed_seconds)
# This is where the border check is
for PADDLE in paddle_group.sprites():
if PADDLE.posy > h - (PADDLE.height/2):
PADDLE.posy = h - (PADDLE.height/2)
elif PADDLE.posy < (PADDLE.height/2):
PADDLE.posy = (PADDLE.height/2)
screen.fill((0,0,0))
paddle_group.draw(screen)
pygame.display.update()
pygame.quit()
边界部分标有注释。
答案 0 :(得分:0)
问题是,您需要在不同时调整paddle
的情况下更正每个posy
rect
。 posx
和posy
存储精灵的位置 - 在这种情况下,它是中心 - 但您在屏幕上看到的位置由rect
确定。因为您添加p#_movey
,然后update
(调整矩形),最后,对越界值进行posy
更正,rect
保留在其中#39;无效的位置。但是,因为已经调整了posy
,所以未来的p#_movey
更改会影响正确的位置,而不是无效的位置(这就是为什么您的精灵在发布移动键之前仍保持OB的原因)
简而言之,这就是:
posy
将p#_movey应用于播放器#{1}}和rect
。update
以保持每个PADDLE.posy
的入口,但不要更新PADDLE in paddle_group
以反映调整。 (PADDLE.rect
确实需要更新。)我能想到两种解决方案:
1)修改您的rect
循环,以便刷新for PADDLE in paddle_group.sprites()
,它看起来像这样:
PADDLE.rect.center
2)或者,您可以在 # on the main loop...
for PADDLE in paddle_group.sprites():
if PADDLE.posy > h - (PADDLE.height/2):
PADDLE.posy = h - (PADDLE.height/2)
elif PADDLE.posy < (PADDLE.height/2):
PADDLE.posy = (PADDLE.height/2)
PADDLE.rect.center = PADDLE.posx, PADDLE.posy
## ^ adding this line, which recenters the rect.
的{{1}}方法中运行边界检查,并从主循环中一起删除paddle
循环。 update
会看起来像这样:
for PADDLE in paddle_group.sprites()
...只要您的边界由paddle.update(..)
(屏幕高度;窗口底部)和 # in class paddle(..) ...
def update(self, mov, tp):
self.posy += mov * self.speed * tp
self.posy = max(self.height / 2, min(self.posy, h - (self.height / 2)))
## ^ Adding this line, which checks boundaries for posy.
## because you're doing it here, there's no need to do it again on the main loop.
self.rect.center = self.posx, self.posy
(窗口顶部)和球拍高度定义。< / p>
这两种解决方案都应该有效,尽管几乎肯定有第三种方法。 希望有所帮助!