1 import pygame #将pygame库导入到python程序中
2 from pygame.locals import * #导入pygame中的常量
3 import sys #导入系统模块
4 SCREENWIDTH = 822 #窗口宽度
5 SCREENHEIGHT = 199 #窗口高度
6 FPS = 30 #更新画面的时间
7
8
9 #定义一个移动地图类
10 classMyMap():11
12 def __init__(self, x, y):13 #加载背景图片
14 self.bg = pygame.image.load("image/bg.png").convert_alpha()15 self.x =x16 self.y =y17
18 defmap_rolling(self):19 if self.x < -790: #小于-790说明地图已经完全移动完毕
20 self.x = 800 #给地图一个新的坐标点
21 else:22 self.x -= 5 #5个像素向左移动
23
24 #更新地图
25 defmap_update(self):26 SCREEN.blit(self.bg, (self.x, self.y))27
28 #背景音乐按钮
29 classMusic_Button():30 is_open = True #背景乐音的标记
31 def __init__(self):32 self.open_img = pygame.image.load('image/btn_open.png').convert_alpha()33 self.close_img = pygame.image.load('image/btn_close.png').convert_alpha()34 self.bg_music = pygame.mixer.Sound('audio/bg_music.wav') #加载背景音乐
35 #判断鼠标是否在,按钮的范围内
36 defis_select(self):37 #获取鼠标,的坐标
38 point_x, point_y =pygame.mouse.get_pos()39 w, h = self.open_img.get_size() #获取按钮图片的大小
40 #判断鼠标是否在按钮范围内
41 in_x = point_x > 20 and point_x < 20 +w42 in_y = point_y > 20 and point_y < 20 +h43 return in_x andin_y44
45
46
47
48
49 from itertools import cycle #导入迭代工具
50
51
52 #玛丽类
53 classMarie():54 def __init__(self):55 #初始化小玛丽矩形
56 self.rect =pygame.Rect(0, 0, 0, 0)57 self.jumpState = False #跳跃的状态
58 self.jumpHeight = 130 #跳跃的高度
59 self.lowest_y = 140 #最低坐标
60 self.jumpValue = 0 #跳跃增变量
61 #小玛丽动图索引
62 self.marieIndex =063 self.marieIndexGen = cycle([0, 1, 2])64 #加载小玛丽图片
65 self.adventure_img =(66 pygame.image.load("image/adventure1.png").convert_alpha(),67 pygame.image.load("image/adventure2.png").convert_alpha(),68 pygame.image.load("image/adventure3.png").convert_alpha(),69 )70 self.jump_audio = pygame.mixer.Sound('audio/jump.wav') #跳音效
71 self.rect.size =self.adventure_img[0].get_size()72 self.x = 50; #绘制小玛丽的X坐标
73 self.y = self.lowest_y; #绘制小玛丽的Y坐标
74 self.rect.topleft =(self.x, self.y)75
76 #跳状态
77 defjump(self):78 self.jumpState =True79
80 #小玛丽移动
81 defmove(self):82 if self.jumpState: #当起跳的时候
83 if self.rect.y >= self.lowest_y: #如果站在地上
84 self.jumpValue = -5 #以5个像素值向上移动
85 if self.rect.y <= self.lowest_y - self.jumpHeight: #小玛丽到达顶部回落
86 self.jumpValue = 5 #以5个像素值向下移动
87 self.rect.y += self.jumpValue #通过循环改变玛丽的Y坐标
88 if self.rect.y >= self.lowest_y: #如果小玛丽回到地面
89 self.jumpState = False #关闭跳跃状态
90
91 #绘制小玛丽
92 defdraw_marie(self):93 #匹配小玛丽动图
94 marieIndex =next(self.marieIndexGen)95 #绘制小玛丽
96 SCREEN.blit(self.adventure_img[marieIndex],97 (self.x, self.rect.y))98
99 import random #随机数
100 #障碍物类
101 classObstacle():102 score = 1 #分数
103 move = 5 #移动距离
104 obstacle_y = 150 #障碍物y坐标
105 def __init__(self):106 #初始化障碍物矩形
107 self.rect =pygame.Rect(0, 0, 0, 0)108 #加载障碍物图片
109 self.missile = pygame.image.load("image/missile.png").convert_alpha()110 self.pipe = pygame.image.load("image/pipe.png").convert_alpha()111 #加载分数图片
112 self.numbers = (pygame.image.load('image/0.png').convert_alpha(),113 pygame.image.load('image/1.png').convert_alpha(),114 pygame.image.load('image/2.png').convert_alpha(),115 pygame.image.load('image/3.png').convert_alpha(),116 pygame.image.load('image/4.png').convert_alpha(),117 pygame.image.load('image/5.png').convert_alpha(),118 pygame.image.load('image/6.png').convert_alpha(),119 pygame.image.load('image/7.png').convert_alpha(),120 pygame.image.load('image/8.png').convert_alpha(),121 pygame.image.load('image/9.png').convert_alpha())122 #加载加分音效
123 self.score_audio = pygame.mixer.Sound('audio/score.wav') #加分
124 #0和1随机数
125 r = random.randint(0, 1)126 if r == 0: #如果随机数为0显示导弹障碍物相反显示管道
127 self.image = self.missile #显示导弹障碍
128 self.move = 15 #移动速度加快
129 self.obstacle_y = 100 #导弹坐标在天上
130 else:131 self.image = self.pipe #显示管道障碍
132 #根据障碍物位图的宽高来设置矩形
133 self.rect.size =self.image.get_size()134 #获取位图宽高
135 self.width, self.height =self.rect.size136 #障碍物绘制坐标
137 self.x = 800
138 self.y =self.obstacle_y139 self.rect.center =(self.x, self.y)140
141 #障碍物移动
142 defobstacle_move(self):143 self.rect.x -=self.move144
145 #绘制障碍物
146 defdraw_obstacle(self):147 SCREEN.blit(self.image, (self.rect.x, self.rect.y))148
149 #获取分数
150 defgetScore(self):151 self.score152 tmp =self.score;153 if tmp == 1:154 self.score_audio.play() #播放加分音乐
155 self.score =0;156 returntmp;157
158 #显示分数
159 defshowScore(self, score):160 #获取得分数字
161 self.scoreDigits = [int(x) for x inlist(str(score))]162 totalWidth = 0 #要显示的所有数字的总宽度
163 for digit inself.scoreDigits:164 #获取积分图片的宽度
165 totalWidth +=self.numbers[digit].get_width()166 #分数横向位置
167 Xoffset = (SCREENWIDTH - (totalWidth+30))168 for digit inself.scoreDigits:169 #绘制分数
170 SCREEN.blit(self.numbers[digit], (Xoffset, SCREENHEIGHT * 0.1))171 #随着数字增加改变位置
172 Xoffset +=self.numbers[digit].get_width()173
174 #游戏结束的方法
175 defgame_over():176 bump_audio = pygame.mixer.Sound('audio/bump.wav') #撞击
177 bump_audio.play() #播放撞击音效
178 #获取窗体宽、高
179 screen_w =pygame.display.Info().current_w180 screen_h =pygame.display.Info().current_h181 #加载游戏结束的图片
182 over_img = pygame.image.load('image/gameover.png').convert_alpha()183 #将游戏结束的图片绘制在窗体的中间位置
184 SCREEN.blit(over_img, ((screen_w - over_img.get_width()) / 2,185 (screen_h - over_img.get_height()) / 2))186
187
188 defmainGame():189 score = 0 #得分
190 over = False #游戏结束标记
191 globalSCREEN, FPSCLOCK192 pygame.init() #经过初始化以后我们就可以尽情地使用pygame了。
193
194 #使用Pygame时钟之前,必须先创建Clock对象的一个实例,
195 #控制每个循环多长时间运行一次。
196 FPSCLOCK =pygame.time.Clock()197 SCREEN = pygame.display.set_mode((SCREENWIDTH, SCREENHEIGHT)) #通常来说我们需要先创建一个窗口,方便我们与程序的交互。
198 pygame.display.set_caption('玛丽冒险') #设置窗口标题
199
200 #创建地图对象
201 bg1 =MyMap(0, 0)202 bg2 = MyMap(800, 0)203
204 #创建小玛丽对象
205 marie =Marie()206
207 addObstacleTimer = 0 #添加障碍物的时间
208 list = [] #障碍物对象列表
209
210 music_button = Music_Button() #创建背景音乐按钮对象
211 btn_img = music_button.open_img #设置背景音乐按钮的默认图片
212 music_button.bg_music.play(-1) #循环播放背景音乐
213
214 whileTrue:215 #获取单击事件
216 for event inpygame.event.get():217
218 if event.type == pygame.MOUSEBUTTONUP: #判断鼠标事件
219 if music_button.is_select(): #判断鼠标是否在静音按钮范围
220 if music_button.is_open: #判断背景音乐状态
221 btn_img = music_button.close_img #单击后显示关闭状态的图片
222 music_button.is_open = False #关闭背景音乐状态
223 music_button.bg_music.stop() #停止背景音乐的播放
224 else:225 btn_img =music_button.open_img226 music_button.is_open =True227 music_button.bg_music.play(-1)228 #如果单击了关闭窗口就将窗口关闭
229 if event.type ==QUIT:230 pygame.quit() #退出窗口
231 sys.exit() #关闭窗口
232
233 #单击键盘空格键,开启跳的状态
234 if event.type == KEYDOWN and event.key ==K_SPACE:235 if marie.rect.y >= marie.lowest_y: #如果小玛丽在地面上
236 marie.jump_audio.play() #播放小玛丽跳跃音效
237 marie.jump() #开启小玛丽跳的状态
238
239 if over == True: #判断游戏结束的开关是否开启
240 mainGame() #如果开启将调用mainGame方法重新启动游戏
241
242
243
244
245 if over ==False:246 #绘制地图起到更新地图的作用
247 bg1.map_update()248 #地图移动
249 bg1.map_rolling()250 bg2.map_update()251 bg2.map_rolling()252
253 #小玛丽移动
254 marie.move()255 #绘制小玛丽
256 marie.draw_marie()257
258 #计算障碍物间隔时间
259 if addObstacleTimer >= 1300:260 r = random.randint(0, 100)261 if r > 40:262 #创建障碍物对象
263 obstacle =Obstacle()264 #将障碍物对象添加到列表中
265 list.append(obstacle)266 #重置添加障碍物时间
267 addObstacleTimer =0268
269 #循环遍历障碍物
270 for i inrange(len(list)):271 #障碍物移动
272 list[i].obstacle_move()273 #绘制障碍物
274 list[i].draw_obstacle()275
276 #判断小玛丽与障碍物是否碰撞
277 ifpygame.sprite.collide_rect(marie, list[i]):278 over = True #碰撞后开启结束开关
279 game_over() #调用游戏结束的方法
280 music_button.bg_music.stop()281 else:282 #判断小玛丽是否跃过了障碍物
283 if (list[i].rect.x + list[i].rect.width) <284>
285 score +=list[i].getScore()286 #显示分数
287 list[i].showScore(score)288
289 addObstacleTimer += 20 #增加障碍物时间
290 SCREEN.blit(btn_img, (20, 20)) #绘制背景音乐按钮
291 pygame.display.update() #更新整个窗口
292 FPSCLOCK.tick(FPS) #循环应该多长时间运行一次
293
294
295 if __name__ == '__main__':296 mainGame()
284>