python - 如何在 Pygame 中制作基本的汽车物理?
问题描述
我想知道如何制作一辆使用箭头键移动和旋转的汽车。我正在尝试制作一个汽车物理游戏,其中玩家控制汽车并开车和停车,但我在如何开始实施控制方面遇到了麻烦。我怎样才能让我的车用箭头键移动它的旋转方向?
例如,如果我按后退箭头键,汽车应该倒车,如果汽车在倒车的同时也在转弯,它应该按照汽车转弯的方式移动。
这是我现在的代码。现在真的没有什么事情发生。
import pygame
pygame.init()
window = pygame.display.set_mode((800,800))
pygame.display.set_caption("car game")
class car:
def __init__(self,x,y,height,width,color):
self.x = x
self.y = y
self.height = height
self.width = width
self.color = color
self.carimage = pygame.image.load("1.png")
self.rect = pygame.Rect(x,y,height,width)
def draw(self):
self.rect.topleft = (self.x,self.y)
window.blit(self.carimage,self.rect)
white = (255,255,2555)
car1 = car(300,300,20,20,white)
def ReDrawWindow():
car1.draw()
# main loop
runninggame = True
while runninggame:
for event in pygame.event.get():
if event.type == pygame.QUIT:
runninggame = False
ReDrawWindow()
pygame.display.update()
pygame.quit()
解决方案
这是改进的代码:
import pygame, math
pygame.init()
window = pygame.display.set_mode((600,600))
pygame.display.set_caption("car game")
img = pygame.image.load("1.png")
class Car:
def __init__(self, x, y, height, width, color):
self.x = x - width / 2
self.y = y - height / 2
self.height = height
self.width = width
self.color = color
self.rect = pygame.Rect(x, y, height, width)
self.surface = pygame.Surface((height, width)) # 1
self.surface.blit(img, (0, 0))
self.angle = 0
self.speed = 0 # 2
def draw(self): # 3
self.rect.topleft = (int(self.x), int(self.y))
rotated = pygame.transform.rotate(self.surface, self.angle)
surface_rect = self.surface.get_rect(topleft = self.rect.topleft)
new_rect = rotated.get_rect(center = surface_rect.center)
window.blit(rotated, new_rect.topleft)
white = (255, 255, 255)
car1 = Car(300, 300, 73, 73, white) # 4
clock = pygame.time.Clock()
runninggame = True
while runninggame:
for event in pygame.event.get():
if event.type == pygame.QUIT:
runninggame = False
pressed = pygame.key.get_pressed()
car1.speed *= 0.9 # 5
if pressed[pygame.K_UP]: car1.speed += 0.5 # 6
if pressed[pygame.K_DOWN]: car1.speed -= 0.5 # 6
if pressed[pygame.K_LEFT]: car1.angle += car1.speed / 2 # 7
if pressed[pygame.K_RIGHT]: car1.angle -= car1.speed / 2 # 7
car1.x -= car1.speed * math.sin(math.radians(car1.angle)) # 8
car1.y -= car1.speed * math.cos(math.radians(-car1.angle)) # 8
window.fill((0, 0, 0)) # 9
car1.draw()
pygame.display.flip()
clock.tick(60) # 10
pygame.quit()
需要注意的一些事项:
- 我创建了一个新表面用于绘制图片。这使它更容易旋转。
- 我为汽车创建了一个速度变量,以存储它的速度。我稍后用它来获得动力。
- draw 函数逆时针旋转图像,因为这就是 Pygame 的工作原理。查看我使用的代码。
- 我使用的汽车尺寸是73、73。把这个作为你图片的宽度和高度,否则汽车将无法正常转动。
- 我把车速稍微减慢一点,这样当你不往前推的时候,车会继续开一会儿。
- 当汽车前后移动时,其最大速度为每帧 5 个像素。(因为 5 * 0.9 + 0.5 = 5。)
- 汽车转弯的角度取决于速度。
- 这是我之前试图说的三角函数。因为 math.sin 和 math.cos 使用弧度,所以我必须将度数转换为弧度。
- 我用黑色填充了屏幕,所以你不会看到早期的帧。
- 用于防止速度过快,意思是“
clock.tick
每秒最多 60 帧”。
我希望你明白一切。
推荐阅读
- visual-studio-code - 在 VS Code 中调试作为 dotnet 解决方案一部分的 C# Azure Functions
- javascript - 如何以更 DRY 的方式收听 3 个元素中的 mouseover 和 mouseout 事件?
- javascript - 如何使用 JavaScript 设置函数参数?
- mybatis - MyBatis 没有 Spring,事务使用提供的连接
- reactjs - TS2345:“字符串”类型的参数 | undefined' 不能分配给'string' 类型的参数。类型“未定义”不可分配给类型“字符串”
- python-3.x - Python:为什么我的正弦波不会改变频率
- javascript - 关于自动刷新一部分在 php 文件中
- rust - 有没有办法将随机数生成器存储为特征对象?
- django - Django NoReverseMatch 使用 views 参数
- javascript - 购物车项目的布尔值在刷新时消失