Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use Python+OpenCV self-made AI Visual version of Snake Game

2025-01-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

Today, the editor will share with you the relevant knowledge points about how to use the Python+OpenCV self-made AI visual version of the Snake game. The content is detailed and the logic is clear. I believe most people still know too much about this knowledge, so share this article for your reference. I hope you can get something after reading this article. Let's take a look.

Introduction

Rule: the index finger tip controls the snakehead, every time the fingertip touches the yellow square, the count adds one, the snake body becomes longer, and the square randomly switches position. If the fingertips stop moving, or if the snake head hits the snake body during the movement, then the game is over. Click the R key on the keyboard to restart the game.

While the game is in progress:

Game end interface:

1. Install toolkit pip install opencv_python==4.2.0.34 # install opencvpip install mediapipe# install mediapipe# pip install mediapipe-- user # if there is an user error, try this pip install cvzone # install cvzone # import kit import cv2import cvzoneimport numpy as npfrom cvzone.HandTrackingModule import HandDetector # import hand detection module import mathimport random

The information of the 21 key points of the hand is as follows. In this section, we mainly study the information of the coordinates of the fingertip of the index finger'8'.

two。 Detect key points of the hand

(1) cvzone.HandTrackingModule.HandDetector () is a method for detecting key points in the hand.

Parameters:

Mode: defaults to False and treats the input image as a video stream. It will attempt to detect the hand in the first input image and further locate the coordinates of the hand after successful detection. In subsequent images, once all maxHands hands are detected and the corresponding hand coordinates are located, it tracks those coordinates without invoking another detection until it loses tracking of any hand. This reduces latency and is ideal for processing video frames. If set to True, hand detection is run on each input image to process a batch of static, possibly irrelevant images.

MaxHands: a maximum of several hands can be detected. Default is 2.

DetectionCon: the minimum confidence value of the hand detection model (between 0 and 1). If the threshold is exceeded, the detection is successful. The default is 0.5

MinTrackingCon: the minimum confidence value of the coordinate tracking model (between 0 and 1), which is used to treat hand coordinates as successful tracking, and if unsuccessful, hand detection is automatically invoked on the next input image. Setting it to a higher value can improve the robustness of the solution, but at the cost of higher latency. If mode is True, this parameter is ignored and hand detection will run on each image. The default is 0.5

Its arguments and return values are similar to the official function mediapipe.solutions.hands.Hands ()

MULTI_HAND_LANDMARKS: a collection of detected / tracked hands, where each hand is represented as a list of 21 hand landmarks, each consisting of x, y, z. X and y are normalized from the width and height of the image to [0primel] respectively. Z represents the landmark depth.

MULTI_HANDEDNESS: whether the hand being detected / tracked is a collection of left hand or right hand. Each hand consists of label (label) and score (score). Label is a string of 'Left' or' Right' values. Score is to predict the estimated probability of the left and right hand.

(2) cvzone.HandTrackingModule.HandDetector.findHands () find the key points of the hand and draw

Parameters:

Img: frame image that needs to detect key points in BGR format

Draw: do you need to draw key points and identification boxes on the original image?

FlipType: whether the image needs to be flipped, when the video image is not mirrored with ourselves, set it to True.

Return value:

Hands: a list of detected hand information consisting of 0 or 1 or 2 dictionaries. If two hands are detected, it is a list of two dictionaries. The dictionary contains: the coordinates of 21 key points, the upper-left coordinates of the detection box and its width and height, and the coordinates of the center point of the detection box to detect which hand it is.

Img: returns the image after drawing key points and connecting lines

The code is as follows:

