本文共 18948 字,大约阅读时间需要 63 分钟。
pygame游戏角色旋转
在本系列的第一篇文章中,我解释了如何使用Python创建一个简单 。 在第二部分中,我们从头 ,从 。 并且,在第三部分中,我们 ,并使其在您(而不是空的)游戏世界中生成。 您可能已经注意到,如果您不能随意移动角色,那么游戏就不会太有趣。 在本文中,我们将使用Pygame添加键盘控件,以便您可以控制角色的动作。
Pygame中有一些函数可以添加其他类型的控件,但是如果您要输入Python代码,肯定会拥有键盘,因此我们将使用它。 了解键盘控件后,您可以自己探索其他选项。
在本系列的第二篇文章中,您创建了退出游戏的钥匙,其原理与运动相同。 但是,使角色移动会更加复杂。
让我们从简单的部分开始:设置控制器键。
在IDLE,Ninja-IDE或文本编辑器中打开Python游戏脚本。
由于游戏必须不断地“监听”键盘事件,因此您将编写需要连续运行的代码。 您能找出在整个游戏期间需要不断运行的代码的位置吗?
如果您回答“在主循环中”,那是对的! 请记住,除非代码处于循环中,否则它将(最多)仅运行一次-如果将其隐藏在永远不会使用的类或函数中,则可能根本不会运行。
要使Python监视传入的按键,请将此代码添加到主循环中。 尚无代码可以使任何事情发生,因此请使用print
语句表示成功。 这是一种常见的调试技术。
while main == True : for event in pygame. event . get ( ) : if event. type == pygame. QUIT : pygame. quit ( ) ; sys . exit ( ) main = False if event. type == pygame. KEYDOWN : if event. key == pygame. K_LEFT or event. key == ord ( 'a' ) : print ( 'left' ) if event. key == pygame. K_RIGHT or event. key == ord ( 'd' ) : print ( 'right' ) if event. key == pygame. K_UP or event. key == ord ( 'w' ) : print ( 'jump' ) if event. type == pygame. KEYUP : if event. key == pygame. K_LEFT or event. key == ord ( 'a' ) : print ( 'left stop' ) if event. key == pygame. K_RIGHT or event. key == ord ( 'd' ) : print ( 'right stop' ) if event. key == ord ( 'q' ) : pygame. quit ( ) sys . exit ( ) main = False
有些人喜欢使用键盘字符W,A,S和D来控制播放器角色,而另一些人则喜欢使用箭头键。 确保同时包含两个选项。
注意:编程时必须考虑所有用户,这一点至关重要。 如果您编写的代码只适合您自己,那么很可能您将是唯一使用您的应用程序的人。 更重要的是,如果您寻找一份能赚钱的代码,那么您就应该编写适合所有人的代码。 给予用户选择(例如使用箭头键或WASD的选项)的标志就是优秀的程序员。
使用Python启动游戏,然后按向右,向左和向上箭头或A,D和W键,观看控制台窗口的输出。
$ python ./your-name_game. py left left stop right right stop jump
这确认Pygame正确检测到按键。 现在是时候进行使精灵移动的艰苦工作了。
要使精灵移动,必须为精灵创建一个表示移动的属性。 当精灵不移动时,此变量设置为0
。
如果您要为子画面设置动画,或者如果您决定将来对其进行动画处理,则还必须跟踪帧以使行走周期保持在正轨上。
在Player类中创建变量。 前两行是针对上下文的(如果您一直遵循的话,您已经在代码中添加了它们),因此仅添加后三行:
def __init__ ( self ) : pygame. sprite . Sprite . __init__ ( self ) self . movex = 0 # move along X self . movey = 0 # move along Y self . frame = 0 # count frames
设置好这些变量后,就该编写精灵的运动了。
播放器Sprite不需要一直响应控制。 有时它不会移动。 因此,控制Sprite的代码只是播放器Sprite要做的所有事情的一小部分。 当您想使Python中的对象执行与其余代码无关的操作时,可以将新代码放在函数中。 Python函数以关键字def
开头,它代表define 。
在Player类中创建一个函数,以将某些像素添加到屏幕上精灵的位置。 不必担心您添加了多少像素; 这将在以后的代码中确定。
def control ( self , x , y ) : ''' control player movement ''' self . movex + = x self . movey + = y
要在Pygame中移动精灵,您必须告诉Python在新位置以及该新位置重新绘制该精灵。
由于Player精灵并不总是在移动,因此更新仅是Player类中的一个功能。 在您先前创建的control
功能之后添加此功能。
为了使精灵看起来正在行走(或正在飞行,或者精灵应该执行的操作),您需要在按下适当的键时更改其在屏幕上的位置。 要使其在屏幕上移动,您需要将其位置(由self.rect.x
和self.rect.y
属性指定)重新定义为其当前位置,再加上所应用的movex
或movey
数量。 (移动所需的像素数将在以后设置。)
def update ( self ) : ''' Update sprite position ''' self . rect . x = self . rect . x + self . movex
对Y位置做同样的事情:
self . rect . y = self . rect . y + self . movey
对于动画,只要精灵移动,就使动画帧前进,并使用相应的动画帧作为播放器图像:
# moving left if self . movex < 0 : self . frame + = 1 if self . frame > 3 *ani: self . frame = 0 self . image = self . images [ self . frame //ani ] # moving right if self . movex > 0 : self . frame + = 1 if self . frame > 3 *ani: self . frame = 0 self . image = self . images [ ( self . frame //ani ) + 4 ]
通过设置变量来告诉代码将多少像素添加到子画面的位置,然后在触发Player子画面功能时使用该变量。
首先,在设置部分中创建变量。 在此代码中,前两行用于上下文,因此只需将第三行添加到脚本中:
player_list = pygame. sprite . Group ( ) player_list. add ( player ) steps = 10 # how many pixels to move
现在您已经拥有了适当的函数和变量,现在可以通过按键触发函数并将变量发送到Sprite。
为此,将主循环中的print
语句替换为播放器精灵的名称(播放器),函数(.control),以及您希望播放器精灵在每个循环中沿X轴和Y轴移动多少步。
if event. type == pygame. KEYDOWN : if event. key == pygame. K_LEFT or event. key == ord ( 'a' ) : player. control ( -steps , 0 ) if event. key == pygame. K_RIGHT or event. key == ord ( 'd' ) : player. control ( steps , 0 ) if event. key == pygame. K_UP or event. key == ord ( 'w' ) : print ( 'jump' ) if event. type == pygame. KEYUP : if event. key == pygame. K_LEFT or event. key == ord ( 'a' ) : player. control ( steps , 0 ) if event. key == pygame. K_RIGHT or event. key == ord ( 'd' ) : player. control ( -steps , 0 ) if event. key == ord ( 'q' ) : pygame. quit ( ) sys . exit ( ) main = False
请记住, steps
是一个变量,表示按键按下时精灵移动多少像素。 如果在按D或向右箭头时将10个像素添加到播放器精灵的位置,则停止按该键时必须减去10( -steps
),以将精灵的动量恢复为0。
立即尝试游戏。 警告:它不会达到您的期望。
你的精灵为什么还没有动呢? 因为主循环不调用update
函数。
将代码添加到您的主循环中,以告诉Python更新播放器精灵的位置。 添加带有注释的行:
player. update ( ) # update player position player_list. draw ( world ) pygame. display . flip ( ) clock. tick ( fps )
再次启动游戏,见证您的玩家精灵在出价时在屏幕上移动。 目前还没有垂直运动,因为这些功能将由重力控制,但这是另一篇文章的另一课。
同时,如果您有权使用操纵杆,请尝试阅读Pygame 模块的文档,并查看是否可以使精灵移动。 或者,查看是否可以使与精灵交互。
最重要的是,玩得开心!
供您参考,这是到目前为止本系列文章中使用的所有代码。
#!/usr/bin/env python3 # draw a world # add a player and player control # add player movement # GNU All-Permissive License # Copying and distribution of this file, with or without modification, # are permitted in any medium without royalty provided the copyright # notice and this notice are preserved. This file is offered as-is, # without any warranty. import pygame import sys import os ''' Objects ''' class Player ( pygame. sprite . Sprite ) : ''' Spawn a player ''' def __init__ ( self ) : pygame. sprite . Sprite . __init__ ( self ) self . movex = 0 self . movey = 0 self . frame = 0 self . images = [ ] for i in range ( 1 , 5 ) : img = pygame. image . load ( os . path . join ( 'images' , 'hero' + str ( i ) + '.png' ) ) . convert ( ) img. convert_alpha ( ) img. set_colorkey ( ALPHA ) self . images . append ( img ) self . image = self . images [ 0 ] self . rect = self . image . get_rect ( ) def control ( self , x , y ) : ''' control player movement ''' self . movex + = x self . movey + = y def update ( self ) : ''' Update sprite position ''' self . rect . x = self . rect . x + self . movex self . rect . y = self . rect . y + self . movey # moving left if self . movex < 0 : self . frame + = 1 if self . frame > 3 *ani: self . frame = 0 self . image = self . images [ self . frame //ani ] # moving right if self . movex > 0 : self . frame + = 1 if self . frame > 3 *ani: self . frame = 0 self . image = self . images [ ( self . frame //ani ) + 4 ] ''' Setup ''' worldx = 960 worldy = 720 fps = 40 # frame rate ani = 4 # animation cycles clock = pygame. time . Clock ( ) pygame. init ( ) main = True BLUE = ( 25 , 25 , 200 ) BLACK = ( 23 , 23 , 23 ) WHITE = ( 254 , 254 , 254 ) ALPHA = ( 0 , 255 , 0 ) world = pygame. display . set_mode ( [ worldx , worldy ] ) backdrop = pygame. image . load ( os . path . join ( 'images' , 'stage.png' ) ) . convert ( ) backdropbox = world. get_rect ( ) player = Player ( ) # spawn player player. rect . x = 0 player. rect . y = 0 player_list = pygame. sprite . Group ( ) player_list. add ( player ) steps = 10 # how fast to move ''' Main loop ''' while main == True : for event in pygame. event . get ( ) : if event. type == pygame. QUIT : pygame. quit ( ) ; sys . exit ( ) main = False if event. type == pygame. KEYDOWN : if event. key == pygame. K_LEFT or event. key == ord ( 'a' ) : player. control ( -steps , 0 ) if event. key == pygame. K_RIGHT or event. key == ord ( 'd' ) : player. control ( steps , 0 ) if event. key == pygame. K_UP or event. key == ord ( 'w' ) : print ( 'jump' ) if event. type == pygame. KEYUP : if event. key == pygame. K_LEFT or event. key == ord ( 'a' ) : player. control ( steps , 0 ) if event. key == pygame. K_RIGHT or event. key == ord ( 'd' ) : player. control ( -steps , 0 ) if event. key == ord ( 'q' ) : pygame. quit ( ) sys . exit ( ) main = False # world.fill(BLACK) world. blit ( backdrop , backdropbox ) player. update ( ) player_list. draw ( world ) #refresh player position pygame. display . flip ( ) clock. tick ( fps )
您已经走了很远,学到了很多东西,但是还有很多事情要做。 在接下来的几篇文章中,您将 ,模拟重力等等。 同时,使用Python进行练习!
翻译自:
pygame游戏角色旋转
转载地址:http://nrbzd.baihongyu.com/