简单驾驶游戏的问题

时间:2016-04-08 17:05:55

标签: python pygame trigonometry

我试图制作一个简单的自上而下驾驶模拟器,按住向上箭头键移动并使用向右/向左箭头键转向。理想情况下,如果您同时按住向上键和向左或向右键,汽车将会移动一圈。

无论方向如何,汽车都应在每个画面上移动相同的距离。我设计了一组方程来计算给定方向(以度为单位)的x和y坐标。它将每个运动视为直角三角形。斜边是汽车无​​论方向如何都会移动的设定距离。另外两个边是实现特定斜边长度所需的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()

1 个答案:

答案 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

    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

它不会停止移动。但是,您的规则可以 彻底 简化。使用cos/sinsin(-y) = -sin(y)后的cos(-x) = cos(x)直接更新x,y坐标,充分发挥三角函数的作用。您的整个脚本可能如下所示:

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)