1

pygameで小さなプログラムを書いた後、問題が発生しました。プログラムは、分割された .GIF アニメーションを取得し、次の方法で画像 (gif のフレーム) を読み込みます。

pygame.image.load(filename)

これは、配列に追加される pygame surface オブジェクトを返します。プログラムは、合計6 つの配列を使用して、約15 フレームを配列にロードします。

私が抱えている問題は、while ループを介して入力を受け入れるときです。ループはアイドル アニメーションと実行中のアニメーションを正常に再生します、キーボードからの入力を受け入れると (pygame のイベント リストから入力を取得します...)

for event in pygame.event.get():経由pygame.KEYDOWN

非常に顕著なラグがあり、応答しないアニメーション セットの切り替えが発生します。この方法でゲームを作る場合は、修正する必要があります。私のコードは非効率的だと思いますが、一時停止を作成しないだけで十分です。どんな助けでも素晴らしいでしょう。

私の推測?pygame.clock.tick()ある種のイベントラグを作成していますが、イベントラグが発生した場合でも、これを修正する方法がわかりません。

問題があると思われるループは次のとおりです。

while running == 2:
pygame.display.flip()
#mouse = pygame.mouse.get_pos()
#events = pygame.event.get()
#(pygame.QUIT, pygame.KEYDOWN, pygame.KEYUP)
for event in pygame.event.get():
#event = pygame.event.wait()
    if event.type == pygame.QUIT:
        sys.exit(0)
    elif event.type == pygame.KEYDOWN:
        print event.key
        wait = 0
        if event.key == pygame.K_d:
            tmpcache = wr
            lastkey = "wr"
        elif event.key == pygame.K_a:
            tmpcache = wl
            lastkey = "wl"
    elif event.type == pygame.KEYUP:
        wait = 1
        if lastkey == "wr":
            tmpcache = sr
        elif lastkey == "wl":
            tmpcache = sl

if wait == 1:           
    for frame in tmpcache:
        screen.blit(test, (0,0))
        screen.blit(frame, (currentchar.posx, currentchar.posy))
        pygame.display.flip()
        clock.tick(charfps)

else:
    for frame in tmpcache:
        screen.blit(test, (0,0))
        screen.blit(frame, (currentchar.posx, currentchar.posy))
        pygame.display.flip()
        clock.tick(charfps)

ここには示されていませんが、いくつかの変数が使用されています。

charfps = 30
currentchar.posx, currentchar.posy両方のタプル(300, 240)

4

1 に答える 1

4

あなたの問題は、メインループ内にサブループを作成することです:

while running == 2:
    pygame.display.flip()
    for event in pygame.event.get():
        ...
    for frame in tmpcache:
        screen.blit(test, (0,0))
        screen.blit(frame, (currentchar.posx, currentchar.posy))
        pygame.display.flip()
        clock.tick(charfps)

したがって、 に 15 個の要素がある場合、フレームごとに15 回tmpcache呼び出していることになり、このサブループ内でコードが実行されている間は、イベントを続行しません。clock.tick()

単純に呼び出すだけでpygame.display.flip()、フレームごとに 1clock.tick(charfps) 回だけ問題を解決できます。

以下は、60 FPS で実行しながら、アニメーションのイメージを 1 秒間に 3 回変更する簡単な例です。

import pygame
from collections import deque

pygame.init()
screen = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()

# just some colored squares for our animation
def get_cache(colors):
    tmp=[]
    for c in colors:
        s = pygame.surface.Surface((50,50))
        s.fill(pygame.color.Color(c))
        tmp.append(s)
    return tmp

walk_left, walk_right = get_cache(('red', 'yellow', 'blue')), get_cache(('black', 'white', 'grey'))

rect = walk_left[0].get_rect(top=100, right=100)
cachedeque = deque(walk_left)
state = None
quit = False

# a simple variable to keep track of time
timer = 0

# a dict of {key: (animation, direction)}
moves = {pygame.K_LEFT:  (walk_left,  (-2, 0)),
         pygame.K_RIGHT: (walk_right, ( 2, 0))}

while not quit:
    quit = pygame.event.get(pygame.QUIT)
    pygame.event.poll()

    # state of the keys
    keys = pygame.key.get_pressed()

    # filter for the keys we're interessted in
    pressed = ((key, _) for (key, _) in moves.iteritems() if keys[key])
    key, (cache, dir) = next(pressed, (None, (None, None)))

    # if a key of the 'moves' dict is pressed:
    if key:
        # if we change the direction, we need another animation
        if state != key: 
            cachedeque = deque(cache)
            state = key
        # move the square                
        rect.move_ip(dir) 
    else:
        state = None

    screen.fill(pygame.color.Color('green'))

    # display first image in cachedeque    
    screen.blit(cachedeque[0], rect)

    # rotate cachedeque to the left, so the second image becomes the first
    # do this three times a second:
    if state and timer >= 1000./3:
        cachedeque.rotate(-1)
        timer = 0

    # call flip() and tick() only once per frame
    pygame.display.flip()

    # keep track of how long it took to draw this frame
    timer += clock.tick(60)

ここに画像の説明を入力

于 2014-01-30T13:14:27.237 に答える