今天我们用python和python的工具包pygame来编写一个贪吃蛇的小游戏

贪吃蛇游戏功能介绍

贪吃蛇的游戏规则如下:

通过上下左右键或者WASD键来移动蛇来,让它吃到食物,每吃到食物,蛇的长度变长,并获得分数。若蛇碰到游戏边际

或者自身,则蛇死亡,游戏结束。

游戏设计思路

根据游戏规则,我们需要:

1.初始化游戏环境。

2.初始化蛇、食物

3.监听键盘动作

4.蛇的运动,吃食物,是否死亡

5.该局游戏结束,是否还有再玩。

其中的难点在于如何在屏幕上展示蛇的运动,其实我们肉眼所见的蛇的运动并不是真实的,而是在后台通过刷新蛇的坐标而实现的。即可以创建一个蛇的坐标列表,每移动一次,则新的坐标加入,同时删除末尾坐标,看起来像是蛇的在移动。

一个简单地设计框图如下:

代码实现

'''
my_snake.py
@author HelloWorld!
@time:2019.10.27'''import random
import pygame
import sys
from pygame.locals import *windows_width=800 #游戏窗口的大小,原点在左上角
windows_height=600cell_size=20  #snake 的大小,需被窗口长宽整除#一些颜色定义
white = (255, 255, 255)
black = (0, 0, 0)
gray = (230, 230, 230)
dark_gray = (40, 40, 40)
DARKGreen = (0, 155, 0)
Green = (0, 255, 0)
Red = (255, 0, 0)
blue = (0, 0, 255)
dark_blue =(0,0, 139)BG_COLOR = (184,224,217)#贪吃蛇的地图尺寸
map_width = int(windows_width / cell_size)
map_height = int(windows_height / cell_size)#蛇的移动速度
snake_speed=5#方向定义
UP = 1
DOWN = 2
LEFT = 3
RIGHT = 4#主函数
def main_game():pygame.init() #初始化gygamescreen=pygame.display.set_mode((windows_width,windows_height))pygame.display.set_caption("贪吃蛇游戏")snake_speed_clock = pygame.time.Clock() # 创建Pygame时钟对象screen.fill(white)while True:run_game(screen,snake_speed_clock) #游戏主体gameover(screen)        #游戏结束def run_game(screen,snake_speed_clock):#初始化蛇的位置,方向,食物的位置start_x=random.randint(3,map_width-8)start_y=random.randint(3,map_width-8)snake_coords=[{'x':start_x,'y':start_y},{'x':start_x-1,'y':start_y},{'x':start_x-2,'y':start_y}]#初始化snake,也可以用列表的的列表direction = RIGHTfood=get_random_location()#循环while True:for event in pygame.event.get(): #键盘事件监听if event.type == pygame.QUIT:pygame.quit()sys.exit()elif event.type == pygame.KEYDOWN: #按键事件if (event.key==K_LEFT or event.key==K_a) and direction!=RIGHT:direction=LEFTelif (event.key==K_RIGHT or event.key==K_d) and direction!=LEFT:direction=RIGHTelif (event.key == K_UP or event.key == K_w) and direction != DOWN:direction = UPelif (event.key == K_DOWN or event.key == K_s) and direction != UP:direction = DOWNelif event.key == K_ESCAPE:pygame.quit()sys.exit()snake_move(direction,snake_coords) #根据方向,移动蛇alive=snake_is_alive(snake_coords)  #判断蛇的死活if not alive:            #如果挂了,则终止循环,跳出run_game函数,执行gameoverbreaksnake_eat_foods(snake_coords,food)  #没挂,则看看迟到食物了吗screen.fill(BG_COLOR)        #游戏背景刷新#下面draw,是把蛇食物等画出来draw_snake(screen, snake_coords)draw_food(screen,food)draw_score(screen, len(snake_coords) - 3)# draw_grid(screen)pygame.display.flip()#控制执行次数snake_speed_clock.tick(snake_speed) # 控制fps#根据移动方向,更新蛇头坐标
def snake_move(directtion,snake_coords):if directtion==UP:newHead={'x':snake_coords[0]['x'],'y':snake_coords[0]['y']-1}elif directtion==DOWN:newHead = {'x': snake_coords[0]['x'], 'y': snake_coords[0]['y'] + 1}elif directtion==LEFT:newHead = {'x': snake_coords[0]['x']-1, 'y': snake_coords[0]['y'] }elif directtion == RIGHT:newHead = {'x': snake_coords[0]['x']+1, 'y': snake_coords[0]['y']}snake_coords.insert(0,newHead)def snake_is_alive(snake_coords): #碰壁或者碰到自身就是死了alive=Trueif snake_coords[0]['x'] == -1 or snake_coords[0]['x'] == map_width or snake_coords[0]['y'] == -1 or snake_coords[0]['y'] == map_height:alive=Falsefor snake_body in snake_coords[1:]:if snake_coords[0]['x']==snake_body['x'] and snake_coords[0]['y']==snake_body['y']:alive=Falsereturn alive#坐标重合,表示吃到食物了,否则就没有,则移动,把
def snake_eat_foods(snake_coords,food):if snake_coords[0]['x']==food['x'] and snake_coords[0]['y']==food['y']:food['x']=random.randint(0, map_width-1)food['y']=random.randint(0, map_height-1)else:del snake_coords[-1]def get_random_location(): #食物的坐标随机生成return {'x':random.randint(0,map_width-1),'y':random.randint(0,map_height-1)}def draw_snake(screen, snake_coords):for coord in snake_coords:x=coord['x']*cell_sizey=coord['y']*cell_sizesegmentRect=pygame.Rect(x,y,cell_size,cell_size)pygame.draw.rect(screen,dark_blue,segmentRect)def draw_food(screen,food):x=food['x']*cell_sizey=food['y']*cell_sizefoodRect=pygame.Rect(x,y,cell_size,cell_size)pygame.draw.rect(screen,Red,foodRect)def draw_grid(screen):for x in range(0,windows_width,cell_size):pygame.draw.line(screen,gray,(x,0),(x,windows_height))for y in range(0,windows_height,cell_size):pygame.draw.line(screen,gray,(0,y),(windows_width,y))
def draw_score(screen, score):font = pygame.font.SysFont(None, 40)score_str = "{:,}".format(score)score_image=font.render('Score: '+score_str,True,Green,gray)score_rect=score_image.get_rect()score_rect.topleft=(windows_width-200,10)screen.blit(score_image, score_rect)def gameover(screen):font=pygame.font.SysFont(None, 40)tips=font.render('Press Q or ESC to quit; Press anykey to continue',True, (65, 105, 225))screen.blit(tips,(80, 300))pygame.display.update()while True:for event in pygame.event.get():if event.type==QUIT:pygame.quit()sys.exit()elif event.type == KEYDOWN:if event.key == K_ESCAPE or event.key == K_q: # 终止程序pygame.quit()sys.exit() # 终止程序else:return # 结束此函数, 重新开始游戏if __name__=='__main__':main_game()

