python 画像 テキストが動的に表示されない、pygame




python 文字 ウィンドウ 表示 (2)

以下のコードは、スコアテキストを表示させる緑色のボタンを作成することになっています。 残念ながら、ボタンは何もしません。私はそれを動作させるために唯一の方法は、clickButton関数の代わりにwhileループにmakeTextの関数呼び出しを置くことです。 誰かがボタンを押してコードを修正しても表示されない理由を説明できますか?

import pygame
import sys
#game stuff
pygame.init()
screen = pygame.display.set_mode((640, 480),0,32)
clock = pygame.time.Clock()

#functions
def makeText(title,text,posx,posy):
    font=pygame.font.Font(None,30)
    scoretext=font.render(str(title)+ ": " +str(text), 1,(0,0,0))
    screen.blit(scoretext, (posx, posy))
def clickButton(name,x,y,width,height):
    if x + width > cur[0] > x and y + height > cur[1] > y:
        if click == (1,0,0):
            makeText("score",300,100,10)
#objects
button1 = pygame.Rect((0,0), (32,32))

while True:
    screen.fill((255,255,255))
    screen.fill((55,155,0), button1)
#update display
    pygame.display.update()
    clock.tick(60)
#event handling
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quit()
        elif event.type == pygame.MOUSEBUTTONDOWN:
            cur = event.pos
            click = pygame.mouse.get_pressed()
            clickButton("button1",button1.left,button1.top,button1.width,button1.height)

問題は、テキストを作成するとメインループが継続してscreen.fillを呼び出し、 pygame.display.update()が呼び出される前にテキストをオーバードローするということです。

あなたはそれを次のように変更できます:

...
def clickButton(name,x,y,width,height):
    print x + width > cur[0] > x and y + height > cur[1] > y
    if x + width > cur[0] > x and y + height > cur[1] > y:
        if click == (1,0,0):
            makeText("score",300,100,10)
#objects
button1 = pygame.Rect((0,0), (32,32))

while True:
    screen.fill((255,255,255))
    screen.fill((55,155,0), button1)

#event handling
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quit()
        elif event.type == pygame.MOUSEBUTTONDOWN:
            cur = event.pos
            click = pygame.mouse.get_pressed()
            clickButton("button1",button1.left,button1.top,button1.width,button1.height)
...

そのため、スクリーンに背景色を塗りつぶした後、 pygame.display.update()が呼び出される前にテキストが作成されますが、 whileループの次の反復でスクリーンが再描画される問題は解決されません。

したがって、解決策は、ボタンが押されたという事実、つまり状態を把握することです。

ここでは、ボタンのクラスとグローバル状態のdictを使用する別のアプローチの例を示します(グローバル変数は必要ありません。ほとんどの場合は避けてください)。これは、ゲームが始まると非常に混乱するためですより複雑になる)。

最初のボタンをクリックしてスコアを表示または非表示にし、2番目のボタンをクリックして背景色を変更して100ポイントを獲得します。

新しいボタンを作成するのがいかに簡単かをご覧ください。 単純な関数を追加するだけです。

import pygame
import sys
import random

pygame.init()
screen = pygame.display.set_mode((640, 480),0,32)
clock = pygame.time.Clock()

# create font only once
font = pygame.font.Font(None,30)

# it's always a good idea to cache all text surfaces, since calling 'Font.render' is
# an expensive function. You'll start to notice once your game becomes more complex
# and uses more text. Also, use python naming conventions
text_cache = {}
def make_text(title, text):
    key = "{title}: {text}".format(title=title, text=text)
    if not key in text_cache:
        text = font.render(key, 1,(0,0,0))
        text_cache[key] = text
        return text
    else:
        return text_cache[key]

# we use the 'Sprite' class because that makes drawing easy
class Button(pygame.sprite.Sprite):
    def __init__(self, rect, color, on_click):
        pygame.sprite.Sprite.__init__(self)
        self.rect = rect
        self.image = pygame.Surface((rect.w, rect.h))
        self.image.fill(color)
        self.on_click = on_click

# this happens when the first button is pressed
def toggle_score_handler(state):
    state['show_score'] = not state['show_score']

# this happens when the second button is pressed
def toggle_backcolor_handler(state):
    state['backcolor'] = random.choice(pygame.color.THECOLORS.values())
    state['score'] += 100

# here we create the buttons and keep them in a 'Group'
buttons = pygame.sprite.Group(Button(pygame.Rect(30, 30, 32, 32), (55, 155 ,0), toggle_score_handler),
                              Button(pygame.Rect(250, 250, 32, 32), (155, 0, 55), toggle_backcolor_handler))

# here's our game state. In a real 
# game you probably have a custom class
state = {'show_score': False,
         'score': 0,
         'backcolor': pygame.color.Color('White')}

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quit()
        # you can check for the first mouse button with 'event.button == 1'
        elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
            # to check if the mouse is inside the button, you 
            # can simple use the 'Rect.collidepoint' function
            for button in (b for b in buttons if b.rect.collidepoint(event.pos)):
                button.on_click(state)

    screen.fill(state['backcolor'])
    # draw all buttons by simple calling 'Group.draw'
    buttons.draw(screen)

    if state['show_score']:
        screen.blit(make_text("score", state['score']), (100, 30))

    pygame.display.update()
    clock.tick(60)


clickButton関数の「クリック」の値をチェックしていますが、clickButtonがそのボタンにアクセスできる場所はどこでも定義されたクリックは表示されません。 おそらく、clickButton関数でクリックを引数として渡す必要があります。そうすればif条件を真にすることができますか?







pygame