2010-12-13 17 views
3

私はpygameライブラリを使用しています。以下は、プレーヤーの取り扱い私のイベントのための擬似コードです:パイゲームの滑らかな動き

#generates multiple events for keys that are held down 
pygame.key.set_repeat(30,30) 

for event in pygame.event.get() 

    nextPos = currentPos 

    if(keyUp): 
     if event.key == w : 
     key_w = false 
     #do the same for s, a and d 

    if(keyDown): 
     if event.key == w: 
     key_w = true 
     #same for s,a and d 

    if(key_w): 
     #update nextPos 

    #do same for key_s, key_a and key_d 

    currentPos = nextPos 

問題は、時々私は、画面上の私のマウスを移動するとことで、イベントを処理している間、私は、同時にキーを押していますキーのイベントがキューに入れられ、これらの複数のキー押下が一緒に実行されるので、プレイヤーは巨大な距離を飛び越えているように見えます。

この問題は、マウスをまったく移動しないと発生しません。

答えて

0

ここではイベントキューが最適な解決策ではないかもしれません。代わりに、フレームごとに1回ポーリングを行う方がよいでしょうか?私の答えに

+0

フレームごとに1回ポーリングしても、マウスを動かすまでは正常に動作します。私がマウスを動かして同時にキーを押すと、プレイヤーは同じ位置に止まってしまいます。 4〜5秒後に、私は以前に押されたキーに応じて再び動き始めます – Karan

+0

OK、部分的に解決されました。私は、pygame.event.set_blockedを使用してイベントキューからmousemotionを削除しました。しかし今、私は弾丸を撃つためにマウスクリックを使いたいです(それはシューティングゲームです)。これは同じ問題を引き起こしていますが、この場合、マウスクリックによるイベントの数が少ないため、プレイヤーは小さな距離をジャンプします – Karan

1

更新:

)(私はすべてのフレームのキーを扱う方法を確認するために私のゲームのコードをチェックし、私がイベントからキー情報を取得しないようですが、使用はpygame.key.get_pressed:

for event in pygame.event.get(): 
     if event.type == pygame.QUIT: 
      gl.loop_main_loop = False # exit main loop and terminate 
    keys = pygame.key.get_pressed() 
    for key, state in enumerate(keys): 
     if (key in self.key_handlers) and state: 
      self.key_handlers[key]() # call key handler proc 

つまり、各関連するキーは1フレームにつき1回しか処理しません。マウスは私が以下に説明する方法で読むことができます。

ゲームに固定フレームレートがない場合は、移動ベクトル計算でデルタ時間を使用することを忘れないでください。


はたぶん良いアイデアは、すべてのキーボードイベント最初の各プロセスの間にあり、自分のキーのステータス表示、あなた(例えばWSAD)への重要なキーはアップまたはダウンしているあなたを教え、すなわち構造を構築します。すべてのイベントがそのフレームで処理されたら、キーステータスデータを使用して移動コードを実行します。

mousemotionイベントを使用してマウスを追跡するのではなく、pygame.mouse.get_pos()とpygame.mouse.get_pressed()を使用して位置とボタンを直接読み取るようにしてください。

あなたの動きコードは、あなたのゲームが可変フレームレートで実行されるという事実(フレームレートを一定に保つためにpygameを強制しない限り)を考慮に入れて、動きベクトル計算で時間デルタを使用するべきです。

Iは、以下の方法を使用
1

...

Iはcooridinate変数を初期化...この場合

x = 300 
y = 300 
pX = 0 
pY = 0 

、xおよびyはプレーヤスプライトによって使用される実際の座標であり、そしてpXのおよびpYはイベントハンドラによって使用されます。

その後、私はプレイヤーの座標が処理されるゲームのメインループの中で最後に

for event in pygame.event.get(): 
    if event.type == pygame.QUIT: 
     sys.exit(0) 

    if event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT: 
     pX -= 2 
    if event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT: 
     pX += 2 
    if event.type == pygame.KEYDOWN and event.key == pygame.K_UP: 
     pY -= 2 
    if event.type == pygame.KEYDOWN and event.key == pygame.K_DOWN: 
     pY += 2  

    if event.type == pygame.KEYUP and event.key == pygame.K_LEFT: 
     pX += 2 
    if event.type == pygame.KEYUP and event.key == pygame.K_RIGHT: 
     pX -= 2 
    if event.type == pygame.KEYUP and event.key == pygame.K_UP: 
     pY += 2 
    if event.type == pygame.KEYUP and event.key == pygame.K_DOWN: 
     pY -= 2 

...イベントハンドラに次のコードを使用して、私は入れ...

x += pX 
y += pY 
0

私はpygame.event.get()を使用しません。

私の意見では、プレイヤーの動きのための最良の入力はpygame.keyです。システムはすべてのフレームに押したキーをチェックします

while True: 
    keys = pygame.key.get_pressed() 
    if keys[K_a]: 
     player.pos.x -= 10 
    if keys[K_d]: 
     player.pos.x += 10 
    if keys[K_w]: 
     player.pos.y -= 10 
    if keys[K_s]: 
     player.pos.y += 10 

この方法:get_pressed()

私はこのようにそれをフォーマットします。