Import cv2import cvzoneimport numpy as npfrom cvzone.HandTrackingModule import HandDetector # Import hand detection module # (1) get camera cap = cv2.VideoCapture (0) # 0 represents the camera that comes with the computer # set sizecap.set (3, 1280) # window width 1280cap.set (4720) # window height 720 # (2) Model configuration detector = HandDetector (maxHands=1 # detect at most 1 hand detectionCon=0.8) # minimum detection confidence 0.8 # (3) Image processing while True: # read one camera image at a time Returns whether the success has been read successfully, and the read frame image img success, img = cap.read () # image is flipped, so that the image and itself are mirrored img = cv2.flip (img, 1) # 0 means to flip up and down, 1 means to flip left and right # to detect the key points in the hand. Return the hand information hands, draw the image img hands after the key points, img = detector.findHands (img, flipType=False) # since the previous line has flipped the image, there is no need to flip # View the key information print (hands) # (4) key processing if hands: # if the hand is detected Then deal with the key point # get the coordinates of the fingertip of the index finger (xpeny) hand = hands [0] # get all the information of a hand lmList = hand ['lmList'] # get the coordinates of the 21 key points of the hand (xQuery yPowerz) pointIndex = lmList [8] [0:2] # only get the key points of the index finger (x Y) coordinates # circle around the tip of the index finger (center coordinates are tuples) Radius 15, cyan filled with cv2.circle (img, tuple (pointIndex), 15, (255 cv2.FILLED 0), cv2.FILLED) # (5) display image cv2.imshow ('img', img) # input image display window name and image # disappear after 1 millisecond retention per frame And press the ESC key to exit if cv2.waitKey (1) & 0xFF = = 27: break # release video resource cap.release () cv2.destroyAllWindows ()

The effect picture is as follows:

Print the hand key information as follows:

[{'lmList': [[1152, 675, 0], [1085, 693,-37], [1030, 698,-68], [1003, 698,-97], [1003, 679,-48], [1001, 546,-81], [1093, 1093,-81], [1134, 652,-110], [1075, 484,-46], [1119,534,-84], [1171,605] 1141], [1217, 659,-45], [1177, 529,-83], [1219, 590,-84], [1253, 642,-73], [1195, 494,-47], [1221, 521,-73], [1245, 566,-65], [1267, 602,-49], 'bbox': (1001, 481,266, 217),' center': (1134,589) 'type':' Right'}] 3. Snake body movement

Construct a class that handles the movement of the snake body, requiring the snake body to keep a fixed length to follow the tip of the index finger when not eating food.

For example, if the current list of snakebody nodes self.points contains [a, b, c, d] these four nodes, a node represents the snake tail and d node represents the snake head. In the next frame, the fingertip of the index finger is moved to point e, and the e node is appended to the snake body node list, so the list now contains [a, b, c, d, e] nodes, where e nodes are new snakeheads.

At this point, it is judged whether the current total snake body length self.currentLength (the sum of the lengths of all nodes in the list) is greater than the snake body fixed length self.allowedLength to ensure that the snake body length remains the same during the movement.

If the current total length of the snake body self.currentLength is greater than the fixed length self.allowedLength, then delete the nodes from end to end in the node list. An in the list [a, b, c, d, e] represents the snake tail node. Delete first to determine whether the total length between the nodes in the list [b, c, d, e] meets the requirements. If it is still larger than the fixed length, then delete node b, and then judge.

If the current total length self.currentLength of the snake body is less than the fixed length self.allowedLength, no processing is done.

Add to the above code:

Import cv2import cvzoneimport numpy as npfrom cvzone.HandTrackingModule import HandDetector # imports the hand detection module import math # to construct a snake mobile class class SnakeGameClass: # (1) initialize def _ _ init__ (self): self.points = [] # the node coordinates of the snake's body self.lengths = [] # the coordinates between the nodes of the snake body self.currentLength = 0 # Current snake length self.allowedLength = 150 # when there is nothing to eat The total length of the snake self.previousHead = (0Power0) # coordinates of the previous snake head node # (II) updating to increase the snake body length def update (self, imgMain, currentHead): # input image The current coordinates of the snakehead px, py = self.previousHead # get the x and y coordinates cx of the previous snakehead, cy = currentHead # the x and y coordinates of the current snakehead node # add the current snakehead coordinates to self.points.append ([cx) in the snake body node coordinate list Cy]) # calculate the distance between two nodes distance = math.hypot (cx-px Cy-py) # calculate the square sum open root # add the distance between nodes to the snake body node distance list self.lengths.append (distance) # increase the current snake body length self.currentLength + = distance # update snake head coordinates self.previousHead = (cx,cy) # (3) reduce the snake tail length That is, the length from the head of the snake to the tail of the snake is not greater than 150 if self.currentLength > self.allowedLength: # traverses the length of all the node segments. The newly updated snakehead index is at the back of the list, and the snaketail index is in front of the list for I, length in enumerate (self.lengths): # reduce the length of the segment from the snaketail to the snakehead, whether the length obtained meets the requirements self.currentLength-= length # delete the length of the snaketail segment from the list And the snake tail node self.lengths.pop (I) self.points.pop (I) # if the current snake body length is less than the specified length, exit the loop if self.currentLength if it meets the requirements

