创建真正的游戏
上一篇博客介绍了如何通过“上下左右”四个按键做到玩家与游戏的交互,今天将开始创建贪吃蛇游戏的三个主要对象:草地、食物、贪吃蛇。(代码是新代码,效果图是旧效果图)
草地就是贪吃蛇和食物所能存在的空间范围,它有两个主要属性——颜色、面积。我会根据这两个属性定义一个草地的类:
1 #定义草地的类模板
2 class GrassMap(object):
3
4 #定义对象属性,实例对象时自动创建
5 def __init__(self,color,living_space):
6 self.living_space = living_space
7 self.color = color
8
9 #在窗口中生成草地对象
10 def generate(self,surface):
11 grass_Rect = pygame.Rect(self.living_space)
12 surface.fill(self.color,grass_Rect)
运行代码,看看在窗体中生成的草地:
食物是贪吃蛇的目标,是贪吃蛇成长的唯一条件,当食物被贪吃蛇吃掉后,会有新的食物在草地中随机生成。食物有三个主要属性:颜色、体型、生成空间;此外,生成食物坐标时还需要传入一个贪吃蛇身体的坐标集做参数。
1 #定义贪吃蛇的食物的类模板
2 class Food(object):
3
4 #实例化的对象属性创建,定义实例化对象时传入的参数
5 def __init__(self,color,size,living_space):
6 self.color = color
7 self.size = size
8 self.living_space = living_space
9 #随机生成游戏开始时食物的初始坐标
10 def generate(self,snakebody):
11 cell_width = self.living_space[2]//self.size
12 cell_height = self.living_space[3]//self.size
13 cell_x = self.living_space[0]//self.size
14 cell_y = self.living_space[1]//self.size
15 #while循环用作检测食物坐标是否存在于贪吃蛇身体坐标集中
16 while True:
17 x = randint(cell_x + 1,cell_x + cell_width - 1)
18 y = randint(cell_y + 1,cell_y + cell_height - 1)
19 self._food_pos = [[x,y]]
20 if self._food_pos[0] not in snakebody:
21 break
22 #判断食物是否被贪吃蛇吃掉,以此来重新生成食物坐标
23 def if_exist(self,exist,snakebody):
24 if exist == 'be eaten':
25 del self._food_pos[0]
26 self.generate(snakebody)
27 #print('rebuild food!')
28 #在窗体中画出食物
29 def draw(self,surface):
30 x = self._food_pos[0][0]*self.size
31 y = self._food_pos[0][1]*self.size
32 food_Rect = pygame.Rect(x,y,self.size,self.size)
33 pygame.draw.rect(surface,self.color,food_Rect)
看看代码的执行效果:
贪吃蛇是游戏的主体,是玩家参与游戏的媒介,玩家通过键盘的“”上下左右“控制贪吃蛇的前进方向,以此控制贪吃蛇吃到食物获得成长。贪吃蛇对象有四个主要属性:颜色、身体长度、体型和生存空间;此外,判断贪吃蛇是否吃到食物时还须传入食物坐标作为参数。
1 #定义贪吃蛇的类模板
2 class Snake(object):
3
4 #实例化的对象属性创建,定义实例化对象时传入的参数
5 def __init__(self,color,length,size,living_space):
6 self.color = color
7 self.length = length
8 self.size = size
9 self.living_space = living_space
10 #生成游戏开始时贪吃蛇的初始坐标
11 def generate(self):
12 init_x = self.living_space[0]
13 init_y = self.living_space[1] + self.living_space[3] - self.size
14 self.snake_body = [[x*self.size+init_x,init_y] for x in range(self.length)]
15 #监测键盘产生的事件,根据不同事件改变贪吃蛇的前进方向
16 def move(self,DIRECTION,foodbody):
17 self.foodstate = 'not be eaten'
18 #print('before mvoe:',self.snake_body)
19 if DIRECTION=='LEFT': self.snake_body.append([self.snake_body[len(self.snake_body)-1][0] - self.size,self.snake_body[len(self.snake_body)-1][1]])
20 if self.eatfood(foodbody):
21 self.foodstate = 'be eaten'
22 else:
23 del self.snake_body[0]
24 elif DIRECTION=='RIGHT': self.snake_body.append([self.snake_body[len(self.snake_body)-1][0] + self.size,self.snake_body[len(self.snake_body)-1][1]])
25 if self.eatfood(foodbody):
26 self.foodstate = 'be eaten'
27 else:
28 del self.snake_body[0]
29 elif DIRECTION=='UP': self.snake_body.append([self.snake_body[len(self.snake_body)-1][0],self.snake_body[len(self.snake_body)-1][1] - self.size])
30 if self.eatfood(foodbody):
31 self.foodstate = 'be eaten'
32 else:
33 del self.snake_body[0]
34 elif DIRECTION=='DOWN': self.snake_body.append([self.snake_body[len(self.snake_body)-1][0],self.snake_body[len(self.snake_body)-1][1] + self.size])
35 if self.eatfood(foodbody):
36 self.foodstate = 'be eaten'
37 else:
38 del self.snake_body[0]
39 #print(self.snake_body)
40 #根据贪吃蛇可能死亡的两种情况判断贪吃蛇的存活状态:1、贪吃蛇碰到草地(生存空间)的边缘壁垒;2、贪吃蛇的头部撞到自己的身体
41 def isdead(self):
42 #条件1
43 if (self.snake_body[len(self.snake_body)-1][0] == self.living_space[0] - self.size or self.snake_body[len(self.snake_body)-1][0] == self.living_space[0] + self.living_space[2])\
44 or (self.snake_body[len(self.snake_body)-1][1] == self.living_space[1] - self.size or self.snake_body[len(self.snake_body)-1][1] == self.living_space[1] + self.living_space[3]):
45 #print('die for me 1')
46 return True
47 for bodynet in self.snake_body[:-1]:
48 if bodynet == self.snake_body[len(self.snake_body)-1]:
49 #print('die for me 2')
50 return True
51 #判断贪吃蛇是否满足成长的条件(即身长+1),也就是贪吃蛇是否吃到食物
52 def eatfood(self,foodbody):
53 if foodbody[0][0]*self.size == self.snake_body[len(self.snake_body)-1][0] and foodbody[0][1]*self.size == self.snake_body[len(self.snake_body)-1][1]:
54 #print('eat!')
55 return True
56 else:
57 return False
58 #在窗体中画出贪吃蛇
59 def draw(self,surface,inner_color):
60 for bodynet in self.snake_body:
61 snake_Rect = pygame.Rect(bodynet[0],bodynet[1],self.size,self.size)
62 pygame.draw.rect(surface,self.color,snake_Rect)
63 inner_Rect = pygame.Rect(bodynet[0]+4,bodynet[1]+4,self.size-8,self.size-8)
64 pygame.draw.rect(surface,inner_color,inner_Rect)
运行下代码看看在窗体中生成的贪吃蛇长什么样(贪吃蛇的样子可以通过实例化时传入的属性自行定义):
就此,基于pygame模块的贪吃蛇游戏的三个主要对象均已建立完成,接下来将搭建主体程序来构建一个完整的贪吃蛇游戏。