在这篇文章中,我们将使用Python和OpenCV创建贪吃蛇游戏。

1.贪吃蛇游戏

在贪吃蛇游戏中,我们使用箭头键控制数字蛇。

一个苹果随机出现在屏幕上,我们的目标是移动蛇,让它吃苹果。蛇在吃了苹果后会变大,我们的目标是让蛇尽可能长。

然而,如果蛇撞到墙或撞到自己,游戏就结束了。

2.用OpenCV实现贪吃蛇游戏

代码展示

import cv2
import numpy as np
from random import randint
from random import choiceclass SnakePart:def __init__(self, front, x, y):self.front = frontself.x = xself.y = ydef move(self):# 跟随它前面的部分移动self.x = self.front.xself.y = self.front.yclass Head:def __init__(self, direction, x, y):self.direction = directionself.x = xself.y = ydef move(self):# 检查它当前的方向,并相应地移动if self.direction == 0:self.x += 1elif self.direction == 1:self.y += 1elif self.direction == 2:self.x -= 1elif self.direction == 3:self.y -= 1def display():# 创建空白图像board = np.zeros([BOARD_SIZE, BOARD_SIZE, 3])# 把蛇涂成绿色for part in snake:board[part.y, part.x] = [0, 255, 0]# 把苹果涂成红色board[appley, applex] = [0, 0, 255]# 显示屏cv2.imshow("Snake Game", np.uint8(board.repeat(CELL_SIZE, 0).repeat(CELL_SIZE, 1)))key = cv2.waitKey(int(1000/SPEED))# 返回按下的键。如果没有按下键,则为-1。 return keydef win_focus():# 全屏打开图像,然后返回正常窗口cv2.namedWindow("Snake Game", cv2.WINDOW_AUTOSIZE);board = np.zeros([BOARD_SIZE * CELL_SIZE, BOARD_SIZE * CELL_SIZE, 3])cv2.imshow("Snake Game", board);cv2.setWindowProperty("Snake Game", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN);cv2.waitKey(2000)cv2.setWindowProperty("Snake Game", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_AUTOSIZE)if __name__ == '__main__' : # 棋盘游戏中每个单元格的大小CELL_SIZE = 20# 游戏中沿宽度排列的单元数BOARD_SIZE = 45# 改变速度使游戏进行得更快SPEED = 12# 吃过苹果后,蛇会按生长单位生长GROWTH = 3# 变量跟踪苹果是否被吃eaten = True# 变量来检查游戏是否应该退出quit = False# 变量跟踪增长。grow = 0# 存储蛇的数组snake = []#蛇的头从棋盘的中心开始。head = Head(0, int((BOARD_SIZE - 1)/2), int((BOARD_SIZE - 1)/2))snake.append(head)# 通过打印说明开始游戏print('w = top, a = left, s = down, d = right')# 让窗口聚焦的丑把戏win_focus()while True:# 检查苹果是否被吃掉,并生成一个新的if eaten:# 列出所有可能的地点s = list(range(0, BOARD_SIZE ** 2))# 删除属于蛇的一部分的cellfor part in snake:s.remove(part.x * BOARD_SIZE + part.y)# 从剩余的cell中随机挑选一个 a = choice(s)applex = int(a/BOARD_SIZE)appley = a % BOARD_SIZEeaten = False# 制作并展示显示屏key = display()# 获取按下的键并相应地移动# 8和27是删除键和退出键# 方向键在OpenCV中很棘手。所以我们使用#键'w', 'a','s','d'表示移动。# w = top, a = left, s = down, d = rightif key == 8 or key == 27:breakelif key == ord("d") :head.direction = 0elif key == ord("s") :head.direction = 1elif key == ord("a") :head.direction = 2elif key == ord("w") :head.direction = 3# 移动snakefor part in snake[::-1]:part.move()    # 碰撞规则if head.x < 0 or head.x > BOARD_SIZE - 1 or head.y < 0 or head.y > BOARD_SIZE - 1:breakfor part in snake[1:]:if head.x == part.x and head.y == part.y:quit = Truebreakif quit:break# 蛇在多帧中逐渐生长    if grow > 0:snake.append(SnakePart(snake[-1], subx, suby))grow -= 1# 当蛇吃苹果的时候,蛇就会长出来if applex == head.x and appley == head.y:subx = snake[-1].xsuby = snake[-1].yeaten = Truegrow += GROWTH

