创建真正的游戏
上一篇博客介绍了如何通过“上下左右”四个按键做到玩家与游戏的交互,今天将开始创建贪吃蛇游戏的三个主要对象:草地、食物、贪吃蛇。(代码是新代码,效果图是旧效果图)
草地就是贪吃蛇和食物所能存在的空间范围,它有两个主要属性——颜色、面积。我会根据这两个属性定义一个草地的类:
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模块的贪吃蛇游戏的三个主要对象均已建立完成,接下来将搭建主体程序来构建一个完整的贪吃蛇游戏。