【问题标题】:Problems with a game游戏的问题
【发布时间】:2021-09-23 18:10:10
【问题描述】:

我是一名年轻的 Python 程序员。我决定使用 pygame 创建一个 2D 游戏 游戏目的:在汽车上尽可能远地行驶,而不会撞到在游戏中“生成”的物体。汽车将驶过田野。

我的装饰精灵有问题(在游戏过程中,树木会“倒”在窗户边缘) Fig1.pic1

所以,树应该在之前的树到达窗口中间之后立即生成,但是当新树生成时,这就是我的情况:图 2。然后游戏开始卡死pic2

这是我的代码:

from superwires import games, color
from random import randrange
games.init(screen_width = 530, screen_height = 600, fps = 60)

#Car sprite

class Car(games.Sprite):
    image = games.load_image("C:/python/car.bmp")
    def __init__(self):
        super(Car, self).__init__(image = Car.image,
                                  x = games.mouse.x,
                                  bottom = games.screen.height - 10)
        self.score = games.Text(value = 0, size = 25, color = color.yellow,
                                top = 5, right = games.screen.width/2)
        games.screen.add(self.score)
    def update(self):
        self.x = games.mouse.x
        if self.left < 65:
            self.left = 65
        if self.right > games.screen.width - 65:
            self.right = games.screen.width - 65

#Tree sprite

class Bush1(games.Sprite):
    image = games.load_image("C:/python/bush.bmp")
    speed = 1
    def __init__(self, x = 20, y = 100):
        super(Bush1, self).__init__(image = Bush1.image,
                                   x = x, y = y,
                                   dy = Bush1.speed)
    def update(self):
        if self.bottom > games.screen.height/2:
            newbush = Bush1()
            newbush.__init__(x = 20, y = -100)
            games.screen.add(newbush)

class Bush2(games.Sprite):
    image = games.load_image("C:/python/bush.bmp")
    speed = 1
    def __init__(self, x = 515, y = 100):
        super(Bush2, self).__init__(image = Bush2.image,
                                   x = x, y = y,
                                   dy = Bush2.speed)

    #Spawning new trees

    def update(self):
        if self.bottom > games.screen.height/2:
            newbush = Bush2()
            newbush.__init__(x = 515, y = -100)
            games.screen.add(newbush)

#Start
def main(): 
    road = games.load_image("road.jpg", transparent = False)
    games.screen.background = road
    bush1 = Bush1()
    bush2 = Bush2()
    car = Car()
    games.screen.add(bush1)
    games.screen.add(bush2)
    games.screen.add(car)
    games.mouse.is_visible = False
    games.screen.event_grab = True
    games.screen.mainloop()

main()

我很高兴知道我在哪里犯了错误。

使用过:Python 3.9、superwires、游戏

【问题讨论】:

  • 您是否在其他地方输出了任何错误?此外,看起来Bush1Bush2 是同一个类,并且您在update 方法中以一种奇怪的方式使用__init____init__ 在你实例化一个新对象时被调用——直接调用它可能会导致意想不到的结果。同样,由于这些类依赖于在全局范围内的 games,因此您可能会遇到引用问题 - 缺少它们或覆盖它们。
  • @NathanielFord 我没有收到任何错误,只是 pic2 中的内容
  • 我看不出这两张图片有什么区别。
  • 创建一个新对象会自动调用__init__。你应该做newbush = Bush2(x=515, y=-100)。而且,由于这些是默认值,因此您根本不需要指定它们。
  • @TimRoberts 请再次检查照片

标签: python game-development


【解决方案1】:

这可能无法解决您遇到的具体问题,但它可能有助于解开并了解正在发生的事情。

在这里您正在创建一个新的Bush1Bush2 对象:

bush1 = Bush1()
bush2 = Bush2()

请注意,这两个类的代码实际上是相同的。区别仅在于 init 默认值。相当于这样做:

bush1 = Bush1()
bush2 = Bush1(515, 100)

