用pygame写个简单的贪吃蛇游戏
来源:互联网 发布:mac打印jpeg 编辑:程序博客网 时间:2024/04/27 15:12
编写游戏无疑是理解面向对象最有效的方法,在学习python面向对象部分的过程中,我尝试写了如下一个简单的贪吃蛇小游戏,作为理解面向对象、事件触发机制、pygame模块的一个途径。OK,废话少说,上代码。
首先介绍页面布局,为了美观,我们把每块蛇的身体定义为14x14像素的矩形,实物为直径14像素的圆。为什么采用14像素这个值呢?因为在身体大小合适的15像素附近,不想用一个奇数导致确定圆心的过程中会有浮点数产生,增加额外的内存消耗。当然您也可以使用16像素balablabla。游戏标题为“Greedy Snake”,窗口大小采用560x560像素,560/14=40,故横向纵向分别可以产生40个贪吃蛇的身体长度。
定义Snake类,包含初始化蛇的位置和蛇移动的初始方向。用一个嵌套列表来存储蛇的身体的位置,初始蛇向右移动,使用复制身体位置的方式移动蛇。
class Snake(object): """This is the snake class, including the initializing, body, eat food, and direction to move.""" def __init__(self): """Using the random module to create a initial snake. The snake has three parts: a head, a body, and a tail.""" self.pos_list = [[42, 42]] self.direction = 'R' def posList(self): "Return all the points of the snake." return self.pos_list def changeDirection(self, direction): "Change the direction of the snake." self.direction = direction def moveDirection(self): "Change the points to keep the snake moving in the given direction." body_length = len(self.pos_list) - 1 while body_length > 0: self.pos_list[body_length] = deepcopy(self.pos_list[body_length - 1]) body_length -= 1 if self.direction == 'R': self.pos_list[0][0] += 14 elif self.direction == 'L': self.pos_list[0][0] -= 14 elif self.direction == 'U': self.pos_list[0][1] -= 14 elif self.direction == 'D': self.pos_list[0][1] += 14 def eatFood(self, foodPoint): "The snake eats a point and add the point to its body." self.pos_list.insert(0, foodPoint)
然后,是食物这个类。类中包含对于食物坐标的初始值,和更新食物坐标的方法。
class Food(object): """Initialize the random coordinate of the food and return it.""" def __init__(self): x = randint(5, 35) * 14 y = randint(5, 35) * 14 self.food_position = [x, y] def foodList(self): "Return the coordinate of the food point." return self.food_position def updateFood(self): "When the food is eaten, update the position of the food." self.food_position[0] = randint(0, 39) * 14 self.food_position[1] = randint(0, 39) * 14
接下来,定义一个贪吃蛇的函数,在这个函数中编写贪吃蛇移动的逻辑,更新食物坐标,判断蛇是否吃到了食物、是否撞到了墙上。逻辑上,如前所述,窗口大小采用560x560,使用时钟控制每秒钟的画面不超过20帧从而控制游戏的画面感,屏幕底色为白色,食物和蛇均为红色,当贪吃蛇撞到墙或者撞到自身时,绘制一幅底色为褐色、字体为红色的“Game Over!”图案,并等待退出事件,关闭窗口。
def snakeMain(): "The logic to run the game." pygame.init() screen = pygame.display.set_mode((560, 560), 0, 32) pygame.display.set_caption("Greedy Snake") clock = pygame.time.Clock() snake = Snake() food = Food() direction_flag = 'R' while True: screen.fill((255, 255, 255)) for event in pygame.event.get(): if event.type == QUIT: exit() if event.type == KEYDOWN: if event.key == K_RIGHT: direction_flag = 'R' elif event.key == K_LEFT: direction_flag = 'L' elif event.key == K_UP: direction_flag = 'U' elif event.key == K_DOWN: direction_flag = 'D' # Draw the food and the snake food_position = deepcopy(food.foodList()) food_position[0] += 7 food_position[1] += 7 pygame.draw.circle(screen, (255, 0, 0), food_position, 10) snake_position = snake.posList() for pos in snake_position: temp_rect = pygame.Rect(pos[0], pos[1], 14, 14) pygame.draw.rect(screen, (255, 0, 0), temp_rect) pygame.display.update() # 20 frame of pictures per second # and move the snake frame_rate = clock.tick(20) snake.changeDirection(direction_flag) snake.moveDirection() #Judge whether the snake eats a food or not food_position = deepcopy(food.foodList()) snake_head = deepcopy(snake.posList()[0]) if direction_flag == 'R': snake_head[0] += 14 elif direction_flag == 'L': snake_head[0] -= 14 elif direction_flag == 'U': snake_head[1] -= 14 elif direction_flag == 'D': snake_head[1] += 14 if snake_head == food_position: snake.eatFood(food_position) food.updateFood() # Judge whether the snake gets a collision or not gameover_flag = False snake_position = snake.posList() snake_head = snake_position[0] if direction_flag == 'R': if snake_head[0] > 546: gameover_flag = True elif direction_flag == 'L': if snake_head[0] < 0: gameover_flag = True elif direction_flag == 'U': if snake_head[1] < 0: gameover_flag = True elif direction_flag == 'D': if snake_head[1] > 546: gameover_flag = True for pos in range(1, len(snake_position) - 1): if snake_head == snake_position[pos]: gameover_flag = True if gameover_flag: pygame.font.init() screen.fill((100, 0, 0)) font = pygame.font.SysFont("arial", 32) text = font.render("Game Over!", True, (255, 0, 0)) screen.blit(text, (260, 260)) pygame.display.update() while True: again_event = pygame.event.poll() if again_event.type == QUIT: exit()
最后,判断是否在当前命名空间中执行该主体函数,如果是,则执行贪吃蛇游戏。
if __name__ == '__main__': snakeMain()
总体来说,这是一个非常简单的贪吃蛇版本,逻辑上还需要继续完善,bug还需要修复。在接下来的修改过程中,我会将它转变成1个像素1个像素之间的移动,而不再将窗口分割成多个矩形,这样可以增加蛇移动的流畅度。另一方面,方向移动方面,向前移动不会再接受向后移动的事件,向左或向右类似,很简单,通过if判断就可以实现。蛇体要采用三幅图像载入,让蛇头、蛇身、蛇尾更美观逼真。加入游戏声音之后,可玩性更强。在标题栏下方增加一个类似扫雷游戏的记分机制,使贪吃蛇能够记录该游戏的得分最高值。
0 0
- 用pygame写个简单的贪吃蛇游戏
- 从头到尾教你写个简单的贪吃蛇游戏
- 用java写的贪吃蛇游戏
- 用java写的贪吃蛇游戏
- python + pygame实现多线程的贪吃蛇游戏
- 用MSC库写贪吃蛇——记我的第一个游戏
- 用Python和Pygame写游戏-从入门到精通(13)简单的AI游戏
- 简单的贪吃蛇游戏
- 以前用java写的贪吃蛇游戏
- 以前用java写的贪吃蛇游戏
- 用java的swing框架自己写贪吃蛇游戏
- 用C语言写贪吃蛇游戏的初探
- java写的简易贪吃蛇游戏
- javascript 写的贪吃蛇游戏
- Python写的贪吃蛇游戏例子
- 《纯C++写的贪吃蛇游戏》
- 写个贪吃蛇
- 贪吃蛇----第一个写出的游戏
- Espresso Logic的DBaas服务将SQL存储过程封装到了RESTful API中
- Java Socket 网络编程常见异常
- 【Content Provider】SQLiteQueryBuilder类
- linux常用命令
- 【Unity3D插件】NGUI屏幕自适应
- 用pygame写个简单的贪吃蛇游戏
- Java第6周实验
- 《算法导论》笔记 第7章 7.4快速排序分析
- 解決在 Xcode 5.1环境下property所造成的 synthesis warning问题?
- debian7.4安装手记
- Berkeley DB数据库和日志文件归档
- Java本地调用JNI使用规范详解
- 终于有点眉目
- 青春--说走就走的旅行