代码解析

首先,我们将导入一些库用于显示和生成苹果的随机位置。

import cv2
import numpy as np
from random import randint
from random import choice

让我们制作几个类来代表游戏。

  • 1.SnakePart:这代表了蛇的身体(不包括头部)。
  • 2.Head:这个类代表蛇头

    SnakePart类有x和y坐标,以及对它前面的另一个SnakePartHead的引用。
class SnakePart:def __init__(self, front, x, y):self.front = frontself.x = xself.y = ydef move(self):# Moves by following the part in front of itself.x = self.front.xself.y = self.front.y

move()方法只是复制前面部件的位置。
Head类也有x和y。此外,它还有一个指定移动方向的direction变量。

class Head:def __init__(self, direction, x, y):self.direction = directionself.x = xself.y = ydef move(self):# 检查它当前的方向,并相应地移动if self.direction == 0:self.x += 1elif self.direction == 1:self.y += 1elif self.direction == 2:self.x -= 1elif self.direction == 3:self.y -= 1

现在,让我们转到主函数,看看游戏是如何实现的。我们首先定义几个有用的常量。
CELL_SIZE指定显示屏上每个单元格的宽度,以像素为单位。
BOARD_SIZE沿显示屏宽度的单元格数。在我们的示例中,CELL_SIZE是20,BOARD_SIZE是45。因此,显示器的大小是20 x 45 = 900像素。
SPEED决定了蛇的快慢。如果游戏对你来说太快,请使用较小的数字。
GROWTH是指蛇吃了一个苹果后生长的单位数。

if __name__ == '__main__' : # Size of each cell in the board gameCELL_SIZE = 20# Number of cells along the width in the gameBOARD_SIZE = 45# Change SPEED to make the game go fasterSPEED = 12# After eating an apple the snake grows by GROWTH unitsGROWTH = 3

接下来,我们定义一些以后会派上用场的变量。

# Variable to track if apple is eaten
eaten = True
# Variable to check if the game should quit
quit = False
# Variable to track growth.
grow = 0

现在,让我们创建一个空数组来存储head 和 snakeparts.。

# Array for storing snake
snake = []
#snake's head starts at the center of the board.
head = Head(0, int((BOARD_SIZE - 1)/2), int((BOARD_SIZE - 1)/2))
snake.append(head)

在进入程序的主while循环之前,让我们先看看显示当前游戏的display()函数。

在下面的代码中,我们执行以下操作。

  • 我们首先创建一个显示屏,并将其填充为零(黑色),
  • 我们将蛇所占据的单元格涂成绿色。
  • 我们把被苹果占据的单元格涂成红色。
  • 如果键盘上有一个键被按下,返回该键的id。
def display():# Create a blank imageboard = np.zeros([BOARD_SIZE * CELL_SIZE, BOARD_SIZE * CELL_SIZE, 3])# Color the snake greenfor part in snake:x = part.x * CELL_SIZEy = part.y * CELL_SIZEboard[y:y + CELL_SIZE, x:x + CELL_SIZE] = [0, 255, 0]# Color the apple red    x = applex * CELL_SIZEy = appley * CELL_SIZEboard[y:y + CELL_SIZE, x:x + CELL_SIZE] = [0, 0, 255]# Display boardcv2.imshow("Snake Game", np.uint8(board))key = cv2.waitKey(int(1000/SPEED))# Return the key pressed. It is -1 if no key is pressed. return key

我们几乎准备好进入游戏的主要while循环了。在此之前,我们先打印一些说明。

# Start the game by printing instructions
print('w = top, a = left, s = down, d = right')
# Ugly trick to bring the window in focus
win_focus()

您将注意到一个函数win_focus()。取决于OpenCV在你的系统上使用的窗口方法,当你运行这个游戏时,显示窗口可能不在焦点中。为了解决这一问题,我们使用了这种丑陋的方法来聚焦游戏窗口,这样用户就不必点击窗口。

在下面的代码中,我们执行以下操作

  • 我们打开一个窗口
  • 显示游戏窗口
  • 将窗口设置为全屏。这使窗口成为焦点。
  • 我们将窗口调整回正常大小。
