2017-06-21 5 views
1

私はpygameライブラリで簡単なゲームを作っています。私は奇妙なバグに気付きました。私が矢印キーの1つをタップしてキャラクターを動かすと、それはそれを一方向に動かします。キーダウンは、押す方向に正の加速をトリガし、キーアップは加速度をゼロにリセットします。これらの値を確認すると、キーアップが発生しているにもかかわらず加速が正のままです。すべてのイベントを見ると、キーダウンとキーアップを登録しますが、pygameはそのキーアップイベントに関連付けられたコードを実行しません。私のキーボードの信号に問題があるかもしれませんが、パイゲームでのイベント処理のように思えます。ここに私のコードは次のとおりです。ここでpygameがキーアップを検出できません

import pygame 

pygame.init() 

display_x = 1024 
display_y = 512 

game_display = pygame.display.set_mode((display_x, display_y)) 
clock = pygame.time.Clock() 

fps = 30 
font = pygame.font.SysFont(None, 25) 

max_velocity = 16 
acceleration = 4 


def print_to_screen(text, color, x, y): 
    screen_text = font.render(text, True, color) 
    game_display.blit(screen_text, [x, y]) 


def game_loop(): 
    game_exit = False 

    lead_x = display_x/2 
    lead_y = display_y/2 
    vel_x = 0 
    vel_y = 0 
    acc_x = 0 
    acc_y = 0 
    tile_size = 32 

    while not game_exit: 
     for event in pygame.event.get(): 
      print(event) 
      if event.type == pygame.QUIT: 
       game_exit = True 
      if event.type == pygame.KEYDOWN: 
       if event.key == pygame.K_LEFT: 
        acc_x = -acceleration 
       if event.key == pygame.K_RIGHT: 
        acc_x = acceleration 
       if event.key == pygame.K_UP: 
        acc_y = -acceleration 
       if event.key == pygame.K_DOWN: 
        acc_y = acceleration 
      if event.type == pygame.KEYUP: 
       if event.key == pygame.K_LEFT and vel_x < 0: 
        acc_x = 0 
       if event.key == pygame.K_RIGHT and vel_x > 0: 
        acc_x = 0 
       if event.key == pygame.K_UP and vel_y < 0: 
        acc_y = 0 
       if event.key == pygame.K_DOWN and vel_y > 0: 
        acc_y = 0 

     if -max_velocity < vel_x < max_velocity: # if velocity isn't max, adds acceleration to velocity 
      vel_x += acc_x 
     if -max_velocity < vel_y < max_velocity: 
      vel_y += acc_y 
     if vel_x < 0: # velocity decay, if vel is less than 0, adds one. no input = slowed down cube 
      vel_x += 1 
     elif vel_x > 0: 
      vel_x -= 1 
     if vel_y < 0: 
      vel_y += 1 
     elif vel_y > 0: 
      vel_y -= 1 

     if (lead_x + vel_x) < 0: # looks into future: if past border in next frame, sets x coord to 0, stops motion 
      vel_x = 0 
      acc_x = 0 
      lead_x = 0 
     elif (lead_x + vel_x) > (display_x - tile_size): 
      vel_x = 0 
      acc_x = 0 
      lead_x = (display_x - tile_size) 
     if (lead_y + vel_y) < 0: 
      vel_y = 0 
      acc_y = 0 
      lead_y = 0 
     elif (lead_y + vel_y) > (display_y - tile_size): 
      vel_y = 0 
      acc_y = 0 
      lead_y = (display_y - tile_size) 

     lead_x += vel_x 
     lead_y += vel_y 

     game_display.fill((255, 255, 255)) 
     pygame.draw.rect(game_display, (255, 0, 0), [lead_x, lead_y, tile_size, tile_size]) 
     print_to_screen(str(int(lead_x)) + ", " + str(int(lead_y)), (0, 0, 0), 0, 0) 
     if vel_x > max_velocity or vel_y > max_velocity: 
      print_to_screen(str(int(vel_x)) + ", " + str(int(vel_y)), (255, 0, 0), 0, 16) 
     else: 
      print_to_screen(str(int(vel_x)) + ", " + str(int(vel_y)), (0, 0, 0), 0, 16) 
     if acc_x > acceleration or acc_y > acceleration: 
      print_to_screen(str(int(acc_x)) + ", " + str(int(acc_y)), (255, 0, 0), 0, 32) 
     else: 
      print_to_screen(str(int(acc_x)) + ", " + str(int(acc_y)), (0, 0, 0), 0, 32) 

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

game_loop() 
pygame.quit() 
quit() 

クイックタップからのイベントデータです:

<Event(2-KeyDown {'unicode': '', 'key': 276, 'mod': 0, 'scancode': 75})> 
<Event(3-KeyUp {'key': 276, 'mod': 0, 'scancode': 75})> 

それはキー上下キーイベントではなく、キーアップが登録されません理由を確認してくださいを示しています。

答えて

2

問題はvel_xは、keyUpイベントイベントと併せて以下または0よりも大きい場合は、あなたがチェックすることです。 (vel_x < 0)我々は左に移動しているときに何が起こるかについて考え、素早く押すとK_RIGHTを解放し、その後、vel_xは依然としてマイナスであるのでif event.key == pygame.K_RIGHT and vel_x > 0: keyUpイベントは無視してacc_xされ、Falseで0

にあなたをリセットしませんacc_xないvel_xが同じでは上下キーとvel_y、acc_yのために行く0より大きい

if event.type == pygame.KEYUP: 
    if event.key == pygame.K_LEFT and acc_x < 0: 
     acc_x = 0 
    if event.key == pygame.K_RIGHT and acc_x > 0: 
     acc_x = 0 

であるかどうかを確認する必要があります。

+0

ありがとう!なぜ私はそれを含めたのか分かりませんが、問題を修正しました。 –

+1

ちょっと、なぜあなたがその条件を追加したのか教えていただけます。 :P 'vel_x> 0'(またはあなたの場合' acc_x')を使わずに素早く左右を押すと、プレイヤーが完全に停止し、キーを放してもう一度押すとスプライトが再び動くことがあります。私はあなたが 'vel'をリセットする前に、プレーヤーがその特定の方向に動いているかどうかを確認するのが良い考えだと思います。 – skrx

+0

それはおそらく理由でした。今すぐ動作するように見えます。それ以来、私はいくつかのコードを変更しました。左と右をタップすれば本当に素早くタップすれば、加速したらすぐに片方の方向をタップしたように、あなたが言ったことをテストします。奇妙な修正では修正されませんでした。 –

0

ことからkeyupブロックを削除し、KeyDownイベントブロックにこれを追加します。

if event.type == pygame.KEYDOWN: 
    if event.key == pygame.K_LEFT: 
    acc_x = -acceleration 
    acc_y = 0 
if event.key == pygame.K_RIGHT: 
    acc_x = acceleration 
    acc_y = 0 
if event.key == pygame.K_UP: 
    acc_y = -acceleration 
    acc_x = 0 
if event.key == pygame.K_DOWN: 
    acc_y = acceleration 
    acc_x = 0 
+0

ありがとうございますが、それは私が探しているものではありません。動きが複雑な理由は、加速と動きを斜めにしたいからです。あなたのコードでこれが削除され、すべてのキーを離したときにプレイヤーは移動を停止しません。 –

+0

よろしいですか?ご了解ありがとう:) – sukhdeep

関連する問題