1 回答

TA貢獻1818條經驗 獲得超8個贊
首先pygame.transform.rotate不變換對象本身,而是創建一個新的旋轉表面并將其返回。
如果你想向某個方向發射子彈,方向是在子彈發射的那一刻定義的,但它不會連續改變。當子彈發射時,設置子彈的起始位置并計算到鼠標位置的方向向量:
self.pos = (x, y)
mx, my = pygame.mouse.get_pos()
self.dir = (mx - x, my - y)
方向向量不應該取決于到鼠標的距離,但它必須是單位向量。通過除以歐幾里得距離來歸一化向量
length = math.hypot(*self.dir)
if length == 0.0:
self.dir = (0, -1)
else:
self.dir = (self.dir[0]/length, self.dir[1]/length)
計算向量的角度并旋轉子彈。一般來說,向量的角度可以通過 計算atan2(y, x)。atan2(-y, x)y軸需要反轉(
angle = math.degrees(math.atan2(-self.dir[1], self.dir[0]))
self.bullet = pygame.Surface((7, 2)).convert_alpha()
self.bullet.fill((255, 255, 255))
self.bullet = pygame.transform.rotate(self.bullet, angle)
要更新子彈的位置,只需縮放方向(按速度)并將其添加到子彈的位置:
self.pos = (self.pos[0]+self.dir[0]*self.speed,
self.pos[1]+self.dir[1]*self.speed)
要將旋轉的子彈繪制在正確的位置,請選取旋轉子彈的邊界矩形并設置中心點self.pos(請參閱如何使用 PyGame 圍繞其中心旋轉圖像?):
bullet_rect = self.bullet.get_rect(center = self.pos)
surf.blit(self.bullet, bullet_rect)
另請參閱向目標或鼠標射擊子彈
最小的例子: repl.it/@Rabbid76/PyGame-FireBulletInDirectionOfMouse
https://i.stack.imgur.com/oyzor.gif
import pygame
import math
pygame.init()
window = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
class Bullet:
def __init__(self, x, y):
self.pos = (x, y)
mx, my = pygame.mouse.get_pos()
self.dir = (mx - x, my - y)
length = math.hypot(*self.dir)
if length == 0.0:
self.dir = (0, -1)
else:
self.dir = (self.dir[0]/length, self.dir[1]/length)
angle = math.degrees(math.atan2(-self.dir[1], self.dir[0]))
self.bullet = pygame.Surface((7, 2)).convert_alpha()
self.bullet.fill((255, 255, 255))
self.bullet = pygame.transform.rotate(self.bullet, angle)
self.speed = 2
def update(self):
self.pos = (self.pos[0]+self.dir[0]*self.speed,
self.pos[1]+self.dir[1]*self.speed)
def draw(self, surf):
bullet_rect = self.bullet.get_rect(center = self.pos)
surf.blit(self.bullet, bullet_rect)
bullets = []
pos = (250, 250)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
bullets.append(Bullet(*pos))
for bullet in bullets[:]:
bullet.update()
if not window.get_rect().collidepoint(bullet.pos):
bullets.remove(bullet)
window.fill(0)
pygame.draw.circle(window, (0, 255, 0), pos, 10)
for bullet in bullets:
bullet.draw(window)
pygame.display.flip()
添加回答
舉報