我一直在构建一个受太空侵略者启发的游戏,并且正忙于构建播放器和子弹组件。我的播放器按预期移动和旋转输入,子弹按初始轨迹发射,但是,在发射子弹后,当我旋转播放器时,子弹在飞行时也会旋转。我知道问题出在哪里,正如您将在我的代码中看到的那样,与子弹相关的角度与用于控制我的播放器的角度相同,并且与每次窗口更新一样,该值应用于子弹的路径.我正在努力寻找将这个角度分配给最初发射的每颗子弹的最佳方法,并且子弹将继续沿着这个初始轨迹前进。我考虑过创建一个数组来存储游戏每个实例的角度,并访问该数组的最新附件以分配给子弹的发射,但这似乎没有必要,因为每个角度只使用一次,所以那里面的内容是没用的。
我想到的另一件事是创造。 bullet 类,其中 bullet 数组的元素有一个 x 和 y 组件(bullet.x 和 bullet.y),具有初始发射条件,但我不太确定如何在不从根本上改变我的代码的情况下实现它。有什么想法吗?
import pygame
import os
import math
clock = pygame.time.Clock()
#standard variables for universal operation
WIDTH = 610
HEIGHT = 760
WIN = pygame.display.set_mode((WIDTH,HEIGHT))
FPS = 60
BORDER = pygame.Rect(0,720,WIDTH,4)
BLACK = (0,0,0)
WHITE = (255,255,255)
GREEN = (0,200,0) #slightly darker green
PLAYER_IMG = pygame.image.load(os.path.join('src', 'player.png'))
PLAYER_VEL = 7
PLAYER_WIDTH = 36
PLAYER_HEIGHT = 22
INIT_PLAYER_ANGLE = 0
ANGULAR_VEL = 5
MAX_ANGLE = 45 #anticlockwise is positive, vice versa
BULLET_VEL = 7
MAX_BULLETS = 3
BULLET_RADIUS = 2
def move_player(player, angle):
#rotation
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_RIGHT] and (angle >= -MAX_ANGLE + ANGULAR_VEL):
angle -= ANGULAR_VEL
if keys_pressed[pygame.K_LEFT] and (angle <= MAX_ANGLE - ANGULAR_VEL):
angle += ANGULAR_VEL
if keys_pressed[pygame.K_UP] or keys_pressed[pygame.K_DOWN]:
angle = 0
rotated_img = pygame.transform.rotate(PLAYER_IMG,angle)
player = rotated_img.get_rect(center=player.center)
#linear translation
keys_pressed = pygame.key.get_pressed()
if (player.x <= WIDTH - PLAYER_WIDTH - PLAYER_VEL) and (keys_pressed[pygame.K_d]):
player.x += PLAYER_VEL
if (player.x >= PLAYER_VEL) and (keys_pressed[pygame.K_a]):
player.x -= PLAYER_VEL
return player, rotated_img, angle
def fire_bullet(bullets, angle):
for bullet in bullets:
if angle<0:
bullet.x += BULLET_VEL*math.sin(math.radians(abs(angle)))
bullet.y -= BULLET_VEL*math.cos(math.radians(abs(angle)))
if angle>0:
bullet.x -= BULLET_VEL*math.sin(math.radians(angle))
bullet.y -= BULLET_VEL*math.cos(math.radians(angle))
if angle == 0:
bullet.y -= BULLET_VEL
def window(player,rotated_img,angle,bullets):
WIN.fill(BLACK) #background
pygame.draw.rect(WIN,GREEN,BORDER) #seperation between game and lower info block
WIN.blit(rotated_img,(player.x,player.y)) #player
for bullet in bullets:
pygame.draw.circle(WIN,GREEN,(bullet.centerx,bullet.centery),BULLET_RADIUS) #bullets
pygame.display.update()
def main():
player = pygame.Rect(WIDTH/2-PLAYER_WIDTH/2,685,PLAYER_WIDTH,PLAYER_HEIGHT)
bullets = []
angle = INIT_PLAYER_ANGLE
running = True
while running: #main game loop
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False #breaks loop if window is shut by user
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
bullet = pygame.Rect(player.x+PLAYER_WIDTH/2-BULLET_RADIUS/2,player.y+BULLET_RADIUS*2,BULLET_RADIUS*2,BULLET_RADIUS*2)
bullets.append(bullet)
fire_bullet(bullets,angle)
player, rotated_img, angle = move_player(player,angle)
window(player,rotated_img,angle,bullets)
pygame.quit()
if __name__ == "__main__":
main()