脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|shell|

服务器之家 - 脚本之家 - Python - Python+Pygame实现神庙逃亡游戏

Python+Pygame实现神庙逃亡游戏

2023-02-15 13:56我的天才女友 Python

这篇文章主要为大家介绍了如何利用Python和Pygame动画制作一个神庙逃亡类似的小游戏。文中的示例代码讲解详细,感兴趣的小伙伴可以动手尝试一下

游戏规则

用pygame动画实现神庙逃亡类似的小游戏,当玩家移动的时候躲避子弹,如果子弹命中玩家或者名字龙都会减速,玩家躲避子弹使更多的子弹打在龙上,当玩家被龙抓到,则游戏输,如果龙被子弹减少速度,与玩家有一定的距离,则玩家获胜。

Python+Pygame实现神庙逃亡游戏

精灵类

?
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
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
 
    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 = pygame.Rect(frame_x, frame_y, self.frame_width, self.frame_height)
            self.image = self.master_image.subsurface(rect)
            self.old_frame = self.frame
 
    def __str__(self):
        return str(self.frame) + "," + str(self.first_frame) + \
               "," + str(self.last_frame) + "," + str(self.frame_width) + \
               "," + str(self.frame_height) + "," + str(self.columns) + \
               "," + str(self.rect)

MySprite继承精灵类,因为在做动画时候,需要许多的参数,这里进行了初始化,master_image 图片的位置,frame、old_frame分别储存第一帧和上一帧的位置,frame_width和frame_height保存宽高,first和last保存帧的第一帧和最后一帧。columns保存列数。last_time时间变量。
X、Y、pos保存精灵的位置x和y的位置。

load载入,赋予对应精灵的值,(rect.width // width) * (rect.height // height) - 1,通过给定的图片的宽高除以参数的值,-1就是初始的位置是从0开始的。

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
dragon = MySprite(screen)
dragon.load("dragon.png", 260, 150, 3)
dragon.position = 100, 230
group.add(dragon)
 
arrow_vel = 8.0
game_over = False
you_win = False
player_jumping = False
jump_vel = 0.0
 
while True:
    framerate.tick(30)
    ticks = pygame.time.get_ticks()
 
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
 
    keys = pygame.key.get_pressed()
    if keys[pygame.K_ESCAPE]:
        sys.exit()
    elif keys[pygame.K_SPACE]:
        if not player_jumping:
            player_jumping = True
            jump_vel = -8.0
 
 
    screen.blit(bg, (0, 0))
 
    if not game_over:
        group.update(ticks, 50)
 
    group.draw(screen)
 
    print_text(font, 350, 360, "Press SPACE to jump!")
 
    if game_over:
        print_text(font, 360, 100, "G A M E O V E R")
        if you_win:
            print_text(font, 330, 130, "YOU BEAT THE DRAGON")
        else:
            print_text(font, 330, 130, "THE DRAGON GOT YOU")
    pygame.display.update()

加载龙,实现龙动画,这里没有龙的位移,玩家躲子弹或者命中子弹都会导致双方的x坐标减少,这里没使用对应的速度改变,减少游戏的开发难度。

加载子弹

?
1
2
3
4
5
6
7
8
def reset_arrow():
    y = random.randint(250, 350)
    arrow.position = 800, y
 
arrow = MySprite(screen)
arrow.load("flame.png", 40, 16, 1)
arrow.position = 800, 320
group.add(arrow)

子弹因为只有一个,如果击中则需要重置,这里写了重置子弹的函数便于调用,random.randint(250, 350)给子弹一个随机的高度。使游戏与变化。

添加玩家

?
1
2
3
4
5
6
7
8
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)
 
player_start_y = player.Y

player_start_y记录玩家初始的y坐标判断玩家是否处于跳跃状态中。

碰撞事件

?
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
if not game_over:
    arrow.X -= arrow_vel
    if arrow.X < 40:
        reset_arrow()
 
if pygame.sprite.collide_rect(arrow, player):
    reset_arrow()
    player.X -= 10
 
if pygame.sprite.collide_rect(arrow, dragon):
    reset_arrow()
    dragon.X -= 10
 
if pygame.sprite.collide_rect(player, dragon):
    game_over = True
 
if dragon.X < -100:
    you_win = True
    game_over = True
 
