利用pygame制作射击游戏时,子弹轨迹与预期弹道发生偏差是什么原因?应该怎么解决?

图片说明

子弹类

class bullet():
    def __init__(self,mx,my):
        self.images = {
            'b10': pygame.image.load('img/bfor10.png'),
            'b20': pygame.image.load('img/bfor20.png'),
            'b30': pygame.image.load('img/bfor30.png'),
            }
        self.rx=950-mx
        self.ry=950-my
        if not self.ry==0:
            self.tan = (self.rx) / (self.ry)
            self.angle=math.atan(self.tan)
        self.speed=10
        self.live=True
        self.size='b10'
        self.img=self.images[self.size]
        self.rect = self.img.get_rect()
        # 设置区域的left 和top
        if self.size=='b10':
            self.rect.left = 950-5
            self.rect.top = 950-5
        elif self.size=='b20':
            self.rect.left = 950 - 10
            self.rect.top = 950 - 10
        elif self.size == 'b30':
            self.rect.left = 950 - 15
            self.rect.top = 950 - 15
    def move(self):
        if self.ry<0:
            self.rect.left+=self.speed*math.sin(self.angle)
            self.rect.top+=self.speed*math.cos(self.angle)
        elif self.ry>0:
                self.rect.left -= self.speed * math.sin(self.angle)
                self.rect.top -= self.speed * math.cos(self.angle)
        else:
            if self.rx<0:
                self.rect.left+=self.speed
            else:
                self.rect.left-=self.speed
    def displaybullet(self):
        game.window.blit(self.img,self.rect)

全部代码

import pygame
import random
import time
import math
class game():
    window=None
    bullet_list=[]
    fish_list=[]
    net_list=[]
    player=None
    def startgame(self):
        pygame.display.init()
        game.window = pygame.display.set_mode([1900, 1000])
        pygame.display.set_caption('fisherman')
        game.player=Battery()
        while True:
            time.sleep(0.05)
            game.window.fill(pygame.Color(80,80,200,20))
            self.getEVENT()
            game.player.displayBattery()
            self.blitbullet()
            pygame.display.update()
    def quit(self):
       exit()
    def getEVENT(self):
        eventlist = pygame.event.get()
        for event in eventlist:
            if event.type == pygame.QUIT:
                self.quit()
            if event.type == pygame.MOUSEMOTION:
                mouseX = event.pos[0]
                mouseY = event.pos[1]
                game.player.msX=mouseX
                game.player.msY=mouseY
            if event.type==pygame.MOUSEBUTTONDOWN:
                game.bullet_list.append(bullet(event.pos[0],event.pos[1]))
    def blitbullet(self):
        for bullet in game.bullet_list:
            bullet.displaybullet()
            bullet.move()
class Baseitem(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
class net(Baseitem):
    def __init__(self):
        pass
    def displaynet(self):
        pass
class fish(Baseitem):
    def __init__(self):
        pass
    def move(self):
        pass
    def display(self):
        pass
class bullet():
    def __init__(self,mx,my):
        self.images = {
            'b10': pygame.image.load('img/bfor10.png'),
            'b20': pygame.image.load('img/bfor20.png'),
            'b30': pygame.image.load('img/bfor30.png'),
            }
        self.rx=950-mx
        self.ry=950-my
        if not self.ry==0:
            self.tan = (self.rx) / (self.ry)
            self.angle=math.atan(self.tan)
        self.speed=10
        self.live=True
        self.size='b10'
        self.img=self.images[self.size]
        self.rect = self.img.get_rect()
        # 设置区域的left 和top
        if self.size=='b10':
            self.rect.left = 950-5
            self.rect.top = 950-5
        elif self.size=='b20':
            self.rect.left = 950 - 10
            self.rect.top = 950 - 10
        elif self.size == 'b30':
            self.rect.left = 950 - 15
            self.rect.top = 950 - 15
    def move(self):
        if self.ry<0:
            self.rect.left+=self.speed*math.sin(self.angle)
            self.rect.top+=self.speed*math.cos(self.angle)
        elif self.ry>0:
                self.rect.left -= self.speed * math.sin(self.angle)
                self.rect.top -= self.speed * math.cos(self.angle)
        else:
            if self.rx<0:
                self.rect.left+=self.speed
            else:
                self.rect.left-=self.speed
    def displaybullet(self):
        game.window.blit(self.img,self.rect)
class Battery():
    def __init__(self):
        self.img=pygame.image.load('img/pt.png')
        self.rect=self.img.get_rect()


        self.msX=950
        self.msY=400
    def displayBattery(self):
        pygame.draw.line(game.window, pygame.Color(0, 0, 0), (self.msX, self.msY), (950, 950))
        self.rect.left=850
        self.rect.top=850
        self.rX = 950 - self.msX
        self.rY = 950 - self.msY
        if not self.rY==0:
            self.tan = self.rX / self.rY
        self.angle_pi=math.atan(self.tan)
        self.angle=self.angle_pi/math.pi*180
        self.changed=(math.sin(math.fabs(self.angle_pi))*200+math.cos(self.angle_pi)*200)/2-100
        self.rect.left-=self.changed
        self.rect.top-=self.changed
        if not self.rY==0:
            if self.rY<0:
                self.timg = pygame.transform.rotate(self.img,180+self.angle)
                game.window.blit(self.timg, self.rect)
            elif self.rY>0:
                self.timg=pygame.transform.rotate(self.img,self.angle)
                game.window.blit(self.timg,self.rect)
        else:
            if  self.rX>=0:
                game.window.blit(pygame.transform.rotate(self.img,90),(850,850))
            else:
                game.window.blit(pygame.transform.rotate(self.img, -90), (850, 850))
if __name__=='__main__':
    game().startgame()


子弹是10x10像素的
从坐标950,950发射

刚开始学Python也第一次在这里提问,希望有大哥能帮我分析一下

原来是数据类型的问题,不去使用pygame自带的get_rect() 改用自己写的rect字典

class bullet():
    def __init__(self,mx,my):
        self.images = {
            'b10': pygame.image.load('img/bfor10.png'),
            'b20': pygame.image.load('img/bfor20.png'),
            'b30': pygame.image.load('img/bfor30.png'),
            }
        self.rx=950-mx
        self.ry=950-my
        if not self.ry==0:
            self.tan = (self.rx) / (self.ry)
            self.angle=math.atan(self.tan)
        self.speed=10
        self.live=True
        self.size='b10'
        self.img=self.images[self.size]
        #self.rect = self.img.get_rect()
        self.rect={
            'left':950.0-5.0,
            'top':950.0-5.0
        }
        # 设置区域的left 和top
        #if self.size=='b10':
           # self.rect.left = 950-5
           #self.rect.top = 950-5
        #elif self.size=='b20':
           # self.rect.left = 950 - 10
           # self.rect.top = 950 - 10
        #elif self.size == 'b30':
           # self.rect.left = 950 - 15
           # self.rect.top = 950 - 15
    def move(self):
        if self.ry<0:
            self.rect.left+=self.speed*math.sin(self.angle)
            self.rect.top+=self.speed*math.cos(self.angle)
        elif self.ry>0:
                self.rect['left']-=self.speed*math.sin(self.angle)
                self.rect['top']-=self.speed*math.cos(self.angle)
                #self.rect.left -= self.speed * math.sin(self.angle)
                #self.rect.top -= self.speed * math.cos(self.angle)
        else:
            if self.rx<0:
                self.rect.left+=self.speed
            else:
                self.rect.left-=self.speed
    def displaybullet(self):
        game.window.blit(self.img,(self.rect['left'],self.rect['top']))