功能抽象及多彩化设计

上面的实现中,我们采用的面向过程的实现方法,没有抽象,如果要设计更大的游戏则是不行的。我们可以采用抽象的方法,让实现更加条理化,同时逻辑更清晰。

同时,如果让食物的颜色不同,同时蛇吃到什么颜色的食物,那么它身体的一部分就变成相应的颜色,那么最终蛇会变成一条多彩蛇,想必很有意思。

下面我们结合上述两点来实现新的功能。代码如下:

'''
@colorful_snake.py
@author HelloWorld!
@time:2019.10.27
@ class is used to design a snake game
'''
import random
import pygame
from pygame.locals import *
import sys
class Settings():def __init__(self):self.windows_width=800 #游戏窗口的大小,原点在左上角self.windows_height=600self.BG_COLOR = (184,224,217)self.cell_size=20  #snake 的大小,需被窗口长宽整除self.map_width = int(self.windows_width / self.cell_size)self.map_height = int(self.windows_height / self.cell_size)self.Green = (0, 255, 0)self.Red = (255, 0, 0)self.Blue = (0, 0, 255)self.orange=(255,128,0)self.purple=(128, 0, 255)self.black = (0, 0, 0)self.white = (255, 255, 255)self.dark_blue = (0, 0, 139)self.gray = (230, 230, 230)#方向self.UP = 1self.DOWN = 2self.LEFT = 3self.RIGHT = 4
class Snake():def __init__(self,settings):self.cell_size=settings.cell_sizeself.snake_coords=[]self.direction=settings.RIGHTself.snake_speed=5self.initialize_snake(settings)def initialize_snake(self,settings):# [{'x':start_x,'y':start_y},{'x':start_x-1,'y':start_y},{'x':start_x-2,'y':start_y}]#初始化snake,也可以用列表的的列表start_x = random.randint(3, settings.map_width - 8)start_y = random.randint(3, settings.map_width - 8)snake_coords = [{'x': start_x, 'y': start_y,'color':settings.dark_blue}, {'x': start_x - 1, 'y': start_y,'color':settings.dark_blue},{'x': start_x - 2, 'y': start_y,'color':settings.dark_blue}] # 初始化snake,也可以用列表的的列表self.snake_coords=snake_coordsdef snake_move(self,settings):if self.direction == settings.UP:newHead = {'x': self.snake_coords[0]['x'], 'y': self.snake_coords[0]['y'] - 1,'color':settings.dark_blue}elif self.direction == settings.DOWN:newHead = {'x': self.snake_coords[0]['x'], 'y': self.snake_coords[0]['y'] + 1,'color':settings.dark_blue}elif self.direction == settings.LEFT:newHead = {'x': self.snake_coords[0]['x'] - 1, 'y': self.snake_coords[0]['y'],'color':settings.dark_blue}elif self.direction == settings.RIGHT:newHead = {'x': self.snake_coords[0]['x'] + 1, 'y': self.snake_coords[0]['y'],'color':settings.dark_blue}self.snake_coords.insert(0, newHead)def snake_is_alive(self,settings):# 碰壁或者碰到自身就是死了alive = Trueif self.snake_coords[0]['x'] == -1 or self.snake_coords[0]['x'] == settings.map_width or self.snake_coords[0]['y'] == -1 or self.snake_coords[0]['y'] ==settings.map_height:alive = Falsefor snake_body in self.snake_coords[1:]:if self.snake_coords[0]['x'] == snake_body['x'] and self.snake_coords[0]['y'] == snake_body['y']:alive = Falsereturn alive
class Food():def __init__(self,settings):self.cell_size=settings.cell_sizeself.color=self.initialize_food(settings)self.x= random.randint(0, settings.map_width - 1)self.y= random.randint(0, settings.map_height - 1)def initialize_food(self,settings):colors=[settings.Green,settings.Red,settings.Blue,settings.orange,settings.purple,settings.black]color=random.choice(colors)return color
class GameFunction():def __init__(self,screen):self.screen=screendef check_event(self,snake,settings):for event in pygame.event.get(): #键盘事件监听if event.type == pygame.QUIT:pygame.quit()sys.exit()elif event.type == pygame.KEYDOWN: #按键事件if (event.key==K_LEFT or event.key==K_a) and snake.direction!=settings.RIGHT:snake.direction=settings.LEFTelif (event.key==K_RIGHT or event.key==K_d) and snake.direction!=settings.LEFT:snake.direction=settings.RIGHTelif (event.key == K_UP or event.key == K_w) and snake.direction != settings.DOWN:snake.direction = settings.UPelif (event.key == K_DOWN or event.key == K_s) and snake.direction != settings.UP:snake.direction = settings.DOWNelif event.key == K_ESCAPE:pygame.quit()sys.exit()def snake_eat_foods(self,snake,food,settings):if snake.snake_coords[0]['x'] == food.x and snake.snake_coords[0]['y'] == food.y:snake.snake_coords[0]['color'] = food.colorfood.x = random.randint(0, settings.map_width - 1)food.y = random.randint(0, settings.map_height - 1)food.color=food.initialize_food(settings)else:for i in range(len(snake.snake_coords)-1):snake.snake_coords[i]['color']=snake.snake_coords[i+1]['color']del snake.snake_coords[-1]def update(self,snake,food,settings,screen,snake_speed_clock):screen.fill(settings.BG_COLOR) # 游戏背景刷新# 下面draw,是把蛇食物等画出来self.draw_snake(screen, snake)self.draw_food(screen, food)self.draw_score(screen,snake,settings)self.draw_grid(screen,settings)pygame.display.flip()# 控制执行次数snake_speed_clock.tick(snake.snake_speed) # 控制fpsdef draw_snake(self,screen,snake):for coord in snake.snake_coords:x = coord['x'] * snake.cell_sizey = coord['y'] * snake.cell_sizesegmentRect = pygame.Rect(x, y, snake.cell_size, snake.cell_size)pygame.draw.rect(screen, coord['color'], segmentRect)def draw_food(self,screen, food):x = food.x* food.cell_sizey = food.y * food.cell_sizefoodRect = pygame.Rect(x, y, food.cell_size, food.cell_size)pygame.draw.rect(screen, food.color, foodRect)def draw_grid(self,screen,settings):for x in range(0, settings.windows_width, settings.cell_size):pygame.draw.line(screen, settings.gray, (x, 0), (x, settings.windows_height))for y in range(0, settings.windows_height,settings.cell_size):pygame.draw.line(screen, settings.gray, (0, y), (settings.windows_width, y))def draw_score(self,screen, snake,settings):score=len(snake.snake_coords)-3font = pygame.font.SysFont(None, 40)score_str = "{:,}".format(score)score_image = font.render('Score: ' + score_str, True, settings.Green, settings.gray)score_rect = score_image.get_rect()score_rect.topleft = (settings.windows_width - 200, 10)screen.blit(score_image, score_rect)def gameover(self,screen):font = pygame.font.SysFont(None, 40)tips = font.render('Press Q or ESC to quit; Press anykey to continue', True, (65, 105, 225))screen.blit(tips, (80, 300))pygame.display.update()while True:for event in pygame.event.get():if event.type == QUIT:pygame.quit()sys.exit()elif event.type == KEYDOWN:if event.key == K_ESCAPE or event.key == K_q: # 终止程序pygame.quit()sys.exit() # 终止程序else:return # 结束此函数, 重新开始游戏
#主函数
def main_game():pygame.init() #初始化gygamesettings=Settings()screen=pygame.display.set_mode((settings.windows_width,settings.windows_height))pygame.display.set_caption("贪吃蛇游戏")snake_speed_clock = pygame.time.Clock() # 创建Pygame时钟对象screen.fill(settings.white)gf=GameFunction(screen)while True:snake = Snake(settings)food = Food(settings)while True:gf.check_event(snake,settings)snake.snake_move(settings)alive = snake.snake_is_alive(settings) # 判断蛇的死活if not alive: # 如果挂了,则终止循环,跳出run_game函数,执行gameoverbreakgf.snake_eat_foods(snake,food,settings)gf.update(snake,food,settings,screen,snake_speed_clock)gf.gameover(screen)        #游戏结束
if __name__=='__main__':main_game()

