Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使子弹般的弹丸运动?_Python_Pygame - Fatal编程技术网

Python 如何使子弹般的弹丸运动?

Python 如何使子弹般的弹丸运动?,python,pygame,Python,Pygame,目前,我尝试这个使射击游戏的基础上,我发现的链接。但是有一个问题,我想改变子弹的属性,但我不知道物理知识,也不知道编码。我想让子弹以抛射的方式移动。有人能帮我编码吗 以下是一些代码: man = player(200, 410, 64, 64) bullets = [] run = True while run: clock.tick(27) for event in pygame.event.get(): if event.type == pygame.QUI

目前,我尝试这个使射击游戏的基础上,我发现的链接。但是有一个问题,我想改变子弹的属性,但我不知道物理知识,也不知道编码。我想让子弹以抛射的方式移动。有人能帮我编码吗

以下是一些代码:

man = player(200, 410, 64, 64)
bullets = []
run = True
while run:
    clock.tick(27)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    for bullet in bullets:
        if bullet.x < 500 and bullet.x > 0:
            bullet.x += bullet.vel
        else:
            bullets.pop(bullets.index(bullet))

    keys = pygame.key.get_pressed()
man=player(200410,64,64)
项目符号=[]
运行=真
运行时:
时钟滴答作响(27)
对于pygame.event.get()中的事件:
如果event.type==pygame.QUIT:
运行=错误
对于子弹中的子弹:
如果bullet.x<500且bullet.x>0:
bullet.x+=bullet.vel
其他:
子弹.弹孔(子弹.索引(子弹))
keys=pygame.key.get_pressed()

基本上,抛射体运动意味着有两种力作用在抛射体上——初始速度(在某个方向上)和重力。当弹丸在空间和时间中移动时,可以通过应用速度、重力和时间来计算其轨迹(它移动的路径)

我不打算在这里讨论公式,只是使用它们。阅读关于抛射体运动的说明。基本上,要移动一个弹丸,我们只需要计算它的速度。基本上,您可以处理对象的移动,就好像它有单独的水平和垂直变化一样

所以,让我们制作一个简单的精灵对象,它随着投射物的运动而移动。为了简单起见,我们将使用PyGame sprite类(以及它提供的所有预先存在的库代码)

所以,我们需要一个图像,xy位置,起始角和速度

class Projectile( pygame.sprite.Sprite ):
    GRAVITY          = -9.8  # Earth

    def __init__( self, bitmap, start_x, start_y, velocity=0, angle=0 ):
        pygame.sprite.Sprite.__init__( self )
        self.image       = bitmap
        self.rect        = bitmap.get_rect()
        self.start_x     = start_x
        self.start_y     = start_y
        self.rect.center = ( ( start_x, start_y ) )
        # Physics
        self.start_time = pygame.time.get_ticks()   # "now" in milliseconds
        self.velocity   = velocity
        self.angle      = math.radians( angle )     # Note: convert Degrees to Radians
就这样。我们可以创建一个类似于:

rock = Projectile( rock_image, 10, 100, 50, 60 )
给出一个弹丸,画成“岩石图像”,从(10100)开始,速度为50,角度为60度

需要注意的是,数学库中的角度通常以(而不是度)为单位指定。我不能用弧度来思考,所以我用课外的度数。这是你的代码,但要按照你想要的方式编写

速度有点奇怪,因为通常你是以米/秒为单位来计算的,这里是像素/毫秒,但我不想讨论这个问题,因为这是一个不重要的离题,用一个数字来缩小

所以现在我们需要添加运动。PyGame精灵的移动由
update()
函数处理。因此,我们需要编写此函数,以便在将来的任何给定时间,都可以计算出绘制“岩石图像”的位置的
x
y
坐标。因此引述:

x=开始速度*现在时间*开始角度
y=开始速度*现在时间*sin(开始角度)-½*重力*现在时间²

这为我们提供了
sproject.update()
函数:

def update( self ):
    time_now = pygame.time.get_ticks()
    if ( self.velocity > 0 ):
        time_change = ( time_now - self.start_time )
        if ( time_change > 0 ):
            time_change /= 100.0  # fudge for metres/second to pixels/millisecond
            # re-calculate the displacement
            # x
            displacement_x  = self.velocity * time_change * math.sin( self.angle )
            # y
            half_gravity_time_squared = self.GRAVITY * time_change * time_change / 2.0
            displacement_y  = self.velocity * time_change * math.cos( self.angle ) + half_gravity_time_squared

            # reposition sprite (subtract y, because in pygame 0 is screen-top)
            self.rect.center = ( ( self.start_x + int( displacement_x ), self.start_y - int( displacement_y ) ) )
显然,这需要更新,以仅在精灵仍在屏幕上时更新它,等等。我们也与教科书中的计算略有不同,因为在PyGame中,正Y在屏幕下方(而通常正Y在上方)

把所有这些放在一起,这里有一个简短的演示,它在屏幕的中心底部创建了20个投射物,以随机速度指向上方:

import pygame
import random
import math

# Window size
WINDOW_WIDTH  = 800
WINDOW_HEIGHT = 400
FPS           = 60

# background colours
INKY_GREY    = ( 128, 128, 128 )

INITIAL_VELOCITY_LOW  = 10  # pixels per millisecond (adjusted later)
INITIAL_VELOCITY_HIGH = 100
LAUNCH_ANGLE          = 80  # random start-angle range

