在我的游戏中,问题是子弹仅从一个地方射出,即从中心射出。当我的玩家沿光标方向旋转时,即使玩家旋转并沿玩家面向的方向沿直线行进,我也希望子弹从玩家顶部发射,当玩家沿光标方向旋转时.
正如您可以在此处看到的,子弹始终朝同一方向,并且始终从同一位置射出。
我尝试使用 getpos() 方法获取光标位置,并尝试从玩家坐标中减去,但未能得到结果。
我认为问题出在 Rotator 类的 def shot(self) 方法中,即使飞船一直在旋转,我也需要获取飞船尖端的坐标。
import math
import random
import os
import pygame as pg
import sys
pg.init()
height=650
width=1200
os_x = 100
os_y = 45
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (os_x,os_y)
screen = pg.display.set_mode((width,height),pg.NOFRAME)
screen_rect = screen.get_rect()
background=pg.image.load('background.png').convert()
background = pg.transform.smoothscale(pg.image.load('background.png'), (width,height))
clock = pg.time.Clock()
running = True
class Mob(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.image = pg.image.load('enemy.png').convert_alpha()
self.image = pg.transform.smoothscale(pg.image.load('enemy.png'), (33,33))
self.rect = self.image.get_rect()
self.rect.x = random.randrange(width - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speedy = random.randrange(1, 8)
self.speedx = random.randrange(-3, 3)
def update(self):
self.rect.x += self.speedx
self.rect.y += self.speedy
if self.rect.top > height + 10 or self.rect.left < -25 or self.rect.right > width + 20:
self.rect.x = random.randrange(width - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speedy = random.randrange(1, 8)
class Rotator(pg.sprite.Sprite):
def __init__(self, screen_rect):
pg.sprite.Sprite.__init__(self)
self.screen_rect = screen_rect
self.master_image = pg.image.load('spaceship.png').convert_alpha()
self.master_image = pg.transform.smoothscale(pg.image.load('spaceship.png'), (33,33))
self.image = self.master_image.copy()
self.rect = self.image.get_rect(center=[width/2,height/2])
self.delay = 10
self.timer = 0.0
self.angle = 0
self.distance = 0
self.angle_offset = 0
def get_angle(self):
mouse = pg.mouse.get_pos()
offset = (self.rect.centerx - mouse[0], self.rect.centery - mouse[1])
self.angle = math.degrees(math.atan2(*offset)) - self.angle_offset
old_center = self.rect.center
self.image = pg.transform.rotozoom(self.master_image, self.angle,1)
self.rect = self.image.get_rect(center=old_center)
self.distance = math.sqrt((offset[0] * offset[0]) + (offset[1] * offset[1]))
def update(self):
self.get_angle()
self.display = 'angle:{:.2f} distance:{:.2f}'.format(self.angle, self.distance)
self.dx = 1
self.dy = 1
self.rect.clamp_ip(self.screen_rect)
def draw(self, surf):
surf.blit(self.image, self.rect)
def shoot(self):
bullet = Bullet(self.rect.centerx, self.rect.centery)
all_sprites.add(bullet)
bullets.add(bullet)
class Bullet(pg.sprite.Sprite):
def __init__(self, x, y):
pg.sprite.Sprite.__init__(self)
self.image = pg.image.load('bullet.png').convert_alpha()
self.image = pg.transform.smoothscale(pg.image.load('bullet.png'), (10,10))
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
self.speedy = -8
def update(self):
self.rect.y += self.speedy
# kill if it moves off the top of the screen
if self.rect.bottom < 0:
self.kill()
all_sprites = pg.sprite.Group()
bullets = pg.sprite.Group()
mobs = pg.sprite.Group()
rotator = Rotator(screen_rect)
all_sprites.add(rotator)
for i in range(5):
m = Mob()
all_sprites.add(m)
mobs.add(m)
while running:
keys = pg.key.get_pressed()
for event in pg.event.get():
if event.type == pg.QUIT:
sys.exit()
pygame.quit()
if event.type == pg.MOUSEBUTTONDOWN:
rotator.shoot()
screen.blit(background, [0, 0])
all_sprites.update()
hits = pg.sprite.groupcollide(mobs, bullets, True, True)
for hit in hits:
m = Mob()
all_sprites.add(m)
mobs.add(m)
hits = pg.sprite.spritecollide(rotator, mobs, False)
if hits:
running = False
all_sprites.draw(screen)
clock.tick(60)
pg.display.update()
最佳答案
参见Shooting a bullet in pygame in the direction of mouse和 calculating direction of the player to shoot pygame 。
当按下鼠标按钮时,将鼠标位置传递给 rotator.shoot()
:
if event.type == pg.MOUSEBUTTONDOWN:
rotator.shoot(event.pos)
计算从旋转器到鼠标位置的方向并将其传递给新子弹对象的构造函数:
def shoot(self, mousepos):
dx = mousepos[0] - self.rect.centerx
dy = mousepos[1] - self.rect.centery
if abs(dx) > 0 or abs(dy) > 0:
bullet = Bullet(self.rect.centerx, self.rect.centery, dx, dy)
all_sprites.add(bullet)
bullets.add(bullet)
使用pygame.math.Vector2
存储子弹的当前位置和子弹的标准化方向( Unit vector ):
class Bullet(pg.sprite.Sprite):
def __init__(self, x, y, dx, dy):
pg.sprite.Sprite.__init__(self)
self.image = pg.transform.smoothscale(pg.image.load('bullet.png').convert_alpha(), (10,10))
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.speed = 8
self.pos = pg.math.Vector2(x, y)
self.dir = pg.math.Vector2(dx, dy).normalize()
在update()
中计算子弹的新位置(self.pos += self.dir * self.speed
)并更新.rect
属性由新位置决定。
.kill()
子弹离开屏幕时。可以通过self.rect.colliderect()
检查:
class Bullet(pg.sprite.Sprite):
# [...]
def update(self):
self.pos += self.dir * self.speed
self.rect.center = (round(self.pos.x), round(self.pos.y))
if not self.rect.colliderect(0, 0, width, height):
self.kill()
关于python - 如何在pygame中从面向光标方向的角色发射子弹?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57243332/