< self.allowedLength: break #(四)绘制蛇 # 当节点列表中有值了,才能绘制 if self.points: # 遍历蛇身节点坐标 for i, point in enumerate(self.points): # 绘制前后两个节点之间的连线 if i != 0: cv2.line(imgMain, tuple(self.points[i-1]), tuple(self.points[i]), (0,255,0), 20) # 在蛇头的位置画个圆 cv2.circle(imgMain, tuple(self.points[-1]), 20, (255,0,0), cv2.FILLED) # 返回更新后的图像 return imgMain #(1)获取摄像头cap = cv2.VideoCapture(0) # 0代表电脑自带的摄像头# 设置显示窗口的sizecap.set(3, 1280) # 窗口宽1280cap.set(4, 720) # 窗口高720 #(2)模型配置detector = HandDetector(maxHands=1, # 最多检测1只手 detectionCon=0.8) # 最小检测置信度0.8 # 接收创建贪吃蛇的类game = SnakeGameClass() #(3)图像处理while True: # 每次读取一帧相机图像,返回是否读取成功success,读取的帧图像img success, img = cap.read() # 图像翻转,使图像和自己呈镜像关系 img = cv2.flip(img, 1) # 0代表上下翻转,1代表左右翻转 # 检测手部关键点。返回手部信息hands,绘制关键点后的图像img hands, img = detector.findHands(img, flipType=False) # 由于上一行翻转过图像了,这里就不用翻转了 # 查看关键点信息 print(hands) #(4)关键点处理 if hands: # 如果检测到手了,那就处理关键点 # 获得食指指尖坐标(x,y) hand = hands[0] # 获取一只手的全部信息 lmList = hand['lmList'] # 获得这只手的21个关键点的坐标(x,y,z) pointIndex = lmList[8][0:2] # 只获取食指指尖关键点的(x,y)坐标 # 更新贪吃蛇的节点,给出蛇头节点坐标。返回更新后的图像 img = game.update(img, pointIndex) #(5)显示图像 cv2.imshow('img', img) # 输入图像显示窗口的名称及图像 # 每帧滞留1毫秒后消失,并且按下ESC键退出 if cv2.waitKey(1) & 0xFF == 27: break # 释放视频资源cap.release()cv2.destroyAllWindows() 效果图如下,蛇身保持默认固定长度随着指尖而移动。 4. 蛇进食增加身体长度 先看下面代码 SnakeGameClass 类中的第(五)步。给食物(即绘制的矩形)随机给出一个中心点坐标,自定义的类方法 randomFoodLocation(),执行该方法则食物的中心点坐标的x在[100,1000]中随机取一个数,y在[100,600]中随机取一个数。 下面代码定义的类中的第(七)步。判断食指指尖(即蛇头节点坐标)是否在矩形内部,如果在内部,那么蛇身移动过程中的固定长度 self.allowedLength 增加50个像素值。得分 self.score 加一。并在下一帧随机改变食物的位置。 在上述代码中补充: import cv2import cvzoneimport numpy as npfrom cvzone.HandTrackingModule import HandDetector # 导入手部检测模块import mathimport random # 构造一个贪吃蛇移动的类class SnakeGameClass: #(一)初始化 def __init__(self): self.score = 0 # 积分器 self.points = [] # 蛇的身体的节点坐标 self.lengths = [] # 蛇身各个节点之间的坐标 self.currentLength = 0 # 当前蛇身长度 self.allowedLength = 150 # 没吃东西时,蛇的总长度 self.previousHead = (0,0) # 前一个蛇头节点的坐标 self.foodPoint = (0,0) # 食物的起始位置 self.randomFoodLocation() # 随机改变食物的位置 #(五)食物随机出现的位置 def randomFoodLocation(self): # x在100至1000之间,y在100至600之间,随机取一个整数 self.foodPoint = random.randint(100, 1000), random.randint(100, 600) #(二)更新增加蛇身长度 def update(self, imgMain, currentHead): # 输入图像,当前蛇头的坐标 px, py = self.previousHead # 获得前一个蛇头的x和y坐标 cx, cy = currentHead # 当前蛇头节点的x和y坐标 # 添加当前蛇头的坐标到蛇身节点坐标列表中 self.points.append([cx,cy]) # 计算两个节点之间的距离 distance = math.hypot(cx-px, cy-py) # 计算平方和开根 # 将节点之间的距离添加到蛇身节点距离列表中 self.lengths.append(distance) # 增加当前蛇身长度 self.currentLength += distance # 更新蛇头坐标 self.previousHead = (cx,cy) #(三)减少蛇尾长度,即移动过程中蛇头到蛇尾的长度不大于150 if self.currentLength >

