Próbuję opracować prostą grę stworzoną za pomocą Pygame (biblioteka Python).
Mam sprite
obiekt, który jest player
i poruszam go za pomocą klawiszy strzałek. Jeśli nie poruszę myszą, duszek porusza się normalnie, ale kiedy poruszam myszą, duszek porusza się szybciej (jak x2 lub x3). player
Obiekt znajduje się wewnątrz charsGroup
var.
Uruchomiłem grę w W7 i Ubuntu. To samo dzieje się w obu systemach operacyjnych.
Mam więcej bytów, które poruszają się jak NPC i pociski, ale nie mają na nie wpływu, tylko gracz. Biorąc to pod uwagę, myślę, że problem może mieć bezpośredni związek z systemem poruszania się gracza (klawisze strzałek).
Oto update()
metoda player
obiektu:
def update(self):
for event in pygame.event.get():
key = pygame.key.get_pressed()
mouseX, mouseY = pygame.mouse.get_pos()
if event.type == pygame.MOUSEBUTTONDOWN:
self.bulletsGroup.add(Bullet(pygame.image.load("bullet.png"),
self.rect.x + (self.image.get_width()/2),
self.rect.y + (self.image.get_height()/2),
mouseX, mouseY, 50, 50))
if key[pygame.K_RIGHT]:
if not self.checkCollision():
self.rect.x += 10
else:
self.rect.x -= 10
if key[pygame.K_LEFT]:
if not self.checkCollision():
self.rect.x -= 10
else:
self.rect.x += 10
if key[pygame.K_UP]:
if not self.checkCollision():
self.rect.y -= 10
else:
self.rect.y += 10
if key[pygame.K_DOWN]:
if not self.checkCollision():
self.rect.y += 10
else:
self.rect.y -= 10
A oto pętla while:
while True:
if PLAYER.healthBase <= 0:
GAMEOVER = True
if not GAMEOVER:
mapTilesGroup.draw(SCREEN)
charsGroup.update()
charsGroup.draw(SCREEN)
npcsGroup.update()
npcsGroup.draw(SCREEN)
drawBullets()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if GAMEOVER:
myfont = pygame.font.SysFont("monospace", 30)
label = myfont.render("GAME OVER!", 1, (255, 255, 0))
SCREEN.blit(label, (400, 300))
freq.tick(0)
pygame.display.flip()
Nie wiem, co więcej możesz mi pomóc, ale o wszystko, czego potrzebujesz (więcej informacji lub kod), poproś o to!
BULLET_IMAGE = pygame.image.load("bullet.png")
a późniejself.bulletsGroup.add(Bullet(BULLET_IMAGE...
Odpowiedzi:
tl; dr nie mieszaj pętli zdarzeń z pętlą gry .
Gdy poruszasz myszą, gra otrzymuje mnóstwo
pygame.MOUSEMOTION
wydarzeń. Tak naprawdę nie używasz tych zdarzeń do aktualizacji pozycji myszy, otrzymujesz bieżący stan myszypygame.mouse.get_pos()
. To nieefektywne, ale to nie problem.Problem polega na tym, że aktualizujesz pozycję gracza w pętli zdarzeń !
Oto co powinno się wydarzyć:
Oto, co robi Twój kod:
Kiedy poruszasz myszą, pętla zdarzeń będzie wykonywana wiele razy na klatkę. Ale kiedy sprawdzasz, które klawisze są naciskane
pygame.key.get_pressed()
, pozostają one wciśnięte, dopóki nie puścisz, jakiś czas później. W związku z tym, że pętla zdarzeń przesuwa się przez zdarzenia ruchu myszy, ponownie zastosuje ruchy gracza.Rozwiązanie jest proste: przenieś odtwarzacz poza pętlę zdarzeń.
źródło
pygame.mouse.get_pos()
to jest nieefektywne? Jakie mam alternatywy?pygame.mouse.get_pos()
pobiera najnowszą pozycję myszy, niezależnie od kolejki zdarzeń, więc nie ma potrzeby umieszczania jej w pętli zdarzeń. Alternatywą byłoby przetworzenie każdegopygame.MOUSEMOTION
osobiście, ale chyba że potrzebujesz każdego wydarzenia (np. Piszesz program malarski), zrobi to najnowsza pozycja.Oto kilka pomysłów na uzupełnienie istniejącej odpowiedzi .
Gaffer On Games ma świetny artykuł na temat pętli gier , do którego odwołuje się wszędzie.
Twoja pętla gry powinna mieć różne niezależne etapy: Wejście, Aktualizacja, Renderowanie.
Możesz na przykład czytać dane wejściowe 30 razy na sekundę (lub w czasie rzeczywistym dla lepszej reakcji), robić 30 aktualizacji na sekundę i renderować 60 klatek na sekundę lub dowolne wartości, które działają dobrze w twojej grze.
źródło