def win_focus():# Ugly trick to get the window in focus.# Opens an image in fullscreen and then back to normal windowcv2.namedWindow("Snake Game", cv2.WINDOW_AUTOSIZE);board = np.zeros([BOARD_SIZE * CELL_SIZE, BOARD_SIZE * CELL_SIZE, 3])cv2.imshow("Snake Game", board);cv2.setWindowProperty("Snake Game", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN);cv2.waitKey(2000)cv2.setWindowProperty("Snake Game", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_AUTOSIZE)

如果遇到任何故障,可以在主函数中注释掉win_focus()

对于代码的主要部分,我们将使用一个while循环,其中每次迭代都是蛇的一次移动。在下面的循环中,我们完成两件事:

  • 检查苹果是否被吃了。
  • 如果是,生成一个新的苹果。在生成苹果的时候,我们确保它的位置不与蛇重叠。
while True:# Checks if the apple is eaten and generates a new oneif eaten:# Create a list of all possible locationss = list(range(0, BOARD_SIZE ** 2))# Delete cells that are part of the snakefor part in snake:s.remove(part.x * BOARD_SIZE + part.y)# Randomly pick from one of the remaining cells    a = choice(s)applex = int(a/BOARD_SIZE)appley = a % BOARD_SIZEeaten = False

接下来,我们显示显示屏,并查找键盘输入。

if/elif 语句检查是否按下了‘w’、‘a’、’、‘d’、escape 或 delete 键。根据键盘输入,蛇改变方向或停止程序。

# Makes and displays the board
key = display()# Gets key presses and moves accordingly
# 8 and 27 are delete and escape keys
# Arrow keys are tricky in OpenCV. So we use
# keys 'w', 'a','s','d' for movement.
# w = top, a = left, s = down, d = rightif key == 8 or key == 27:break
elif key == ord("d") :head.direction = 0
elif key == ord("s") :head.direction = 1
elif key == ord("a") :head.direction = 2
elif key == ord("w") :head.direction = 3

根据键盘输入,我们移动蛇。您可能还记得,SnakePartmove方法只是在它前面复制蛇部分的位置。

# Moving the snake
for part in snake[::-1]:part.move()

接下来,我们实现碰撞检查。下面的代码实现了两个规则:

  • 如果蛇的头移出显示屏,游戏就结束了。
  • 如果蛇的头部与蛇的身体发生碰撞,游戏就结束了。
# Collision rulesif head.x < 0 or head.x > BOARD_SIZE - 1 or head.y < 0 or head.y > BOARD_SIZE - 1:breakfor part in snake[1:]:if head.x == part.x and head.y == part.y:quit = Truebreakif quit:break

最后,我们制定了蛇吃苹果生长的规则。当苹果被吃掉的时候,生长变量的增量GROWTH是不变的,蛇每帧生长一个单元格,直到它完全长大。

# The snake grows gradually over multiple frames    if grow > 0:snake.append(SnakePart(snake[-1], subx, suby))grow -= 1# Grows the snake when it eats an appleif applex == head.x and appley == head.y:subx = snake[-1].xsuby = snake[-1].yeaten = Truegrow += GROWTH

参考目录

https://learnopencv.com/snake-game-with-opencv-python/

