Python:游戏:贪吃蛇(附源码)
程序员文章站
2022-04-14 21:57:37
贪吃蛇是个非常简单的游戏,适合练手。 首先分析一下这个游戏 1、蛇怎么画? 蛇是由一个个小方块组成的,那么我们可以用一个 list 记录每一个小方块的坐标,显示的时候将所有小方块画出来即可。 2、蛇怎么移动? 第一反应就是想蚯蚓蠕动一样,每一个方块向前移动一格,但这样做很麻烦,仔细想下,其实除了头尾 ......
贪吃蛇是个非常简单的游戏,适合练手。
首先分析一下这个游戏
1、蛇怎么画?
蛇是由一个个小方块组成的,那么我们可以用一个 list 记录每一个小方块的坐标,显示的时候将所有小方块画出来即可。
2、蛇怎么移动?
第一反应就是想蚯蚓蠕动一样,每一个方块向前移动一格,但这样做很麻烦,仔细想下,其实除了头尾,蛇的其他部分根本就没有动过,那就简单了,将下一格的坐标添加到 list 开头,并移除 list 的最后一个元素,就相当于蛇向前移动了一格。
3、如何判定游戏结束?
蛇移动超出了游戏区的范围或者碰到了自己就算输了,超出范围很容易判断,碰到自己也容易,只要判断下一格的坐标是否已经包含在蛇的 list 中就可以了。
理清了这些问题,我们就可以开始编码了。
先看一下我的游戏截图
本例中,回车键:开始游戏,空格键:暂停 / 继续,方向键 或 wsad 键:控制移动方向。
每吃一个食物加10分,每增加100分速度加快一级,没有设置关卡,我玩到1100分,速度太快了,然后就 game over 了
"""贪吃蛇""" import random import sys import time import pygame from pygame.locals import * from collections import deque screen_width = 600 screen_height = 480 size = 20 def print_text(screen, font, x, y, text, fcolor=(255, 255, 255)): imgtext = font.render(text, true, fcolor) screen.blit(imgtext, (x, y)) def main(): pygame.init() screen = pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption('贪吃蛇') light = (100, 100, 100) # 蛇的颜色 dark = (200, 200, 200) # 食物颜色 font1 = pygame.font.sysfont('simhei', 24) # 得分的字体 font2 = pygame.font.font(none, 72) # game over 的字体 red = (200, 30, 30) # game over 的字体颜色 fwidth, fheight = font2.size('game over') line_width = 1 # 网格线宽度 black = (0, 0, 0) # 网格线颜色 bgcolor = (40, 40, 60) # 背景色 # 方向,起始向右 pos_x = 1 pos_y = 0 # 如果蛇正在向右移动,那么快速点击向下向左,由于程序刷新没那么快,向下事件会被向左覆盖掉,导致蛇后退,直接game over # b 变量就是用于防止这种情况的发生 b = true # 范围 scope_x = (0, screen_width // size - 1) scope_y = (2, screen_height // size - 1) # 蛇 snake = deque() # 食物 food_x = 0 food_y = 0 # 初始化蛇 def _init_snake(): nonlocal snake snake.clear() snake.append((2, scope_y[0])) snake.append((1, scope_y[0])) snake.append((0, scope_y[0])) # 食物 def _create_food(): nonlocal food_x, food_y food_x = random.randint(scope_x[0], scope_x[1]) food_y = random.randint(scope_y[0], scope_y[1]) while (food_x, food_y) in snake: # 为了防止食物出到蛇身上 food_x = random.randint(scope_x[0], scope_x[1]) food_y = random.randint(scope_y[0], scope_y[1]) _init_snake() _create_food() game_over = true start = false # 是否开始,当start = true,game_over = true 时,才显示 game over score = 0 # 得分 orispeed = 0.5 # 原始速度 speed = orispeed last_move_time = none pause = false # 暂停 while true: for event in pygame.event.get(): if event.type == quit: sys.exit() elif event.type == keydown: if event.key == k_return: if game_over: start = true game_over = false b = true _init_snake() _create_food() pos_x = 1 pos_y = 0 # 得分 score = 0 last_move_time = time.time() elif event.key == k_space: if not game_over: pause = not pause elif event.key in (k_w, k_up): # 这个判断是为了防止蛇向上移时按了向下键,导致直接 game over if b and not pos_y: pos_x = 0 pos_y = -1 b = false elif event.key in (k_s, k_down): if b and not pos_y: pos_x = 0 pos_y = 1 b = false elif event.key in (k_a, k_left): if b and not pos_x: pos_x = -1 pos_y = 0 b = false elif event.key in (k_d, k_right): if b and not pos_x: pos_x = 1 pos_y = 0 b = false # 填充背景色 screen.fill(bgcolor) # 画网格线 竖线 for x in range(size, screen_width, size): pygame.draw.line(screen, black, (x, scope_y[0] * size), (x, screen_height), line_width) # 画网格线 横线 for y in range(scope_y[0] * size, screen_height, size): pygame.draw.line(screen, black, (0, y), (screen_width, y), line_width) if game_over: if start: print_text(screen, font2, (screen_width - fwidth)//2, (screen_height - fheight)//2, 'game over', red) else: curtime = time.time() if curtime - last_move_time > speed: if not pause: b = true last_move_time = curtime next_s = (snake[0][0] + pos_x, snake[0][1] + pos_y) if next_s[0] == food_x and next_s[1] == food_y: # 吃到了食物 _create_food() snake.appendleft(next_s) score += 10 speed = orispeed - 0.03 * (score // 100) else: if scope_x[0] <= next_s[0] <= scope_x[1] and scope_y[0] <= next_s[1] <= scope_y[1] \ and next_s not in snake: snake.appendleft(next_s) snake.pop() else: game_over = true # 画食物 if not game_over: # 避免 game over 的时候把 game over 的字给遮住了 pygame.draw.rect(screen, light, (food_x * size, food_y * size, size, size), 0) # 画蛇 for s in snake: pygame.draw.rect(screen, dark, (s[0] * size + line_width, s[1] * size + line_width, size - line_width * 2, size - line_width * 2), 0) print_text(screen, font1, 30, 7, f'速度: {score//100}') print_text(screen, font1, 450, 7, f'得分: {score}') pygame.display.update() if __name__ == '__main__': main()
上一篇: 重学C语言之结构体
下一篇: P1199 三国游戏 题解