程序效果如下:

总结

1、通过上述的代码,功能基本实现

2、多彩版的蛇的色彩太鲜艳,看起来太难受了

3、多彩版的在运行中存在不稳定情况,具体原因还没查看,请大家帮忙指出代码中的问题。

以上所述是小编给大家介绍的python 使用pygame工具包实现贪吃蛇游戏,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

原文链接:https://www.jb51.net/article/173123.htm

jquery实现上下左右键盘监听_python 使用pygame工具包实现贪吃蛇游戏(多彩版)相关推荐

  1. jquery实现上下左右键盘监听_基于 jQuery 实现键盘事件监听控件

    最近项目里要做一个画板,需要对键盘事件进行监听,来进行诸如撤回.重做.移动.缩放等操作,因此顺手实现了一个键盘事件监听控件,期间略有收获,整理出来,希望对大家有所帮助,更希望能获得高手的指点. 1. ...

  2. jquery实现上下左右键盘监听_通过上下左右键和回车键切换光标实现代码

    客户有这样一个需求在列表中的文本框里输入数据时,要能够通过上下左右键来切换光标,按回车键就把光标移到下一个文本框,接下来将为你介绍下如何实现,感兴趣的朋友可以参考下 做项目时,客户提出这样一个要求,在 ...

  3. jquery实现上下左右键盘监听_jQuery监听键盘事件及相关操作使用

    一.首先需要知道的是: 1.keydown() keydown事件会在键盘按下时触发. 2.keyup() keyup事件会在按键释放时触发,也就是你按下键盘起来后的事件 3.keypress() k ...

  4. JAVA飞机移动斜着走_通过键盘的能够使飞机上下左右八个方向移动,现在实现键盘监听时没有反应是怎么回事,哪里出错了?...

    通过键盘的能够使飞机上下左右八个方向移动,现在实现键盘监听时没有反应是怎么回事,哪里出错了? 关注:93  答案:2  mip版 解决时间 2021-01-30 07:58 提问者雨份凉伴 2021- ...

  5. Java实现拼图小游戏(6)—— 移动图片(键盘监听实操练习)

    移动图片 一.前言 二.步骤 1.让我们的类继承KeyListener接口 2.改写initData方法 3.实现向上移动 4.实现向下移动 5.实现向左移动 6.实现向右移动 7.改写initIma ...

  6. java swing button和键盘监听冲突问题

    原因: 点击button会让jframe失去焦点,然后键盘监听不起作用 解决: 让jframe重新获取焦点就行了 jf.setFocusable(true); // JFrame jf = new J ...

  7. qmainwindow键盘监听

    class MyWidget(QtGui.QmainWindow):     keyPressed = QtCore.pyqtSignal() def keyPressEvent(self, even ...

  8. C#全局键盘监听(Hook)的使用(转载)

    一.为什么需要全局键盘监听? 在某些情况下应用程序需要实现快捷键执行特定功能,例如大家熟知的QQ截图功能Ctrl+Alt+A快捷键,只要QQ程序在运行(无论是拥有焦点还是处于后台运行状态),都可以按下 ...

  9. C#全局键盘监听(Hook)

    一.为什么需要全局键盘监听? 在某些情况下应用程序需要实现快捷键执行特定功能,例如大家熟知的QQ截图功能Ctrl+Alt+A快捷键,只要QQ程序在运行(无论是拥有焦点还是处于后台运行状态),都可以按下 ...

最新文章

  1. Nature:要想真正研究宿主-肠道微生物的相互作用,必须将相对定量变成绝对定量...
  2. ​Hmily重启后月度报告
  3. 深度学习背后的数学_深度学习背后的简单数学
  4. ASP.NET MVC下的四种验证编程方式
  5. JQuery 函数 操作
  6. SpringMVC-动力节点-王鹤
  7. OpenCV:图片的几何变换
  8. 常见Linux版本概览
  9. 十三水牌型 图片_十三水三分天下是什么 十三水三分天下牌型详解
  10. silvaco学习日记(四)
  11. 单片机延时程序分析(汇编详细版)
  12. java设计模式--设配器adapter
  13. 零知识证明java实现
  14. SI信号仿真及软件 HyperLynx
  15. 2022淘宝天猫京东双十一交易额有多少?双11交易的数据
  16. Photon Pun
  17. 印象笔记,石墨笔记和Effie哪个更适合学生?
  18. ios -生成推广海报
  19. wkhtmltopdf 字体无效问题
  20. Go 并发 -- 信道

热门文章

  1. Spring Boot 中关于 %2e 的 Trick
  2. 面试 | MySQL InnoDB一棵B+树可以存放多少行数据?
  3. Linux 下 4 种实时监控日志文件的方法,总有一种适合你
  4. 以Dubbo为例,聊聊如何为开源项目做贡献
  5. 一篇文章,带你了解 “机器学习工程师” 必备技能图谱
  6. matlab对比度锐化,对比度、清晰度与锐化的理解
  7. 散列表的设计与实现_python基础之字典与集合实现
  8. 微信小程序开发记录一,开发工具的使用
  9. “sockaddr_in”:“struct”类型重定义
  10. you should specify the `steps` argument