if player_jumping:
    player.Y += jump_vel
    jump_vel += 0.5
    if player.Y > player_start_y:
        player_jumping = False
        player.Y = player_start_y
        jump_vel = 0.0

这里需要检验玩家、子弹和龙两两相碰的事件。

完整代码

?
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
import sys, time, random, math, pygame
from pygame.locals import *
 
 
class MySprite(pygame.sprite.Sprite):
    def __init__(self, target):
        pygame.sprite.Sprite.__init__(self# extend the base Sprite class
        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
 
    # X property
    def _getx(self):
        return self.rect.x
 
    def _setx(self, value):
        self.rect.x = value
 
    X = property(_getx, _setx)
 
    # Y property
    def _gety(self):
        return self.rect.y
 
    def _sety(self, value):
        self.rect.y = value
 
    Y = property(_gety, _sety)
 
    # position property
    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
        # try to auto-calculate total frames
        rect = self.master_image.get_rect()
        self.last_frame = (rect.width // width) * (rect.height // height) - 1
 
    def update(self, current_time, rate=30):
        # update animation frame number
        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
 
        # build current frame only if it changed
        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 = pygame.Rect(frame_x, frame_y, self.frame_width, self.frame_height)
            self.image = self.master_image.subsurface(rect)
            self.old_frame = self.frame
 
    def __str__(self):
        return str(self.frame) + "," + str(self.first_frame) + \
               "," + str(self.last_frame) + "," + str(self.frame_width) + \
               "," + str(self.frame_height) + "," + str(self.columns) + \
               "," + str(self.rect)
 
 
def print_text(font, x, y, text, color=(255, 255, 255)):
    imgText = font.render(text, True, color)
    screen.blit(imgText, (x, y))
 
 
def reset_arrow():
    y = random.randint(250, 350)
    arrow.position = 800, y
 
 
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Escape Dragon")
font = pygame.font.Font(None, 18)
framerate = pygame.time.Clock()
 
 
bg = pygame.image.load('background.png').convert_alpha()
 
group = pygame.sprite.Group()
 
dragon = MySprite(screen)
dragon.load("dragon.png", 260, 150, 3)
dragon.position = 100, 230
group.add(dragon)
 
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)
 
arrow = MySprite(screen)
arrow.load("flame.png", 40, 16, 1)
arrow.position = 800, 320
group.add(arrow)
 
 
arrow_vel = 8.0
game_over = False
you_win = False
player_jumping = False
jump_vel = 0.0
player_start_y = player.Y
 
while True:
    framerate.tick(30)
    ticks = pygame.time.get_ticks()
 
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
 
    keys = pygame.key.get_pressed()
    if keys[pygame.K_ESCAPE]:
        sys.exit()
    elif keys[pygame.K_SPACE]:
        if not player_jumping:
            player_jumping = True
            jump_vel = -8.0
 
    if not game_over:
        arrow.X -= arrow_vel
        if arrow.X < 40:
            reset_arrow()
 
    if pygame.sprite.collide_rect(arrow, player):
        reset_arrow()
        player.X -= 10
 
    if pygame.sprite.collide_rect(arrow, dragon):
        reset_arrow()
        dragon.X -= 10
 
    if pygame.sprite.collide_rect(player, dragon):
        game_over = True
 
    if dragon.X < -100:
        you_win = True
        game_over = True
 
    if player_jumping:
        player.Y += jump_vel
        jump_vel += 0.5
        if player.Y > player_start_y:
            player_jumping = False
            player.Y = player_start_y
            jump_vel = 0.0
 
    screen.blit(bg, (0, 0))
 
    if not game_over:
        group.update(ticks, 50)
 
    group.draw(screen)
 
    print_text(font, 350, 360, "Press SPACE to jump!")
 
    if game_over:
        print_text(font, 360, 100, "G A M E O V E R")
        if you_win:
            print_text(font, 330, 130, "YOU BEAT THE DRAGON")
        else:
            print_text(font, 330, 130, "THE DRAGON GOT YOU")
    pygame.display.update()

以上就是Python+Pygame实现神庙逃亡游戏的详细内容,更多关于Python Pygame神庙逃亡的资料请关注服务器之家其它相关文章!

原文链接:https://blog.csdn.net/qq_40801987/article/details/124871408

延伸 · 阅读

精彩推荐