创建真正的游戏


  上一篇博客介绍了如何通过“上下左右”四个按键做到玩家与游戏的交互,今天将开始创建贪吃蛇游戏的三个主要对象:草地、食物、贪吃蛇。(代码是新代码,效果图是旧效果图)

草地就是贪吃蛇和食物所能存在的空间范围,它有两个主要属性——颜色、面积。我会根据这两个属性定义一个草地的类:

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)

 

  运行代码,看看在窗体中生成的草地:

  

greenhills hex文件_greenhills hex文件

    食物是贪吃蛇的目标,是贪吃蛇成长的唯一条件,当食物被贪吃蛇吃掉后,会有新的食物在草地中随机生成。食物有三个主要属性:颜色、体型、生成空间;此外,生成食物坐标时还需要传入一个贪吃蛇身体的坐标集做参数。   

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)

  看看代码的执行效果:

  

greenhills hex文件_贪吃蛇_02

  贪吃蛇是游戏的主体,是玩家参与游戏的媒介,玩家通过键盘的“”上下左右“控制贪吃蛇的前进方向,以此控制贪吃蛇吃到食物获得成长。贪吃蛇对象有四个主要属性:颜色、身体长度、体型和生存空间;此外,判断贪吃蛇是否吃到食物时还须传入食物坐标作为参数。

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)

  运行下代码看看在窗体中生成的贪吃蛇长什么样(贪吃蛇的样子可以通过实例化时传入的属性自行定义):

  

greenhills hex文件_类模板_03

  就此,基于pygame模块的贪吃蛇游戏的三个主要对象均已建立完成,接下来将搭建主体程序来构建一个完整的贪吃蛇游戏。