class Projectile( pygame.sprite.Sprite ):
    GRAVITY          = -9.8  

    def __init__( self, bitmap, start_x, start_y, velocity=0, angle=0 ):
        pygame.sprite.Sprite.__init__( self )
        self.image       = bitmap
        self.rect        = bitmap.get_rect()
        self.start_x     = start_x
        self.start_y     = start_y
        self.rect.center = ( ( start_x, start_y ) )
        # Physics
        self.start_time = pygame.time.get_ticks()   # "now" in milliseconds
        self.velocity   = velocity
        self.angle      = math.radians( angle )     # Note: convert Degrees to Radians            

    def update( self ):
        time_now = pygame.time.get_ticks()
        if ( self.velocity > 0 and self.rect.y < WINDOW_HEIGHT - self.rect.height ):
            time_change = ( time_now - self.start_time ) 
            if ( time_change > 0 ):
                time_change /= 100.0  # fudge for metres/second to pixels/millisecond
                # re-calculate the displacement
                # x
                displacement_x  = self.velocity * time_change * math.sin( self.angle ) 
                # y
                half_gravity_time_squared = self.GRAVITY * time_change * time_change / 2.0
                displacement_y  = self.velocity * time_change * math.cos( self.angle ) + half_gravity_time_squared 

                # reposition sprite
                self.rect.center = ( ( self.start_x + int( displacement_x ), self.start_y - int( displacement_y ) ) )

                # Stop at the bottom of the window
                if ( self.rect.y >= WINDOW_HEIGHT - self.rect.height ):
                    self.rect.y = WINDOW_HEIGHT - self.rect.height
                    self.velocity = 0
                    self.kill()   # remove the sprite


### MAIN
pygame.init()
SURFACE = pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.RESIZABLE
window  = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), SURFACE )
pygame.display.set_caption("Projectile Motion Example")

# Load resource image(s)
sprite_image = pygame.image.load( "ball.png" )#.convert_alpha()

# Make some sprites 
screen_centre_x = WINDOW_WIDTH  // 2
screen_bottom_y = WINDOW_HEIGHT - 10
SPRITES = pygame.sprite.Group()   
for i in range( 20 ):
    speed = random.randrange( INITIAL_VELOCITY_LOW, INITIAL_VELOCITY_HIGH )  # metres per second
    angle = random.randrange( -LAUNCH_ANGLE, LAUNCH_ANGLE ) 
    new_sprite = Projectile( sprite_image, screen_centre_x, screen_bottom_y, speed, angle )
    SPRITES.add( new_sprite )

# Main Loop
clock = pygame.time.Clock()
done  = False
while not done:
    # Handle user-input
    for event in pygame.event.get():
        if ( event.type == pygame.QUIT ):
            done = True

    # Repaint the screen
    window.fill( INKY_GREY )
    SPRITES.update()          # re-position the sprites
    SPRITES.draw( window )    # draw the sprites

    # Update the window, but not more than 60fps
    pygame.display.flip()
    clock.tick_busy_loop( FPS )

pygame.quit()
导入pygame
随机输入
输入数学
#窗口大小
窗宽=800
窗户高度=400
FPS=60
#背景色
墨灰色=(128128128)
初始速度低=每毫秒10像素(稍后调整)
初始速度高=100
发射角=80#随机起始角范围
类射弹(pygame.sprite.sprite):
重力=-9.8
def uuu init uuuu(自、位图、开始x、开始y、速度=0、角度=0):
pygame.sprite.sprite.\uuuuu init\uuuuuuu(自我)
self.image=位图
self.rect=bitmap.get_rect()
self.start\u x=start\u x
self.start\u y=start\u y
self.rect.center=((开始x,开始y))
#物理学
self.start_time=pygame.time.get_ticks()#“now”以毫秒为单位
自速度=速度
self.angle=数学弧度(角度)#注意:将度转换为弧度
def更新(自我):
time\u now=pygame.time.get\u ticks()
如果(自速度>0且自校正y<窗口高度-自校正高度):
time\u change=(time\u now-self.start\u time)
如果(时间变化>0):
时间变化/=100.0米/秒到像素/毫秒
#重新计算位移
#x
位移x=自速度*时间变化*数学sin(自角度)
#y
半重力时间平方=self.gravity*时间变化*时间变化/2.0
位移y=自速度*时间变化*数学cos(自角度)+重力的一半时间的平方
#重新定位雪碧
self.rect.center=((self.start_x+int(displacement_x),self.start_y-int(displacement_y)))
#停在窗口的底部
如果(self.rect.y>=窗口高度-self.rect.HEIGHT):
self.rect.y=窗高度-self.rect.HEIGHT
自速度=0
self.kill()#移除精灵
###主要
pygame.init()
SURFACE=pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.resizeable
window=pygame.display.set_模式((窗口宽度,窗口高度),表面)
pygame.display.set_标题(“投射物运动示例”)
#加载资源映像
sprite_image=pygame.image.load(“ball.png”)#.convert_alpha()
#做些雪碧
屏幕\中心\ x=窗口\宽度//2
屏幕\底部\ y=窗口\高度-10
SPRITES=pygame.sprite.Group()
对于范围(20)内的i:
速度=随机。随机范围(初始速度低,初始速度高)#米/秒
角度=随机.randrange(-LAUNCH\u angle,LAUNCH\u angle)
新的精灵=投射物(精灵图像、屏幕中心、scre