1

Okay, so I am starting to have fun with pygame. But I've got a problem. I tried to somehow enchance my code, make it organised, so I've decided to use classes here. It looks like this:

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

Okay, works. But what if I want to, for example fill the windows with white color? Then I have to define a method fill(), which will just self.display.fill(), right? Is there a way, to handle it normally, without defining hundreds of pygame-already-existing methods in my class?

And one another thing. If I do something by using my class, and I screw up, I always get this msg:

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

And I actually don't know what the heck is wrong. If I do this normally, without classes, then I get erros such as, pygame object blabla has no method blablabla or something like that, I just know what's happening. Is there a way to get through this, and find what's going on?

Thanks in advance for your help!

4
  • You could set a parent class which defines the color then your MainWindow could inherit from it Commented Feb 26, 2016 at 3:15
  • Yes, I know, but I wanted a situation similair to yours, but when MainWindow would inherit like from some pygame class, so methods are inherited, no need to define them XD And I guess it's not possible :( Commented Feb 26, 2016 at 3:18
  • Why not just set the class I'm suggesting instead as a mixin? Commented Feb 26, 2016 at 3:25
  • Like MainWindow(ClassWithFill, PyGameClass), I'm not sure what you mean by "when MainWindow would inherit like from some pygame class, so methods are inherited" but if you mean what I think you do a mixin allows you to inherit more than 1 class. Commented Feb 26, 2016 at 3:30

1 Answer 1

5

What you are doing here is on the right track, but it is done the wrong way. Your main "game loop" should be inside the class itself as a method, rather than calling stuff from outside the class in an actual loop. Here is a basic example of what you should be doing.

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

The main loop will call itself when the object MainRun() is created.

If you need more examples on specific things such as object handling let me know and I will see if I can throw some more information up for you.

I hope this helps you with your programming and the best of luck to you.

========================= EDIT ================================

In this case for these special operations make them object specific. Instead of using one generic method to blit your objects, make each object have its own function. This is done this way to allow for more options with each object you make. The general idea for the code is below... I have created a simple player object here.

#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

Now here is how you use the object's methods... I have included an event loop to help show how to use the move function. Just add this code to your main loop wherever it is needed and you will be all set.

#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

Be sure to use the same display name of the display inside your draw function.

Sign up to request clarification or add additional context in comments.

2 Comments

Okay, thanks. But I wanted to ask for something like this: So I've got my class, but you've created a MainRun() class. I wanted it to be like MainWindow(), because it would be like: awkay, mainWindow = MainWindow(800,600), got my window object, now lets set a caption to it mainWindow.caption("My window"), okay, now lets blit a background image to it` mainWindow.background("image.png"). And a background() method would still call pygame class method - load, and then blit(). And even if those method exist in pygame, I still need to define them in my class, and I dont want to do that
Ok I have updated the answer under the === EDIT === section to show how to use other objects inside your game.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.