Self.allowedLength: # traverses the length of all node segments. The newly updated snakehead index is at the back of the list, and the snaketail index is in front of the list for I, length in enumerate (self.lengths): # reduce the length of the segment from the snaketail to the snakehead, whether the length obtained meets the requirements self.currentLength-= length # delete the length of the snaketail segment from the list And the snake tail node self.lengths.pop (I) self.points.pop (I) # if the current snake body length is less than the specified length, exit the loop if self.currentLength if it meets the requirements

< self.allowedLength: break #(七)检查蛇是否吃了食物 rx, ry = self.foodPoint # 得到食物的中心点坐标位置 # 绘制矩形作为蛇的食物 cv2.rectangle(imgMain, (rx-20, ry-20), (rx+20, ry+20), (255,255,0), cv2.FILLED) cv2.rectangle(imgMain, (rx-20, ry-20), (rx+20, ry+20), (0,255,255), 5) cv2.rectangle(imgMain, (rx-5, ry-5), (rx+5, ry+5), (0,0,255), cv2.FILLED) # 检查指尖(即蛇头cx,cy)是否在矩形内部 if rx-20 < cx < rx+20 and ry-20< cy < ry+20: # 随机更换食物的位置 self.randomFoodLocation() # 增加蛇身的限制长度,每吃1个食物就能变长50 self.allowedLength += 50 # 吃食物的计数加一 self.score += 1 print('eat!', f'score:{self.score}') #(四)绘制蛇 # 当节点列表中有值了,才能绘制 if self.points: # 遍历蛇身节点坐标 for i, point in enumerate(self.points): # 绘制前后两个节点之间的连线 if i != 0: cv2.line(imgMain, tuple(self.points[i-1]), tuple(self.points[i]), (0,255,0), 20) cv2.line(imgMain, tuple(self.points[i-1]), tuple(self.points[i]), (0,0,255), 15) # 在蛇头的位置画个圆 cv2.circle(imgMain, tuple(self.points[-1]), 20, (255,255,0), cv2.FILLED) cv2.circle(imgMain, tuple(self.points[-1]), 18, (255,0,0), 3) cv2.circle(imgMain, tuple(self.points[-1]), 5, (0,0,0), cv2.FILLED) # 返回更新后的图像 return imgMain #(1)获取摄像头cap = cv2.VideoCapture(0) # 0代表电脑自带的摄像头# 设置显示窗口的sizecap.set(3, 1280) # 窗口宽1280cap.set(4, 720) # 窗口高720 #(2)模型配置detector = HandDetector(maxHands=1, # 最多检测1只手 detectionCon=0.8) # 最小检测置信度0.8 # 接收创建贪吃蛇的类game = SnakeGameClass() #(3)图像处理while True: # 每次读取一帧相机图像,返回是否读取成功success,读取的帧图像img success, img = cap.read() # 图像翻转,使图像和自己呈镜像关系 img = cv2.flip(img, 1) # 0代表上下翻转,1代表左右翻转 # 检测手部关键点。返回手部信息hands,绘制关键点后的图像img hands, img = detector.findHands(img, flipType=False) # 由于上一行翻转过图像了,这里就不用翻转了 #(4)关键点处理 if hands: # 如果检测到手了,那就处理关键点 # 获得食指指尖坐标(x,y) hand = hands[0] # 获取一只手的全部信息 lmList = hand['lmList'] # 获得这只手的21个关键点的坐标(x,y,z) pointIndex = lmList[8][0:2] # 只获取食指指尖关键点的(x,y)坐标 # 更新贪吃蛇的节点,给出蛇头节点坐标。返回更新后的图像 img = game.update(img, pointIndex) #(5)显示图像 cv2.imshow('img', img) # 输入图像显示窗口的名称及图像 # 每帧滞留1毫秒后消失,并且按下ESC键退出 if cv2.waitKey(1) & 0xFF == 27: break # 释放视频资源cap.release()cv2.destroyAllWindows() 效果图如下: 5. 自身碰撞及界面的处理 先看到自定义类 SnakeGameClass 中的第(八)步,蛇身节点列表 self.points 中包含从蛇头到蛇尾的所有节点。如 [a, b, c, d, e] 节点,a 节点代表蛇尾,e 节点代表蛇头。这里我就粗糙地判断一下是否碰撞,如果大家有更好的判断方法可以改动这第(八)步。计算蛇头 e 节点到所有节点之间的距离,如果小于某个值就代表碰撞了,游戏结束 self.gameover = True 再看到自定义类中的第(三)步。如果游戏结束 self.gameover = True,那就在下一帧中绘制结算界面,不再执行蛇身移动程序。 再看到主程序中的第(5)步。其中 k == ord('r'),按下键盘上的 r 键来重新游戏。将所有蛇身变量初始化,并将 self.gameover = False,退出结算界面,使得下一帧能执行蛇身移动操作。 在上述代码中补充: import cv2import cvzonefrom matplotlib.cbook import pts_to_midstepimport numpy as npfrom cvzone.HandTrackingModule import HandDetector # 导入手部检测模块import mathimport random # 构造一个贪吃蛇移动的类class SnakeGameClass: #(一)初始化 def __init__(self): self.score = 0 # 积分器 self.points = [] # 蛇的身体的节点坐标 self.lengths = [] # 蛇身各个节点之间的坐标 self.currentLength = 0 # 当前蛇身长度 self.allowedLength = 150 # 没吃东西时,蛇的总长度 self.previousHead = (0,0) # 前一个蛇头节点的坐标 self.foodPoint = (0,0) # 食物的起始位置 self.randomFoodLocation() # 随机改变食物的位置 self.gameover = False # 蛇头撞到蛇身,变成True,游戏结束 #(二)食物随机出现的位置 def randomFoodLocation(self): # x在100至1000之间,y在100至600之间,随机取一个整数 self.foodPoint = random.randint(100, 1000), random.randint(100, 600) #(三)更新增加蛇身长度 def update(self, imgMain, currentHead): # 输入图像,当前蛇头的坐标 # 游戏结束,显示文本 if self.gameover: cvzone.putTextRect(imgMain, 'GameOver', [400,300], 5, 3, colorR=(0,255,255), colorT=(0,0,255)) cvzone.putTextRect(imgMain, f'Score:{self.score}', [450,400], 5, 3, colorR=(255,255,0)) cvzone.putTextRect(imgMain, f"Press Key 'R' to Restart", [230,500], 4, 3, colorR=(0,255,0), colorT=(255,0,0)) else: px, py = self.previousHead # 获得前一个蛇头的x和y坐标 cx, cy = currentHead # 当前蛇头节点的x和y坐标 # 添加当前蛇头的坐标到蛇身节点坐标列表中 self.points.append([cx,cy]) # 计算两个节点之间的距离 distance = math.hypot(cx-px, cy-py) # 计算平方和开根 # 将节点之间的距离添加到蛇身节点距离列表中 self.lengths.append(distance) # 增加当前蛇身长度 self.currentLength += distance # 更新蛇头坐标 self.previousHead = (cx,cy) #(四)减少蛇尾长度,即移动过程中蛇头到蛇尾的长度不大于150 if self.currentLength >

