我正在用pygame做游戏。我有一个角色的位置发生了这样的变化(L,R和D也有3个):
if keys[pygame.K_UP]:
y -= 10
每60毫秒将字符移动10个像素。我想编写一个函数,该函数在按下键的时间越长时增加速度,然后在释放键后重置速度。我已经尝试过了:
def speed(velocity):
velocity *= 2
return velocity
if keys[pygame.K_UP]:
y -= speed(10)
这只会将参数增加2,但不会随着按下键的时间增加而增加,并且我不知道释放键后如何将变量重置为其初始状态。 我将如何实施呢? 谢谢。
答案 0 :(得分:1)
您已经开始使用正确的方法,但是问题是您将速度存储在函数内部的局部变量中。每次调用该函数时都会重置此变量。
相反,您应该将速度存储在其他位置:
# Somewhere earlier in the program, eg. before your main loop
# Store the initial speed in a variable
base_speed = 10
# Initialise current speed to initial speed
speed = base_speed
然后在检查是否按下键时,可以执行以下操作:
if keys[pygame.K_UP]:
y -= speed
# Increase speed for the next round
speed *= 2
else:
# Did not press the key this time
# Reset current speed to the initial speed (10, stored in the variable base_speed)
speed = base_speed
这种解决方案的重要部分是
speed
已在您执行签入的任何循环之前初始化,因此不会在您每次进入循环时都被重置,并且
,它是在与使用它的函数相同的函数中初始化的,因此该函数可以访问它
答案 1 :(得分:1)
这是一个实时下降精灵的小例子。按下上可以降低速度,而按下下可以提高速度。我可能使示例复杂化了,但是如果将 Up 推入足够的次数,花盆就会掉下来。
我已经将此实现为继承自PyGame sprite class的对象。使用对象带来的好处之一就是能够将项目的所有属性(例如位置,位图,速度等)保持在对象内部。这意味着您的程序不会出现 this 和 that 的全局变量。 PyGame Sprite还带来了许多有用且优雅的功能。当然,在开始时需要做一些额外的工作,但是后来,编程进度将变得更加顺畅和轻松。 (如果您不想使用对象,则至少将所有内容放入python字典或类似的东西中,以将它们{"x":0, "y":0, "speed":3}
等保持在一起。)
无论如何...代码的重要部分是FallingSprite.update()
。在最后一次调用update()
和now
之间花费时间,使用它来计算对象在给定速度下应移动多少像素。该代码使用简单的恒定速度计算,而不是适当的重力下降计算,但是公式可以互换。计算出差值,然后将其应用于x
和y
co精灵的rect
的坐标(用于设置屏幕上的位置)。如果对象落在屏幕底部(或顶部),则会“环绕”以重新开始。
import pygame
import time
import sys
# Window size
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 400
# background colour
SKY_BLUE = (161, 255, 254)
class FallingSprite( pygame.sprite.Sprite ):
""" A falling flower-pot sprite. Falls at a given velocity in real-time """
def __init__( self ):
pygame.sprite.Sprite.__init__( self )
self.image = pygame.image.load("flower_pot.png").convert_alpha()
self.rect = self.image.get_rect()
self.rect.center = ( WINDOW_WIDTH//2, -50 )
self.fall_speed = 150 # pixels / second
self.image_height= self.image.get_rect().height
self.last_update = int( time.time() * 1000.0 )
def update( self ):
# There should have been movement since the last update
# calculate the new position
time_now = int( time.time() * 1000.0 )
time_change = time_now - self.last_update # How long since last update?
# If we're moving, and time has passed
if ( self.fall_speed != 0 and time_change > 0 ):
distance_moved = time_change * abs( self.fall_speed ) / 1000
now_x, now_y = self.rect.center # Where am I, right now
# Fall down (or up)
if ( self.fall_speed > 0 ):
updated_y = now_y + distance_moved
else:
updated_y = now_y - distance_moved
# Did we fall off the bottom of the screen?
if ( updated_y > WINDOW_HEIGHT + self.image_height ):
updated_y = -self.image.get_rect().height # move to just above top of screen
# ... or off the top?
elif ( updated_y < 0 - self.image_height ):
updated_y = WINDOW_HEIGHT + self.image_height # move to just below screen
# Reposition the sprite
self.rect.center = ( now_x, updated_y )
self.last_update = time_now
def adjustSpeed( self, amount ):
self.fall_speed += amount
def stop( self ):
self.fall_speed = 0
### MAIN
pygame.init()
WINDOW = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE )
pygame.display.set_caption("Flowerpot")
# Add some sprites
FALLERS = pygame.sprite.Group() # a group, for a single sprite
flower_pot_sprite = FallingSprite()
FALLERS.add( flower_pot_sprite )
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
elif ( event.type == pygame.VIDEORESIZE ):
WINDOW_WIDTH = event.w
WINDOW_HEIGHT = event.h
WINDOW = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE )
# Movement keys
keys = pygame.key.get_pressed()
if ( keys[pygame.K_UP] ):
flower_pot_sprite.adjustSpeed( -5 )
print( "slower... ", end='' )
sys.stdout.flush()
elif ( keys[pygame.K_DOWN] ):
flower_pot_sprite.adjustSpeed( 5 )
print( "faster! ", end='' )
sys.stdout.flush()
# Move the flower-pot, did it hit anything?
FALLERS.update() # re-position the flower-pot
# Re-draw the screen
WINDOW.fill( SKY_BLUE )
FALLERS.draw( WINDOW ) # draw the flower-pot
pygame.display.flip()
# Update the window, but not more than 60fps
clock.tick_busy_loop( 60 )
pygame.quit()
我意识到从技术上来说这是一个仙人掌锅,请不要写信。