博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
pygame游戏角色旋转_使用Pygame移动游戏角色
阅读量:2529 次
发布时间:2019-05-11

本文共 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.xself.rect.y属性指定)重新定义为其当前位置,再加上所应用的movexmovey数量。 (移动所需的像素数将在以后设置。)

         
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/

你可能感兴趣的文章
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_6_字节输出流写多个字节的方法...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_03 过滤器_2_FileNameFilter过滤器的使用和Lambda表达式...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_8_字节输入流_InputStream类&FileInputStream...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_3_字节输出流_OutputStream类&FileOutputStream...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_10_字节输入流一次读取一个字节的原理...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_5_文件存储的原理和记事本打开文本显示原理...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_12_练习_文件复制...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_7_字节输出流的续写和换行...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_1_字符输入流_Reader类&FileRead...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_9_字节输入流读取字节数据...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_3_字符输出流_Writer类&FileWriter类...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_11_字节输入流一次读取多个字节...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_5_flush方法和close方法的区别...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_13_使用字节流读取中文的问题...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_7_字符输出流的续写和换行...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_2_字符输入流读取字符数据...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_9_JDK7和JDK9流中异常的处理...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_4字符输出流的基本使用_写出单个字符...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_06 Properties集合_2_Properties集合中的方法store...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_6_字符输出流写数据的其他方法...
查看>>