【问题标题】:Using classes in Pygame在 Pygame 中使用类
【发布时间】:2016-02-26 03:01:56
【问题描述】:

好的,所以我开始享受 pygame 的乐趣。但我有一个问题。我试图以某种方式增强我的代码,使其井井有条,所以我决定在这里使用类。它看起来像这样:

import pygame
from pygame.locals import *
import sys

pygame.init()

class MainWindow:
    def __init__(self, width, height):
        self.width=width
        self.height=height
        self.display=pygame.display.set_mode((self.width,self.height))
        pygame.display.set_caption("Caption")
    def background(self)
        img = pygame.image.load("image.png")
        self.display.blit(img, (0,0))            

mainWindow = MainWindow(800,600)

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.exit()
            sys.exit()
        mainWindow.background()
    pygame.display.update()

好的,工作。但是如果我想用白色填充窗口呢?然后我必须定义一个方法fill(),它就是self.display.fill(),对吧?有没有办法正常处理它,而无需在我的类中定义数百个 pygame 已经存在的方法?

还有另一件事。如果我使用我的课程做某事,但我搞砸了,我总是会收到这个消息:

  File "C:/Python35/game.py", line 23, in <module>
    pygame.display.update()
pygame.error

而且我实际上不知道到底出了什么问题。如果我在没有课程的情况下正常执行此操作,那么我会得到诸如pygame object blabla has no method blablabla 之类的错误,我只知道发生了什么。有没有办法解决这个问题并找出发生了什么?

提前感谢您的帮助!

【问题讨论】:

  • 您可以设置一个定义颜色的父类,然后您的 MainWindow 可以从它继承
  • 是的,我知道,但我想要一个与你类似的情况,但是当 MainWindow 会像从某个 pygame 类继承时,所以方法是继承的,不需要定义它们 XD 我想这是不可能的:(
  • 为什么不直接将我建议的类设置为 mixin?
  • 像 MainWindow(ClassWithFill, PyGameClass),我不确定你的意思是“当 MainWindow 会像从某个 pygame 类继承,所以方法被继承”但如果你的意思是我认为你做的mixin 允许你继承多个类。

标签: python class pygame


【解决方案1】:

你在这里所做的事情是正确的,但它是以错误的方式完成的。您的主要“游戏循环”应该作为一种方法在类本身内部,而不是在实际循环中从类外部调用东西。这是您应该做的一个基本示例。

# Load and initialize Modules here
import pygame
pygame.init()

# Window Information
displayw = 800
displayh = 600
window = pygame.display.set_mode((displayw,displayh))

# Clock
windowclock = pygame.time.Clock()

# Load other things such as images and sound files here
image = pygame.image.load("foo.png").convert # Use convert_alpha() for images with transparency

# Main Class
class MainRun(object):
    def __init__(self,displayw,displayh):
        self.dw = displayw
        self.dh = displayh
        self.Main()

    def Main(self):
        #Put all variables up here
        stopped = False

        while stopped == False:
            window.fill((255,255,255)) #Tuple for filling display... Current is white

            #Event Tasking
            #Add all your event tasking things here
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    quit()
                elif event.type == pygame.KEYDOWN:
                    stopped = True

            #Add things like player updates here
            #Also things like score updates or drawing additional items
            # Remember things on top get done first so they will update in the order yours is set at

            # Remember to update your clock and display at the end
            pygame.display.update()
            windowclock.tick(60)

        # If you need to reset variables here
        # This includes things like score resets

    # After your main loop throw in extra things such as a main menu or a pause menu
    # Make sure you throw them in your main loop somewhere where they can be activated by the user

# All player classes and object classes should be made outside of the main class and called inside the class
#The end of your code should look something like this
if __name__ == __main__:
    MainRun()

当 MainRun() 对象被创建时,主循环会调用自己。

如果您需要更多关于特定事物(例如对象处理)的示例,请告诉我,我会看看是否可以为您提供更多信息。

我希望这对您的编程有所帮助,并祝您好运。

========================== 编辑===================== ===========

在这种情况下,这些特殊操作使它们特定于对象。不要使用一种通用方法来 blit 对象,而是让每个对象都有自己的功能。这样做是为了为您制作的每个对象提供更多选项。代码的大致思路如下...我在这里创建了一个简单的播放器对象。

#Simple player object
class Player(object):
    def __init__(self,x,y,image):
        self.x = x
        self.y = y
        self.image = image

    #Method to draw object
    def draw(self):
        window.blit(self.image,(self.x,self.y))

    #Method to move object (special input of speedx and speedy)
    def move(self,speedx,speedy):
        self.x += speedx
        self.y += speedy

现在这里是你如何使用对象的方法...我已经包含了一个事件循环来帮助展示如何使用移动功能。只需将此代码添加到您需要的主循环中即可。

#Creating a player object
player = Player(0,0,playerimage)

#When you want to draw the player object use its draw() method
player.draw()

#Same for moving the player object
#I have included an event loop to show an example
#I used the arrow keys in this case
speedx = 0
speedy = 0

for event in pygame.event.get():
    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_UP:
            speedy = -5
            speedx = 0
        elif event.key == pygame.K_DOWN:
            speedy = 5
            speedx = 0
        elif event.key == pygame.K_RIGHT:
            speedy = 0
            speedx = 5
        elif event.key == pygame.K_LEFT:
            speedy = 0
            speedx = -5
    elif event.type == pygame.KEYUP:
        speedx = 0
        speedy = 0

#Now after you event loop in your object updates section do...
player.move(speedx,speedy)
#And be sure to redraw your player
player.draw()

#The same idea goes for other objects such as obstacles or even scrolling backgrounds

确保在绘图函数中使用与显示相同的显示名称。

【讨论】:

  • 好的,谢谢。但我想要求这样的事情:所以我有我的课程,但你已经创建了一个 MainRun() 课程。我希望它像 MainWindow(),因为它会像:awkay,mainWindow = MainWindow(800,600),得到我的窗口对象,现在让我们为其设置标题mainWindow.caption("My window"),好的,现在让我们为它添加背景图像`@ 987654326@。 background() 方法仍然会调用 pygame 类方法 - 加载,然后是 blit()。即使那些方法存在于pygame中,我仍然需要在我的类中定义它们,我不想这样做
  • 好的,我已经更新了 === EDIT === 部分下的答案,以展示如何在游戏中使用其他对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-14
  • 2013-04-04
  • 2014-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多