Python 在pygame中,如何从面向光标方向的角色中射击子弹?

Python 在pygame中,如何从面向光标方向的角色中射击子弹?,python,pygame,Python,Pygame,在我的游戏中,问题是子弹只来自一个地方,即中心。当我的播放器沿光标方向旋转时,我希望子弹从播放器顶部射出,即使播放器沿光标方向旋转并沿播放器朝向的方向直线移动 正如你在这里看到的,子弹总是在同一个方向,总是从同一个地方出来 我尝试使用getpos()方法获取光标位置,并尝试从玩家坐标中减去,但未能获得结果 我想问题出在旋转器类的def-shot(self)方法中,我需要得到宇宙飞船尖端的坐标,即使它一直在旋转 import math import random import os im

在我的游戏中,问题是子弹只来自一个地方,即中心。当我的播放器沿光标方向旋转时,我希望子弹从播放器顶部射出,即使播放器沿光标方向旋转并沿播放器朝向的方向直线移动

正如你在这里看到的,子弹总是在同一个方向,总是从同一个地方出来

我尝试使用getpos()方法获取光标位置,并尝试从玩家坐标中减去,但未能获得结果

我想问题出在旋转器类的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()
导入数学
随机输入
导入操作系统
导入pygame作为pg
导入系统
第init页()
高度=650
宽度=1200
os_x=100
os_y=45
操作系统环境['SDL\u视频窗口位置]=%d,%d%(操作系统x,操作系统y)
屏幕=pg.display.set_模式((宽度、高度),pg.NOFRAME)
screen\u rect=screen.get\u rect()
background=pg.image.load('background.png').convert()
背景=pg.transform.smoothscale(pg.image.load('background.png'),(宽度、高度))
时钟=pg.time.clock()
运行=真
类移动(第页精灵,精灵):
定义初始化(自):
精灵精灵。精灵。精灵初始(自我)
self.image=pg.image.load('friend.png')。convert_alpha()
self.image=pg.transform.smoothscale(pg.image.load('friend.png'),(33,33))
self.rect=self.image.get_rect()
self.rect.x=random.randrange(宽度-self.rect.width)
self.rect.y=random.randrange(-100,-40)
self.speedy=random.randrange(1,8)
self.speedx=random.randrange(-3,3)
def更新(自我):
self.rect.x+=self.speedx
self.rect.y+=自加速
如果self.rect.top>高度+10或self.rect.left<-25或self.rect.right>宽度+20:
self.rect.x=random.randrange(宽度-self.rect.width)
self.rect.y=random.randrange(-100,-40)
self.speedy=random.randrange(1,8)
类旋转器(pg.sprite.sprite):
定义初始化(自身、屏幕):
精灵精灵。精灵。精灵初始(自我)
self.screen\u rect=screen\u 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\u image.copy()
self.rect=self.image.get_rect(中心=[width/2,height/2])
self.delay=10
self.timer=0.0
自转角=0
self.distance=0
自转角_偏移=0
def get_角度(自身):
mouse=pg.mouse.get_pos()
偏移量=(self.rect.centerx-鼠标[0],self.rect.centery-鼠标[1])
self.angle=math.degrees(math.atan2(*offset))-self.angle\u offset
旧中心=自整中心
self.image=pg.transform.rotozoom(self.master\u图像,self.angle,1)
self.rect=self.image.get_rect(中心=旧中心)
self.distance=math.sqrt((偏移量[0]*偏移量[0])+(偏移量[1]*偏移量[1]))
def更新(自我):
self.get_angle()
self.display='angle:{.2f}距离:{.2f}'。格式(self.angle,self.distance)
self.dx=1
self.dy=1
自校正夹具(自校正屏幕)
def绘图(自我、冲浪):
surf.blit(self.image,self.rect)
def喷射(自):
项目符号=项目符号(self.rect.centerx、self.rect.centery)
所有精灵。添加(项目符号)
项目符号。添加(项目符号)
类项目符号(第页精灵,精灵):
定义初始化(self,x,y):
精灵精灵。精灵。精灵初始(自我)
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()
自校正y=y
self.rect.x=x
self.speedy=-8
def更新(自我):
self.rect.y+=自加速
#如果它离开屏幕顶部,则杀死它
如果self.rect.bottom<0:
self.kill()
所有精灵=pg.sprite.Group()
项目符号=pg.sprite.Group()
mobs=pg.sprite.Group()
旋转器=旋转器(屏幕右)
所有精灵。添加(旋转器)
对于范围(5)中的i:
m=Mob()
所有精灵。添加(m)
暴徒。添加(m)
运行时:
keys=pg.key.get_pressed()
对于pg.event.get()中的事件:
如果event.type==pg.QUIT:
sys.exit()
pygame.quit()
如果event.type==pg.MOUSEBUTTONDOWN:
旋转器
screen.blit(背景[0,0])
所有精灵更新()
hits=pg.sprite.groupcollide(怪物,子弹,真,真)
点击率:
m=Mob()
所有精灵。添加(m)
暴徒。添加(m)
hits=pg.sprite.spritecollide(旋转体、怪物、假)
如果点击:
运行=错误
所有精灵。绘制(屏幕)
时钟滴答(60)
pg.display.update()

按下鼠标按钮时,将鼠标位置传递给旋转器.shoot():

if event.type == pg.MOUSEBUTTONDOWN:
    rotator.shoot(event.pos)
计算从旋转器到鼠标位置的方向,并将其传递给新bullet对象的构造函数:

def拍摄(自身、鼠标点):
dx=鼠标点[0]-self.rect.centerx
dy=鼠标点[1]-self.rect.centery
如果abs(dx)>0或abs(dy)>0:
项目符号=项目符号(self.rect.centerx、self.rect.centery、dx、dy)
所有精灵。添加(项目符号)
项目符号。添加(项目符号)
用于存储项目符号的当前位置和项目符号的规格化方向():

类项目符号(pg.sprite.sprite):
定义初始化(self,x,y,dx,dy):
精灵精灵。精灵。精灵初始(自我)
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)
自身速度=8
self.pos=pg.math.Vector2(x,y)
self.dir=pg.math.Vector2(dx,dy).normalize()
结石