जब मैं मूव करता हूं तो मेरा स्प्राइट प्लेयर तेज क्यों चलता है?


17

मैं Pygame (पाइथन लाइब्रेरी) के साथ बनाया गया एक सरल गेम विकसित करने की कोशिश कर रहा हूं।

मेरे पास एक spriteऑब्जेक्ट है जो कि है playerऔर मैं इसे तीर कुंजियों का उपयोग करके स्थानांतरित करता हूं। यदि मैं माउस को स्थानांतरित नहीं करता हूं, तो स्प्राइट सामान्य रूप से चलता है, लेकिन जब मैं माउस को स्थानांतरित करता हूं, तो स्प्राइट तेजी से बढ़ता है (जैसे x2 या 3)। playerऑब्जेक्ट के अंदर है charsGroupवर।

मैंने डब्ल्यू 7 और उबंटू में खेल चलाया है। दोनों ओएस में एक ही बात होती है।

मेरे पास और भी संस्थाएं हैं जो एनपीसी और गोलियों की तरह चलती हैं लेकिन वे प्रभावित नहीं होती हैं, सिर्फ खिलाड़ी। इसे देखते हुए, मुझे लगता है कि इस समस्या का खिलाड़ी के चलती प्रणाली (तीर कुंजी) के साथ सीधा संबंध है।

यहाँ वस्तु की update()विधि है 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

और यहाँ लूप है:

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

मुझे नहीं पता कि आपको मेरी मदद करने के लिए और क्या चाहिए, लेकिन जिस चीज़ की आपको ज़रूरत है (अधिक जानकारी या कोड) बस उसके लिए पूछें!


5
आपका सटीक बग वास्तव में कई अनुप्रयोगों में मौजूद है। एक बड़े दस्तावेज़ में चयन करने की कोशिश करें और अपने कर्सर को किनारे से स्थानांतरित करें। आमतौर पर प्रोग्राम का एज स्क्रॉल किक करेगा और धीरे-धीरे डॉक्यूमेंट का अधिक चयन करेगा। यदि आप अपने माउस को साइड से घुमाते हैं, तो यह आमतौर पर बहुत तेज़ी से स्क्रॉल होता है, क्योंकि उनकी स्क्रॉल स्पीड उनके इवेंट लूप से जुड़ी होती है, और एक्स मोशन उनके इवेंट लूप को बार-बार जगाते हैं।
बेन जैक्सन

2
@BenJackson मुझे लगता है कि एक उपयोगी बग बनने के लिए जब स्क्रॉलिंग की शुरुआत धीमी है।
user253751

1
यह आपकी बग से संबंधित नहीं है, लेकिन मैं एक बार छवि को लोड करने और उसे किसी ऑब्जेक्ट में संग्रहीत करने की सलाह दूंगा। BULLET_IMAGE = pygame.image.load("bullet.png")और फिर बाद मेंself.bulletsGroup.add(Bullet(BULLET_IMAGE...
DJMcMayhem

@DJMcMayhem आप पूरी तरह से सही हैं, मैंने इसे बाकी छवियों के साथ किया है, लेकिन मैंने इसे इस के साथ याद किया .. धन्यवाद! :)
ड्रयूमबास

जवाबों:


42

tl; अपने खेल लूप के साथ अपने ईवेंट लूप को न मिलाएं ।

जब आप अपना माउस घुमाते हैं, तो गेम को pygame.MOUSEMOTIONघटनाओं का भार मिलता है । आप वास्तव में अपने माउस की स्थिति को अपडेट करने के लिए इन घटनाओं का उपयोग नहीं करते हैं, आपको माउस का उपयोग करने की वर्तमान स्थिति मिल रही है pygame.mouse.get_pos()। यह अक्षम है, लेकिन यह समस्या नहीं है।

समस्या यह है कि आप इवेंट लूप के अंदर खिलाड़ी की स्थिति को अपडेट कर रहे हैं !

यही होना चाहिए:

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

यह वही है जो आपका कोड करता है:

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

जब आप अपना माउस घुमाते हैं, तो ईवेंट लूप प्रति फ्रेम में कई बार निष्पादित होगा। लेकिन जब आप जांचते हैं कि किस कुंजी के साथ दबाया जाता है pygame.key.get_pressed(), तो वे तब तक दबाए रहते हैं जब तक आप जाने नहीं देते, कुछ समय बाद। जैसा कि आपका ईवेंट लूप माउस मूव इवेंट्स के माध्यम से मंथन कर रहा है, यह खिलाड़ी के चाल को बार-बार लागू करेगा।

समाधान सरल है: खिलाड़ी को इवेंट लूप के बाहर ले जाएं।


1
धन्यवाद! यह अब पूरी तरह से काम करता है और शायद मुझे कभी एहसास नहीं हुआ कि क्या हो रहा है! Btw, आप क्यों कहते हैं कि pygame.mouse.get_pos()अक्षम है? मेरे पास क्या विकल्प हैं?
प्रातः काल

हाय वहाँ @congusbongus, क्या आप मुझे समझा सकते हैं? धन्यवाद।
दोपहर

@Drumnbass pygame.mouse.get_pos()को इवेंट कतार की परवाह किए बिना माउस की नवीनतम स्थिति प्राप्त होती है, इसलिए इसे इवेंट लूप के अंदर रखने की कोई आवश्यकता नहीं है। इसका विकल्प यह होगा pygame.MOUSEMOTIONकि आप हर प्रक्रिया करें, लेकिन जब तक आपको हर कार्यक्रम की जरूरत न हो (उदाहरण के लिए आप पेंटिंग प्रोग्राम लिख रहे हों), तो नवीनतम स्थिति यह करेगी।
कॉंगसबोंगस

3

मौजूदा उत्तर के पूरक के लिए यहां कुछ और विचार दिए गए हैं ।

गेफर ऑन गेम्स में गेम लूप्स पर एक शानदार लेख है जिसे हर जगह संदर्भित किया गया है।

आपके गेम लूप में अलग-अलग स्वतंत्र चरण होने चाहिए: इनपुट, अपडेट, रेंडर।

उदाहरण के लिए, आप प्रति सेकंड 30 बार इनपुट पढ़ सकते हैं (या बेहतर जवाबदेही के लिए वास्तविक समय में), प्रति सेकंड 30 अपडेट करते हैं और प्रति सेकंड 60 फ्रेम रेंडर करते हैं, या जो भी मान आपके गेम के लिए अच्छा काम करते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.