如何在pygame中制作一个向上移动的抛射物?

2024-04-29 16:30:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我写了一个游戏,就是在按下空格键时,在屏幕上打出一个蓝色方块。然而,我得到的只是射击者上方的蓝色方块。这是我的代码:

import pygame, sys, random
from gameobjects import *


def main():

    pygame.init()

    screen = pygame.display.set_mode((800, 800))

    numberOfColumns = 5
    columnWidth = screen.get_width() / numberOfColumns

    numberOfRows = 5
    rowWidth = screen.get_width() / numberOfRows

    magazineImage = pygame.image.load("images/Magazine.bmp")
    magazineIssueOneImage = pygame.image.load("images/Magazine #1.bmp")

    monsterState1 = pygame.image.load("images/Zombie Pos 1.bmp")
    monsterState2 = pygame.image.load("images/Zombie Pos 2.bmp")
    monsterState3 = pygame.image.load("images/Zombie Pos 3.bmp")
    monsters = []

    forryState1 = pygame.image.load("images/Forry Pos 1.bmp")    
    forryState2 = pygame.image.load("images/Forry Pos 2.bmp")
    forryDelayTime = 8

    gameObjects = []
    gameObjectBlittingCounter = 0

    monsterSpawnSpotList = [(rowWidth * -5), (rowWidth * -4), (rowWidth * -3), (rowWidth * -2), (rowWidth * -1)]

    for monster in range(0, 5):
        monster = Monster(monsterState1, monsterState2, monsterState3, ((columnWidth / 2 - monsterState1.get_width() / 2) + gameObjectBlittingCounter * columnWidth), random.choice(monsterSpawnSpotList))
        monsters.append(monster)
        gameObjects.append(monster)
        gameObjectBlittingCounter += 1

    forry = Forry(forryState1, forryState2, columnWidth, rowWidth, screen, forryDelayTime, magazineImage, magazineIssueOneImage)
    gameObjects.append(forry)


    while True:


        screen.fill((0,255,0))

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

        #Update Projectiles

        if forry.projectileCall == True:
            magazine = Magazine(magazineImage, forry)
            gameObjects.append(magazine)

        #Update Game Objects

        for gameObject in gameObjects:
            gameObject.update()


        #Render
        gameObjectBlittingCounter = 0

        for gameObject in gameObjects:
            screen.blit(gameObjects[gameObjectBlittingCounter].image, ((gameObjects[gameObjectBlittingCounter].rect.x), (gameObjects[gameObjectBlittingCounter].rect.y)))
            gameObjectBlittingCounter += 1


        pygame.display.flip()




if __name__ == "__main__":
    main()

文件游戏对象.py看起来像这样:

^{pr2}$

我的杂志是蓝色的正方形

那为什么我的炮弹不上屏幕呢?在

+

在下面的答案中进行了所有修复后,现在我遇到了另一个错误:

当蓝色的盒子从屏幕上消失时,它应该是因为自我毁灭()在Magazine类的更新功能中。在

然而,当他们中的一个离开屏幕的时候,并不是被杀,而是给了我这些错误:

Traceback (most recent call last):
  File "main.py", line 106, in <module>
    main()
  File "main.py", line 78, in main
    projectileObject.update()
  File "/Users/number1son100/Desktop/Famous Monsters Game/gameobjects.py", line 117, in update
    self.kill()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pygame/sprite.py", line 174, in kill
    for c in self.__g.keys():
AttributeError: 'Magazine' object has no attribute '_Sprite__g'

Tags: inpyposimageformainloadscreen
1条回答
网友
1楼 · 发布于 2024-04-29 16:30:41

回答

有一段时间,一个典型的“就在我们眼皮底下”的案例让我难堪:

看看Magazine下的“update”函数的缩进,它向右缩进了一个太多,这意味着它是一个定义了-inside-\uyu init_u9()的函数,而不是您想要的magage方法。如果这对你来说没有多大意义,那就“dedent”那个块,看起来像这样

class Magazine(pygame.sprite.Sprite):
    def __init__(self, image, shooter):
        self.image = image
        self.rect = image.get_rect()
        self.rect.x = shooter.rect.x
        self.rect.y = shooter.rect.y - shooter.image.get_height()

    def update(self):
        self.rect.y -= 5
        if self.rect.y <= 0 - self.image.get_height():
            self.kill()

一些解释为什么什么都没有发生但没有错误:因为你的更新函数不是一个杂志的方法,它没有覆盖继承的方法游戏精灵精灵精灵. 因此,当从主循环调用它时,调用的是placehold/basic方法,而不是自定义方法。这意味着您没有得到错误/异常,但它没有工作!在

接下来,这里还有几个主要问题需要纠正:

补遗

(一)

这不一定是个问题,但您可以像这里一样使用python“for x in y”语法:

^{pr2}$

稍后在“渲染”部分中,即:

^{3}$

变成:

    for gameObject in gameObjects:
        screen.blit(gameObject.image, gameObject.rect)

请注意,您可以只传递整个rect,而不是拆分到rect.x和rect.y

(二)

你会注意到,一旦你修复了更新函数,你当前的代码会在你按下空格键的时候产生多个快照,这是因为你的生成机制会检查是否按住空格键并在每个循环中生成一个投射物,尝试从循环中删除这种生成,当按下或释放空格时只执行一次

(三)

限制帧率

在我的测试中,帧速率可能会很高,使游戏运行异常。使用一个游戏机。时钟对象和调用时钟滴答声(帧率)在循环中

(四)

为了准备进一步的复杂性,请考虑将“游戏对象”列表分成几种不同的类型(enemyObjects、projectleobjects等),因为这些类型在某个时候可能需要不同的处理,或者可以避免在发生这种情况时循环整个列表,只对敌人产生影响。在


最后是我的网站的一个小插件,我有一些pygame库的源代码和文档,您可以使用这些库,将来可能会对您有所帮助。在

相关问题 更多 >