Self.allowedLength: # traverses the length of all node segments. The newly updated snakehead index is at the back of the list, and the snaketail index is in front of the list for I, length in enumerate (self.lengths): # reduce the length of the segment from the snaketail to the snakehead, whether the length obtained meets the requirements self.currentLength-= length # delete the length of the snaketail segment from the list And the snake tail node self.lengths.pop (I) self.points.pop (I) # if the current snake body length is less than the specified length, it meets the requirements Exit the cycle if self.currentLength < self.allowedLength: break # (v) draw the scoreboard cvzone.putTextRect (imgMain, f'Score: {self.score}', [50Power80], 4, 3, colorR= (255pint 0)) # (VI) check whether the snake has eaten the food rx Ry = self.foodPoint # get the coordinate location of the central point of the food # draw a rectangle as the snake's food cv2.rectangle (imgMain, (rx-20, ry-20), (rx+20, ry+20), (255pm 255), cv2.FILLED) cv2.rectangle (imgMain, (rx-20, ry-20), (rx+20, ry+20), (0255255) 5) cv2.rectangle (imgMain, (rx-5, ry-5), (rx+5, ry+5), (0J0255), cv2.FILLED) # check fingertips (that is, snakehead cx Cy) whether if rx-20 < cx < rx+20 and ry-20 < cy < ry+20: # randomly change the position of food inside the rectangle self.randomFoodLocation () # increase the limited length of the snake body Every time you eat one food, you can grow 50 self.allowedLength + = 50 # the count of eating food plus one self.score + = 1 print ('eattered food, f'score: {self.score}') # (7) draw snake # when there is a value in the node list To draw if self.points: # traversing the snake body node coordinates for I, point in enumerate (self.points): # drawing the connection between the two nodes if I! = 0: cv2.line (imgMain, tuple (self.points [I-1]) Tuple (self.points [I]), (0Pie255Power0), 20) cv2.line (imgMain, tuple (self.points [I-1]), tuple (self.points [I]), (0P0255), 15) # draw a circle in the position of the snakehead cv2.circle (imgMain, tuple (self.points [- 1]), 20, (255cr.255) Cv2.FILLED) cv2.circle (imgMain, tuple (self.points [- 1]), 18, (255 tuple 0), 3) cv2.circle (imgMain, tuple (self.points [- 1]), 5, (0memo) Cv2.FILLED) # (VIII) check that the snakehead collides with its own for point in self.points [:-2]: # not counting the distance between the snakehead and itself # calculate the distance between the snakehead and each node dist = math.hypot (cx-point [0]) Cy-point [1]) # if the distance is less than 1.8, Then prove that you collided with if dist < 1.8: # Game over self.gameover = True # return the updated image return imgMain # (1) get the camera cap = cv2.VideoCapture (0) # 0 represents the computer's own camera # set the sizecap.set of the display window (3 1280) # window width 1280cap.set (4720) # window height 720 # (2) Model configuration detector = HandDetector (maxHands=1, # detect at most 1 hand detectionCon=0.8) # minimum detection confidence 0.8 # receive the creation of gluttonous snake like game = SnakeGameClass () # (3) Image processing while True: # read one camera image at a time Returns whether the success has been read successfully, and the read frame image img success, img = cap.read () # image is flipped, so that the image and itself are mirrored img = cv2.flip (img, 1) # 0 means to flip up and down, 1 means to flip left and right # to detect the key points in the hand. Return the hand information hands, draw the image img hands after the key point, img = detector.findHands (img, flipType=False) # since the previous line has flipped the image, there is no need to flip # (4) key processing if hands: # if detected Then deal with the key point # get the coordinates of the fingertip of the index finger (xpeny) hand = hands [0] # get all the information of a hand lmList = hand ['lmList'] # get the coordinates of the 21 key points of the hand (xQuery yPowerz) pointIndex = lmList [8] [0:2] # only get the key points of the index finger (x Y) coordinates # update Snake's node The coordinates of snakehead nodes are given. Return the updated image img = game.update (img, pointIndex) # (5) display image cv2.imshow ('img' Img) # enter the name and image of the image display window # restart the game k = cv2.waitKey (1) # disappear after 1 millisecond of retention per frame if k = = ord ('r'): # keyboard'r' key represents restart of the game game.gameover = False game.score = 0 # integrator game.points = [] # snake Node coordinates of the body game.lengths = [] # coordinates between the nodes of the snake body game.currentLength = 0 # current length of the snake body game.allowedLength = 150 # when not eating Total length of snake game.previousHead = (0Power0) # coordinates of the previous snakehead node game.randomFoodLocation () # randomly change the position of the food if k & 0xFF = = 27: # Keyboard ESC key exit program break # release video resource cap.release () cv2.destroyAllWindows ()

The effect is as follows: in the process of moving, every time the snakehead touches a food, the snakehead will grow longer. if the snakehead node stops moving or the snakehead node is too close to the snakebody node, the game will end.

These are all the contents of this article entitled "how to use Python+OpenCV to make a visual version of AI Snake Game". Thank you for reading! I believe you will gain a lot after reading this article. The editor will update different knowledge for you every day. If you want to learn more knowledge, please pay attention to the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report