创建真正的游戏
上一篇博客介绍了如何通过“上下左右”四个按键做到玩家与游戏的交互,今天将开始创建贪吃蛇游戏的三个主要对象:草地、食物、贪吃蛇。
草地就是贪吃蛇和食物所能存在的空间范围,它有两个主要属性——颜色、面积。我会根据这两个属性定义一个草地的类:
1 #定义草地的类模板 2 class GrassMap(object): 3 #定义对象属性,实例对象时自动创建 4 def __init__(self,color,living_space): 5 self.living_space = living_space 6 self.color = color 7 #在窗口中生成草地对象 8 def generate(self): 9 screen.fill(self.color,self.living_space) 10 #简单测试——在窗体中画出定义的草地对象 11 if __name__ == '__main__' : 12 import pygame 13 pygame.init() #初始化pygame模块 14 screen = pygame.display.set_mode((640,480),0,32) #创建一个窗体 15 pygame.display.set_caption("测试草地对象") #创建一个标题 16 grassmap = GrassMap((0,250,0),(60,60,520,350)) #实例一个草地对象 17 grassmap.generate() #在窗体中生成草地对象(转换为为pygame中的surface对象) 18 pygame.display.update() #刷新生成的草地对象到窗体中
运行代码,看看在窗体中生成的草地:
食物是贪吃蛇的目标,是贪吃蛇成长的唯一条件,当食物被贪吃蛇吃掉后,会有新的食物在草地中随机生成。食物有三个主要属性:颜色、体型、生成空间;此外,生成食物坐标时还需要传入一个贪吃蛇身体的坐标集做参数。
1 #定义贪吃蛇的食物的类模板 2 class Food(object): 3 #实例化的对象属性创建,定义实例化对象时传入的参数 4 def __init__(self,color,size,living_space): 5 self.color = color 6 self.size = size 7 self.living_space = living_space 8 #随机生成游戏开始时食物的初始坐标 9 def generate(self,snakebody): 10 #while循环用作检测食物坐标是否存在于贪吃蛇身体坐标集中 11 while True: 12 x = randint(self.living_space[0],self.living_space[2]-self.size) 13 y = randint(self.living_space[1],self.living_space[3]-self.size) 14 self._food_pos = [x,y] 15 if self._food_pos not in snakebody: 16 break 17 #print(self._food_pos) 18 #判断食物是否被贪吃蛇吃掉,以此来重新生成食物坐标 19 def if_exist(self,exist): 20 if exist: 21 self.generate() 22 else: 23 pass 24 #在窗体中画出食物 25 def draw(self,surface): 26 pygame.draw.circle(surface,self.color,self._food_pos,self.size) 27 28 #简单测试——在窗体中画出定义的食物对象 29 if __name__ == '__main__': 30 from random import randint 31 import pygame 32 pygame.init() 33 screen = pygame.display.set_mode((640,480),0,32) 34 pygame.display.set_caption("测试食物对象") 35 food = Food((255,0,0),10,(60,60,520,350)) 36 food.generate([[60,60],[70,70]]) 37 #food.if_exist(True) 38 food.draw(screen) 39 pygame.display.update()
看看代码的执行效果:
贪吃蛇是游戏的主体,是玩家参与游戏的媒介,玩家通过键盘的“”上下左右“控制贪吃蛇的前进方向,以此控制贪吃蛇吃到食物获得成长。贪吃蛇对象有四个主要属性:颜色、身体长度、体型和生存空间;此外,判断贪吃蛇是否吃到食物时还须传入食物坐标作为参数。
1 #定义贪吃蛇的类模板 2 class Snake(object): 3 #实例化的对象属性创建,定义实例化对象时传入的参数 4 def __init__(self,color,length,size,living_space): 5 self.color = color 6 self.length = length 7 self.size = size 8 self.living_space = living_space 9 #随机生成游戏开始时贪吃蛇的初始坐标 10 def generate(self): 11 x = randint(self.living_space[0],self.living_space[2]-self.size) 12 y = randint(self.living_space[1],self.living_space[3]-self.size) 13 init_pos = [x,y] 14 self.snake_body = [[x*self.size+init_pos[0],init_pos[1]] for x in range(self.length)] 15 self.head = len(self.snake_body) - 1 16 self.tail = 0 17 #监测键盘产生的事件,根据不同事件改变贪吃蛇的前进方向 18 def move(self): 19 direction = 'RIGHT' 20 pressed_keys = pygame.key.get_pressed() 21 if pressed_keys[K_LEFT] and not direction == 'RIGHT': 22 self.snake_body.append([self.snake_body[self.head][0] - 1,self.snake_body[self.head][1]]) 23 del self.snake_body[self.tail] 24 directino = 'LEFT' 25 elif pressed_keys[K_RIGHT] and not direction == 'LEFT': 26 self.snake_body.append([self.snake_body[self.head][0] + 1,self.snake_body[self.head][1]]) 27 del self.snake_body[self.tail] 28 direction = 'RIGHT' 29 elif pressed_keys[K_UP] and not direction == 'DOWN': 30 self.snake_body.append([self.snake_body[self.head][0],self.snake_body[self.head][1] - 1]) 31 del self.snake_body[self.tail] 32 diretion = 'UP' 33 elif pressed_keys[K_DOWN] and not direction == 'UP': 34 self.snake_body.append([self.snake_body[self.head][0],self.snake_body[self.head][1] + 1]) 35 del self.snake_body[self.tail] 36 diretion = 'DOWN' 37 else: 38 pygame.event.set_block(KEYDOWN) 39 self.snake_body.append([self.snake_body[self.head][0] + 1,self.snake_body[self.head][1]]) 40 del self.snake_body[self.tail] 41 #根据贪吃蛇可能死亡的两种情况判断贪吃蛇的存活状态:1、贪吃蛇碰到草地(生存空间)的边缘壁垒;2、贪吃蛇的头部撞到自己的身体 42 def isalive(self): 43 #条件1 44 if (self.snake_body[self.head][0] > self.living_space[0] and self.snake_body[self.head][2] < self.living_space[0]-self.size)\ 45 or (self.snake_body[self.head][1] > self.living_space[1] and self.snake_body[self.head][3] < self.living_space[0]-self.size): 46 return True 47 #条件2 48 count = 0 49 for bodynet in self.snake_body: 50 count += self.snake_body.count(bodynet) 51 if count > len(self.snake_body): 52 return True 53 #判断贪吃蛇是否满足成长的条件(即身长+1),也就是贪吃蛇是否吃到食物 54 def eatfood(self,foodbody): 55 if foodbody == self.snake_body[self.head]: 56 self.snakebody.insert(0,[self.snake_body[self.tail][0],self.snake_body[self.tail][1]-1]) 57 return True 58 #在窗体中画出贪吃蛇 59 def draw(self,surface,inner_color): 60 for bodynet in self.snake_body: 61 #print(bodynet) 62 snake_cell = pygame.Rect(bodynet[0],bodynet[1],self.size,self.size) 63 pygame.draw.rect(surface,self.color,snake_cell) 64 inner_cell = pygame.Rect(bodynet[0]+4,bodynet[1]+4,self.size-8,self.size-8) 65 pygame.draw.rect(surface,inner_color,inner_cell) 66 67 #简单测试——在窗体中画出定义的贪吃蛇对象 68 if __name__ == '__main__': 69 import pygame 70 from random import randint 71 pygame.init() 72 screen = pygame.display.set_mode((640,480),0,32) 73 pygame.display.set_caption("测试贪吃蛇对象") 74 snake = Snake((100,100,0),4,20,(60,60,520,350)) 75 snake.generate() 76 snake.draw(screen,(250,250,0)) 77 pygame.display.update()
运行下代码看看在窗体中生成的贪吃蛇长什么样(贪吃蛇的样子可以通过实例化时传入的属性自行定义):
就此,基于pygame模块的贪吃蛇游戏的三个主要对象均已建立完成,接下来将搭建主体程序来构建一个完整的贪吃蛇游戏。