2012-04-22 2 views
1

Heyo 방지, 이것은이다 "수입에서 수입"사회자가 나는 2를 가지고있는 2파이썬과 파이 게임 : 생성 디스플레이 표면을 두 번

병합 주시기 그래서 질문은, 이전에 내게로 질문의 확장의 비트 파일 : A.py 및 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? 

나는 글로브과 글로벌 값을 할당라는 빈 파일을 시도했지만, 내가 찾은 대부분의 시간은 그냥 내 코드는 투박보고한다 쓰기가 어렵다. 마찬가지로 .. 나는 init 파이 게임 중 두 번 중 하나를 원하지 않습니다. 'Pythonic'방법이 있습니까?

답변

5

이 질문은 구조화 된 파이썬 응용 프로그램에 실제로 적용될 수 있습니다.

실행 가능한 python 스크립트는 진입 점을 갖습니다. 이것은 응용 프로그램을 시작하기 위해 호출하는 스크립트입니다. 이 스크립트 내에서 라이브러리 모듈을 가져 와서 확장 기능을 재사용 할 수 있습니다.

응용 프로그램에 단일 진입 점이 있어야합니다. A.py이라고 가정합니다.
B.py은 해당 기능을 가져 와서 사용할 라이브러리 모듈입니다. 글로벌 tv 변수가 작동 할 것으로 기대할 필요는 없습니다. 대신, 적어도 인수를 취하는 함수가 있어야합니다. 또는 심지어 사용할 클래스로 인스턴스화 된 클래스입니다. 이 방법의 장점은 B 모듈은 이제 재사용 항상

def blitSpecial(surf): 
    surf.blit() 

A.py

tv

B.py라는 글로벌 표면을 제공하는 몇 가지 실행의 주요 스크립트에 의존하지 않는 것입니다

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

이것은 좋은 습관입니다. 모든 모듈이 메인 스크립트의 전역 객체에 의존한다면, 재사용 성이 훨씬 떨어진다.

특히 파이 게임 상황에서 사용자 지정 클래스와 유틸리티 기능을 위해 다른 모든 모듈을 사용하는 A.py에 화면이있는 모든 것이 발생해야합니다.

+0

하지만 다음과 같은 것들을하는 것은 정말 짜증이납니다. dostuff (tv, main, houses, buildings, people, tiles) – SuperDisk

+1

@SuperDisk : 동의합니다. 그 이유는 속성을 사용하여 인스턴스화 된 클래스를 작성하고 작성해야하는 이유입니다. 그리고 그 방법들은 그 속성들에 대해 작업합니다. 이것은 모듈 작성 방법의 아주 기본적인 예입니다. 많은 파이 게임 예제에서 볼 수 있듯이, 사람들은 기존 클래스를 서브 클래스 화하여 사용자 정의 작업을 수행합니다. 제대로 했으므로 10 개의 인수를 가진 함수를 호출 할 필요가 없습니다. – jdi

0

는 한 번만 pygame.init()를 호출해야합니다, 그래서 당신의 코드는 다음과 같이 보일 것입니다 생각 :

#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) 
+0

여기에 몇 개의 레이블이 섞여 있다고 생각합니까? 'setup()'은 당신의'A' 모듈에 있습니다. 또한, 문서들은'init'이 여러 번 호출하는 것이 안전하다고 말한다. – jdi

+0

여러 번 호출하는 것이 안전하지만 필요하지는 않습니다. – snim2

+0

'setup '이'A' 또는'B'에 있어야하는지에 관해서는, 당신의 대답은 조금 더 깔끔한 것 같아요. 나는 OP에'A.py'에'display.set_mode'가 있었기 때문에'A'에 남겨 두었습니다. – snim2

0

당신은 매개 변수로 pygame.Surface 객체를 가지고 함수를 작성할 수 있습니다 :

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) 

필자는 다른 스프라이트 기반 엔진과 비교해 얼마나 빠르거나 느린지 개인적으로 알지 못하지만 그 자체를 그리거나 지울 수있는 클래스를 만드는 것은 매우 빠릅니다.

사용하려면 디스플레이 화면과 TV 개체를 만드십시오.

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

화면에 TV의 사본을 그릴 할 때마다 당신은 당신이 나중에 재미있는 물건을 할 수있는 그런

myTVobj.erase(screen, background) 

사용

myTVobj.draw(screen) 

개체를 지우려면 전화 TV 클래스에서 생성 된 객체를 목록에 붙여 넣는 것과 같습니다.

tv_list = [] 
tv_list.append(myTVobj) 

TV에 전체 TV를 추가하여 동시에 모두 그릴 수 있습니다.

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

for tv in tv_list: 
    tv.draw(screen) 

또는 당신은 단지 마지막으로, 당신은 당신이 주위를 이동할 수 있습니다 귀하의 TV 클래스에 또 하나 개의 기능을 추가 할 수있는 한 줄

for tv in tv_list: 
    tv.erase(screen) 

을 변경하여 모두 삭제할 수 있습니다. .rect 멤버를 '위치 표시 자'로 취급하는 경우 멤버 (hehe)와 함께 객체의 화면상의 업데이트 위치를 변경하기 만하면됩니다.

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