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