基于此,您似乎对 Python 中的类如何工作存在误解。两个几乎等效但换常数的update 块强化了这一点:

    def update(self):
        if self.bottom > games.screen.height/2:
            newbush = Bush1()
            newbush.__init__(x = 20, y = -100)
            games.screen.add(newbush)

在这些块的第三行,您正在创建一个新对象。然后你重新调用对象__init__ 方法。当您创建一个新对象时,会运行几个隐藏的“私有”方法,其中最后一个__init__ 方法。通常,如果您需要更改对象的实例化,您会更改该方法。您永远不需要重新调用该方法。

最后,据我所知,您实际上并没有在移动灌木丛。我怀疑当您说“开始冻结”时,正在发生的事情是您有许多相互重叠的灌木实例,并且游戏处理每个循环的时间越来越长。在每个 init 方法中放置一个 print 语句可能有助于识别这个问题,但您的框架可能有更好的方法来做到这一点。 (我不熟悉它们。)

稍微重构一下以清理类的使用和适当地确定变量的范围应该会产生类似这样的结果(尽管几乎可以肯定我们可以做的更多):

from superwires import games, color
from random import randrange
games.init(screen_width = 530, screen_height = 600, fps = 60)

#Car sprite

class Car(games.Sprite):
    
    def __init__(self, image: str):
        self.__image = games.load_image(image)
        #  Is the car really instantiated at the point the mouse currently is at?
        super().__init__(image = self.__image,
                         x = games.mouse.x,
                         bottom = games.screen.height - 10)
        #  Is 'score' really a field of 'car'?
        self.score = games.Text(value = 0, 
                                size = 25, 
                                color = color.yellow,
                                top = 5, 
                                right = games.screen.width/2)
        games.screen.add(self.score)

    def update(self):
        self.x = games.mouse.x
        self.left = 65 if self.left < 65 else self.left
        # This should probably be defined in a broader scope
        max_right = games.screen.width - 65
        self.right = self.right if self.right <= max_right else max_right 


class Bush(games.Sprite):
    speed = 1
    def __init__(self, 
                 image: str 
                 x: int, 
                 y: int):
        self.__image = games.load_image(image)
        self.__start_x = x
        self.__start_y = y
        super().__init__(image = self.__image,
                         x = x, 
                         y = y,
                         dy = Bush.speed)

    def update(self):
        if self.bottom > games.screen.height/2:
            # uses the same initial values as this object
            newbush = Bush(self.__image, 
                           self.__start_x,
                           -100)  # start vertically above the screen
            games.screen.add(newbush)

#Start
def main(): 
    road = games.load_image("road.jpg", transparent = False)
    games.screen.background = road
    bush1 = Bush("C:/python/bush.bmp", 20, 100)
    bush2 = Bush("C:/python/bush.bmp", 515, 100)
    car = Car("C:/python/car.bmp")
    games.screen.add(bush1)
    games.screen.add(bush2)
    games.screen.add(car)
    games.mouse.is_visible = False
    games.screen.event_grab = True
    games.screen.mainloop()

main()

【讨论】:

  • 仅供参考,由于“dy”参数,精灵在每一帧上自动移动。
  • @TimRoberts 这是有道理的。提供的update 方法是否有可能覆盖超类的方法,并且需要在它执行其他所有操作之前或之后调用它?
【解决方案2】:

这是你的问题。一旦你的第一个灌木到达中点,你就在每一帧上创建两个新的灌木。这就是你在 pic2 中看到的——你有数百个稍微重叠的灌木。仅当旧灌木正好位于中点而不是位于或低于中点时,您才需要创建新灌木:

    if self.bottom == games.screen.height//2:

你也可以考虑在灌木从底部掉下来后删除

【讨论】:

  • 就是这样——错误的输出完全会因为这个以及冻结而发生。
  • @NathanielFord 我在上面试过你的代码。我在“Bush”类的“更新”方法中遇到错误: "newbush = Bush(self.__image," "self.__image = games.load_image(image)" "image = pygame.image.load (文件名) TypeError: not a file object
  • 这看起来不像 Nathaniel 的代码。您可能是时候发布一个新问题了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-14
  • 2011-04-12
相关资源
最近更新 更多