OpenCV进阶(3)基于OpenCV的贪吃蛇游戏相关推荐

  1. python贪吃蛇设计目标_基于 pygame 设计贪吃蛇游戏

    基于 pygame 设计贪吃蛇游戏 贪吃蛇游戏通过玩家控制蛇移动,不断吃到食物增长,直到碰到蛇身或边界游戏结束.其运行效果如下所示: 游戏开始时,先导入可能需要用到的包. import time im ...

  2. 基于React的贪吃蛇游戏的设计与实现

    代码地址如下: http://www.demodashi.com/demo/11818.html 贪吃蛇小游戏(第二版) 一年半前层用react写过贪吃蛇小游戏https://github.com/c ...

  3. 基于HTML5的贪吃蛇游戏的设计与实现

    基于HTML5的贪吃蛇游戏的设计与实现 功能要求: 贪吃蛇游戏是一款经典的单机休闲游戏,玩家通过上下左右按键控制蛇头的移动方向使其向指定方向前进,并吃掉随机位置上产生食物来获得分数.每吃掉一次食物,贪 ...

  4. Linux下基于SDL库贪吃蛇游戏

    Linux下基于SDL库贪吃蛇游戏   SDL(Simple DirectMediaLayer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成.SDL提供了数种控制图像.声音.输出入的函数,让开 ...

  5. 基于EasyX的贪吃蛇游戏

    基于EasyX的贪吃蛇游戏 一.预备知识 二.游戏逻辑 1.贪吃蛇元素 2.贪吃蛇规则 三.游戏设计 1.地图设计 2.移动设计 3.速度设计 4.整体设计 一.预备知识 1.使用EasyX必须要知道 ...

  6. 基于单片机的贪吃蛇游戏设计_前端入门,基于html,css,javascript的贪吃蛇游戏

    源代码: 贪吃蛇 .box1{ font-size: 15px; float:left; display: block; margin-right: 150px; } .box2{ font-size ...

  7. 基于单片机的贪吃蛇游戏

    绪论 1.1 研究背景与意义 随着社会的发展,人们生活的步调日益加快,越来越多的人加入了全球化的世界. 人们不再拘泥于--,J,块天地,加班,出差成了现代人不可避免的公务.而此时一款可以 随时随地娱乐 ...

  8. 基于linux的贪吃蛇游戏设计_贪吃蛇还能这么玩?绝对是你从未体验过的全新版本(上)...

    上个月 Gitee 宣布推出「Python 贪吃蛇魔改大赛」的活动,受到了众多开发者们的欢迎.半个多月后,我们收到了共计 42 个参赛作品,有的作品创意无限,有的作品视觉效果极佳,看看下面的作品一览, ...

  9. 基于java的贪吃蛇游戏

    贪吃蛇的游戏开发 实验内容: 1)实现贪吃蛇游戏基本功能,屏幕上随机出现一个"食物",称为豆子,上下左右 控制"蛇"的移动,吃到"豆子"以后 ...

  10. 基于MFC的贪吃蛇游戏

    一.软件说明 贪吃蛇游戏是一款有趣的益智游戏,可以锻炼大脑的反映能力,在游戏中娱乐和放松自己.该贪吃蛇采用传统的游戏规则,实现蛇的移动.进食.增长以及死亡过程,并统计所得分数.最初蛇只有3节,每吃一个 ...

最新文章

  1. sql 2008数据库日志清理(转)
  2. Android 程序打包及签名
  3. iis 跨域_织梦会员登录二级域名不能跨域
  4. stateless_Spring Stateless State Security第3部分:JWT +社会认证
  5. 第三十七期:刷脸支付叫好不叫座,为啥消费者和商家都不愿用先进科技?
  6. 坑爹的水题之“元芳你怎么看”
  7. 理解ASP.NET中的三层结构
  8. Bezier曲线扫盲
  9. 138. Copy List with Random Pointer
  10. 解决requests.text乱码问题content.decode()
  11. 设置jupyter notebook软件的字体样式
  12. vue 实现图片预览
  13. axure rp8.1 注册码
  14. 微课录制神器,新手老师必备录屏软件!
  15. 检测应用位于后台,并弹出手势解锁,解锁成功进入主界面
  16. linux各个版本简介 (未完待续)
  17. android 耳机数据传输,智能手机耳机电路工作原理
  18. 【爬虫】python爬虫从入门到放弃
  19. 详解动态规划01背包问题--JavaScript实现
  20. 江南百景图显示服务器错误,江南百景图通讯失败请保持网络畅通并重试

热门文章

  1. Android 简单的计算器实现
  2. lpv4的地址格式由多少个字节组成_2020年智慧树艺术品拍卖第八单元章节测试答案...
  3. 中国移动云能力中心校招面试总结(三面)
  4. linux软件安装之详解apt、yum、dnf 和 pkg包安装
  5. Ubuntu20.04 安装HPC_SDK加速库
  6. 管道-过滤器软件架构
  7. 乔布斯05年斯坦福大学毕业典礼上的演讲
  8. 乔布斯在斯坦福大学的演讲视频
  9. 毕业设计英文文献java_计算机专业毕业设计论文外文文献中英文翻译——java对象...
  10. 不念过往,不畏将来——告别曾经