不得不承认《Python游戏编程入门》这本书翻译、排版非常之烂,但是里面的demo还是很好的,之前做了些改编放到这里。
先是素材:
背景
所有素材均取自此书
接下来就是精灵类的创建了:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
class MySprite(pygame.sprite.Sprite):
def __init__( self , target):
pygame.sprite.Sprite.__init__( self )
self .master_image = None
self .frame = 0
self .old_frame = - 1
self .frame_width = 1
self .frame_height = 1
self .first_frame = 0
self .last_frame = 0
self .columns = 1
self .last_time = 0
# 使用property方法,让精灵类对坐标操作更方便
def _getx( self ):
return self .rect.x
def _setx( self , value):
self .rect.x = value
X = property (_getx, _setx)
def _gety( self ):
return self .rect.y
def _sety( self , value):
self .rect.y = value
Y = property (_gety, _sety)
def _getpos( self ):
return self .rect.topleft
def _setpos( self , pos):
self .rect.topleft = pos
position = property (_getpos, _setpos)
# load方法中定义了图片位置,长宽和帧的列数,由此来将素材切成一帧一帧
def load( self , filename, width, height, columns):
self .master_image = pygame.image.load(filename).convert_alpha()
self .frame_width = width
self .frame_height = height
self .rect = Rect( 0 , 0 , width, height)
self .columns = columns
rect = self .master_image.get_rect()
self .last_frame = (rect.width / / width) * (rect.height / / height) - 1
def update( self , current_time, rate = 30 ):
# 更新帧数
if current_time > self .last_time + rate:
self .frame + = 1
if self .frame > self .last_frame:
self .frame = self .first_frame
self .last_time = current_time
# 当帧数发生改变时,创建新的图片
if self .frame ! = self .old_frame:
frame_x = ( self .frame % self .columns) * self .frame_width
frame_y = ( self .frame / / self .columns) * self .frame_height
rect = Rect(frame_x, frame_y, self .frame_width, self .frame_height)
self .image = self .master_image.subsurface(rect)
self .old_frame = self .frame
|
将精灵类“放置”到游戏屏幕上,并加上背景
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
pygame.init()
screen = pygame.display.set_mode(( 800 , 600 ))
font = pygame.font.Font( None , 24 )
framerate = pygame.time.Clock()
bg = pygame.image.load( "background.png" ).convert_alpha()
pl = pygame.image.load( 'caveman.png' ).convert_alpha()
# 创建精灵组
group = pygame.sprite.Group()
player = MySprite(screen)
player.load( "caveman.png" , 50 , 64 , 8 )
player.first_frame = 1
player.last_frame = 7
player.position = 400 , 303
group.add(player)
while True :
for event in pygame.event.get():
if event. type = = QUIT:
sys.exit()
# 设置帧数
framerate.tick( 30 )
ticks = pygame.time.get_ticks()
|
这样的话精灵就在画布上了,我们得让它能左右移动:
1
2
3
4
5
6
7
8
|
keys = pygame.key.get_pressed()
if keys[K_ESCAPE]:
sys.exit()
if keys[K_RIGHT]:
player.X + = 8
if keys[K_LEFT]:
if player.X > 0 :
player.X - = 8
|
然后实现跳跃及二段跳跃
这里需要说下二段跳跃的注意点:
1.直到落地前,只能跳两次,也就是说精灵进行二次跳跃后不能再跳了
2.按下空格后,精灵的加速度重置
这需要修改前面的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
jump_vel = 0.0
# 设置一个记录跳跃次数的变量
space_number = 0
# 跳跃判断
player_jumping = False
player_start_y = player.Y
while True :
for event in pygame.event.get():
if event. type = = QUIT:
sys.exit()
if event. type = = KEYDOWN:
if event.key = = K_SPACE:
# 跳跃次数小于2次时,
if space_number < 2 :
jump_vel = - 15.0
space_number + = 1
player_jumping = True
keys = pygame.key.get_pressed()
if keys[K_ESCAPE]:
sys.exit()
if keys[K_RIGHT]:
player.X + = 8
if keys[K_LEFT]:
if player.X > 0 :
player.X - = 8
# 设置帧数
framerate.tick( 30 )
ticks = pygame.time.get_ticks()
# 当按下空格后,jump_vel变量不断变大,直到接触地面
if player_jumping:
player.Y + = jump_vel
jump_vel + = 2
# 落地后,重置跳跃速度和其他判断变量
if player.Y > = player_start_y:
player_jumping = False
player.Y = player_start_y
jump_vel = 0
space_number = 0
# 创建背景
screen.blit(bg, ( 0 , 0 ))
# 精灵组更新
group.update(ticks, 50 )
group.draw(screen)
pygame.display.update()
|
所有代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
import sys, time, random, math, pygame
from pygame. locals import *
class MySprite(pygame.sprite.Sprite):
def __init__( self , target):
pygame.sprite.Sprite.__init__( self )
self .master_image = None
self .frame = 0
self .old_frame = - 1
self .frame_width = 1
self .frame_height = 1
self .first_frame = 0
self .last_frame = 0
self .columns = 1
self .last_time = 0
# 使用property方法,让精灵类对坐标操作更方便
def _getx( self ):
return self .rect.x
def _setx( self , value):
self .rect.x = value
X = property (_getx, _setx)
def _gety( self ):
return self .rect.y
def _sety( self , value):
self .rect.y = value
Y = property (_gety, _sety)
def _getpos( self ):
return self .rect.topleft
def _setpos( self , pos):
self .rect.topleft = pos
position = property (_getpos, _setpos)
def load( self , filename, width, height, columns):
self .master_image = pygame.image.load(filename).convert_alpha()
self .frame_width = width
self .frame_height = height
self .rect = Rect( 0 , 0 , width, height)
self .columns = columns
rect = self .master_image.get_rect()
self .last_frame = (rect.width / / width) * (rect.height / / height) - 1
def update( self , current_time, rate = 30 ):
# 更新帧数
if current_time > self .last_time + rate:
self .frame + = 1
if self .frame > self .last_frame:
self .frame = self .first_frame
self .last_time = current_time
# 当帧数发生改变时,创建新的图片
if self .frame ! = self .old_frame:
frame_x = ( self .frame % self .columns) * self .frame_width
frame_y = ( self .frame / / self .columns) * self .frame_height
rect = Rect(frame_x, frame_y, self .frame_width, self .frame_height)
self .image = self .master_image.subsurface(rect)
self .old_frame = self .frame
pygame.init()
screen = pygame.display.set_mode(( 800 , 600 ))
font = pygame.font.Font( None , 24 )
framerate = pygame.time.Clock()
bg = pygame.image.load( "background.png" ).convert_alpha()
pl = pygame.image.load( 'caveman.png' ).convert_alpha()
# 创建精灵组
group = pygame.sprite.Group()
player = MySprite(screen)
player.load( "caveman.png" , 50 , 64 , 8 )
player.first_frame = 1
player.last_frame = 7
player.position = 400 , 303
group.add(player)
jump_vel = 0.0
# 设置一个记录跳跃次数的变量
space_number = 0
# 跳跃判断
player_jumping = False
player_start_y = player.Y
while True :
for event in pygame.event.get():
if event. type = = QUIT:
sys.exit()
if event. type = = KEYDOWN:
if event.key = = K_SPACE:
# 跳跃次数小于2次时,
if space_number < 2 :
jump_vel = - 15.0
space_number + = 1
player_jumping = True
keys = pygame.key.get_pressed()
if keys[K_ESCAPE]:
sys.exit()
if keys[K_RIGHT]:
player.X + = 8
if keys[K_LEFT]:
if player.X > 0 :
player.X - = 8
# 设置帧数
framerate.tick( 30 )
ticks = pygame.time.get_ticks()
# 当按下空格后,jump_vel变量不断变大,直到接触地面
if player_jumping:
player.Y + = jump_vel
jump_vel + = 2
# 落地后
if player.Y > = player_start_y:
player_jumping = False
player.Y = player_start_y
jump_vel = 0
space_number = 0
rush_number = 0
# 创建背景
screen.blit(bg, ( 0 , 0 ))
# 精灵组更新
group.update(ticks, 50 )
group.draw(screen)
pygame.display.update()
|
这样,一个粗糙的、会二段跳的精灵就完成了。
很感谢这本书提供单次跳跃的思路,让我有思考二段跳的想法。其实像二段跳这类看上去容易,但实现其实还是需要思考一番的。
以上这篇pygame 精灵的行走及二段跳的实现方法(必看篇)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。