Gia tốc và ma sát
Thuộc phần Vòng lặp trò chơi trong hành trình Pygame của Coddy. Bài học 24 trên 35.
Quả puck bắt đầu với tốc độ tối đa và dừng hẳn khi bạn buông phím. Trên băng, nó nên tăng tốc rồi trượt đi. Hai thay đổi sẽ giúp làm được điều đó.
Gia tốc (acceleration) cho biết vận tốc thay đổi nhanh đến mức nào, tính bằng pixel mỗi giây, trong mỗi giây. Các phím điều khiển gia tốc, còn gia tốc làm thay đổi vận tốc:
acc = pygame.Vector2(0, 0)
if keys[pygame.K_RIGHT]:
acc.x = 600
vel += acc * dt
vel -= vel * 2 * dt
pos += vel * dtTạo mới acc trong mỗi khung hình để nó bằng không khi không có phím nào được nhấn. Vận tốc giữ nguyên giá trị qua từng khung hình, nên quả puck tiếp tục trượt.
Lực ma sát (friction) nằm ở dòng thứ hai. vel * 2 * dt là một phần nhỏ của vận tốc, phần này lớn hơn khi quả puck chạy nhanh. Trừ phần đó đi trong mỗi khung hình sẽ làm quả puck chạy nhanh chậm lại nhanh chóng, còn quả puck chạy chậm thì chậm lại từ từ cho đến khi dừng hẳn. Số lớn hơn 2 tạo ra mặt sàn gồ ghề hơn.
Nếu giữ phím đủ lâu, lực đẩy và lực ma sát sẽ cân bằng ở tốc độ tối đa 600 / 2 = 300 pixel mỗi giây.
Thử thách
Trung bìnhLàm cho đĩa trượt như trên băng.
- Trong vòng lặp, thay
vel = pygame.Vector2(0, 0)bằngacc = pygame.Vector2(0, 0), rồi đặt mỗi phím mũi tên làm choacc.xhoặcacc.ycó giá trị600hoặc-600. - Trước khi di chuyển đĩa, cộng
acc * dtvàovel, rồi trừvel * 2 * dtkhỏi nó.
Nhấn Chơi rồi nhấn một phím mũi tên: đĩa sẽ trượt và chậm dần. Sau đó, nhấn Kiểm tra.
Tự làm thử
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Ice Puck")
clock = pygame.time.Clock()
pos = pygame.Vector2(240, 180)
vel = pygame.Vector2(0, 0)
dt = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
vel = pygame.Vector2(0, 0)
if keys[pygame.K_LEFT]:
vel.x = -200
if keys[pygame.K_RIGHT]:
vel.x = 200
if keys[pygame.K_UP]:
vel.y = -200
if keys[pygame.K_DOWN]:
vel.y = 200
pos += vel * dt
pos.x = max(14, min(pos.x, 466))
pos.y = max(14, min(pos.y, 346))
screen.fill((200, 225, 240))
pygame.draw.circle(screen, (40, 50, 70), pos, 14)
pygame.display.flip()
dt = clock.tick(60) / 1000
pygame.quit()
Tất cả bài học trong Vòng lặp trò chơi
1Di chuyển hình vuông
Mở cửa sổTô nền4Di chuyển theo thời gian
Thời gian deltaPixel mỗi giâyVector2Gia tốc và ma sátDi chuyển vòng quanh màn hìnhTự luyện tập: Playground Pygame