【python】OpenCV—Greedy Snake

在这里插入图片描述

1、代码实现

import cv2
import numpy as np
from random import choice


class SnakePart:

    def __init__(self, front, x, y):
        self.front = front
        self.x = x
        self.y = y

    def move(self):
        # 跟随它前面的部分移动
        self.x = self.front.x
        self.y = self.front.y


class Head:  # snake 用来存它
    def __init__(self, direction, x, y):
        self.direction = direction
        self.x = x
        self.y = y

    def move(self):
        # 检查它当前的方向,并相应地移动
        if self.direction == 0:  # d 初始化的时候往右边跑
            self.x += 1
        elif self.direction == 1: # s 下
            self.y += 1
        elif self.direction == 2: # a 左
            self.x -= 1
        elif self.direction == 3: # w 上
            self.y -= 1


def 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 key


def 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 = 30
    # 改变速度使游戏进行得更快
    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))
            # 删除属于蛇的一部分的cell
            for part in snake:
                s.remove(part.x * BOARD_SIZE + part.y)

            # 从剩余的cell中随机挑选一个
            a = choice(s)
            applex = int(a / BOARD_SIZE)
            appley = a % BOARD_SIZE

            eaten = False

        # 制作并展示显示屏
        key = display()

        # 获取按下的键并相应地移动
        # 8和27是删除键和退出键
        # 方向键在OpenCV中很棘手。所以我们使用
        # 键'w', 'a','s','d'表示移动。
        # w = top, a = left, s = down, d = right

        if 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

        # 移动snake,头在最前面,头先动,所以逆序遍历
        for part in snake[::-1]:
            part.move()

        # 碰撞规则1、越界
        if head.x < 0 or head.x > BOARD_SIZE - 1 or head.y < 0 or head.y > BOARD_SIZE - 1:
            break

        # 碰撞规则2、吃到自己了
        for part in snake[1:]:
            if head.x == part.x and head.y == part.y:
                quit = True
                break

        if quit:
            break

        # 蛇在多帧中逐渐生长,头snake[-1]已经在吃下苹果的下一个位置了
        if grow > 0: 
            snake.append(SnakePart(snake[-1], subx, suby))
            grow -= 1

        # 当蛇吃苹果的时候,蛇就会长出来
        if applex == head.x and appley == head.y:
            subx = snake[-1].x
            suby = snake[-1].y
            eaten = True
            grow += GROWTH

在这里插入图片描述

2、涉及到的库——cv2.setWindowProperty

cv2.setWindowProperty 是 OpenCV 库中的一个函数,用于设置窗口的属性。这个函数允许你控制窗口的某些行为,比如窗口的标题、是否允许调整窗口大小等。这对于在使用 OpenCV 进行图像处理或视频处理时,创建更加友好和可控的用户界面非常有用。

函数原型如下:

cv2.setWindowProperty(winname, propid, propvalue)
  • winname:字符串类型,指定窗口的名称。这个名称是在创建窗口时通过 cv2.namedWindow() 或在显示图像时通过 cv2.imshow() 指定的。

  • propid:指定要改变的窗口属性的标识符。这是一个整数,OpenCV 提供了多个预定义的常量来表示不同的属性,例如 cv2.WND_PROP_FULLSCREEN(全屏模式)、cv2.WND_PROP_AUTOSIZE(自动调整窗口大小以匹配图像)等。

  • propvalue:根据 propid 的不同,这个参数可以是一个布尔值(如 True 或 False)、整数或其他类型,用于设置属性的新值。

一些常用的属性标识符包括:

  • cv2.WND_PROP_FULLSCREEN:设置窗口是否全屏。propvalue 为cv2.WINDOW_FULLSCREEN 时启用全屏,为 0 时禁用全屏。
  • cv2.WND_PROP_AUTOSIZE:设置窗口大小是否根据显示图像的大小自动调整。propvalue 为 cv2.WINDOW_AUTOSIZE 时启用自动调整,为 cv2.WINDOW_NORMAL 时允许用户调整窗口大小。

示例代码:

import cv2  
  
