2016-04-08 14 views
-1

私はシンプルなトップダウン運転シミュレーターを作成しようとしています。上向きの矢印キーを押しながら移動し、左右の矢印キーを使って操縦します。理想的には、アップキーと左または右キーを同時に押したままにすると、車は円内を移動します。簡単なドライビングゲームの問題

車は、方向に関係なく、各フレームの画面上で同じ距離を移動する必要があります。私は与えられた方向(度)でx座標とy座標を計算する一連の方程式を考案しました。それは右の三角形のようにそれぞれの動きを扱います。斜辺は、車が方向に関係なく移動する設定距離です。他の2つの側面は、特定の斜辺長を達成するために必要なxおよびy値です。それはコサイン関数を使って片方を見つけ出し、ピタゴラスの最後の方程式を求める定理を使います。

グラフ用紙でテストしたところ、方向に関係なく毎回同じ距離移動しました。問題は、車が円で動かないことです(ステアリングを続けている場合)。デフォルトの方向は0度なので、上キーを保持すると車はまっすぐ上に移動します。時計回り(右矢印キー)に回すと、車は右に曲がり始めるでしょう。しかし、ある点では、それは円で動かないでしょう。コードを実行してみると意味があります。方向をラジアンに変換され、*

は、それはPythonは上記の私のコメントに続いて

import pygame, math 

screen = pygame.display.set_mode((1000, 700)) 
clock = pygame.time.Clock() 

# The center of the sceen 
x = 475 
y = 325 

drive = 0 # 0 = not moving, 1 = moving 
turn = 0 # 1 = clockwise, -1 = counter-clockwise 

d = 0 

def move(d, c): 
    d = math.radians(d) 
    a = math.cos(d) * c 
    b = math.sqrt((c**2) - (a**2)) 

    return a, b 


def main(): 
    while True: 
     global x, y, drive, turn, d 
     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       pygame.quit() 
       quit() 

      if event.type == pygame.KEYDOWN: 
       if event.key == pygame.K_UP: 
        drive = 1 
       if event.key == pygame.K_RIGHT: 
        turn = 1 
       if event.key == pygame.K_LEFT: 
        turn = -1 
      if event.type == pygame.KEYUP: 
       if event.key == pygame.K_UP: 
        drive = 0 
       if event.key == pygame.K_RIGHT: 
        turn = 0 
       if event.key == pygame.K_LEFT: 
        turn = 0 


     if drive == 1: 
      if turn == 1 and d != 359: # Turn Clockwise 
       d += 4 
      if turn == 1 and d == 359: 
       d = 0 
      if turn == -1 and d != 0: # Turn Counter Clockwise 
       d -= 4 
      if turn == -1 and d == 0: 
       d = 359 


     ''' move()[0] = a 
      move()[1] = b ''' 
     if drive == 1: 
      if d >= 0 and d < 90: 
       x += move(d, 6)[1] 
       y -= move(d, 6)[0] 


      if d >= 90 and d < 180: 
       x += move(d-90, 6)[0] 
       y += move(d-90, 6)[1] 


      if d >= 180 and d < 270: 
       x -= move(d-90, 6)[1] 
       y += move(d-90, 6)[0] 


      if d >= 270 and d < 360: 
       x -= move(d-180, 6)[1] 
       y += move(d-180, 6)[0] 



     screen.fill((40,40,40)) 
     pygame.draw.rect(screen, (0,0,255), (round(x, 0), round(y, 0), 50, 50)) 


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


main() 
+0

あなたのコードでは、 'd> 360'または' d <0'の場合はどうなりますか?たとえば、 'd + = 4'は決して359と等しくないので、時計回りに十分に回すと' d> 360'となるので、これはたくさん起こると思います。 – wflynny

+0

私はそれを認識しませんでした。それを私の注目に持ってくれてありがとう。それはまったく動かないでしょう。 –

答えて

1

を使用するものであるので、それはあなたが変更した場合のようになります。

if drive == 1: 
     if turn == 1 and d != 359: # Turn Clockwise 
      d += 4 
     if turn == 1 and d == 359: 
      d = 0 
     if turn == -1 and d != 0: # Turn Counter Clockwise 
      d -= 4 
     if turn == -1 and d == 0: 
      d = 359 

​​

移動を停止しません。ただし、あなたのルールはと大幅にとなります。 sin(-y) = -sin(y)cos(-x) = cos(x)からx、y座標を直接cos/sinに更新することで、三角関数の全機能を使用してください。スクリプト全体は次のようになります:

def main(): 
    # define these here since you aren't modifying them outside of main 
    x = 475 
    y = 325 
    drive = 0 # 0 = not moving, 1 = moving 
    turn = 0 # 1 = clockwise, -1 = counter-clockwise 
    # set to -90 since 0 points east. 
    d = -90 

    while True: 
     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       pygame.quit() 
       quit() 

      if event.type == pygame.KEYDOWN: 
       if event.key == pygame.K_UP: 
        drive = 1 
       elif event.key == pygame.K_RIGHT: 
        turn = 1 
       elif event.key == pygame.K_LEFT: 
        turn = -1 
      if event.type == pygame.KEYUP: 
       if event.key == pygame.K_UP: 
        drive = 0 
       elif event.key in (pygame.K_RIGHT, pygame.K_LEFT): 
        turn = 0 

     if drive == 1: 
      d += turn * 4 

      x += 6 * math.cos(math.radians(d)) 
      y += 6 * math.sin(math.radians(d)) 

     screen.fill((40,40,40)) 
     pygame.draw.rect(screen, (0,0,255), (round(x, 0), round(y, 0), 50, 50)) 

     pygame.display.update() 
     clock.tick(20) 
+0

ありがとう!これは本当に多くの助けになります。それは完璧に動作しますが、私はd + = turn * 4という行をよく理解していません。また、なぜノースの代わりに東方が0度ですか? –