我正在使用Pygame制作类似于Asteroids的自上而下的太空射击游戏。我有一个用箭头键控制的播放器,用鼠标按钮射击激光,但我也想使激光朝着鼠标光标的方向移动,而不仅仅是沿直线移动。有谁知道该怎么做?
import pygame
pygame.init()
import random
from pygame.math import Vector2
inPlay = True
screen = pygame.display.set_mode((900, 700))
#colour
BLUE=(0,0,255)
RED=(255,0,0)
WHITE=(255,255,255)
BLACK=(0,0,0)
#bullet
bulletSpeed=15
class Player(pygame.sprite.Sprite):
def __init__(self,x,y,speed,picture=None):
pygame.sprite.Sprite.__init__(self)
self.pic = pygame.Surface((50, 30), pygame.SRCALPHA)
pygame.draw.rect(self.pic, BLUE,(0, 5, 60, 60),0)
self.orig_pic = self.pic # Store a reference to the original.
self.rect = self.pic.get_rect(center=(x,y))
self.pos = Vector2(x,y)
self.image=pygame.image.load(picture)
self.x=x
self.y=y
self.speed=speed
def rotate(self):
# The vector to the target (the mouse position or middle shape).
direction = pygame.mouse.get_pos() - self.pos
radius, angle = direction.as_polar()
# Rotate the pic by the negative angle
self.pic = pygame.transform.rotate(self.orig_pic, -angle)
# Create another rect
self.rect = self.pic.get_rect(center=self.rect.center)
def moveRight(self):
self.x=self.x+self.speed
self.update()
def moveLeft(self):
self.x=self.x-self.speed
self.update()
def moveUp(self):
self.y=self.y-self.speed
self.update()
def moveDown(self):
self.y=self.y+self.speed
self.update()
def update(self):
self.rotate()
self.rect=pygame.Rect(self.x,self.y, self.rect.width, self.rect.height)
def draw_on(self, surface):
surface.blit(self.image, self.rect)
class Bullets(pygame.sprite.Group):
def __init__(self):
pygame.sprite.Group.__init__(self)
def move(self):
for bullet in self:
bullet.moveUp()
def decay(self):
for bullet in self:
if bullet.y < -100:
self.remove(bullet)
def redraw_game_window():
screen.fill(BLACK)
player.draw_on(screen)
bullets.draw(screen)
pygame.display.update()
#player
shipSpeed=5
player = Player(450,600,shipSpeed,'player.png')
RB=width-player.rect.width
CEILING = 3*player.rect.height # for ship movement
FLOOR = height - player.rect.height #
#bullet
bullets = Bullets()
clock = pygame.time.Clock()
while inPlay:
for event in pygame.event.get():
if event.type == pygame.QUIT:
inPlay=False
if event.type == pygame.MOUSEBUTTONDOWN:
bullet = Player(player.x, player.y, bulletSpeed, "bullet.png")
bullet.x = bullet.x + round(player.rect.width/2) - round(bullet.rect.width/2) +10
bullet.y = bullet.y - bullet.rect.height -30
bullets.add(bullet)
keys=pygame.key.get_pressed()
pygame.event.get()
if keys[pygame.K_LEFT] or keys[pygame.K_a] and player.x>0:
player.moveLeft()
if keys[pygame.K_RIGHT] or keys[pygame.K_d] and player.x<RB: # if right arrow has been pressed
player.moveRight() # move the ball right
if keys[pygame.K_UP] or keys[pygame.K_w] and player.y > CEILING:
player.moveUp()
if keys[pygame.K_DOWN] or keys[pygame.K_s] and player.y <FLOOR:
player.moveDown()
redraw_game_window()
bullets.move()
bullets.decay()
player.update()
clock.tick(30)
pygame.quit()
答案 0 :(得分:0)
在创建新项目符号时,定义类型为pygame.math.Vector2
的属性pos
和dir
。属性pos
包含子弹的当前位置,属性dir
是包含运动方向的矢量。向量的量就是速度。方向是从项目符号到鼠标单击事件event.pos
的位置的向量:
while inPlay:
for event in pygame.event.get():
if event.type == pygame.QUIT:
inPlay=False
if event.type == pygame.MOUSEBUTTONDOWN:
bullet = Player(player.x, player.y, bulletSpeed, "bullet.png")
bullet.x = bullet.x + round(player.rect.width/2) - round(bullet.rect.width/2) +10
bullet.y = bullet.y - bullet.rect.height -30
bullet.pos = pygame.math.Vector2(bullet.x, bullet.y)
mouse_pos = pygame.math.Vector2(event.pos[0], event.pos[1])
bullet.dir = (mouse_pos - bullet.pos).normalize() * bullet.speed
bullets.add(bullet)
通过在类bullet.dir
的方法bullet.pos
中将move
添加到Bullets
来计算子弹的新位置:
class Bullets(pygame.sprite.Group):
def __init__(self):
pygame.sprite.Group.__init__(self)
def move(self):
for bullet in self:
bullet.pos += bullet.dir
bullet.x = bullet.pos[0]
bullet.y = bullet.pos[1]
self.update()
def decay(self):
for bullet in self:
if bullet.y < -100:
self.remove(bullet)