下面是代码分享一下:
空格键停止,回车键开始。
"""贪吃蛇"""
import random
import sys
import time
import copy
import pygame
from pygame.locals import *
from collections import deque
SCREEN_WIDTH = 800 # 屏幕宽度
SCREEN_HEIGHT = 480 # 屏幕高度
SIZE = 20 # 小方格大小
LINE_WIDTH = 3 # 网格线宽度
# 游戏区域的坐标范围
SCOPE_X = (0, SCREEN_WIDTH // SIZE - 1)
SCOPE_Y = (2, SCREEN_HEIGHT // SIZE - 1)
# 食物的分值及颜色
# FOOD_STYLE_LIST = [(10, (255, 100, 100)), (20, (100, 255, 100)), (30, (100, 100, 255))]
FOOD_STYLE_LIST = [(10, (255, 0, 0)), (20, (0, 255, 0)), (30, (0, 0, 255)), (100, (255, 255, 0))]
# 幸运食物出现概率(蛇身减一,速度不增加)
FOOD_LUCK=(0,7)
# LIGHT = (100, 100, 100)
DARK = (200, 200, 200) # 蛇的颜色
BLACK = (0, 0, 0) # 网格线颜色
RED = (200, 30, 30) # 红色,GAME OVER 的字体颜色
BGCOLOR = (40, 40, 60) # 背景色
def print_text(screen, font, x, y, text, fcolor=(255, 255, 255)):imgText = font.render(text, True, fcolor)screen.blit(imgText, (x, y))
# 初始化蛇
def init_snake():snake = deque()snake.append((2, SCOPE_Y[0]))# snake.append((1, SCOPE_Y[0]+1)), snake.append((1, SCOPE_Y[0])), snake.append((1, SCOPE_Y[0]+2))snake.append((1, SCOPE_Y[0]))snake.append((0, SCOPE_Y[0]))return snake
def create_food(snake):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])return food_x, food_y
def get_food_style():if random.randint(FOOD_LUCK[0],FOOD_LUCK[1])==FOOD_LUCK[1]:return FOOD_STYLE_LIST[3]else:return FOOD_STYLE_LIST[random.randint(0, 2)]
def main():pygame.init()screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) #pygame创建窗口pygame.display.set_caption('贪吃蛇') #窗口名称font1 = pygame.font.SysFont('SimHei', 16) # 得分的字体font_ypos = 12 #位置font2 = pygame.font.Font(None, 72) # GAME OVER 的字体fwidth, fheight = font2.size('GAME OVER')# 如果蛇正在向右移动,那么快速点击向下向左,由于程序刷新没那么快,向下事件会被向左覆盖掉,导致蛇后退,直接GAME OVER# b 变量就是用于防止这种情况的发生b = True# 蛇snake = init_snake()# 食物food = create_food(snake)food_style = get_food_style()# 方向pos = (1, 0) #(左-1 右1,上-1 下1)game_over = Truestart = False # 是否开始,当start = True,game_over = True 时,才显示 GAME OVERscore = 0 # 得分orispeed =0.5 # 原始速度speed = orispeedluck_times=0last_move_time = Nonelast_draw_time = Nonepause = False # 暂停BG_r = 40 #手动背景调整BG_g = 40BG_b = 60BG_auto=TrueREC_score=[]REC_save=Falsewhile 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 = Falseb = Truesnake = init_snake()food = create_food(snake)food_style = get_food_style()pos = (1, 0)# 得分score = 0REC_save=TrueREC_score.append(score)last_move_time = time.time()last_draw_time = last_move_timeluck_times = 0elif event.key == K_SPACE: #处理空格键事件 暂停和继续if not game_over:pause = not pauseelif event.key in (K_w, K_UP):# 这个判断是为了防止蛇向上移时按了向下键,导致直接 GAME OVERif b and not pos[1]:pos = (0, -1)b = Falseelif event.key in (K_s, K_DOWN):if b and not pos[1]:pos = (0, 1)b = Falseelif event.key in (K_a, K_LEFT):if b and not pos[0]:pos = (-1, 0)b = Falseelif event.key in (K_d, K_RIGHT):if b and not pos[0]:pos = (1, 0)b = Falseelif event.key in (K_r,K_g,K_b): #背景色调整 L键控制开关(R,G,B)键控制3原色if event.key==K_r:BG_r=BG_r+5if BG_r>=125:BG_r=40elif event.key==K_g:BG_g=BG_g+5if BG_g>=125:BG_g=40elif event.key==K_b:BG_g=BG_b+5if BG_b>=125:BG_b=40elif event.key==K_l:BG_auto=not BG_auto# 填充背景色if BG_auto:screen.fill(BGCOLOR)else:screen.fill((BG_r,BG_g,BG_b))# 画网格线 竖线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 not game_over:curTime = time.time()if curTime - last_move_time > speed: #控制移动速度speed值越小,刷新越快if not pause:b = Truelast_move_time = curTimenext_s = (snake[0][0] + pos[0], snake[0][1] + pos[1]) #按方向读取下一个前进位if next_s == food:# 吃到了食物snake.appendleft(next_s)score += food_style[0]if REC_save: #记录得分REC_score.pop()REC_score.append(score)if food_style[0] == FOOD_STYLE_LIST[3][0] and len(snake) > 3:snake.pop()snake.pop()luck_times+=1else:speed = orispeed - 0.03 * (score // 100-luck_times)food = create_food(snake)food_style = get_food_style()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 的字给遮住了if food_style[0] == FOOD_STYLE_LIST[3][0]:curTime = time.time()if curTime-last_draw_time>0.01: #闪烁时间pygame.draw.rect(screen, food_style[1], (food[0] * SIZE, food[1] * SIZE, SIZE, SIZE), 0)last_draw_time=curTimeelse:pygame.draw.rect(screen, food_style[1], (food[0] * SIZE, food[1] * 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, font_ypos, f'速度: {score//100-luck_times}')print_text(screen, font1, 630, font_ypos, f'得分: {score}')if game_over:if start:print_text(screen, font2, (SCREEN_WIDTH - fwidth) // 2, (SCREEN_HEIGHT - fheight) // 2, 'GAME OVER', RED)TMP_score=copy.deepcopy(REC_score)TMP_score.sort()TMP_score.reverse()if len(REC_score):print_text(screen, font1, 230, font_ypos, f'最高得分: {TMP_score[0]}')print_text(screen, font1, 430, font_ypos, f'当前排名: {TMP_score.index(REC_score[len(REC_score)-1])+1}')else:print_text(screen, font1, 230, font_ypos, f'最高得分: {score}')print_text(screen, font1, 430, font_ypos, f'当前排名: {score}')pygame.display.update()
if __name__ == '__main__':main()
下面是运行效果:
代码可以直接复制
如果有啥问题可以问我看到一定会回复大家,如果大家喜欢可以作者点赞和关注
大家的支持是我创作下去的最大动力