Fareyi hareket ettirdiğimde sprite çalarım neden daha hızlı hareket ediyor?


17

Pygame (Python kütüphanesi) ile yapılan basit bir oyun geliştirmeye çalışıyorum.

Bir spritenesnem var playerve ok tuşlarını kullanarak hareket ettiriyorum. Fareyi hareket ettirmezsem hareketli grafik normal hareket eder, ancak fareyi hareket ettirdiğimde hareketli grafik daha hızlı hareket eder (x2 veya x3 gibi). playerNesne içinde olan charsGroupvar.

Oyunu W7 ve Ubuntu'da çalıştırdım. Her iki işletim sisteminde de aynı şey olur.

NPC'ler ve mermiler gibi hareket eden daha fazla varlığım var ama etkilenmiyorlar, sadece oyuncu. Bu göz önüne alındığında, sorunun belki oyuncu hareket sistemi (ok tuşları) ile doğrudan bir bağlantısı olduğunu düşünüyorum.

İşte nesnenin update()yöntemi player:

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

İşte while döngüsü:

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() 

Bana daha ne yardım edebilirsin bilmiyorum, ama ihtiyacınız olan her şey (daha fazla bilgi veya kod) sadece isteyin!


5
Kesin hata aslında birçok uygulamada var. Büyük bir belgede sürüklemeyi seçip imlecinizi kenardan uzaklaştırmayı deneyin. Genellikle programın kenar kaydırma özelliği devreye girer ve belgenin yavaşça daha fazlasını seçer. Farenizi bir yandan diğer yana hareket ettirirseniz, kaydırma hızları olay döngülerine bağlı olduğundan ve X hareketleri olay döngülerini tekrar tekrar uyandırdığı için genellikle çok daha hızlı kaydırılır.
Ben Jackson

2
@BenJackson Kaydırma ile başlamak için çok yavaş olduğunda yararlı bir hata olduğunu düşünüyorum.
user253751

1
Bu, hatanızla ilgisizdir, ancak görüntüyü bir kez yüklemenizi ve bir nesnede saklamanızı öneririm. BULLET_IMAGE = pygame.image.load("bullet.png")ve daha sonraself.bulletsGroup.add(Bullet(BULLET_IMAGE...
DJMcMayhem

@DJMcMayhem Tamamen haklısın, görüntülerin geri kalanıyla yaptım ama bunu kaçırdım .. teşekkürler! :)
Drumnbass

Yanıtlar:


42

tl; dr senin karışmaz olay döngü sizin ile oyun döngü .

Farenizi hareket ettirdiğinizde, oyun bir sürü pygame.MOUSEMOTIONolay alır . Aslında bu olayları fare konumunuzu güncellemek için kullanmıyorsunuz.pygame.mouse.get_pos() . Bu verimsiz, ama sorun değil.

Sorun, olay döngüsü içindeki oynatıcı konumunu güncellemeniz !

Olması gereken budur:

game loop:
    event loop # get key presses, mouse moves etc.)
    if key pressed in the event loop:
        move the player

Kodunuzun yaptığı budur:

game loop:
    event loop:
        if key pressed:
            move the player

Farenizi hareket ettirdiğinizde, olay döngüsü kare başına birçok kez yürütülür. Ancak hangi tuşlara basıldığını kontrol ettiğinizdepygame.key.get_pressed() ettiğinizde, bir süre sonra bırakana kadar basılı kalırlar. Etkinlik döngünüz fare taşıma olaylarını çalkalarken, oyuncu hareketlerini tekrar tekrar uygulayacaktır.

Çözüm basit: oynatıcıyı olay döngüsünün dışına taşıyın.


1
Teşekkürler! Şimdi mükemmel çalışıyor ve muhtemelen ne olduğunu asla fark etmemiştim! Btw, bunun neden pygame.mouse.get_pos()verimsiz olduğunu söylüyorsun ? Ne gibi alternatiflerim var?
Drumnbass

Merhaba, @congusbongus, bana bunu açıklayabilir misin? Teşekkürler.
Drumnbass

@Drumnbass pygame.mouse.get_pos(), olay sırasından bağımsız olarak farenin en son konumunu alır, bu nedenle olay döngüsünün içine koymaya gerek yoktur. Alternatif, her şeyi işlemek olacaktır pygame.MOUSEMOTION, ancak her olaya ihtiyacınız yoksa (örneğin bir boyama programı yazıyorsanız), en son pozisyon olacaktır.
congusbongus

3

İşte mevcut cevabı tamamlamak için bazı düşünceler .

Gaffer On Games oyun döngülerinde harika bir makaleye sahip her yerde atıfta bulunulan sahiptir.

Oyun döngünüzün farklı bağımsız aşamaları olmalıdır: Girdi, Güncelle, Oluştur.

Örneğin, saniyede 30 kez (ya da daha iyi yanıt verebilmek için gerçek zamanlı olarak) girdileri okuyabilir, saniyede 30 güncelleme yapabilir ve saniyede 60 kare oluşturabilir ya da oyununuz için uygun olan değerleri yapabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.