本系列博客介绍以python+pygame库进行小游戏的开发。有写的不对之处还望各位海涵。
我们一同在前几期的博客中已经学到了很多pygame的基本知识了,现在该做个小游戏实战一下了。
前几期博客链接:
第一篇:初识pygame http://www.cnblogs.com/msxh/p/4966899.html
第二篇:pygame中的IO、数据 http://www.cnblogs.com/msxh/p/4973003.html
第三篇:pygame事件与设备轮询 http://www.cnblogs.com/msxh/p/4979380.html
第四篇:pygame中加载位图及些常用的数学函数 http://www.cnblogs.com/msxh/p/4990435.html
本次我们要做一个很简单的小游戏:从天上会随机的掉下鱼,你需要使用鼠标操纵猫去接住鱼,丢失一条鱼损失一条命,一共有10条命,同时还要避免接到炸弹。接住鱼会有积分。
游戏效果图如下:
游戏下载地址:http://pan.baidu.com/s/1qWA4xZ2
源代码下载地址:http://pan.baidu.com/s/1i3is15j
还是先上一下完整的源代码吧:
1 # -*-coding:utf-8-*- s = '
2 #AoDaMiao Like Eating Fish
3 import sys, random, time, pygame
4 from pygame.locals import *
5
6 def print_text(font, x, y, text, color=(255,255,255)):
7 imgText = font.render(text, True, color)
8 screen.blit(imgText, (x,y))
9
10
11 #main program begins
12 pygame.init()
13 screen = pygame.display.set_mode((600,500))
14 pygame.display.set_caption("嗷大喵爱吃鱼!")
15 font1 = pygame.font.Font(None, 24)
16 font2 = pygame.font.Font(None, 18)
17 font3 = pygame.font.Font(None, 34)
18 pygame.mouse.set_visible(False)
19 white = 255,255,255
20 red = 220, 50, 50
21 yellow = 230,230,50
22 black = 0,0,0
23 cat=pygame.image.load("aodamiao_2.png")
24 width,height=cat.get_size()
25 pic=pygame.transform.scale(cat,(width,height))
26 fish=pygame.image.load("fish.png")
27 width,height=fish.get_size()
28 fish=pygame.transform.smoothscale(fish,(width//3,height//3))
29 init=pygame.image.load("init.png")
30 lives = 10
31 score = 0
32 clock_start = 0
33 game_over = 1
34 mouse_x = mouse_y = 0
35 Round =1
36 mine=0
37 mine_png=pygame.image.load("mine.png")
38 cat2=pygame.image.load("aodamiao_3.png")
39 flag=0
40
41 pos_x = 300
42 pos_y = 410-40
43
44 bomb_x = random.randint(0,500)
45 mine_x=random.randint(0,500)
46 bomb_y = -50
47 vel_y = 0.4
48 vel_yy=0.6
49 mine_y=-100
50
51 #repeating loop
52 while True:
53 for event in pygame.event.get():
54 if event.type == pygame.QUIT:
55 #sys.exit()
56 pygame.quit()
57 exit()
58 elif event.type == MOUSEMOTION:
59 mouse_x,mouse_y = event.pos
60 move_x,move_y = event.rel
61 elif event.type == MOUSEBUTTONUP:
62 if game_over:
63 game_over = False
64 lives = 10
65 score = 0
66 Round =1
67 vel_y=0.4
68 mine=0
69 flag=0
70 pic=cat
71 bomb_y = -50
72
73 keys = pygame.key.get_pressed()
74 if keys[K_ESCAPE]:
75 sys.exit()
76
77 screen.fill((0,0,100))
78
79 if game_over:
80 screen.blit(init,(60, 60))
81 print_text(font3, 200, 400,"Clicked To Play!")
82 print_text(font2, 310, 480,"Copyright@2015 developed by xiaoxiami")
83 else:
84 #Round setting
85 if score >300 and score <600:
86 Round=2
87 elif score >600 and score <900:
88 Round =3
89 elif score >900 and score <1200:
90 Round=4
91 elif score >1200 and score <1500:
92 Round =5
93 elif score >=1500:
94 Round =6
95 #draw the Round
96 print_text(font1, 280, 0, "Round: " + str(Round))
97 #speed setting
98 if Round ==1:
99 vel_y=0.4
100 elif Round ==2:
101 vel_y=0.6
102 elif Round ==3:
103 vel_y=0.8
104 elif Round ==4:
105 vel_y=1.0
106 elif Round ==5:
107 vel_y=1.2
108 #mine number setting
109 #mine=random.randint(1,9)
110 #move the fish
111 bomb_y += vel_y
112 mine_y+=vel_yy
113
114 #has the player missed the fish?
115 if bomb_y > 500:
116 bomb_x = random.randint(0, 500)
117 bomb_y = -50
118 lives -= 1
119 if lives == 0:
120 game_over = True
121 #see if player has caught the fish
122 elif bomb_y > pos_y:
123 if bomb_x > pos_x-10 and bomb_x < pos_x + 70:
124 score += 10
125 bomb_x = random.randint(0, 500)
126 bomb_y = -50
127 if Round >2:
128 #has the player missed the mine?
129 if mine_y > 500:
130 mine_x = random.randint(0, 500)
131 mine_y = -50
132 #see if player has caught the mine
133 elif mine_y > pos_y:
134 if mine_x > pos_x and mine_x < pos_x + 40:
135 mine_x = random.randint(0, 500)
136 mine_y = -50
137 lives-=1
138 pic=cat2
139 if lives == 0:
140 game_over = True
141
142 #draw the fish
143 screen.blit(fish,(bomb_x,int(bomb_y)))
144 #draw the mine
145 if Round >2:
146 screen.blit(mine_png,(mine_x,int(mine_y)))
147
148 #set cat position
149 pos_x = mouse_x
150 if pos_x < 0:
151 pos_x = 0
152 elif pos_x > 510:
153 pos_x = 500
154 #draw cat
155 if lives<5:
156 pic=cat2
157 screen.blit(pic,(pos_x,pos_y))
158
159 #print # of lives
160 print_text(font1, 0, 0, "LIVES: " + str(lives))
161
162 #print score
163 print_text(font1, 500, 0, "SCORE: " + str(score))
164
165 pygame.display.update()
166
167
关于位图的加载,设备轮询等等的内容我们就不在这里赘述了,不熟悉的可以查看前几期的博客。
为了让游戏更有趣味性,我们设置一下鱼的速度是可以变的。当得到的分数在不同区间的时候,会有不同的速度。(速度会越来快。)详见代码83-107行。
为了判断玩家是否错过鱼或者接到鱼,我们还需要写一个简单的碰撞检测函数:
#如果错过鱼的话,就重置鱼的位置,给它一个随机的x值,然后生命值 减一
if bomb_y > 500:
bomb_x = random.randint(0, 500)
bomb_y = -50
lives -= 1
if lives == 0:
game_over = True
#简单碰撞检测函数,查看是否接住鱼
elif bomb_y > pos_y:
if bomb_x > pos_x-10 and bomb_x < pos_x + 70:
score += 10
bomb_x = random.randint(0, 500)
bomb_y = -50
同理炸弹的检测和这个是类似的。
if bomb_y > 500:
bomb_x = random.randint(0, 500)
bomb_y = -50
lives -= 1
if lives == 0:
game_over = True
为了控制猫的坐标不超出屏幕范围,我们加入了如下的代码:
pos_x = mouse_x
if pos_x < 0:
pos_x = 0
elif pos_x > 510:
pos_x = 500
猫在接到炸弹。或者生命值小于5的时候,会变成哭脸,因此我们还需要加载一张哭脸的位图,然后在程序中添加一些相应的逻辑代码:
#加载猫的哭脸位图
cat2=pygame.image.load("aodamiao_3.png")
#当接到炸弹的时候,猫变成哭脸
elif mine_y > pos_y:
if mine_x > pos_x and mine_x < pos_x + 40:
mine_x = random.randint(0, 500)
mine_y = -50
lives-=1
pic=cat2
if lives == 0:
game_over = True
#当猫的生命值小于5时,猫变成哭脸
if lives<5:
pic=cat2
最后我们可以使用py2exe将其打包成exe并发布。py2exe打包流程请看这里:http://www.cnblogs.com/msxh/p/4886628.html
通过这个十分简陋的游戏,我们大概回顾了一下之前学到的知识。(游戏相当的简陋了,连声音都没有。。。)
下个博客我们将深入学习pygame中的Sprite(精灵)模块,并且了解如何加载动画和Sprite中的碰撞检测函数。