Question

Heyo, this is a bit of an extension of the "Imports within imports" question asked earlier by me, so moderators feel free to merge the 2.

I have 2 files: A.py and B.py

#A.py
import pygame
import B
pygame.init()
tv = pygame.display.set_mode((256, 256))
tv.blit(<some surface here>)


#B.py
import pygame
pygame.init()
tv.blit()??? <--- I need to blit to tv, but how do I do it here?

I've tried making a blank file called Globe and assigning global values to it, but most of the time I've found it just makes my code look clunky and hard to write. As well.. I don't want to init pygame twice either. Is there any 'Pythonic' way to do it?

Était-ce utile?

La solution

This question could really apply to any structured python application.

An executable python script is going to have an entry-point. This is the script that you call to start the application. Within this script, it can import library modules to reuse extended functionality.

Your application needs to have a single entry point. Lets assume it will be A.py.
B.py would be a library module that you will import and use its functions. It should not have to expect a global tv variable to operate on. Instead, it should have, at the very least, functions that take arguments. Or even, a class that is instantiated with a surface to use. The benefit of this approach is that your B module is now reusable and not dependent on some executable main script providing a global surface always called tv

B.py

def blitSpecial(surf):
    surf.blit()

A.py

import B

tv = pygame.display.set_mode((256, 256))
B.blitSpecial(tv)

This is a good habit to get into. If all your modules depend on global objects from a main script, they will be far less reusable.

Specifically for your pygame situation, everything with the screen surface should be happening in A.py which is using all of the other modules for custom classes and utility functions.

Autres conseils

You can write functions that take pygame.Surface objects as parameters:

class TV():
    def __init__(self):
        self.img = ... 

        ### insert code to load image here

        self.rect = self.img.get_rect()

    def draw(self, surface):
        surface.blit(self.img, self.rect.topleft)

    def erase(self, surface, background):
        surface.blit(background, self.rect)

I don't personally know how fast/slow this is compared to other sprite-based engines, but it's a very quick way to build out a class that can draw/erase itself.

To use it, just create a display screen and a TV object.

screen = pygame.display.set_mode((256, 256))     
background = pygame.Surface((0,0),(256,256))

background.fill(pygame.Color(0,0,0))
screen.fill(pygame.Color(0,0,0))

myTVobj = TV()

Every time you want to draw a copy of the TV onto the screen you call

myTVobj.draw(screen)

To erase the object, use

myTVobj.erase(screen, background)

Then you can do fun stuff later with objects created from the TV class, like stick them in a list.

tv_list = []
tv_list.append(myTVobj)

You can add a whole bunch of TVs to a list and draw all of them at the same time.

tv_list = []
tv_list.append(myTVobj)
tv_list.append(myTVobj)
tv_list.append(myTVobj)

for tv in tv_list:
    tv.draw(screen)

Or you can erase them all just by changing one line

for tv in tv_list:
    tv.erase(screen)

Finally, you can add one more function to your TV class that lets you move it around. If you treat the .rect member as a 'position marker', all you have to do is fiddle with its members (hehe) to change your object's onscreen update location.

def move(self, move_amount=(1,0):
    self.rect.move_ip(move_amount[0], move_amount[1])

You only need to call pygame.init() once, so I think your code should look something like this:

#A.py
import pygame
import B

def setup():
    pygame.init()
    tv = pygame.display.set_mode((256, 256))
    ...
    mysurface = ...
    tv.blit(mysurface)
    return tv


#B.py
import pygame
def mydraw(surface):
    ...
    surface.blit()

# In whatever file you like :)
if __name__ == '__main__':
    surface_A = B.setup() # Do this first
    mydraw(surface_A)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top