2011-06-20 30 views
1

私は、pygameを使って簡単なタイプの教師に取り組んでいます。私の問題は、私は白い背景、waves1.pngを持つ画像を使用しているということです。今私は、白をイメージ内で透明にしたいと指定しました(self.image.set_colorkey((255, 255, 255)))。これはテキストブロック以外すべてのものです。波がtextオブジェクトと交差すると、波の白い背景がテキストの上に表示されます。あなたはpygameを持っているなら、これを実行することができます(waves1.pngイメージを除く)。画像の背景を透明にする問題:pygame

import pygame 
from pygame.locals import * 

class TextSprite(pygame.sprite.Sprite): 
    def __init__(self): 
     pygame.sprite.Sprite.__init__(self) 
     self.wordList = ['words yes', 'hello', 'this is a sentence', 'this is another sentence'] # read directly from external file 
     self.pos = 0 
     self.wordNum = 0 
     self.update1() 

    def update1(self): 
     # Render the given word 
     self.image = pygame.font.Font(None, 36).render(self.wordList[self.wordNum], 1, (0, 0, 0)) 
     # Render the correctly guessed letters 
     self.correct = pygame.font.Font(None, 36).render(self.wordList[self.wordNum][:self.pos], 1, (255, 0, 0)) 
     # Copy correct letters onto given word 
     self.image.blit(self.correct, (0, 0)) 

     self.rect = self.image.get_rect() 
     # set the center of the center the given word to the center of the screen 
     self.rect.center = pygame.display.get_surface().get_rect().center 

    def keyin(self, key): 
     word = self.wordList[self.wordNum] 
     letter = word[self.pos] 
     if letter == key: 
      self.pos = self.pos + 1 
     if self.pos == len(word): 
      self.reset() 
     self.update1() 

    def reset(self): 
     self.pos = 0 
     self.wordNum = self.wordNum + 1 
     self.update1() 



class Waves(pygame.sprite.Sprite): 

    # Constructor. Pass in the color of the block, 
    # and its x and y position 
    def __init__(self, filename): 
     # Call the parent class (Sprite) constructor 
     pygame.sprite.Sprite.__init__(self) 

     # Create an image of the block, and fill it with a color. 
     # This could also be an image loaded from the disk. 
     self.image = pygame.image.load(filename).convert() 
     # makes any white in the image transparent 
     self.image.set_colorkey((255, 255, 255)) 
     self.rect = self.image.get_rect() 

    # Decrease the y coordinate so the waves look like they're moving up 
    def update(self, text): 
     self.rect.y = self.rect.y - 6 
     if self.rect.y <= 200: 
      text.reset() 
      self.rect.y = 485 


def main(): 

    #I - Import and initialize 
    pygame.init() 

    #D - Display configuration 
    # The screen variable is a pygame Surface object 
    # Note that the set_mode() method creates a Surface object for you automatically 
    screen = pygame.display.set_mode((640, 480)) 
    pygame.display.set_caption("Typing Game") 

    #E - Entities (just background for now) 
    background = pygame.Surface(screen.get_size()) 
    background = background.convert() 
    background.fill((255, 255, 255)) 
    screen.blit(background, (0,0)) 



    #A - Action (broken into ALTER steps) 

    #A - Assign values to key variables 
    clock = pygame.time.Clock() 
    keepGoing = True 

    # Collect the sprite in a list 
    all = pygame.sprite.RenderPlain() 
    waveList = pygame.sprite.RenderPlain() 

    text = TextSprite() 
    all.add(text) 

    waves = Waves("waves1.png") 
    waveList.add(waves) 
    waves.rect.x = 0 
    waves.rect.y = 485 

    #L - Set up main loop 
    while keepGoing: 

     #T - Timer to set frame rate 
     # Tick is a method in the Clock class that determines the maximum frame rate 
     clock.tick(30) 

     #E - Event handling 
     for event in pygame.event.get(): 
      if event.type == QUIT: 
       keepGoing = False 
      elif event.type == KEYDOWN: 
       if event.key == K_ESCAPE: 
        keepGoing = False 
       else: 
        text.keyin(event.unicode) 

     # update position of waves 
     waves.update(text) 

     # clears screen 
     all.clear(screen, background) 

     # update screen 
     all.draw(screen) 

     waveList.clear(screen, background) 
     waveList.draw(screen) 


     # display.flip is a method that copies everything from the screen object to the actual visual display 
     pygame.display.flip() 

pygame.quit() 
if __name__ == '__main__': main() 

答えて

1

あなたのオプションであるかどうかわかりませんが、pngのネイティブアルファ透明度を使用すると、より良い結果が得られるはずです。

自分でpngを編集/再作成できる場合は、透明な背景を使用してみてください。

そこから、画像をロードするconvert_alpha()を使用できます。 (代わりにカラーキーを使用しての)

http://pygame.org/docs/ref/surface.html#Surface.convert_alpha

EDIT:つの他の態様は、画像がカラーキーに干渉するアルファチャネルを有することができることです。両方を使用しようとしていないことを確認するのに最適です。

画像のアルファチャンネルをプログラムで検出できると言われています。以下のような何か...

if self.image.get_masks()[3]!=0: 
    print "image has alpha!" 

ここhttp://pygame.org/docs/ref/surface.html#Surface.get_masks

HTHよくやっ

1

を参照してください!透過とカラーキーを利用するには、実際にすべてを正しく行ったことがあります(つまり、サーフェス上でコンバートを呼び出すこと、set_colorkeyメソッドに色を確実に渡すなど)。

問題は、それぞれのスプライトグループ "all"と "waveList"で描画してクリアする呼び出しの順序にあります。 all.drawを呼び出してテキストブロックをレンダリングしたら、それに続いてwaveList.clearを呼び出します。

テキストスプライトを描画したら、波スプライトの下のスペースをクリアしたくない、またはすでに描画されているテキストブロックと重なっている領域を消去しないという問題があります。あなたはこれを適切に行いたい場合は

、この順序でそれをやってみてください。

  1. waves.update()
  2. all.clear(スクリーン、バックグラウンド)
  3. waveList.clear(画面を、背景)
  4. all.draw(画面)
  5. waveList.draw(画面)

(MOR単純に、waveList.clear(screen、background)をall.clear(screen、background)のすぐ下の行に移動します。それはすべきです)

私はスプライトグループを使って作業していますが、通常は、各スプライトグループがクリア、更新、衝突チェック(ある場合)、描画などの順序で同じメソッドを呼び出します。

通常、これは正しい順序で物事を処理します。その後、スプライトのレイヤリングがあるかどうかに注意を払う必要があるかもしれませんが、それは別の話です。

関連する問題