# 创建一个窗口  
cv2.namedWindow('Example Window', cv2.WINDOW_NORMAL)  
  
# 显示图像(这里假设你有一个名为 image 的图像变量)  
# cv2.imshow('Example Window', image)  
  
# 设置窗口为自动调整大小  
cv2.setWindowProperty('Example Window', cv2.WND_PROP_AUTOSIZE, cv2.WINDOW_AUTOSIZE)  
  
# 如果需要,可以设置为允许用户调整窗口大小  
# cv2.setWindowProperty('Example Window', cv2.WND_PROP_AUTOSIZE, cv2.WINDOW_NORMAL)  
  
# 注意:这里只是演示如何设置窗口属性,没有实际显示图像  
  
# 等待按键操作  
cv2.waitKey(0)  
cv2.destroyAllWindows()

请注意,由于 OpenCV 主要是一个计算机视觉库,而不是一个完整的 GUI 工具包,因此它的窗口管理功能相对有限。如果你需要更复杂的用户界面或窗口管理功能,可能需要考虑使用其他 GUI 库,如 Tkinter、PyQt 或 wxPython 等。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于Python编程中的贪吃蛇游戏,你可以使用Pygame库来实现。下面是一个简单的示例代码: ```python import pygame import random # 初始化游戏 pygame.init() # 定义窗口大小和颜色 win_width = 800 win_height = 600 win_color = (0, 0, 0) # 创建窗口 win = pygame.display.set_mode((win_width, win_height)) pygame.display.set_caption("Greedy Snake") # 定义贪吃蛇的颜色、大小和速度 snake_color = (0, 255, 0) snake_size = 20 snake_speed = 10 # 蛇的初始位置和移动方向 snake_x = win_width // 2 snake_y = win_height // 2 snake_dx = 0 snake_dy = 0 # 食物的颜色和初始位置 food_color = (255, 0, 0) food_size = 20 food_x = random.randint(0, win_width - food_size) food_y = random.randint(0, win_height - food_size) # 蛇的身体列表,初始长度为1 snake_body = [] snake_length = 1 # 游戏结束标志 game_over = False # 游戏主循环 while not game_over: # 处理事件 for event in pygame.event.get(): if event.type == pygame.QUIT: game_over = True # 获取键盘输入,控制蛇的移动方向 keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: snake_dx = -snake_speed snake_dy = 0 elif keys[pygame.K_RIGHT]: snake_dx = snake_speed snake_dy = 0 elif keys[pygame.K_UP]: snake_dx = 0 snake_dy = -snake_speed elif keys[pygame.K_DOWN]: snake_dx = 0 snake_dy = snake_speed # 更新蛇的位置 snake_x += snake_dx snake_y += snake_dy # 检测蛇是否吃到食物 if snake_x < food_x + food_size and snake_x + snake_size > food_x and \ snake_y < food_y + food_size and snake_y + snake_size > food_y: food_x = random.randint(0, win_width - food_size) food_y = random.randint(0, win_height - food_size) snake_length += 1 # 渲染游戏界面 win.fill(win_color) pygame.draw.rect(win, food_color, (food_x, food_y, food_size, food_size)) # 更新蛇的身体列表 snake_body.append((snake_x, snake_y)) if len(snake_body) > snake_length: del snake_body[0] # 检测蛇是否碰到自己或边界,游戏结束 if (snake_x, snake_y) in snake_body[:-1] or \ snake_x < 0 or snake_x >= win_width or \ snake_y < 0 or snake_y >= win_height: game_over = True # 绘制蛇的身体 for body_part in snake_body: pygame.draw.rect(win, snake_color, (body_part[0], body_part[1], snake_size, snake_size)) # 更新屏幕显示 pygame.display.flip() # 退出游戏 pygame.quit() ``` 你可以将以上代码保存为一个Python文件,然后运行它,即可开始玩贪吃蛇游戏。在游戏界面中,蛇的目标是吃到食物,每吃到一个食物,蛇的长度增加。当蛇碰到自己的身体或边界时,游戏结束。祝你编程愉快!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值